Skip to content

Commit

Permalink
provide option for tab to apply completion
Browse files Browse the repository at this point in the history
improve completion when completion menu is not showing

improve apply completion with enter

improve completion with enter in ptpython
  • Loading branch information
marskar committed Oct 10, 2020
1 parent 86e1571 commit 6afc560
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
85 changes: 85 additions & 0 deletions ptpython/key_bindings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from jedi import Interpreter
from prompt_toolkit.completion import CompleteEvent
from prompt_toolkit.application import get_app
from prompt_toolkit.document import Document
from prompt_toolkit.enums import DEFAULT_BUFFER
Expand All @@ -6,10 +8,13 @@
emacs_insert_mode,
emacs_mode,
has_focus,
has_completions,
completion_is_selected,
has_selection,
vi_insert_mode,
)
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.key_binding.key_processor import KeyPress
from prompt_toolkit.keys import Keys

from .utils import document_is_multiline_python
Expand Down Expand Up @@ -201,6 +206,86 @@ def _(event):
" Abort when Control-C has been pressed. "
event.app.exit(exception=KeyboardInterrupt, style="class:aborting")

def is_callable(text=""):
completions = Interpreter(text, [locals()]).complete()
match = next((i for i in completions if i.name == text), None)
return match.type in ("class", "function") if match else None

@Condition
def tac():
return python_input.tab_apply_completion

insert_mode = vi_insert_mode | emacs_insert_mode
focused_insert = insert_mode & has_focus(DEFAULT_BUFFER)
shown_not_selected = has_completions & ~completion_is_selected
alt_enter = [KeyPress(Keys.Escape), KeyPress(Keys.Enter)]

# apply selected completion
@handle('c-j', filter=focused_insert & completion_is_selected & tac)
@handle("enter", filter=focused_insert & completion_is_selected & tac)
def _(event):
b = event.current_buffer
text = b.text
completion = b.complete_state.current_completion
b.apply_completion(completion)
if is_callable(completion.text) or is_callable(b.document.get_word_under_cursor()):
b.insert_text("()")
b.cursor_left()
if text == b.text:
event.cli.key_processor.feed_multiple(alt_enter)

# apply first completion option when completion menu is showing
@handle('c-j', filter=focused_insert & shown_not_selected & tac)
@handle("enter", filter=focused_insert & shown_not_selected & tac)
def _(event):
b = event.current_buffer
text = b.text
b.complete_next()
completion = b.complete_state.current_completion
if is_callable(completion.text) or is_callable(b.document.get_word_under_cursor()):
b.insert_text("()")
b.cursor_left()
if text == b.text:
event.cli.key_processor.feed_multiple(alt_enter)

# apply completion if there is only one option, otherwise start completion
@handle("tab", filter=focused_insert & ~has_completions & tac)
@handle("c-space", filter=focused_insert & ~has_completions & tac)
def _(event):
b = event.current_buffer
complete_event = CompleteEvent(completion_requested=True)
completions = b.completer.get_completions(b.document, complete_event)
if len(completions) == 1:
completion = completions[0]
b.apply_completion(completion)
if is_callable(completion.text) or is_callable(b.document.get_word_under_cursor()):
b.insert_text("()")
b.cursor_left()
else:
b.start_completion(insert_common_part=True)

# apply first completion option if completion menu is showing
@handle("tab", filter=focused_insert & shown_not_selected & tac)
@handle("c-space", filter=focused_insert & shown_not_selected & tac)
def _(event):
b = event.current_buffer
b.complete_next()
completion = b.complete_state.current_completion
if is_callable(completion.text) or is_callable(b.document.get_word_under_cursor()):
b.insert_text("()")
b.cursor_left()

# apply selected completion option
@handle("tab", filter=focused_insert & completion_is_selected & tac)
@handle("c-space", filter=focused_insert & completion_is_selected & tac)
def _(event):
b = event.current_buffer
completion = b.complete_state.current_completion
b.apply_completion(completion)
if is_callable(completion.text) or is_callable(b.document.get_word_under_cursor()):
b.insert_text("()")
b.cursor_left()

return bindings


Expand Down
1 change: 1 addition & 0 deletions ptpython/python_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ def __init__(
self.enable_system_bindings: bool = True
self.enable_input_validation: bool = True
self.enable_auto_suggest: bool = False
self.tab_apply_completion: bool = True
self.enable_mouse_support: bool = False
self.enable_history_search: bool = False # When True, like readline, going
# back in history will filter the
Expand Down

0 comments on commit 6afc560

Please sign in to comment.