diff --git a/common.c b/common.c index 7bf600167..f622deb11 100644 --- a/common.c +++ b/common.c @@ -408,6 +408,11 @@ wchar_t *wcsvarname( wchar_t *str ) return 0; } +int wcsvarchr( wchar_t chr ) +{ + return ( (iswalnum(chr)) || (chr == L'_' )); +} + /** The glibc version of wcswidth seems to hang on some strings. fish uses this replacement. diff --git a/common.h b/common.h index 1de6f8de9..0466c562b 100644 --- a/common.h +++ b/common.h @@ -151,6 +151,14 @@ wchar_t *wcsdupcat2( const wchar_t *a, ... ); wchar_t *wcsvarname( wchar_t *str ); +/** + Test if the given string is valid in a variable name + + \return 1 if this is a valid name, 0 otherwise +*/ + +int wcsvarchr( wchar_t chr ); + /** A wcswidth workalike. Fish uses this since the regular wcswidth seems flaky. diff --git a/highlight.c b/highlight.c index df9c72452..a785ab24b 100644 --- a/highlight.c +++ b/highlight.c @@ -219,9 +219,17 @@ static void highlight_param( const wchar_t * buff, break; } + case L'$': + { + wchar_t n = buff[in_pos+1]; + color[in_pos] = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR; + color[in_pos+1] = HIGHLIGHT_NORMAL; + break; + } + + case L'*': case L'?': - case L'$': case L'(': case L')': { @@ -349,8 +357,9 @@ static void highlight_param( const wchar_t * buff, case '$': { - color[in_pos] = HIGHLIGHT_OPERATOR; - color[in_pos+1] = HIGHLIGHT_QUOTE; + wchar_t n = buff[in_pos+1]; + color[in_pos] = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR; + color[in_pos+1] = HIGHLIGHT_QUOTE; break; } diff --git a/parser.c b/parser.c index c4cbab149..b0aef8e30 100644 --- a/parser.c +++ b/parser.c @@ -2684,10 +2684,11 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) default: { - if( !iswalnum(*(pos+1)) && - *(pos+1)!=L'_' && - *(pos+1)!=VARIABLE_EXPAND && - *(pos+1)!=VARIABLE_EXPAND_SINGLE ) + wchar_t n = *(pos+1); + + if( n != VARIABLE_EXPAND && + n != VARIABLE_EXPAND_SINGLE && + !wcsvarchr(n) ) { err=1; if( babble )