Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/basic.py: 7%
163 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
1# pylint: disable=function-redefined
2from __future__ import annotations
4from prompt_toolkit.application.current import get_app
5from prompt_toolkit.filters import (
6 Condition,
7 emacs_insert_mode,
8 has_selection,
9 in_paste_mode,
10 is_multiline,
11 vi_insert_mode,
12)
13from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent
14from prompt_toolkit.keys import Keys
16from ..key_bindings import KeyBindings
17from .named_commands import get_by_name
19__all__ = [
20 "load_basic_bindings",
21]
23E = KeyPressEvent
26def if_no_repeat(event: E) -> bool:
27 """Callable that returns True when the previous event was delivered to
28 another handler."""
29 return not event.is_repeat
32def load_basic_bindings() -> KeyBindings:
33 key_bindings = KeyBindings()
34 insert_mode = vi_insert_mode | emacs_insert_mode
35 handle = key_bindings.add
37 @handle("c-a")
38 @handle("c-b")
39 @handle("c-c")
40 @handle("c-d")
41 @handle("c-e")
42 @handle("c-f")
43 @handle("c-g")
44 @handle("c-h")
45 @handle("c-i")
46 @handle("c-j")
47 @handle("c-k")
48 @handle("c-l")
49 @handle("c-m")
50 @handle("c-n")
51 @handle("c-o")
52 @handle("c-p")
53 @handle("c-q")
54 @handle("c-r")
55 @handle("c-s")
56 @handle("c-t")
57 @handle("c-u")
58 @handle("c-v")
59 @handle("c-w")
60 @handle("c-x")
61 @handle("c-y")
62 @handle("c-z")
63 @handle("f1")
64 @handle("f2")
65 @handle("f3")
66 @handle("f4")
67 @handle("f5")
68 @handle("f6")
69 @handle("f7")
70 @handle("f8")
71 @handle("f9")
72 @handle("f10")
73 @handle("f11")
74 @handle("f12")
75 @handle("f13")
76 @handle("f14")
77 @handle("f15")
78 @handle("f16")
79 @handle("f17")
80 @handle("f18")
81 @handle("f19")
82 @handle("f20")
83 @handle("f21")
84 @handle("f22")
85 @handle("f23")
86 @handle("f24")
87 @handle("c-@") # Also c-space.
88 @handle("c-\\")
89 @handle("c-]")
90 @handle("c-^")
91 @handle("c-_")
92 @handle("backspace")
93 @handle("up")
94 @handle("down")
95 @handle("right")
96 @handle("left")
97 @handle("s-up")
98 @handle("s-down")
99 @handle("s-right")
100 @handle("s-left")
101 @handle("home")
102 @handle("end")
103 @handle("s-home")
104 @handle("s-end")
105 @handle("delete")
106 @handle("s-delete")
107 @handle("c-delete")
108 @handle("pageup")
109 @handle("pagedown")
110 @handle("s-tab")
111 @handle("tab")
112 @handle("c-s-left")
113 @handle("c-s-right")
114 @handle("c-s-home")
115 @handle("c-s-end")
116 @handle("c-left")
117 @handle("c-right")
118 @handle("c-up")
119 @handle("c-down")
120 @handle("c-home")
121 @handle("c-end")
122 @handle("insert")
123 @handle("s-insert")
124 @handle("c-insert")
125 @handle("<sigint>")
126 @handle(Keys.Ignore)
127 def _ignore(event: E) -> None:
128 """
129 First, for any of these keys, Don't do anything by default. Also don't
130 catch them in the 'Any' handler which will insert them as data.
132 If people want to insert these characters as a literal, they can always
133 do by doing a quoted insert. (ControlQ in emacs mode, ControlV in Vi
134 mode.)
135 """
136 pass
138 # Readline-style bindings.
139 handle("home")(get_by_name("beginning-of-line"))
140 handle("end")(get_by_name("end-of-line"))
141 handle("left")(get_by_name("backward-char"))
142 handle("right")(get_by_name("forward-char"))
143 handle("c-up")(get_by_name("previous-history"))
144 handle("c-down")(get_by_name("next-history"))
145 handle("c-l")(get_by_name("clear-screen"))
147 handle("c-k", filter=insert_mode)(get_by_name("kill-line"))
148 handle("c-u", filter=insert_mode)(get_by_name("unix-line-discard"))
149 handle("backspace", filter=insert_mode, save_before=if_no_repeat)(
150 get_by_name("backward-delete-char")
151 )
152 handle("delete", filter=insert_mode, save_before=if_no_repeat)(
153 get_by_name("delete-char")
154 )
155 handle("c-delete", filter=insert_mode, save_before=if_no_repeat)(
156 get_by_name("delete-char")
157 )
158 handle(Keys.Any, filter=insert_mode, save_before=if_no_repeat)(
159 get_by_name("self-insert")
160 )
161 handle("c-t", filter=insert_mode)(get_by_name("transpose-chars"))
162 handle("c-i", filter=insert_mode)(get_by_name("menu-complete"))
163 handle("s-tab", filter=insert_mode)(get_by_name("menu-complete-backward"))
165 # Control-W should delete, using whitespace as separator, while M-Del
166 # should delete using [^a-zA-Z0-9] as a boundary.
167 handle("c-w", filter=insert_mode)(get_by_name("unix-word-rubout"))
169 handle("pageup", filter=~has_selection)(get_by_name("previous-history"))
170 handle("pagedown", filter=~has_selection)(get_by_name("next-history"))
172 # CTRL keys.
174 @Condition
175 def has_text_before_cursor() -> bool:
176 return bool(get_app().current_buffer.text)
178 handle("c-d", filter=has_text_before_cursor & insert_mode)(
179 get_by_name("delete-char")
180 )
182 @handle("enter", filter=insert_mode & is_multiline)
183 def _newline(event: E) -> None:
184 """
185 Newline (in case of multiline input.
186 """
187 event.current_buffer.newline(copy_margin=not in_paste_mode())
189 @handle("c-j")
190 def _newline2(event: E) -> None:
191 r"""
192 By default, handle \n as if it were a \r (enter).
193 (It appears that some terminals send \n instead of \r when pressing
194 enter. - at least the Linux subsystem for Windows.)
195 """
196 event.key_processor.feed(KeyPress(Keys.ControlM, "\r"), first=True)
198 # Delete the word before the cursor.
200 @handle("up")
201 def _go_up(event: E) -> None:
202 event.current_buffer.auto_up(count=event.arg)
204 @handle("down")
205 def _go_down(event: E) -> None:
206 event.current_buffer.auto_down(count=event.arg)
208 @handle("delete", filter=has_selection)
209 def _cut(event: E) -> None:
210 data = event.current_buffer.cut_selection()
211 event.app.clipboard.set_data(data)
213 # Global bindings.
215 @handle("c-z")
216 def _insert_ctrl_z(event: E) -> None:
217 """
218 By default, control-Z should literally insert Ctrl-Z.
219 (Ansi Ctrl-Z, code 26 in MSDOS means End-Of-File.
220 In a Python REPL for instance, it's possible to type
221 Control-Z followed by enter to quit.)
223 When the system bindings are loaded and suspend-to-background is
224 supported, that will override this binding.
225 """
226 event.current_buffer.insert_text(event.data)
228 @handle(Keys.BracketedPaste)
229 def _paste(event: E) -> None:
230 """
231 Pasting from clipboard.
232 """
233 data = event.data
235 # Be sure to use \n as line ending.
236 # Some terminals (Like iTerm2) seem to paste \r\n line endings in a
237 # bracketed paste. See: https://github.com/ipython/ipython/issues/9737
238 data = data.replace("\r\n", "\n")
239 data = data.replace("\r", "\n")
241 event.current_buffer.insert_text(data)
243 @Condition
244 def in_quoted_insert() -> bool:
245 return get_app().quoted_insert
247 @handle(Keys.Any, filter=in_quoted_insert, eager=True)
248 def _insert_text(event: E) -> None:
249 """
250 Handle quoted insert.
251 """
252 event.current_buffer.insert_text(event.data, overwrite=False)
253 event.app.quoted_insert = False
255 return key_bindings