Show More
@@ -0,0 +1,165 b'' | |||
|
1 | import signal | |
|
2 | import sys | |
|
3 | ||
|
4 | from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER | |
|
5 | from prompt_toolkit.filters import (HasFocus, HasSelection, Condition, | |
|
6 | ViInsertMode, EmacsInsertMode, HasCompletions) | |
|
7 | from prompt_toolkit.filters.cli import ViMode | |
|
8 | from prompt_toolkit.keys import Keys | |
|
9 | from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline | |
|
10 | ||
|
11 | @Condition | |
|
12 | def cursor_in_leading_ws(cli): | |
|
13 | before = cli.application.buffer.document.current_line_before_cursor | |
|
14 | return (not before) or before.isspace() | |
|
15 | ||
|
16 | def register_ipython_shortcuts(registry, shell): | |
|
17 | """Set up the prompt_toolkit keyboard shortcuts for IPython""" | |
|
18 | insert_mode = ViInsertMode() | EmacsInsertMode() | |
|
19 | ||
|
20 | # Ctrl+J == Enter, seemingly | |
|
21 | registry.add_binding(Keys.ControlJ, | |
|
22 | filter=(HasFocus(DEFAULT_BUFFER) | |
|
23 | & ~HasSelection() | |
|
24 | & insert_mode | |
|
25 | ))(newline_or_execute_outer(shell)) | |
|
26 | ||
|
27 | registry.add_binding(Keys.ControlP, | |
|
28 | filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER) | |
|
29 | ))(previous_history_or_previous_completion) | |
|
30 | ||
|
31 | registry.add_binding(Keys.ControlN, | |
|
32 | filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER) | |
|
33 | ))(next_history_or_next_completion) | |
|
34 | ||
|
35 | registry.add_binding(Keys.ControlG, | |
|
36 | filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions() | |
|
37 | ))(dismiss_completion) | |
|
38 | ||
|
39 | registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER) | |
|
40 | )(reset_buffer) | |
|
41 | ||
|
42 | registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER) | |
|
43 | )(reset_search_buffer) | |
|
44 | ||
|
45 | supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) | |
|
46 | registry.add_binding(Keys.ControlZ, filter=supports_suspend | |
|
47 | )(suspend_to_bg) | |
|
48 | ||
|
49 | # Ctrl+I == Tab | |
|
50 | registry.add_binding(Keys.ControlI, | |
|
51 | filter=(HasFocus(DEFAULT_BUFFER) | |
|
52 | & ~HasSelection() | |
|
53 | & insert_mode | |
|
54 | & cursor_in_leading_ws | |
|
55 | ))(indent_buffer) | |
|
56 | ||
|
57 | if shell.display_completions == 'readlinelike': | |
|
58 | registry.add_binding(Keys.ControlI, | |
|
59 | filter=(HasFocus(DEFAULT_BUFFER) | |
|
60 | & ~HasSelection() | |
|
61 | & insert_mode | |
|
62 | & ~cursor_in_leading_ws | |
|
63 | ))(display_completions_like_readline) | |
|
64 | ||
|
65 | if sys.platform == 'win32': | |
|
66 | registry.add_binding(Keys.ControlV, | |
|
67 | filter=( | |
|
68 | HasFocus( | |
|
69 | DEFAULT_BUFFER) & ~ViMode() | |
|
70 | ))(win_paste) | |
|
71 | ||
|
72 | ||
|
73 | def newline_or_execute_outer(shell): | |
|
74 | def newline_or_execute(event): | |
|
75 | """When the user presses return, insert a newline or execute the code.""" | |
|
76 | b = event.current_buffer | |
|
77 | d = b.document | |
|
78 | ||
|
79 | if b.complete_state: | |
|
80 | cc = b.complete_state.current_completion | |
|
81 | if cc: | |
|
82 | b.apply_completion(cc) | |
|
83 | else: | |
|
84 | b.cancel_completion() | |
|
85 | return | |
|
86 | ||
|
87 | if not (d.on_last_line or d.cursor_position_row >= d.line_count | |
|
88 | - d.empty_line_count_at_the_end()): | |
|
89 | b.newline() | |
|
90 | return | |
|
91 | ||
|
92 | status, indent = shell.input_splitter.check_complete(d.text + '\n') | |
|
93 | ||
|
94 | if (status != 'incomplete') and b.accept_action.is_returnable: | |
|
95 | b.accept_action.validate_and_handle(event.cli, b) | |
|
96 | else: | |
|
97 | b.insert_text('\n' + (' ' * (indent or 0))) | |
|
98 | return newline_or_execute | |
|
99 | ||
|
100 | ||
|
101 | def previous_history_or_previous_completion(event): | |
|
102 | """ | |
|
103 | Control-P in vi edit mode on readline is history next, unlike default prompt toolkit. | |
|
104 | ||
|
105 | If completer is open this still select previous completion. | |
|
106 | """ | |
|
107 | event.current_buffer.auto_up() | |
|
108 | ||
|
109 | ||
|
110 | def next_history_or_next_completion(event): | |
|
111 | """ | |
|
112 | Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit. | |
|
113 | ||
|
114 | If completer is open this still select next completion. | |
|
115 | """ | |
|
116 | event.current_buffer.auto_down() | |
|
117 | ||
|
118 | ||
|
119 | def dismiss_completion(event): | |
|
120 | b = event.current_buffer | |
|
121 | if b.complete_state: | |
|
122 | b.cancel_completion() | |
|
123 | ||
|
124 | ||
|
125 | def reset_buffer(event): | |
|
126 | b = event.current_buffer | |
|
127 | if b.complete_state: | |
|
128 | b.cancel_completion() | |
|
129 | else: | |
|
130 | b.reset() | |
|
131 | ||
|
132 | ||
|
133 | def reset_search_buffer(event): | |
|
134 | if event.current_buffer.document.text: | |
|
135 | event.current_buffer.reset() | |
|
136 | else: | |
|
137 | event.cli.push_focus(DEFAULT_BUFFER) | |
|
138 | ||
|
139 | def suspend_to_bg(event): | |
|
140 | event.cli.suspend_to_background() | |
|
141 | ||
|
142 | def indent_buffer(event): | |
|
143 | event.current_buffer.insert_text(' ' * 4) | |
|
144 | ||
|
145 | ||
|
146 | ||
|
147 | ||
|
148 | if sys.platform == 'win32': | |
|
149 | from IPython.core.error import TryNext | |
|
150 | from IPython.lib.clipboard import (ClipboardEmpty, | |
|
151 | win32_clipboard_get, | |
|
152 | tkinter_clipboard_get) | |
|
153 | ||
|
154 | ||
|
155 | def win_paste(event): | |
|
156 | try: | |
|
157 | text = win32_clipboard_get() | |
|
158 | except TryNext: | |
|
159 | try: | |
|
160 | text = tkinter_clipboard_get() | |
|
161 | except (TryNext, ClipboardEmpty): | |
|
162 | return | |
|
163 | except ClipboardEmpty: | |
|
164 | return | |
|
165 | event.current_buffer.insert_text(text.replace('\t', ' ' * 4)) |
@@ -3,28 +3,22 b' from __future__ import print_function' | |||
|
3 | 3 | |
|
4 | 4 | import os |
|
5 | 5 | import sys |
|
6 | import signal | |
|
7 | 6 | from warnings import warn |
|
8 | 7 | |
|
9 | from IPython.core.error import TryNext | |
|
10 | 8 | from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC |
|
11 | 9 | from IPython.utils.py3compat import PY3, cast_unicode_py2, input |
|
12 | 10 | from IPython.utils.terminal import toggle_set_term_title, set_term_title |
|
13 | 11 | from IPython.utils.process import abbrev_cwd |
|
14 | 12 | from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum |
|
15 | 13 | |
|
16 |
from prompt_toolkit.enums import DEFAULT_BUFFER, |
|
|
17 |
from prompt_toolkit.filters import (HasFocus, |
|
|
18 | ViInsertMode, EmacsInsertMode, IsDone, HasCompletions) | |
|
19 | from prompt_toolkit.filters.cli import ViMode | |
|
14 | from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode | |
|
15 | from prompt_toolkit.filters import (HasFocus, Condition, IsDone) | |
|
20 | 16 | from prompt_toolkit.history import InMemoryHistory |
|
21 | 17 | from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout |
|
22 | 18 | from prompt_toolkit.interface import CommandLineInterface |
|
23 | 19 | from prompt_toolkit.key_binding.manager import KeyBindingManager |
|
24 | from prompt_toolkit.keys import Keys | |
|
25 | 20 | from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor |
|
26 | 21 | from prompt_toolkit.styles import PygmentsStyle, DynamicStyle |
|
27 | from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline | |
|
28 | 22 | |
|
29 | 23 | from pygments.styles import get_style_by_name, get_all_styles |
|
30 | 24 | from pygments.token import Token |
@@ -34,6 +28,7 b' from .magics import TerminalMagics' | |||
|
34 | 28 | from .pt_inputhooks import get_inputhook_func |
|
35 | 29 | from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook |
|
36 | 30 | from .ptutils import IPythonPTCompleter, IPythonPTLexer |
|
31 | from .shortcuts import register_ipython_shortcuts | |
|
37 | 32 | |
|
38 | 33 | DISPLAY_BANNER_DEPRECATED = object() |
|
39 | 34 | |
@@ -212,128 +207,9 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
212 | 207 | self.prompt_for_code = prompt |
|
213 | 208 | return |
|
214 | 209 | |
|
210 | # Set up keyboard shortcuts | |
|
215 | 211 | kbmanager = KeyBindingManager.for_prompt() |
|
216 | insert_mode = ViInsertMode() | EmacsInsertMode() | |
|
217 | # Ctrl+J == Enter, seemingly | |
|
218 | @kbmanager.registry.add_binding(Keys.ControlJ, | |
|
219 | filter=(HasFocus(DEFAULT_BUFFER) | |
|
220 | & ~HasSelection() | |
|
221 | & insert_mode | |
|
222 | )) | |
|
223 | def _(event): | |
|
224 | b = event.current_buffer | |
|
225 | d = b.document | |
|
226 | ||
|
227 | if b.complete_state: | |
|
228 | cc = b.complete_state.current_completion | |
|
229 | if cc: | |
|
230 | b.apply_completion(cc) | |
|
231 | else: | |
|
232 | b.cancel_completion() | |
|
233 | return | |
|
234 | ||
|
235 | if not (d.on_last_line or d.cursor_position_row >= d.line_count | |
|
236 | - d.empty_line_count_at_the_end()): | |
|
237 | b.newline() | |
|
238 | return | |
|
239 | ||
|
240 | status, indent = self.input_splitter.check_complete(d.text + '\n') | |
|
241 | ||
|
242 | if (status != 'incomplete') and b.accept_action.is_returnable: | |
|
243 | b.accept_action.validate_and_handle(event.cli, b) | |
|
244 | else: | |
|
245 | b.insert_text('\n' + (' ' * (indent or 0))) | |
|
246 | ||
|
247 | @kbmanager.registry.add_binding(Keys.ControlP, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER))) | |
|
248 | def _previous_history_or_previous_completion(event): | |
|
249 | """ | |
|
250 | Control-P in vi edit mode on readline is history next, unlike default prompt toolkit. | |
|
251 | ||
|
252 | If completer is open this still select previous completion. | |
|
253 | """ | |
|
254 | event.current_buffer.auto_up() | |
|
255 | ||
|
256 | @kbmanager.registry.add_binding(Keys.ControlN, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER))) | |
|
257 | def _next_history_or_next_completion(event): | |
|
258 | """ | |
|
259 | Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit. | |
|
260 | ||
|
261 | If completer is open this still select next completion. | |
|
262 | """ | |
|
263 | event.current_buffer.auto_down() | |
|
264 | ||
|
265 | @kbmanager.registry.add_binding(Keys.ControlG, filter=( | |
|
266 | HasFocus(DEFAULT_BUFFER) & HasCompletions() | |
|
267 | )) | |
|
268 | def _dismiss_completion(event): | |
|
269 | b = event.current_buffer | |
|
270 | if b.complete_state: | |
|
271 | b.cancel_completion() | |
|
272 | ||
|
273 | @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)) | |
|
274 | def _reset_buffer(event): | |
|
275 | b = event.current_buffer | |
|
276 | if b.complete_state: | |
|
277 | b.cancel_completion() | |
|
278 | else: | |
|
279 | b.reset() | |
|
280 | ||
|
281 | @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)) | |
|
282 | def _reset_search_buffer(event): | |
|
283 | if event.current_buffer.document.text: | |
|
284 | event.current_buffer.reset() | |
|
285 | else: | |
|
286 | event.cli.push_focus(DEFAULT_BUFFER) | |
|
287 | ||
|
288 | supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) | |
|
289 | ||
|
290 | @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend) | |
|
291 | def _suspend_to_bg(event): | |
|
292 | event.cli.suspend_to_background() | |
|
293 | ||
|
294 | @Condition | |
|
295 | def cursor_in_leading_ws(cli): | |
|
296 | before = cli.application.buffer.document.current_line_before_cursor | |
|
297 | return (not before) or before.isspace() | |
|
298 | ||
|
299 | # Ctrl+I == Tab | |
|
300 | @kbmanager.registry.add_binding(Keys.ControlI, | |
|
301 | filter=(HasFocus(DEFAULT_BUFFER) | |
|
302 | & ~HasSelection() | |
|
303 | & insert_mode | |
|
304 | & cursor_in_leading_ws | |
|
305 | )) | |
|
306 | def _indent_buffer(event): | |
|
307 | event.current_buffer.insert_text(' ' * 4) | |
|
308 | ||
|
309 | ||
|
310 | if self.display_completions == 'readlinelike': | |
|
311 | @kbmanager.registry.add_binding(Keys.ControlI, | |
|
312 | filter=(HasFocus(DEFAULT_BUFFER) | |
|
313 | & ~HasSelection() | |
|
314 | & insert_mode | |
|
315 | & ~cursor_in_leading_ws | |
|
316 | )) | |
|
317 | def _disaply_compl(ev): | |
|
318 | display_completions_like_readline(ev) | |
|
319 | ||
|
320 | ||
|
321 | if sys.platform == 'win32': | |
|
322 | from IPython.lib.clipboard import (ClipboardEmpty, | |
|
323 | win32_clipboard_get, tkinter_clipboard_get) | |
|
324 | @kbmanager.registry.add_binding(Keys.ControlV, | |
|
325 | filter=(HasFocus(DEFAULT_BUFFER) & ~ViMode())) | |
|
326 | def _paste(event): | |
|
327 | try: | |
|
328 | text = win32_clipboard_get() | |
|
329 | except TryNext: | |
|
330 | try: | |
|
331 | text = tkinter_clipboard_get() | |
|
332 | except (TryNext, ClipboardEmpty): | |
|
333 | return | |
|
334 | except ClipboardEmpty: | |
|
335 | return | |
|
336 | event.current_buffer.insert_text(text.replace('\t', ' ' * 4)) | |
|
212 | register_ipython_shortcuts(kbmanager.registry, self) | |
|
337 | 213 | |
|
338 | 214 | # Pre-populate history from IPython's history database |
|
339 | 215 | history = InMemoryHistory() |
General Comments 0
You need to be logged in to leave comments.
Login now