##// END OF EJS Templates
filter ControlO insertion on EmacsInsertMode
Gil Forsyth -
Show More
@@ -1,185 +1,185 b''
1 import signal
1 import signal
2 import sys
2 import sys
3
3
4 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
4 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
5 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
5 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
6 ViInsertMode, EmacsInsertMode, HasCompletions)
6 ViInsertMode, EmacsInsertMode, HasCompletions)
7 from prompt_toolkit.filters.cli import ViMode
7 from prompt_toolkit.filters.cli import ViMode
8 from prompt_toolkit.keys import Keys
8 from prompt_toolkit.keys import Keys
9 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
9 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
10
10
11 from IPython.utils.decorators import undoc
11 from IPython.utils.decorators import undoc
12
12
13 @Condition
13 @Condition
14 def cursor_in_leading_ws(cli):
14 def cursor_in_leading_ws(cli):
15 before = cli.application.buffer.document.current_line_before_cursor
15 before = cli.application.buffer.document.current_line_before_cursor
16 return (not before) or before.isspace()
16 return (not before) or before.isspace()
17
17
18 def register_ipython_shortcuts(registry, shell):
18 def register_ipython_shortcuts(registry, shell):
19 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
19 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
20 insert_mode = ViInsertMode() | EmacsInsertMode()
20 insert_mode = ViInsertMode() | EmacsInsertMode()
21
21
22 # Ctrl+J == Enter, seemingly
22 # Ctrl+J == Enter, seemingly
23 registry.add_binding(Keys.ControlJ,
23 registry.add_binding(Keys.ControlJ,
24 filter=(HasFocus(DEFAULT_BUFFER)
24 filter=(HasFocus(DEFAULT_BUFFER)
25 & ~HasSelection()
25 & ~HasSelection()
26 & insert_mode
26 & insert_mode
27 ))(newline_or_execute_outer(shell))
27 ))(newline_or_execute_outer(shell))
28
28
29 registry.add_binding(Keys.ControlP,
29 registry.add_binding(Keys.ControlP,
30 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
30 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
31 ))(previous_history_or_previous_completion)
31 ))(previous_history_or_previous_completion)
32
32
33 registry.add_binding(Keys.ControlN,
33 registry.add_binding(Keys.ControlN,
34 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
34 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
35 ))(next_history_or_next_completion)
35 ))(next_history_or_next_completion)
36
36
37 registry.add_binding(Keys.ControlG,
37 registry.add_binding(Keys.ControlG,
38 filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
38 filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
39 ))(dismiss_completion)
39 ))(dismiss_completion)
40
40
41 registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
41 registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
42 )(reset_buffer)
42 )(reset_buffer)
43
43
44 registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
44 registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
45 )(reset_search_buffer)
45 )(reset_search_buffer)
46
46
47 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
47 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
48 registry.add_binding(Keys.ControlZ, filter=supports_suspend
48 registry.add_binding(Keys.ControlZ, filter=supports_suspend
49 )(suspend_to_bg)
49 )(suspend_to_bg)
50
50
51 # Ctrl+I == Tab
51 # Ctrl+I == Tab
52 registry.add_binding(Keys.ControlI,
52 registry.add_binding(Keys.ControlI,
53 filter=(HasFocus(DEFAULT_BUFFER)
53 filter=(HasFocus(DEFAULT_BUFFER)
54 & ~HasSelection()
54 & ~HasSelection()
55 & insert_mode
55 & insert_mode
56 & cursor_in_leading_ws
56 & cursor_in_leading_ws
57 ))(indent_buffer)
57 ))(indent_buffer)
58
58
59 registry.add_binding(Keys.ControlO,
59 registry.add_binding(Keys.ControlO,
60 filter=(HasFocus(DEFAULT_BUFFER)
60 filter=(HasFocus(DEFAULT_BUFFER)
61 & insert_mode))(newline_with_copy_margin)
61 & EmacsInsertMode()))(newline_with_copy_margin)
62
62
63 if shell.display_completions == 'readlinelike':
63 if shell.display_completions == 'readlinelike':
64 registry.add_binding(Keys.ControlI,
64 registry.add_binding(Keys.ControlI,
65 filter=(HasFocus(DEFAULT_BUFFER)
65 filter=(HasFocus(DEFAULT_BUFFER)
66 & ~HasSelection()
66 & ~HasSelection()
67 & insert_mode
67 & insert_mode
68 & ~cursor_in_leading_ws
68 & ~cursor_in_leading_ws
69 ))(display_completions_like_readline)
69 ))(display_completions_like_readline)
70
70
71 if sys.platform == 'win32':
71 if sys.platform == 'win32':
72 registry.add_binding(Keys.ControlV,
72 registry.add_binding(Keys.ControlV,
73 filter=(
73 filter=(
74 HasFocus(
74 HasFocus(
75 DEFAULT_BUFFER) & ~ViMode()
75 DEFAULT_BUFFER) & ~ViMode()
76 ))(win_paste)
76 ))(win_paste)
77
77
78
78
79 def newline_or_execute_outer(shell):
79 def newline_or_execute_outer(shell):
80 def newline_or_execute(event):
80 def newline_or_execute(event):
81 """When the user presses return, insert a newline or execute the code."""
81 """When the user presses return, insert a newline or execute the code."""
82 b = event.current_buffer
82 b = event.current_buffer
83 d = b.document
83 d = b.document
84
84
85 if b.complete_state:
85 if b.complete_state:
86 cc = b.complete_state.current_completion
86 cc = b.complete_state.current_completion
87 if cc:
87 if cc:
88 b.apply_completion(cc)
88 b.apply_completion(cc)
89 else:
89 else:
90 b.cancel_completion()
90 b.cancel_completion()
91 return
91 return
92
92
93 if not (d.on_last_line or d.cursor_position_row >= d.line_count
93 if not (d.on_last_line or d.cursor_position_row >= d.line_count
94 - d.empty_line_count_at_the_end()):
94 - d.empty_line_count_at_the_end()):
95 b.newline()
95 b.newline()
96 return
96 return
97
97
98 status, indent = shell.input_splitter.check_complete(d.text + '\n')
98 status, indent = shell.input_splitter.check_complete(d.text + '\n')
99
99
100 if (status != 'incomplete') and b.accept_action.is_returnable:
100 if (status != 'incomplete') and b.accept_action.is_returnable:
101 b.accept_action.validate_and_handle(event.cli, b)
101 b.accept_action.validate_and_handle(event.cli, b)
102 else:
102 else:
103 b.insert_text('\n' + (' ' * (indent or 0)))
103 b.insert_text('\n' + (' ' * (indent or 0)))
104 return newline_or_execute
104 return newline_or_execute
105
105
106
106
107 def previous_history_or_previous_completion(event):
107 def previous_history_or_previous_completion(event):
108 """
108 """
109 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
109 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
110
110
111 If completer is open this still select previous completion.
111 If completer is open this still select previous completion.
112 """
112 """
113 event.current_buffer.auto_up()
113 event.current_buffer.auto_up()
114
114
115
115
116 def next_history_or_next_completion(event):
116 def next_history_or_next_completion(event):
117 """
117 """
118 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
118 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
119
119
120 If completer is open this still select next completion.
120 If completer is open this still select next completion.
121 """
121 """
122 event.current_buffer.auto_down()
122 event.current_buffer.auto_down()
123
123
124
124
125 def dismiss_completion(event):
125 def dismiss_completion(event):
126 b = event.current_buffer
126 b = event.current_buffer
127 if b.complete_state:
127 if b.complete_state:
128 b.cancel_completion()
128 b.cancel_completion()
129
129
130
130
131 def reset_buffer(event):
131 def reset_buffer(event):
132 b = event.current_buffer
132 b = event.current_buffer
133 if b.complete_state:
133 if b.complete_state:
134 b.cancel_completion()
134 b.cancel_completion()
135 else:
135 else:
136 b.reset()
136 b.reset()
137
137
138
138
139 def reset_search_buffer(event):
139 def reset_search_buffer(event):
140 if event.current_buffer.document.text:
140 if event.current_buffer.document.text:
141 event.current_buffer.reset()
141 event.current_buffer.reset()
142 else:
142 else:
143 event.cli.push_focus(DEFAULT_BUFFER)
143 event.cli.push_focus(DEFAULT_BUFFER)
144
144
145 def suspend_to_bg(event):
145 def suspend_to_bg(event):
146 event.cli.suspend_to_background()
146 event.cli.suspend_to_background()
147
147
148 def indent_buffer(event):
148 def indent_buffer(event):
149 event.current_buffer.insert_text(' ' * 4)
149 event.current_buffer.insert_text(' ' * 4)
150
150
151 def newline_with_copy_margin(event):
151 def newline_with_copy_margin(event):
152 """
152 """
153 Preserve margin and cursor position when using
153 Preserve margin and cursor position when using
154 Control-O to insert a newline in EMACS mode
154 Control-O to insert a newline in EMACS mode
155 """
155 """
156 b = event.current_buffer
156 b = event.current_buffer
157 cursor_start_pos = b.document.cursor_position_col
157 cursor_start_pos = b.document.cursor_position_col
158 b.newline(copy_margin=True)
158 b.newline(copy_margin=True)
159 b.cursor_up(count=1)
159 b.cursor_up(count=1)
160 cursor_end_pos = b.document.cursor_position_col
160 cursor_end_pos = b.document.cursor_position_col
161 if cursor_start_pos != cursor_end_pos:
161 if cursor_start_pos != cursor_end_pos:
162 pos_diff = cursor_start_pos - cursor_end_pos
162 pos_diff = cursor_start_pos - cursor_end_pos
163 b.cursor_right(count=pos_diff)
163 b.cursor_right(count=pos_diff)
164
164
165
165
166
166
167
167
168 if sys.platform == 'win32':
168 if sys.platform == 'win32':
169 from IPython.core.error import TryNext
169 from IPython.core.error import TryNext
170 from IPython.lib.clipboard import (ClipboardEmpty,
170 from IPython.lib.clipboard import (ClipboardEmpty,
171 win32_clipboard_get,
171 win32_clipboard_get,
172 tkinter_clipboard_get)
172 tkinter_clipboard_get)
173
173
174 @undoc
174 @undoc
175 def win_paste(event):
175 def win_paste(event):
176 try:
176 try:
177 text = win32_clipboard_get()
177 text = win32_clipboard_get()
178 except TryNext:
178 except TryNext:
179 try:
179 try:
180 text = tkinter_clipboard_get()
180 text = tkinter_clipboard_get()
181 except (TryNext, ClipboardEmpty):
181 except (TryNext, ClipboardEmpty):
182 return
182 return
183 except ClipboardEmpty:
183 except ClipboardEmpty:
184 return
184 return
185 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
185 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
General Comments 0
You need to be logged in to leave comments. Login now