Skip to content

Commit c0a44da

Browse files
Fix in 'x' and 'X' Vi key bindings. Correctly handle line endings and args.
1 parent 9242969 commit c0a44da

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

prompt_toolkit/key_binding/bindings/vi.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -749,13 +749,19 @@ def _(event):
749749
"""
750750
Delete character.
751751
"""
752-
text = event.current_buffer.delete(count=event.arg)
753-
event.app.clipboard.set_text(text)
752+
buff = event.current_buffer
753+
count = min(event.arg, len(buff.document.current_line_after_cursor))
754+
if count:
755+
text = event.current_buffer.delete(count=count)
756+
event.app.clipboard.set_text(text)
754757

755758
@handle('X', filter=vi_navigation_mode)
756759
def _(event):
757-
text = event.current_buffer.delete_before_cursor()
758-
event.app.clipboard.set_text(text)
760+
buff = event.current_buffer
761+
count = min(event.arg, len(buff.document.current_line_before_cursor))
762+
if count:
763+
text = event.current_buffer.delete_before_cursor(count=count)
764+
event.app.clipboard.set_text(text)
759765

760766
@handle('y', 'y', filter=vi_navigation_mode)
761767
@handle('Y', filter=vi_navigation_mode)

tests/test_cli.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,56 @@ def test_vi_visual_line_copy():
773773
assert (result.text ==
774774
'-line1\n-line2\n-line3\n-line4\n-line2\n-line3\n-line2\n-line3\n-line5\n-line6')
775775

776+
def test_vi_character_delete_after_cursor():
777+
" Test 'x' keypress. "
778+
feed = partial(_feed_cli_with_input, editing_mode=EditingMode.VI,
779+
multiline=True)
780+
781+
# Delete one character.
782+
result, cli = feed('abcd\x1bHx\r')
783+
assert result.text == 'bcd'
784+
785+
# Delete multiple character.s
786+
result, cli = feed('abcd\x1bH3x\r')
787+
assert result.text == 'd'
788+
789+
# Delete on empty line.
790+
result, cli = feed('\x1bo\x1bo\x1bggx\r')
791+
assert result.text == '\n\n'
792+
793+
# Delete multiple on empty line.
794+
result, cli = feed('\x1bo\x1bo\x1bgg10x\r')
795+
assert result.text == '\n\n'
796+
797+
# Delete multiple on empty line.
798+
result, cli = feed('hello\x1bo\x1bo\x1bgg3x\r')
799+
assert result.text == 'lo\n\n'
800+
801+
802+
def test_vi_character_delete_before_cursor():
803+
" Test 'X' keypress. "
804+
feed = partial(_feed_cli_with_input, editing_mode=EditingMode.VI,
805+
multiline=True)
806+
807+
# Delete one character.
808+
result, cli = feed('abcd\x1bX\r')
809+
assert result.text == 'abd'
810+
811+
# Delete multiple character.
812+
result, cli = feed('hello world\x1b3X\r')
813+
assert result.text == 'hello wd'
814+
815+
# Delete multiple character on multiple lines.
816+
result, cli = feed('hello\x1boworld\x1bgg$3X\r')
817+
assert result.text == 'ho\nworld'
818+
819+
result, cli = feed('hello\x1boworld\x1b100X\r')
820+
assert result.text == 'hello\nd'
821+
822+
# Delete on empty line.
823+
result, cli = feed('\x1bo\x1bo\x1b10X\r')
824+
assert result.text == '\n\n'
825+
776826

777827
def test_vi_character_paste():
778828
feed = partial(_feed_cli_with_input, editing_mode=EditingMode.VI)

0 commit comments

Comments
 (0)