Skip to content

Commit e0614f6

Browse files
committed
Add support for a custom completion key/key-combo in Prompt-toolkit using the completekey input
1 parent d79e377 commit e0614f6

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

cmd2/cmd2.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
from prompt_toolkit.formatted_text import ANSI
145145
from prompt_toolkit.history import InMemoryHistory
146146
from prompt_toolkit.input import DummyInput
147+
from prompt_toolkit.key_binding import KeyBindings
147148
from prompt_toolkit.output import DummyOutput
148149
from prompt_toolkit.patch_stdout import patch_stdout
149150
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession, set_title
@@ -389,9 +390,19 @@ def __init__(
389390

390391
# Key used for tab completion
391392
self.completekey = completekey
393+
key_bindings = None
392394
if self.completekey != self.DEFAULT_COMPLETEKEY:
393-
# TODO(T or K): Configure prompt_toolkit `KeyBindings` with the custom key for completion # noqa: FIX002, TD003
394-
pass
395+
# Configure prompt_toolkit `KeyBindings` with the custom key for completion
396+
key_bindings = KeyBindings()
397+
398+
@key_bindings.add(self.completekey)
399+
def _(event: Any) -> None:
400+
"""Trigger completion."""
401+
b = event.current_buffer
402+
if b.complete_state:
403+
b.complete_next()
404+
else:
405+
b.start_completion(select_first=False)
395406

396407
# Attributes which should NOT be dynamically settable via the set command at runtime
397408
self.default_to_shell = False # Attempt to run unrecognized commands as shell commands
@@ -448,6 +459,7 @@ def __init__(
448459
complete_style=CompleteStyle.COLUMN,
449460
complete_in_thread=True,
450461
complete_while_typing=False,
462+
key_bindings=key_bindings,
451463
)
452464
except (NoConsoleScreenBufferError, AttributeError, ValueError):
453465
# Fallback to dummy input/output if PromptSession initialization fails.
@@ -461,6 +473,7 @@ def __init__(
461473
complete_style=CompleteStyle.COLUMN,
462474
complete_in_thread=True,
463475
complete_while_typing=False,
476+
key_bindings=key_bindings,
464477
)
465478

466479
# Commands to exclude from the history command

tests/test_custom_key_binding.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from prompt_toolkit.keys import Keys
2+
3+
import cmd2
4+
5+
6+
def test_custom_completekey_ctrl_k():
7+
# Test setting a custom completekey to <CTRL> + K
8+
# In prompt_toolkit, this is 'c-k'
9+
app = cmd2.Cmd(completekey='c-k')
10+
11+
assert app.completekey == 'c-k'
12+
assert app.session.key_bindings is not None
13+
14+
# Check that we have a binding for c-k (Keys.ControlK)
15+
found = False
16+
for binding in app.session.key_bindings.bindings:
17+
# binding.keys is a tuple of keys
18+
if binding.keys == (Keys.ControlK,):
19+
found = True
20+
break
21+
22+
assert found, "Could not find binding for 'c-k' (Keys.ControlK) in session key bindings"

0 commit comments

Comments
 (0)