diff --git a/NEWS b/NEWS index 18f5fabfa..d430fb986 100644 --- a/NEWS +++ b/NEWS @@ -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, + 7 will now move the cursor seven positions to the left. + In vi control mode, this would be entered as: 7 . + 2020-09-14: - Corrected rounding of floating point values by ksh's printf %f formatting diff --git a/src/cmd/ksh93/edit/emacs.c b/src/cmd/ksh93/edit/emacs.c index 533907027..77741e068 100644 --- a/src/cmd/ksh93/edit/emacs.c +++ b/src/cmd/ksh93/edit/emacs.c @@ -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); diff --git a/src/cmd/ksh93/edit/vi.c b/src/cmd/ksh93/edit/vi.c index 5bb5047ba..3c1a5650b 100644 --- a/src/cmd/ksh93/edit/vi.c +++ b/src/cmd/ksh93/edit/vi.c @@ -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); diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index c1fbc0bfc..337d4a483 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-09-14" +#define SH_RELEASE "93u+m 2020-09-17" diff --git a/src/cmd/ksh93/sh.1 b/src/cmd/ksh93/sh.1 index a98039c05..b2166b943 100644 --- a/src/cmd/ksh93/sh.1 +++ b/src/cmd/ksh93/sh.1 @@ -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