mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Parse quotes when extracting words from command history (#291)
This avoids splitting on quoted whitespace when extracting words from the command history using the emacs M-. or vi _ command. Example: if the prior command is $ ls Stairway\ To\ Heaven.mp3 then, M-. in Emacs editing mode (and _ in vi mode) now inserts Stairway\ To\ Heaven.mp3 instead of Heaven.mp3. The behavior is similar for 'Stairway To Heaven.mp3' and "Stairway To Heaven.mp3". src/cmd/ksh93/edit/history.c: hist_word(): - Skip over single-quoted and double-quoted strings and backslash-escaped characters. src/cmd/ksh93/tests/pty.sh: - Add regression test for this feature in vi mode. Since emacs and vi both use the same code for this, that should be good enough. Co-authored-by: Martijn Dekker <martijn@inlv.org>
This commit is contained in:
parent
d087b031f0
commit
7439e3dffe
3 changed files with 36 additions and 4 deletions
5
NEWS
5
NEWS
|
@ -5,6 +5,11 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
|||
|
||||
2021-04-30:
|
||||
|
||||
- The emacs 'ESC .' (M-.) and vi '_' commands now take shell quoting into
|
||||
account when repeating a word from the previous command line. For example, if
|
||||
the previous command is 'ls Stairway\ To\ Heaven.mp3', then they now insert
|
||||
'Stairway\ To\ Heaven.mp3' instead of 'Heaven.mp3'. Thanks to Govind Kamat.
|
||||
|
||||
- Fixed a bug introduced on 2020-09-05 that caused "echo ${var:+'{}'}"
|
||||
to be misparsed.
|
||||
|
||||
|
|
|
@ -1057,6 +1057,8 @@ int hist_copy(char *s1,int size,int command,int line)
|
|||
char *hist_word(char *string,int size,int word)
|
||||
{
|
||||
register int c;
|
||||
register int is_space;
|
||||
register int quoted;
|
||||
register char *s1 = string;
|
||||
register unsigned char *cp = (unsigned char*)s1;
|
||||
register int flag = 0;
|
||||
|
@ -1064,21 +1066,32 @@ char *hist_word(char *string,int size,int word)
|
|||
if(!hp)
|
||||
return(NIL(char*));
|
||||
hist_copy(string,size,(int)hp->histind-1,-1);
|
||||
for(;c = *cp;cp++)
|
||||
for(quoted=0;c = *cp;cp++)
|
||||
{
|
||||
c = isspace(c);
|
||||
if(c && flag)
|
||||
is_space = isspace(c) && !quoted;
|
||||
if(is_space && flag)
|
||||
{
|
||||
*cp = 0;
|
||||
if(--word==0)
|
||||
break;
|
||||
flag = 0;
|
||||
}
|
||||
else if(c==0 && flag==0)
|
||||
else if(is_space==0 && flag==0)
|
||||
{
|
||||
s1 = (char*)cp;
|
||||
flag++;
|
||||
}
|
||||
if (c=='\'' && !quoted)
|
||||
{
|
||||
for(cp++;*cp && *cp != c;cp++)
|
||||
;
|
||||
}
|
||||
else if (c=='\"' && !quoted)
|
||||
{
|
||||
for(cp++;*cp && (*cp != c || quoted);cp++)
|
||||
quoted = *cp=='\\' ? !quoted : 0;
|
||||
}
|
||||
quoted = *cp=='\\' ? !quoted : 0;
|
||||
}
|
||||
*cp = 0;
|
||||
if(s1 != string)
|
||||
|
|
|
@ -812,5 +812,19 @@ r ^:test-1: echo ok\r\n$
|
|||
r ^ok\r\n$
|
||||
!
|
||||
|
||||
# err_exit #
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L split on quoted whitespace when extracting words from command history
|
||||
# https://github.com/ksh93/ksh/pull/291
|
||||
|
||||
d 15
|
||||
p :test-1:
|
||||
w true ls One\\ "Two Three"$'Four Five'.mp3
|
||||
r ^:test-1: true ls One\\ "Two Three"\$'Four Five'\.mp3\r\n$
|
||||
p :test-2:
|
||||
w :\E_
|
||||
r ^:test-2: : One\\ "Two Three"\$'Four Five'\.mp3\r\n$
|
||||
!
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue