##// END OF EJS Templates
Pull shortcut definitions out to a separate module
Thomas Kluyver -
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, SEARCH_BUFFER, EditingMode
17 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
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