Skip to content

Commit c3b2aee

Browse files
committed
provide option for tab to apply completion
improve completion when completion menu is not showing improve apply completion with enter improve completion with enter in ptpython
1 parent 86e1571 commit c3b2aee

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

Diff for: ptpython/key_bindings.py

+86
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from jedi import Interpreter
2+
from prompt_toolkit.completion import CompleteEvent
13
from prompt_toolkit.application import get_app
24
from prompt_toolkit.document import Document
35
from prompt_toolkit.enums import DEFAULT_BUFFER
@@ -6,10 +8,13 @@
68
emacs_insert_mode,
79
emacs_mode,
810
has_focus,
11+
has_completions,
12+
completion_is_selected,
913
has_selection,
1014
vi_insert_mode,
1115
)
1216
from prompt_toolkit.key_binding import KeyBindings
17+
from prompt_toolkit.key_binding.key_processor import KeyPress
1318
from prompt_toolkit.keys import Keys
1419

1520
from .utils import document_is_multiline_python
@@ -201,6 +206,87 @@ def _(event):
201206
" Abort when Control-C has been pressed. "
202207
event.app.exit(exception=KeyboardInterrupt, style="class:aborting")
203208

209+
def is_callable(text=""):
210+
completions = Interpreter(text, [locals()]).complete()
211+
match = next((i for i in completions if i.name == text), None)
212+
return match.type in ("class", "function") if match else None
213+
214+
@Condition
215+
def tac():
216+
return python_input.tab_apply_completion
217+
218+
insert_mode = vi_insert_mode | emacs_insert_mode
219+
focused_insert = insert_mode & has_focus(DEFAULT_BUFFER)
220+
shown_not_selected = has_completions & ~completion_is_selected
221+
alt_enter = [KeyPress(Keys.Escape), KeyPress(Keys.Enter)]
222+
223+
# apply selected completion
224+
@handle('c-j', filter=focused_insert & completion_is_selected & tac)
225+
@handle("enter", filter=focused_insert & completion_is_selected & tac)
226+
def _(event):
227+
b = event.current_buffer
228+
text = b.text
229+
completion = b.complete_state.current_completion
230+
if is_callable(completion.text):
231+
b.insert_text("()")
232+
b.cursor_left()
233+
if text == b.text:
234+
event.cli.key_processor.feed_multiple(alt_enter)
235+
236+
# apply first completion option when completion menu is showing
237+
@handle('c-j', filter=focused_insert & shown_not_selected & tac)
238+
@handle("enter", filter=focused_insert & shown_not_selected & tac)
239+
def _(event):
240+
b = event.current_buffer
241+
text = b.text
242+
b.complete_next()
243+
completion = b.complete_state.current_completion
244+
b.apply_completion(completion)
245+
if is_callable(completion.text):
246+
b.insert_text("()")
247+
b.cursor_left()
248+
if text == b.text:
249+
event.cli.key_processor.feed_multiple(alt_enter)
250+
251+
# apply completion if there is only one option, otherwise start completion
252+
@handle("tab", filter=focused_insert & ~has_completions & tac)
253+
@handle("c-space", filter=focused_insert & ~has_completions & tac)
254+
def _(event):
255+
b = event.current_buffer
256+
complete_event = CompleteEvent(completion_requested=True)
257+
completions = b.completer.get_completions(b.document, complete_event)
258+
if len(completions) == 1:
259+
completion = completions[0]
260+
b.apply_completion(completion)
261+
if is_callable(completion.text):
262+
b.insert_text("()")
263+
b.cursor_left()
264+
else:
265+
b.start_completion(insert_common_part=True)
266+
267+
# apply first completion option if completion menu is showing
268+
@handle("tab", filter=focused_insert & shown_not_selected & tac)
269+
@handle("c-space", filter=focused_insert & shown_not_selected & tac)
270+
def _(event):
271+
b = event.current_buffer
272+
b.complete_next()
273+
completion = b.complete_state.current_completion
274+
b.apply_completion(completion)
275+
if is_callable(completion.text):
276+
b.insert_text("()")
277+
b.cursor_left()
278+
279+
# apply selected completion option
280+
@handle("tab", filter=focused_insert & completion_is_selected & tac)
281+
@handle("c-space", filter=focused_insert & completion_is_selected & tac)
282+
def _(event):
283+
b = event.current_buffer
284+
completion = b.complete_state.current_completion
285+
b.apply_completion(completion)
286+
if is_callable(completion.text):
287+
b.insert_text("()")
288+
b.cursor_left()
289+
204290
return bindings
205291

206292

Diff for: ptpython/python_input.py

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ def __init__(
234234
self.enable_system_bindings: bool = True
235235
self.enable_input_validation: bool = True
236236
self.enable_auto_suggest: bool = False
237+
self.emacs_bindings_in_vi_insert_mode: bool = True
237238
self.enable_mouse_support: bool = False
238239
self.enable_history_search: bool = False # When True, like readline, going
239240
# back in history will filter the

0 commit comments

Comments
 (0)