##// 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 import os
4 import os
5 import sys
5 import sys
6 import signal
7 from warnings import warn
6 from warnings import warn
8
7
9 from IPython.core.error import TryNext
10 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
8 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
11 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
9 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
12 from IPython.utils.terminal import toggle_set_term_title, set_term_title
10 from IPython.utils.terminal import toggle_set_term_title, set_term_title
13 from IPython.utils.process import abbrev_cwd
11 from IPython.utils.process import abbrev_cwd
14 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum
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
14 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
17 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
15 from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
18 ViInsertMode, EmacsInsertMode, IsDone, HasCompletions)
19 from prompt_toolkit.filters.cli import ViMode
20 from prompt_toolkit.history import InMemoryHistory
16 from prompt_toolkit.history import InMemoryHistory
21 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
17 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
22 from prompt_toolkit.interface import CommandLineInterface
18 from prompt_toolkit.interface import CommandLineInterface
23 from prompt_toolkit.key_binding.manager import KeyBindingManager
19 from prompt_toolkit.key_binding.manager import KeyBindingManager
24 from prompt_toolkit.keys import Keys
25 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
20 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
26 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
21 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
27 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
28
22
29 from pygments.styles import get_style_by_name, get_all_styles
23 from pygments.styles import get_style_by_name, get_all_styles
30 from pygments.token import Token
24 from pygments.token import Token
@@ -34,6 +28,7 b' from .magics import TerminalMagics'
34 from .pt_inputhooks import get_inputhook_func
28 from .pt_inputhooks import get_inputhook_func
35 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
29 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
36 from .ptutils import IPythonPTCompleter, IPythonPTLexer
30 from .ptutils import IPythonPTCompleter, IPythonPTLexer
31 from .shortcuts import register_ipython_shortcuts
37
32
38 DISPLAY_BANNER_DEPRECATED = object()
33 DISPLAY_BANNER_DEPRECATED = object()
39
34
@@ -212,128 +207,9 b' class TerminalInteractiveShell(InteractiveShell):'
212 self.prompt_for_code = prompt
207 self.prompt_for_code = prompt
213 return
208 return
214
209
210 # Set up keyboard shortcuts
215 kbmanager = KeyBindingManager.for_prompt()
211 kbmanager = KeyBindingManager.for_prompt()
216 insert_mode = ViInsertMode() | EmacsInsertMode()
212 register_ipython_shortcuts(kbmanager.registry, self)
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))
337
213
338 # Pre-populate history from IPython's history database
214 # Pre-populate history from IPython's history database
339 history = InMemoryHistory()
215 history = InMemoryHistory()
General Comments 0
You need to be logged in to leave comments. Login now