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