1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

Fix behaviour of tabs in raw Bourne Shell-like editing mode

When neither '-o emacs' nor '-o vi' is active, there were a couple
of bugs with entering tab characters:
1. Tab completion was erroneously left active. The cause of this
   was that raw Bourne edit mode is handled by ed_viread() in vi.c
   on shells with wide character support, instead of the default
   ed_read() in edit.c, and the former failed to check if vi mode
   is active when processing tab characters.
2. When entering literal tab characters, the cursor was moved to
   the right only one character, instead of the amount of
   characters corresponding to the tab.

src/cmd/ksh93/edit/vi.c: getline():
- Before processing '\t' (tab) for command completion, check that
  the 'vi' shell option (SH_VI) is active.

src/cmd/ksh93/edit/edit.c: ed_virt_to_phys():
- When translating literal tabs to on-terminal spaces and when
  recalculating the cursor position, remove erroneous checks for
  SH_VI; this is also needed in raw Bourne mode. According to my
  own testing, this has no effect on emacs mode (knock on wood).

src/cmd/ksh93/tests/pty.sh:
- Add two regression tests. An odd race condition reveals itself in
  either pty or in ksh's raw/Bourne edit mode; see comment in test.
  Effect is we have to expect either literal tabs or tabs expanded
  to spaces, until that is tracked down and fixed.

Fixes #43.
This commit is contained in:
Martijn Dekker 2020-06-26 07:19:58 +02:00
parent 4cecde1dd3
commit 8c705bf3b7
4 changed files with 47 additions and 5 deletions

5
NEWS
View file

@ -8,6 +8,11 @@ Any uppercase BUG_* names are modernish shell bug IDs.
- Fixed buggy tab completion of tilde-expanded paths such as
~/some in 'vi' mode.
- In the raw/default Bourne Shell-like editing mode that occurs when neither
the 'emacs' nor the 'vi' shell option is active:
* tab completion is now correctly disabled, instead of enabled and broken;
* entering tab characters now moves the cursor the correct amount.
2020-06-23:
- Fixed a bug that caused combining process substitution with redirection

View file

@ -1342,8 +1342,7 @@ int ed_virt_to_phys(Edit_t *ep,genchar *virt,genchar *phys,int cur,int voff,int
if(c=='\t')
{
c = dp-phys;
if(sh_isoption(SH_VI))
c += ep->e_plen;
c += ep->e_plen;
c = TABSIZE - c%TABSIZE;
while(--c>0)
*dp++ = ' ';
@ -1354,8 +1353,7 @@ int ed_virt_to_phys(Edit_t *ep,genchar *virt,genchar *phys,int cur,int voff,int
*dp++ = '^';
c = printchar(c);
}
/* in vi mode the cursor is at the last character */
if(curp == sp && sh_isoption(SH_VI))
if(curp == sp)
r = dp - phys;
}
*dp++ = c;

View file

@ -1541,7 +1541,11 @@ static void getline(register Vi_t* vp,register int mode)
return;
case '\t': /** command completion **/
if(mode!=SEARCH && last_virt>=0 && (vp->ed->e_tabcount|| !isblank(cur_virt)) && vp->ed->sh->nextprompt)
if(sh_isoption(SH_VI) &&
mode != SEARCH &&
last_virt >= 0 &&
(vp->ed->e_tabcount || !isblank(cur_virt)) &&
vp->ed->sh->nextprompt)
{
if(virtual[cur_virt]=='\\')
{

View file

@ -470,5 +470,40 @@ u ^/tmp/fakehome/testfile\r?\n$
!
rm -r /tmp/fakehome
# err_exit #
LC_ALL=C tst $LINENO <<"!"
L raw Bourne mode literal tab characters with wide characters disabled
# This gets handled by ed_read() in edit.c; it does not expand tab
# characters on the command line.
w set +o vi +o emacs
p :test-2:
w true /de\tv/nu\tl\tl
r ^:test-2: true /de\tv/nu\tl\tl\r\n$
p :test-3:
!
# err_exit #
LC_ALL=C.UTF-8 tst $LINENO <<"!"
L raw Bourne mode literal tab characters with wide characters enabled
# This gets handled by ed_viread() in vi.c (even though vi mode is off);
# it expands tab characters to spaces on the command line.
w set +o vi +o emacs
p :test-2:
w true /de\tv/nu\tl\tl
# TODO: there is some race condition in either pty or in ksh's default edit
# mode, which causes it to expect/generate either tabs ('\t') or expanded
# spaces, randomly, intermittently. This is functionally equivalent as it
# only affects either pty or (invisibly) the editing command line, so not a
# high priority. Until this is tracked down and fixed, accept both.
r ^:test-2: true (/de\tv/nu\tl\tl|/de v/nu l l)\r\n$
p :test-3:
!
# ======
exit $((Errors<125?Errors:125))