Skip to content

Commit 997952a

Browse files
koronchrisbra
authored andcommitted
patch 9.1.2048: MS-Windows: backspace behavior wrong with ConPTY
Problem: Pressing backspace in ConPTY on Windows deletes an entire word, not just a single character. This is the same as pressing Alt + backspace in cmd.exe. Solution: When using ConPTY on Windows, the `VTERM_KEY_BACKSPACE` key is now sent when the Backspace key or Ctrl+H is detected. (Muraoka Taro) Historically, Windows has assigned the code 0x7F (DEL) to backspace, and it seems necessary to follow that behavior when using ConPTY. closes: #19065 Signed-off-by: Muraoka Taro <koron.kaoriya@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent bfd4f75 commit 997952a

3 files changed

Lines changed: 56 additions & 3 deletions

File tree

src/terminal.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,9 +1584,26 @@ term_convert_key(term_T *term, int c, int modmask, char *buf)
15841584
{
15851585
// don't use VTERM_KEY_ENTER, it may do an unwanted conversion
15861586

1587-
// don't use VTERM_KEY_BACKSPACE, it always
1588-
// becomes 0x7f DEL
1589-
case K_BS: c = term_backspace_char; break;
1587+
case K_BS:
1588+
#ifdef MSWIN
1589+
// In ConPTY, we must use VTERM_KEY_BACKSPACE, otherwise it will
1590+
// delete one word, equivalent to Alt+Backspace.
1591+
if (term->tl_conpty)
1592+
key = VTERM_KEY_BACKSPACE;
1593+
else
1594+
#endif
1595+
// don't use VTERM_KEY_BACKSPACE, it always becomes 0x7f DEL
1596+
c = term_backspace_char;
1597+
break;
1598+
1599+
#ifdef MSWIN
1600+
case BS:
1601+
// In ConPTY, we must use VTERM_KEY_BACKSPACE, otherwise it will
1602+
// delete one word, equivalent to Alt+Backspace.
1603+
if (term->tl_conpty)
1604+
key = VTERM_KEY_BACKSPACE;
1605+
break;
1606+
#endif
15901607

15911608
case ESC: key = VTERM_KEY_ESCAPE; break;
15921609
case K_DEL: key = VTERM_KEY_DEL; break;

src/testdir/test_terminal3.vim

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,4 +1090,38 @@ func Test_terminal_ansi_color_windows_cui()
10901090
call assert_equal(expected_colors, term_scrape(buf, 1)[:len_to_check-1]->map({_, v -> v['bg']}))
10911091
endfunc
10921092

1093+
func Test_terminal_backspace_on_windows()
1094+
if !has('win32')
1095+
throw 'Skipped: only for the Windows CUI'
1096+
endif
1097+
" Specify a simple prompt for easy comparison
1098+
let save_prompt = $PROMPT
1099+
let $PROMPT = '>'
1100+
1101+
" Return the prompt line before the cursor
1102+
func s:get_cmd_prompt(buf)
1103+
let cur = term_getcursor(a:buf)
1104+
return term_getline(a:buf, cur[0])[:cur[1]-2]
1105+
endfunc
1106+
1107+
let buf = term_start('cmd.exe')
1108+
call WaitForAssert({-> assert_equal('>', s:get_cmd_prompt(buf))}, 100)
1109+
1110+
" Verify sent characters are echoed back
1111+
call term_sendkeys(buf, 'foo bar')
1112+
call WaitForAssert({-> assert_equal('>foo bar', s:get_cmd_prompt(buf))}, 100)
1113+
" Backspace should delete a character in front of the cursor
1114+
call term_sendkeys(buf, "\<BS>")
1115+
call WaitForAssert({-> assert_equal('>foo ba', s:get_cmd_prompt(buf))}, 100)
1116+
" Ctrl+H behaves like Backspace
1117+
call term_sendkeys(buf, "\<C-H>")
1118+
call WaitForAssert({-> assert_equal('>foo b', s:get_cmd_prompt(buf))}, 100)
1119+
" Send a total of four BS and Ctrl+H to erase four characters.
1120+
call term_sendkeys(buf, "\<BS>\<BS>\<C-H>\<C-H>")
1121+
call WaitForAssert({-> assert_equal('>f', s:get_cmd_prompt(buf))}, 100)
1122+
1123+
delfunc s:get_cmd_prompt
1124+
let $PROMPT = save_prompt
1125+
endfunc
1126+
10931127
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static char *(features[]) =
734734

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
2048,
737739
/**/
738740
2047,
739741
/**/

0 commit comments

Comments
 (0)