Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/prompt_toolkit/key_binding/bindings/vi.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,13 +544,22 @@ def _complete_prev(event: E) -> None:
b.start_completion(select_last=True)

@handle("c-g", filter=vi_insert_mode)
@handle("c-y", filter=vi_insert_mode)
def _accept_completion(event: E) -> None:
"""
Accept current completion.
"""
event.current_buffer.complete_state = None

@handle("c-y", filter=vi_insert_mode)
def _accept_completion_or_yank(event: E) -> None:
"""
Accept current completion, or yank when no completion is active.
"""
if event.current_buffer.complete_state is None:
get_by_name("yank").handler(event)
else:
event.current_buffer.complete_state = None

@handle("c-e", filter=vi_insert_mode)
def _cancel_completion(event: E) -> None:
"""
Expand Down
70 changes: 70 additions & 0 deletions tests/test_vi_insert_bindings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from prompt_toolkit.buffer import CompletionState
from prompt_toolkit.clipboard import ClipboardData, InMemoryClipboard
from prompt_toolkit.completion import Completion
from prompt_toolkit.document import Document
from prompt_toolkit.enums import EditingMode
from prompt_toolkit.input.defaults import create_pipe_input
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.output import DummyOutput
from prompt_toolkit.shortcuts import PromptSession


def test_ctrl_y_yanks_text_killed_by_ctrl_u_in_vi_insert_mode():
with create_pipe_input() as inp:
inp.send_text("hello\x15\x19\r")
session = PromptSession(
input=inp,
output=DummyOutput(),
editing_mode=EditingMode.VI,
clipboard=InMemoryClipboard(),
)
result = session.prompt()

assert result == "hello"


def test_ctrl_y_still_accepts_active_completion_in_vi_insert_mode():
clipboard = InMemoryClipboard(ClipboardData("clipboard text"))

with create_pipe_input() as inp:
inp.send_text("\x19\r")
session = PromptSession(
input=inp,
output=DummyOutput(),
editing_mode=EditingMode.VI,
clipboard=clipboard,
)

def activate_completion() -> None:
buffer = session.default_buffer
buffer.document = Document("he", 2)
buffer.complete_state = CompletionState(
buffer.document,
[Completion("hello", start_position=-2)],
)
buffer.go_to_completion(0)

result = session.prompt(pre_run=activate_completion)

assert result == "hello"
assert clipboard.get_data().text == "clipboard text"


def test_custom_ctrl_y_binding_overrides_vi_default():
bindings = KeyBindings()

@bindings.add("c-y")
def custom_ctrl_y(event):
event.current_buffer.insert_text("CUSTOM")

with create_pipe_input() as inp:
inp.send_text("\x19\r")
session = PromptSession(
input=inp,
output=DummyOutput(),
editing_mode=EditingMode.VI,
key_bindings=bindings,
)
result = session.prompt()

assert result == "CUSTOM"
Loading