@@ -420,6 +420,56 @@ _zsh_highlight_highlighter_main_paint()
420420 done
421421}
422422
423+ # Try to expand $1, if it's possible to do so safely.
424+ #
425+ # Uses two parameters from the caller: $parameter_name_pattern and $res.
426+ #
427+ # If expansion was done, set $reply to the expansion and return true.
428+ # Otherwise, return false.
429+ _zsh_highlight_main_highlighter__try_expand_parameter ()
430+ {
431+ local arg=" $1 "
432+ unset reply
433+ {
434+ # ### For now, expand just '$foo' or '${foo}', possibly with braces, but with
435+ # ### no other features of the parameter expansion syntax. (No ${(x)foo},
436+ # ### no ${foo[x]}, no ${foo:-x}.)
437+ {
438+ local -a match mbegin mend
439+ local MATCH; integer MBEGIN MEND
440+ local parameter_name
441+ local -a words
442+ if [[ $arg [1] == ' $' ]] && [[ ${arg[2]} == ' {' ]] && [[ ${arg[-1]} == ' }' ]]; then
443+ parameter_name=${${arg: 2} % ?}
444+ elif [[ $arg [1] == ' $' ]]; then
445+ parameter_name=${arg: 1}
446+ fi
447+ if [[ $res == none ]] && zmodload -e zsh/parameter &&
448+ [[ ${parameter_name} =~ ^${~parameter_name_pattern} $ ]] &&
449+ [[ ${parameters[(e)$MATCH]} != * special* ]]
450+ then
451+ # Set $arg and update $res.
452+ case ${(tP)MATCH} in
453+ (* array* |* assoc* )
454+ words=( ${(P)MATCH} )
455+ ;;
456+ (" " )
457+ # not set
458+ words=( )
459+ ;;
460+ (* )
461+ # scalar, presumably
462+ words=( ${(P)MATCH} )
463+ ;;
464+ esac
465+ reply=( " ${words[@]} " )
466+ else
467+ return 1
468+ fi
469+ }
470+ }
471+ }
472+
423473# $1 is the offset of $4 from the parent buffer. Added to the returned highlights.
424474# $2 is the initial braces_stack (for a closing paren).
425475# $3 is 1 if $4 contains the end of $BUFFER, else 0.
@@ -676,42 +726,13 @@ _zsh_highlight_main_highlighter_highlight_list()
676726 fi
677727
678728 # Expand parameters.
679- #
680- # ### For now, expand just '$foo' or '${foo}', possibly with braces, but with
681- # ### no other features of the parameter expansion syntax. (No ${(x)foo},
682- # ### no ${foo[x]}, no ${foo:-x}.)
683- () {
729+ if _zsh_highlight_main_highlighter__try_expand_parameter " $arg " ; then
684730 # That's not entirely correct --- if the parameter's value happens to be a reserved
685731 # word, the parameter expansion will be highlighted as a reserved word --- but that
686732 # incorrectness is outweighed by the usability improvement of permitting the use of
687733 # parameters that refer to commands, functions, and builtins.
688- local -a match mbegin mend
689- local MATCH; integer MBEGIN MEND
690- local parameter_name
691- local -a words
692- if [[ $arg [1] == ' $' ]] && [[ ${arg[2]} == ' {' ]] && [[ ${arg[-1]} == ' }' ]]; then
693- parameter_name=${${arg: 2} % ?}
694- elif [[ $arg [1] == ' $' ]]; then
695- parameter_name=${arg: 1}
696- fi
697- if [[ $res == none ]] && zmodload -e zsh/parameter &&
698- [[ ${parameter_name} =~ ^${~parameter_name_pattern} $ ]] &&
699- [[ ${parameters[(e)$MATCH]} != * special* ]]
700- then
701- # Set $arg and update $res.
702- case ${(tP)MATCH} in
703- (* array* |* assoc* )
704- words=( ${(P)MATCH} )
705- ;;
706- (" " )
707- # not set
708- words=( )
709- ;;
710- (* )
711- # scalar, presumably
712- words=( ${(P)MATCH} )
713- ;;
714- esac
734+ () {
735+ local -a words; words=( " ${reply[@]} " )
715736 if (( $# words == 0 )) ; then
716737 # Parameter elision is happening
717738 (( ++ in_redirection ))
@@ -724,8 +745,8 @@ _zsh_highlight_main_highlighter_highlight_list()
724745 _zsh_highlight_main__type " $arg " 0
725746 res=$REPLY
726747 fi
727- fi
728- }
748+ }
749+ fi
729750
730751 # Parse the sudo command line
731752 if (( ! in_redirection )) ; then
0 commit comments