##// END OF EJS Templates
Move printing blank line to before each input prompt
Thomas Kluyver -
Show More
@@ -1,115 +1,115 b''
1 from IPython.core.interactiveshell import InteractiveShell
1 from IPython.core.interactiveshell import InteractiveShell
2
2
3 from prompt_toolkit.completion import Completer, Completion
3 from prompt_toolkit.completion import Completer, Completion
4 from prompt_toolkit.history import InMemoryHistory
4 from prompt_toolkit.history import InMemoryHistory
5 from prompt_toolkit.shortcuts import create_prompt_application
5 from prompt_toolkit.shortcuts import create_prompt_application
6 from prompt_toolkit.interface import CommandLineInterface
6 from prompt_toolkit.interface import CommandLineInterface
7 from prompt_toolkit.key_binding.manager import KeyBindingManager
7 from prompt_toolkit.key_binding.manager import KeyBindingManager
8 from prompt_toolkit.keys import Keys
8 from prompt_toolkit.keys import Keys
9 from prompt_toolkit.layout.lexers import PygmentsLexer
9 from prompt_toolkit.layout.lexers import PygmentsLexer
10 from prompt_toolkit.styles import PygmentsStyle
10 from prompt_toolkit.styles import PygmentsStyle
11
11
12 from pygments.lexers import Python3Lexer
12 from pygments.lexers import Python3Lexer
13 from pygments.token import Token
13 from pygments.token import Token
14
14
15
15
16 class IPythonPTCompleter(Completer):
16 class IPythonPTCompleter(Completer):
17 """Adaptor to provide IPython completions to prompt_toolkit"""
17 """Adaptor to provide IPython completions to prompt_toolkit"""
18 def __init__(self, ipy_completer):
18 def __init__(self, ipy_completer):
19 self.ipy_completer = ipy_completer
19 self.ipy_completer = ipy_completer
20
20
21 def get_completions(self, document, complete_event):
21 def get_completions(self, document, complete_event):
22 used, matches = self.ipy_completer.complete(
22 used, matches = self.ipy_completer.complete(
23 line_buffer=document.current_line,
23 line_buffer=document.current_line,
24 cursor_pos=document.cursor_position_col
24 cursor_pos=document.cursor_position_col
25 )
25 )
26 start_pos = -len(used)
26 start_pos = -len(used)
27 for m in matches:
27 for m in matches:
28 yield Completion(m, start_position=start_pos)
28 yield Completion(m, start_position=start_pos)
29
29
30
30
31 class PTInteractiveShell(InteractiveShell):
31 class PTInteractiveShell(InteractiveShell):
32 colors_force = True
32 colors_force = True
33
33
34 pt_cli = None
34 pt_cli = None
35
35
36 def get_prompt_tokens(self, cli):
36 def get_prompt_tokens(self, cli):
37 return [
37 return [
38 (Token.Prompt, 'In ['),
38 (Token.Prompt, 'In ['),
39 (Token.PromptNum, str(self.execution_count)),
39 (Token.PromptNum, str(self.execution_count)),
40 (Token.Prompt, ']: '),
40 (Token.Prompt, ']: '),
41 ]
41 ]
42
42
43
43
44 def init_prompt_toolkit_cli(self):
44 def init_prompt_toolkit_cli(self):
45 kbmanager = KeyBindingManager.for_prompt()
45 kbmanager = KeyBindingManager.for_prompt()
46 @kbmanager.registry.add_binding(Keys.ControlJ) # Ctrl+J == Enter, seemingly
46 @kbmanager.registry.add_binding(Keys.ControlJ) # Ctrl+J == Enter, seemingly
47 def _(event):
47 def _(event):
48 b = event.current_buffer
48 b = event.current_buffer
49 if not b.document.on_last_line:
49 if not b.document.on_last_line:
50 b.newline()
50 b.newline()
51 return
51 return
52
52
53 status, indent = self.input_splitter.check_complete(b.document.text)
53 status, indent = self.input_splitter.check_complete(b.document.text)
54
54
55 if (status != 'incomplete') and b.accept_action.is_returnable:
55 if (status != 'incomplete') and b.accept_action.is_returnable:
56 b.accept_action.validate_and_handle(event.cli, b)
56 b.accept_action.validate_and_handle(event.cli, b)
57 else:
57 else:
58 b.insert_text('\n' + (' ' * (indent or 0)))
58 b.insert_text('\n' + (' ' * (indent or 0)))
59
59
60 @kbmanager.registry.add_binding(Keys.ControlC)
60 @kbmanager.registry.add_binding(Keys.ControlC)
61 def _(event):
61 def _(event):
62 event.current_buffer.reset()
62 event.current_buffer.reset()
63
63
64 # Pre-populate history from IPython's history database
64 # Pre-populate history from IPython's history database
65 history = InMemoryHistory()
65 history = InMemoryHistory()
66 last_cell = u""
66 last_cell = u""
67 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
67 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
68 include_latest=True):
68 include_latest=True):
69 # Ignore blank lines and consecutive duplicates
69 # Ignore blank lines and consecutive duplicates
70 cell = cell.rstrip()
70 cell = cell.rstrip()
71 if cell and (cell != last_cell):
71 if cell and (cell != last_cell):
72 history.append(cell)
72 history.append(cell)
73
73
74 style = PygmentsStyle.from_defaults({
74 style = PygmentsStyle.from_defaults({
75 Token.Prompt: '#009900',
75 Token.Prompt: '#009900',
76 Token.PromptNum: '#00ff00 bold',
76 Token.PromptNum: '#00ff00 bold',
77 Token.Number: '#007700',
77 Token.Number: '#007700',
78 Token.Operator: '#bbbbbb',
78 Token.Operator: '#bbbbbb',
79 })
79 })
80
80
81 app = create_prompt_application(multiline=True,
81 app = create_prompt_application(multiline=True,
82 lexer=PygmentsLexer(Python3Lexer),
82 lexer=PygmentsLexer(Python3Lexer),
83 get_prompt_tokens=self.get_prompt_tokens,
83 get_prompt_tokens=self.get_prompt_tokens,
84 key_bindings_registry=kbmanager.registry,
84 key_bindings_registry=kbmanager.registry,
85 history=history,
85 history=history,
86 completer=IPythonPTCompleter(self.Completer),
86 completer=IPythonPTCompleter(self.Completer),
87 style=style,
87 style=style,
88 )
88 )
89
89
90 self.pt_cli = CommandLineInterface(app)
90 self.pt_cli = CommandLineInterface(app)
91
91
92 def __init__(self, *args, **kwargs):
92 def __init__(self, *args, **kwargs):
93 super(PTInteractiveShell, self).__init__(*args, **kwargs)
93 super(PTInteractiveShell, self).__init__(*args, **kwargs)
94 self.init_prompt_toolkit_cli()
94 self.init_prompt_toolkit_cli()
95 self.keep_running = True
95 self.keep_running = True
96
96
97 def ask_exit(self):
97 def ask_exit(self):
98 self.keep_running = False
98 self.keep_running = False
99
99
100 def interact(self):
100 def interact(self):
101 while self.keep_running:
101 while self.keep_running:
102 print(self.separate_in, end='')
102 try:
103 try:
103 document = self.pt_cli.run()
104 document = self.pt_cli.run()
104 except EOFError:
105 except EOFError:
105 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
106 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
106 self.ask_exit()
107 self.ask_exit()
107
108
108 else:
109 else:
109 if document:
110 if document:
110 self.run_cell(document.text, store_history=True)
111 self.run_cell(document.text, store_history=True)
111 print(self.separate_in, end='')
112
112
113
113
114 if __name__ == '__main__':
114 if __name__ == '__main__':
115 PTInteractiveShell.instance().interact()
115 PTInteractiveShell.instance().interact()
General Comments 0
You need to be logged in to leave comments. Login now