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

emacs, vi: Support repeat parameters to VT220 keys (re: f2a3f4e3)

In the vi and emacs line editors, repeat count parameters can now
also be used for the arrow keys and the forward-delete key. E.g.,
in emacs mode, <ESC> 7 <left-arrow> will now move the cursor seven
positions to the left. In vi control mode, this would be entered
as: 7 <left-arrow>.

src/cmd/ksh93/edit/emacs.c:
- ed_emacsread(): Upon getting ^[ (ESC), save current repeat count
  in a new variable; restore and reset it upon the next character.
- escape(): Minor bugfix: when processing a ^[[x sequence where 'x'
  is a character other than '~' (which would be DEL), also reinsert
  the final character into the buffer so scripts can detect them.

src/cmd/ksh93/edit/vi.c:
- cntlmode(): Do not reset the repeat count if the command is '[',
  the character following ESC in VT220 escape sequences.
- mvcursor():
  * Do not use getcount() to get the character following '[', as
    that was parsing repetition parameters in the wrong place.
    There wouldn't be any, so this would reset the repeat count.
  * After that, no more need for the special-casing of ^[[3~ (DEL)
    introduced in f2a3f4e3. Move it to within the 'switch' block.
  * When handling left and right arrows and Home and End keys, do
    not modify cursor directly but ed_ungetchar() the corresponding
    traditional command keys as with the rest. Otherwise a repeat
    count parameter would now wrongly survive those keys.

src/cmd/ksh93/sh.1:
- Document control character notation used for vi mode docs.
- Since vi control mode beeps and aborts on ESC except if a
  subsequent [ is already in the input buffer upon receiving ESC,
  document that VT220 escape sequences only preserve repeat counts
  when entered into the input buffer all at once.
- Don't skip the initial ESC in the documentation of the VT220
  escape sequences. In control mode, skipping the initial ESC still
  works as before, but that is now undocumented, as it's really
  nothing more than an artefact of VT220 escape processing.
- Move the two long paragraphs on '-o viraw' and canonical (i.e.
  line-based) input processing from the vi editor introduction to
  the options section under 'viraw'. It is much too arcane for the
  intro, and besides, ksh 93u+ (and hence also 93u+m) has
  SHOPT_VIRAW enabled by default, so the shell is compiled to force
  this option on at all times, making it even less relevant for
  most users.
This commit is contained in:
Martijn Dekker 2020-09-17 17:28:03 +02:00
parent c24c3dc0af
commit 13c3fb21e9
5 changed files with 106 additions and 58 deletions

7
NEWS
View file

@ -3,6 +3,13 @@ For full details, see the git log at: https://github.com/ksh93/ksh
Any uppercase BUG_* names are modernish shell bug IDs.
2020-09-17:
- In the vi and emacs line editors, repeat count parameters can now also be
used for the arrow keys and the forward-delete key. E.g., in emacs mode,
<ESC> 7 <left-arrow> will now move the cursor seven positions to the left.
In vi control mode, this would be entered as: 7 <left-arrow>.
2020-09-14:
- Corrected rounding of floating point values by ksh's printf %f formatting

View file

@ -184,6 +184,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
register int count;
register Emacs_t *ep = ed->e_emacs;
int adjust,oadjust;
int vt220_save_repeat = 0;
char backslash;
genchar *kptr;
char prompt[PRSIZE];
@ -313,6 +314,11 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
killing = 0;
#endif
oadjust = count = adjust;
if(vt220_save_repeat)
{
count = vt220_save_repeat;
vt220_save_repeat = 0;
}
if(count<0)
count = 1;
adjust = -1;
@ -607,6 +613,7 @@ update:
ep->ed->e_nocrnl = 0;
continue;
case cntl('[') :
vt220_save_repeat = oadjust;
do_escape:
adjust = escape(ep,out,oadjust);
continue;
@ -1067,6 +1074,7 @@ static int escape(register Emacs_t* ep,register genchar *out,int count)
switch(i=ed_getchar(ep->ed,1))
{
case 'A':
/* VT220 up arrow */
#if SHOPT_EDPREDICT
if(!ep->ed->hlist && cur>0 && eol==cur && (cur<(SEARCHSIZE-2) || ep->prevdirection == -2))
#else
@ -1094,23 +1102,28 @@ static int escape(register Emacs_t* ep,register genchar *out,int count)
ed_ungetchar(ep->ed,cntl('P'));
return(-1);
case 'B':
/* VT220 down arrow */
ed_ungetchar(ep->ed,cntl('N'));
return(-1);
case 'C':
/* VT220 right arrow */
ed_ungetchar(ep->ed,cntl('F'));
return(-1);
case 'D':
/* VT220 left arrow */
ed_ungetchar(ep->ed,cntl('B'));
return(-1);
case 'H':
/* VT220 Home key */
ed_ungetchar(ep->ed,cntl('A'));
return(-1);
case 'F':
case 'Y':
/* VT220 End key */
ed_ungetchar(ep->ed,cntl('E'));
return(-1);
case '3':
if(ed_getchar(ep->ed,1)=='~')
if((ch=ed_getchar(ep->ed,1))=='~')
{ /*
* VT220 forward-delete key.
* Since ERASECHAR and EOFCHAR are usually both mapped to ^D, we
@ -1121,6 +1134,7 @@ static int escape(register Emacs_t* ep,register genchar *out,int count)
ed_ungetchar(ep->ed,ERASECHAR);
return(-1);
}
ed_ungetchar(ep->ed,ch);
/* FALLTHROUGH */
default:
ed_ungetchar(ep->ed,i);

View file

@ -762,7 +762,8 @@ static int cntlmode(Vi_t *vp)
if(mvcursor(vp,c))
{
sync_cursor(vp);
vp->repeat = 1;
if( c != '[' )
vp->repeat = 1;
continue;
}
@ -1053,10 +1054,7 @@ static int cntlmode(Vi_t *vp)
{
ed_ungetchar(vp->ed,c=ed_getchar(vp->ed,1));
if(c=='[')
{
vp->repeat = 1;
continue;
}
}
default:
ringbell:
@ -1606,7 +1604,6 @@ static int mvcursor(register Vi_t* vp,register int motion)
register int tcur_virt;
register int incr = -1;
register int bound = 0;
int c;
switch(motion)
{
@ -1633,16 +1630,10 @@ static int mvcursor(register Vi_t* vp,register int motion)
break;
case '[':
c = ed_getchar(vp->ed,-1);
if(c=='3' && ed_getchar(vp->ed,-1)=='~')
{
/* VT220 forward-delete key */
ed_ungetchar(vp->ed,'x');
return(1);
}
switch(motion=getcount(vp,c))
switch(motion=ed_getchar(vp->ed,-1))
{
case 'A':
/* VT220 up arrow */
#if SHOPT_EDPREDICT
if(!vp->ed->hlist && cur_virt>=0 && cur_virt<(SEARCHSIZE-2) && cur_virt == last_virt)
#else
@ -1665,22 +1656,36 @@ static int mvcursor(register Vi_t* vp,register int motion)
ed_ungetchar(vp->ed,'k');
return(1);
case 'B':
/* VT220 down arrow */
ed_ungetchar(vp->ed,'j');
return(1);
case 'C':
motion = last_virt;
incr = 1;
goto walk;
/* VT220 right arrow */
ed_ungetchar(vp->ed,'l');
return(1);
case 'D':
motion = first_virt;
goto walk;
/* VT220 left arrow */
ed_ungetchar(vp->ed,'h');
return(1);
case 'H':
tcur_virt = 0;
break;
/* VT220 Home key */
ed_ungetchar(vp->ed,'0');
return(1);
case 'F':
case 'Y':
tcur_virt = last_virt;
break;
/* VT220 End key */
ed_ungetchar(vp->ed,'$');
return(1);
case '3':
bound = ed_getchar(vp->ed,-1);
if(bound=='~')
{
/* VT220 forward-delete key */
ed_ungetchar(vp->ed,'x');
return(1);
}
ed_ungetchar(vp->ed,bound);
/* FALLTHROUGH */
default:
ed_ungetchar(vp->ed,motion);
return(0);

View file

@ -17,4 +17,4 @@
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#define SH_RELEASE "93u+m 2020-09-14"
#define SH_RELEASE "93u+m 2020-09-17"

View file

@ -4598,7 +4598,7 @@ Neither the `RETURN' nor the `LINE FEED' key is
entered after edit commands except when noted.
.PP
The \fBM-[\fR multi-character commands below are DEC VT220 escape sequences
generated by keys on modern PC/Mac keyboards, such as the arrow keys.
generated by special keys on standard PC keyboards, such as the arrow keys.
You could type them directly but they are meant to recognize the keys
in question, which are indicated in parentheses.
.PP
@ -4899,9 +4899,9 @@ The commands that accept a parameter are
.BR M-d ,
.BR M-f ,
.BR M-h ,
.B M-l
and
.BR M-^H .
.BR M-l ,
.BR M-^H ,
and the arrow keys and forward-delete key.
.PP
.TP 10
.BI M- letter
@ -5027,25 +5027,27 @@ Most control commands accept an optional repeat
.I count
prior to the command.
.PP
When in
.B vi
mode on most systems,
canonical processing is initially enabled and the
command will be echoed again if the speed is 1200 baud or greater and it
contains any control characters or less than one second has elapsed
since the prompt was printed.
The ESC character terminates canonical processing for the remainder of the command
and the user can then modify the command line.
This scheme has the advantages of canonical processing with the type-ahead
echoing of raw mode.
The notation for control characters used below is
.B ^
followed by a character. For instance,
.B ^H
is entered by holding down the Control key and pressing H.
.B ^[
(Control+\fB[\fR) is equivalent to the ESC key.
The notation for escape sequences is
.B ^[
followed by one or more characters.
.PP
If the option
.B viraw
is also set, the terminal will always have canonical processing
disabled.
This mode is implicit for systems that do not support two
alternate end of line delimiters,
and may be helpful for certain terminals.
The \fB^[[\fR (ESC \fB[\fR) multi-character commands below are DEC VT220 escape
sequences generated by special keys on standard PC keyboards, such as the arrow
keys, which are indicated in parentheses. When in
.I input\^
mode, these keys will switch you to
.I control\^
mode before performing the associated action.
These sequences can use preceding repeat count parameters, but only when the
\fB^[\fR and the subsequent \fB[\fR are entered into the input buffer at the
same time, such as when pressing one of those keys.
.SS "\ \ \ \ \ Input Edit Commands"
.PP
.RS
@ -5110,8 +5112,8 @@ These commands will move the cursor.
[\f2count\fP]\f3l\fP
Cursor forward (right) one character.
.TP 10
[\f2count\fP]\f3[C\fP
Cursor forward (right) one character.
[\f2count\fP]\f3^[[C\fP
(Right arrow) Same as \f3l\fP.
.TP 10
[\f2count\fP]\f3w\fP
Cursor forward one alpha-numeric word.
@ -5128,8 +5130,8 @@ Cursor to end of the current blank delimited word.
[\f2count\fP]\f3h\fP
Cursor backward (left) one character.
.TP 10
[\f2count\fP]\f3[D\fP
Cursor backward (left) one character.
[\f2count\fP]\f3^[[D\fP
(Left arrow) Same as \f3h\fP.
.TP 10
[\f2count\fP]\f3b\fP
Cursor backward one word.
@ -5178,17 +5180,20 @@ times.
.B 0
Cursor to start of line.
.TP 10
.B ^
Cursor to start of line.
.B ^[[H
(Home) Same as \f30\fP.
.TP 10
.B [H
.B ^
Cursor to first non-blank character in line.
.TP 10
.B $
Cursor to end of line.
.TP 10
.B [Y
Cursor to end of line.
.B ^[[F
(End) Same as \f3$\fP.
.TP 10
.B ^[[Y
Same as \f3$\fP.
.TP 10
.B %
Moves to balancing
@ -5218,11 +5223,12 @@ the previous command back in time is accessed.
Equivalent to
.BR k .
.TP 10
[\f2count\fP]\f3[A\fP
[\f2count\fP]\f3^[[A\fP
(Up arrow)
If cursor is at the end of the line it is equivalent to
.B /
with
.I string^\
.I string\^
set to the contents of the current line.
Otherwise, it is equivalent to
.BR k .
@ -5238,7 +5244,8 @@ the next command forward in time is accessed.
Equivalent to
.BR j .
.TP 10
[\f2count\fP]\f3[B\fP
[\f2count\fP]\f3^[[B\fP
(Down arrow)
Equivalent to
.BR j .
.TP 10
@ -5356,6 +5363,9 @@ and advance the cursor.
[\f2count\fP]\f3x\fP
Delete current character.
.TP 10
[\f2count\fP]\f3^[[3~\fP
(Forward delete) Same as \f3x\fP.
.TP 10
[\f2count\fP]\f3X\fP
Delete preceding character.
.TP 10
@ -7118,6 +7128,18 @@ Each character is processed as it is typed
in
.I vi\^
mode.
The shell may have been compiled to force this option on at all times.
Otherwise, canonical processing (line-by-line input) is initially enabled
and the command line will be echoed again if the speed is 1200 baud or
greater and it contains any control characters or less than one second has
elapsed since the prompt was printed. The ESC character terminates canonical
processing for the remainder of the command and the user can then modify the
command line. This scheme has the advantages of canonical processing with
the type-ahead echoing of raw mode. If the
.B viraw
option is set, the terminal will always have canonical processing disabled.
This mode is implicit for systems that do not support two alternate end of
line delimiters, and may be helpful for certain terminals.
.TP 8
.B xtrace
Same as