mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix completion following $'foo\'bar'
On an interactive shell in emacs or vi, type a command with a $'…' quoted string that contains a backslash-escaped single quote, like: $ true $'foo\'bar' ▁ Then begin to type the name of a file present in the current working directory and press tab. Nothing happens as completion fails to work. The completion code does not recognise $'…' strings. Instead, it parses them as '…' strings in which there are no backslash escapes, so it considers the last ' to open a second quoted string which is not terminated. Plus, when replacing a $'…' string with a (backslash-escaped) completed string, the initial '$' is not replaced: $ $'/etc/hosts<Tab> $ $/etc/hosts src/cmd/ksh93/edit/completion.c: - find_begin(): - Learn how to recognise $'…' strings. A new local dollarquote flag variable is used to distinguish them from regular '…' strings. The difference is that backslash escapes (and only those) should be recognised as in "…". - Set a special type -1 for $'…' as the caller will need a way to distinguish those from '…'. - ed_expand(): When replacing a quoted string, remove an extra initial character (being the $ in $') if the type set by find_begin() is -1. Resolves: https://github.com/ksh93/ksh/issues/462
This commit is contained in:
parent
7a5423dfb6
commit
80f8cc497f
3 changed files with 27 additions and 8 deletions
3
NEWS
3
NEWS
|
@ -9,6 +9,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
||||||
substitution after entering: '`something<TAB> or generate a spurious
|
substitution after entering: '`something<TAB> or generate a spurious
|
||||||
'end of file unexpected' syntax error after entering: '$(something<TAB>.
|
'end of file unexpected' syntax error after entering: '$(something<TAB>.
|
||||||
|
|
||||||
|
- Fixed bug where tab completion stopped working for arguments following a
|
||||||
|
quoted string with an escaped backslash in the form $'foo\'bar'.
|
||||||
|
|
||||||
2022-06-04:
|
2022-06-04:
|
||||||
|
|
||||||
- Added a new --functrace long-form shell option which causes the -x/--xtrace
|
- Added a new --functrace long-form shell option which causes the -x/--xtrace
|
||||||
|
|
|
@ -105,12 +105,17 @@ static char *overlaid(register char *str,register const char *newstr,int nocase)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns pointer to beginning of expansion and sets type of expansion
|
* returns pointer to beginning of expansion and sets type of expansion
|
||||||
|
*
|
||||||
|
* Detects variable expansions, command substitutions, and three quoting styles:
|
||||||
|
* 1. '...' inquote=='\'', dollarquote==0; no special characters
|
||||||
|
* 2. $'...' inquote=='\'', dollarquote==1; skips \.
|
||||||
|
* 3. "..." inquote=='"', dollarquote==0; skips \., $..., ${...}, $(...), `...`
|
||||||
*/
|
*/
|
||||||
static char *find_begin(char outbuff[], char *last, int endchar, int *type)
|
static char *find_begin(char outbuff[], char *last, int endchar, int *type)
|
||||||
{
|
{
|
||||||
register char *cp=outbuff, *bp, *xp;
|
register char *cp=outbuff, *bp, *xp;
|
||||||
register int c,inquote = 0, inassign=0;
|
char inquote = 0, dollarquote = 0, inassign = 0;
|
||||||
int mode=*type;
|
int mode=*type, c;
|
||||||
bp = outbuff;
|
bp = outbuff;
|
||||||
*type = 0;
|
*type = 0;
|
||||||
mbinit();
|
mbinit();
|
||||||
|
@ -127,10 +132,10 @@ static char *find_begin(char outbuff[], char *last, int endchar, int *type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(inquote==c)
|
if(inquote==c)
|
||||||
inquote = 0;
|
inquote = dollarquote = 0;
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\':
|
||||||
if(inquote != '\'')
|
if(inquote != '\'' || dollarquote)
|
||||||
mbchar(cp);
|
mbchar(cp);
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
|
@ -177,6 +182,8 @@ static char *find_begin(char outbuff[], char *last, int endchar, int *type)
|
||||||
if(*(cp=xp)!=')')
|
if(*(cp=xp)!=')')
|
||||||
bp = xp;
|
bp = xp;
|
||||||
}
|
}
|
||||||
|
else if(c=='\'' && !inquote)
|
||||||
|
dollarquote = 1;
|
||||||
break;
|
break;
|
||||||
case '`':
|
case '`':
|
||||||
if(inquote=='\'')
|
if(inquote=='\'')
|
||||||
|
@ -214,7 +221,11 @@ static char *find_begin(char outbuff[], char *last, int endchar, int *type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(inquote && *bp==inquote)
|
if(inquote && *bp==inquote)
|
||||||
*type = *bp++;
|
{
|
||||||
|
/* set special type -1 for $'...' */
|
||||||
|
*type = dollarquote ? -1 : inquote;
|
||||||
|
bp++;
|
||||||
|
}
|
||||||
return(bp);
|
return(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +371,11 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
|
||||||
com = sh_argbuild(&narg,comptr,0);
|
com = sh_argbuild(&narg,comptr,0);
|
||||||
/* special handling for leading quotes */
|
/* special handling for leading quotes */
|
||||||
if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
|
if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
|
||||||
begin--;
|
{
|
||||||
|
begin--;
|
||||||
|
if(var == -1) /* $'...' */
|
||||||
|
begin--; /* also remove initial dollar */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sh_offstate(SH_COMPLETE);
|
sh_offstate(SH_COMPLETE);
|
||||||
/* allow a search to be aborted */
|
/* allow a search to be aborted */
|
||||||
|
|
|
@ -821,11 +821,12 @@ r \thist -lnN 1\r\n$
|
||||||
((SHOPT_VSH || SHOPT_ESH)) && tst $LINENO <<"!"
|
((SHOPT_VSH || SHOPT_ESH)) && tst $LINENO <<"!"
|
||||||
L tab completion while expanding ${.sh.*} variables
|
L tab completion while expanding ${.sh.*} variables
|
||||||
# https://github.com/att/ast/issues/1461
|
# https://github.com/att/ast/issues/1461
|
||||||
|
# also tests $'...' string: https://github.com/ksh93/ksh/issues/462
|
||||||
|
|
||||||
d 15
|
d 15
|
||||||
p :test-1:
|
p :test-1:
|
||||||
w test \$\{.sh.level\t
|
w test \$'foo\\'bar' \$\{.sh.level\t
|
||||||
r ^:test-1: test \$\{.sh.level\}\r\n$
|
r ^:test-1: test \$'foo\\'bar' \$\{.sh.level\}\r\n$
|
||||||
!
|
!
|
||||||
|
|
||||||
((SHOPT_VSH || SHOPT_ESH)) && tst $LINENO <<"!"
|
((SHOPT_VSH || SHOPT_ESH)) && tst $LINENO <<"!"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue