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