##// END OF EJS Templates
Add blank line before input prompt
Thomas Kluyver -
Show More
@@ -1,112 +1,113 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 pt_cli = None
32 pt_cli = None
33
33
34 def get_prompt_tokens(self, cli):
34 def get_prompt_tokens(self, cli):
35 return [
35 return [
36 (Token.Prompt, 'In ['),
36 (Token.Prompt, 'In ['),
37 (Token.PromptNum, str(self.execution_count)),
37 (Token.PromptNum, str(self.execution_count)),
38 (Token.Prompt, ']: '),
38 (Token.Prompt, ']: '),
39 ]
39 ]
40
40
41
41
42 def init_prompt_toolkit_cli(self):
42 def init_prompt_toolkit_cli(self):
43 kbmanager = KeyBindingManager.for_prompt()
43 kbmanager = KeyBindingManager.for_prompt()
44 @kbmanager.registry.add_binding(Keys.ControlJ) # Ctrl+J == Enter, seemingly
44 @kbmanager.registry.add_binding(Keys.ControlJ) # Ctrl+J == Enter, seemingly
45 def _(event):
45 def _(event):
46 b = event.current_buffer
46 b = event.current_buffer
47 if not b.document.on_last_line:
47 if not b.document.on_last_line:
48 b.newline()
48 b.newline()
49 return
49 return
50
50
51 status, indent = self.input_splitter.check_complete(b.document.text)
51 status, indent = self.input_splitter.check_complete(b.document.text)
52
52
53 if (status != 'incomplete') and b.accept_action.is_returnable:
53 if (status != 'incomplete') and b.accept_action.is_returnable:
54 b.accept_action.validate_and_handle(event.cli, b)
54 b.accept_action.validate_and_handle(event.cli, b)
55 else:
55 else:
56 b.insert_text('\n' + (' ' * (indent or 0)))
56 b.insert_text('\n' + (' ' * (indent or 0)))
57
57
58 @kbmanager.registry.add_binding(Keys.ControlC)
58 @kbmanager.registry.add_binding(Keys.ControlC)
59 def _(event):
59 def _(event):
60 event.current_buffer.reset()
60 event.current_buffer.reset()
61
61
62 # Pre-populate history from IPython's history database
62 # Pre-populate history from IPython's history database
63 history = InMemoryHistory()
63 history = InMemoryHistory()
64 last_cell = u""
64 last_cell = u""
65 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
65 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
66 include_latest=True):
66 include_latest=True):
67 # Ignore blank lines and consecutive duplicates
67 # Ignore blank lines and consecutive duplicates
68 cell = cell.rstrip()
68 cell = cell.rstrip()
69 if cell and (cell != last_cell):
69 if cell and (cell != last_cell):
70 history.append(cell)
70 history.append(cell)
71
71
72 style = PygmentsStyle.from_defaults({
72 style = PygmentsStyle.from_defaults({
73 Token.Prompt: '#009900',
73 Token.Prompt: '#009900',
74 Token.PromptNum: '#00ff00 bold',
74 Token.PromptNum: '#00ff00 bold',
75 Token.Number: '#007700',
75 Token.Number: '#007700',
76 Token.Operator: '#bbbbbb',
76 Token.Operator: '#bbbbbb',
77 })
77 })
78
78
79 app = create_prompt_application(multiline=True,
79 app = create_prompt_application(multiline=True,
80 lexer=PygmentsLexer(Python3Lexer),
80 lexer=PygmentsLexer(Python3Lexer),
81 get_prompt_tokens=self.get_prompt_tokens,
81 get_prompt_tokens=self.get_prompt_tokens,
82 key_bindings_registry=kbmanager.registry,
82 key_bindings_registry=kbmanager.registry,
83 history=history,
83 history=history,
84 completer=IPythonPTCompleter(self.Completer),
84 completer=IPythonPTCompleter(self.Completer),
85 style=style,
85 style=style,
86 )
86 )
87
87
88 self.pt_cli = CommandLineInterface(app)
88 self.pt_cli = CommandLineInterface(app)
89
89
90 def __init__(self, *args, **kwargs):
90 def __init__(self, *args, **kwargs):
91 super(PTInteractiveShell, self).__init__(*args, **kwargs)
91 super(PTInteractiveShell, self).__init__(*args, **kwargs)
92 self.init_prompt_toolkit_cli()
92 self.init_prompt_toolkit_cli()
93 self.keep_running = True
93 self.keep_running = True
94
94
95 def ask_exit(self):
95 def ask_exit(self):
96 self.keep_running = False
96 self.keep_running = False
97
97
98 def interact(self):
98 def interact(self):
99 while self.keep_running:
99 while self.keep_running:
100 try:
100 try:
101 document = self.pt_cli.run()
101 document = self.pt_cli.run()
102 except EOFError:
102 except EOFError:
103 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
103 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
104 self.ask_exit()
104 self.ask_exit()
105
105
106 else:
106 else:
107 if document:
107 if document:
108 self.run_cell(document.text, store_history=True)
108 self.run_cell(document.text, store_history=True)
109 print(self.separate_in, end='')
109
110
110
111
111 if __name__ == '__main__':
112 if __name__ == '__main__':
112 PTInteractiveShell.instance().interact()
113 PTInteractiveShell.instance().interact()
General Comments 0
You need to be logged in to leave comments. Login now