1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix bugs with backslash escaping in interactive vi mode (#57)

This commit fixes the following bugs in the 'vi' editing mode
backslash escape feature. Ref.: Bolsky & Korn (1995), p. 113, which
states for \: "Similar to Control+V [...] except that it escapes
only the next Erase or Kill charactrer".

1. The vi mode now only escapes the next character if the last
   character input was a backslash, fixing the bug demonstrated at:
   https://asciinema.org/a/E3Rq3et07MMQG5BaF7vkXQTg0
2. Escaping backslashes are now disabled in vi.c if the vi mode is
   disabled (note that vi.c handles raw editing mode in UTF-8
   locales). This makes the behavior of the raw editing mode
   consistent in C/POSIX and UTF-8 locales.
3. An odd interaction with Backspace when the character prior to a
   separate buffer entered with Shift-C was a backslash has been
   fixed. Demonstration at: https://asciinema.org/a/314833
   ^? will no longer be output repeatedly when attempting to erase
   a separate buffer with a Backspace, although, to be consistent
   with vi(1), you still cannot backspace past it before escaping
   out of it. Ref.:
   https://github.com/ksh93/ksh/issues/56#issuecomment-653586994

src/cmd/ksh93/edit/vi.c:
- Prevent a backslash from escaping the next input if the previous
  input wasn't a backslash. This is done by unsetting a variable
  named backslash if a backslash escaped a character. backslash is
  set to the result of c == '\\' when the user enters a new
  character.
- Disable escaping backslashes in the raw editing mode because
  it should not be enabled there.

src/cmd/ksh93/tests/pty.sh:
- Add some tests for how ksh handles backslashes in each
  editing mode to test for the bugs fixed by this commit.

Fixes #56.
This commit is contained in:
Johnothan King 2020-07-03 12:08:00 -07:00 committed by Martijn Dekker
parent 035a4cb3f4
commit a0dcdeeade
3 changed files with 57 additions and 3 deletions

View file

@ -1363,7 +1363,7 @@ static void getline(register Vi_t* vp,register int mode)
{
register int c;
register int tmp;
int max_virt=0, last_save=0;
int max_virt=0, last_save=0, backslash=0;
genchar saveline[MAXLINE];
vp->addnl = 1;
@ -1460,8 +1460,9 @@ static void getline(register Vi_t* vp,register int mode)
/*** treat as backspace ***/
case '\b': /** backspace **/
if( virtual[cur_virt] == '\\' )
if( sh_isoption(SH_VI) && backslash && virtual[cur_virt] == '\\' )
{
backslash = 0;
cdelete(vp,1, BAD);
append(vp,usrerase, mode);
}
@ -1505,8 +1506,9 @@ static void getline(register Vi_t* vp,register int mode)
break;
case UKILL: /** user kill line char **/
if( virtual[cur_virt] == '\\' )
if( sh_isoption(SH_VI) && backslash && virtual[cur_virt] == '\\' )
{
backslash = 0;
cdelete(vp,1, BAD);
append(vp,usrkill, mode);
}
@ -1580,6 +1582,7 @@ static void getline(register Vi_t* vp,register int mode)
mode = APPEND;
max_virt = last_virt+3;
}
backslash = (c == '\\');
append(vp,c, mode);
break;
}