sudo/redirections: Fix part of issue #221, "sudo and redirection don't mix".
This commit is contained in:
		
							parent
							
								
									c6355a31b7
								
							
						
					
					
						commit
						be006aded5
					
				|  | @ -85,7 +85,6 @@ _zsh_highlight_main_highlighter() | ||||||
|   emulate -L zsh |   emulate -L zsh | ||||||
|   setopt localoptions extendedglob bareglobqual |   setopt localoptions extendedglob bareglobqual | ||||||
|   local start_pos=0 end_pos highlight_glob=true arg style |   local start_pos=0 end_pos highlight_glob=true arg style | ||||||
|   local redirection=false # true when we've seen a redirection operator before seeing the command word |  | ||||||
|   typeset -a ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR |   typeset -a ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR | ||||||
|   typeset -a ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS |   typeset -a ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS | ||||||
|   local buf="$PREBUFFER$BUFFER" |   local buf="$PREBUFFER$BUFFER" | ||||||
|  | @ -112,9 +111,21 @@ _zsh_highlight_main_highlighter() | ||||||
|   # The tokens are always added with both leading and trailing colons to serve as |   # The tokens are always added with both leading and trailing colons to serve as | ||||||
|   # word delimiters (an improvised array); [[ $x == *:foo:* ]] and x=${x//:foo:/}  |   # word delimiters (an improvised array); [[ $x == *:foo:* ]] and x=${x//:foo:/}  | ||||||
|   # will DTRT regardless of how many elements or repetitions $x has.. |   # will DTRT regardless of how many elements or repetitions $x has.. | ||||||
|  |   # | ||||||
|  |   # Handling of redirections: upon seeing a redirection token, we must stall | ||||||
|  |   # the current state --- both $this_word and $next_word --- for two iterations | ||||||
|  |   # (one for the redirection operator, one for the word following it representing | ||||||
|  |   # the redirection target).  Therefore, we set $in_redirection to 2 upon seeing a | ||||||
|  |   # redirection operator, decrement it each iteration, and stall the current state | ||||||
|  |   # when it is non-zero. | ||||||
|   local this_word=':start:' next_word |   local this_word=':start:' next_word | ||||||
|  |   integer in_redirection | ||||||
|   for arg in ${(z)buf}; do |   for arg in ${(z)buf}; do | ||||||
|     next_word=':regular:' |     if (( in_redirection == 0 )); then | ||||||
|  |       next_word=':regular:' | ||||||
|  |     else | ||||||
|  |       (( --in_redirection )) | ||||||
|  |     fi | ||||||
|     # $already_added is set to 1 to disable adding an entry to region_highlight |     # $already_added is set to 1 to disable adding an entry to region_highlight | ||||||
|     # for this iteration.  Currently, that is done for "" and $'' strings, |     # for this iteration.  Currently, that is done for "" and $'' strings, | ||||||
|     # which add the entry early so escape sequences within the string override |     # which add the entry early so escape sequences within the string override | ||||||
|  | @ -145,18 +156,21 @@ _zsh_highlight_main_highlighter() | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     # Parse the sudo command line |     # Parse the sudo command line | ||||||
|     if [[ $this_word == *':sudo_opt:'* ]]; then |     if (( ! in_redirection )); then | ||||||
|       case "$arg" in |       if [[ $this_word == *':sudo_opt:'* ]]; then | ||||||
|         # Flag that requires an argument |         case "$arg" in | ||||||
|         '-'[Cgprtu]) next_word=':sudo_arg:';; |           # Flag that requires an argument | ||||||
|         # This prevents misbehavior with sudo -u -otherargument |           '-'[Cgprtu]) next_word=':sudo_arg:';; | ||||||
|         '-'*)        next_word+=':sudo_opt:';; |           # This prevents misbehavior with sudo -u -otherargument | ||||||
|         *)           this_word+=':start:';; |           '-'*)        next_word+=':sudo_opt:';; | ||||||
|       esac |           *)           this_word+=':start:';; | ||||||
|     elif [[ $this_word == *':sudo_arg:'* ]]; then |         esac | ||||||
|       next_word+=':sudo_opt:' |       elif [[ $this_word == *':sudo_arg:'* ]]; then | ||||||
|  |         next_word+=':sudo_opt:' | ||||||
|  |       fi | ||||||
|     fi |     fi | ||||||
|     if [[ $this_word == *':start:'* ]] && ! $redirection; then # $arg is the command word | 
 | ||||||
|  |     if [[ $this_word == *':start:'* ]] && (( in_redirection == 0 )); then # $arg is the command word | ||||||
|      if [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]]; then |      if [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]]; then | ||||||
|       style=$ZSH_HIGHLIGHT_STYLES[precommand] |       style=$ZSH_HIGHLIGHT_STYLES[precommand] | ||||||
|      elif [[ "$arg" = "sudo" ]]; then |      elif [[ "$arg" = "sudo" ]]; then | ||||||
|  | @ -190,7 +204,7 @@ _zsh_highlight_main_highlighter() | ||||||
|                           style=$ZSH_HIGHLIGHT_STYLES[history-expansion] |                           style=$ZSH_HIGHLIGHT_STYLES[history-expansion] | ||||||
|                         elif [[ $arg[1] == '<' || $arg[1] == '>' ]]; then |                         elif [[ $arg[1] == '<' || $arg[1] == '>' ]]; then | ||||||
|                           style=$ZSH_HIGHLIGHT_STYLES[redirection] |                           style=$ZSH_HIGHLIGHT_STYLES[redirection] | ||||||
|                           redirection=true |                           (( in_redirection=2 )) | ||||||
|                         elif [[ $arg[1,2] == '((' ]]; then |                         elif [[ $arg[1,2] == '((' ]]; then | ||||||
|                           # Arithmetic evaluation. |                           # Arithmetic evaluation. | ||||||
|                           # |                           # | ||||||
|  | @ -214,11 +228,7 @@ _zsh_highlight_main_highlighter() | ||||||
|                         ;; |                         ;; | ||||||
|       esac |       esac | ||||||
|      fi |      fi | ||||||
|     else # $arg is the file target of a prefix redirection, or a non-command word |     else # $arg is a non-command word | ||||||
|       if $redirection; then |  | ||||||
|         redirection=false |  | ||||||
|         next_word+=':start:' |  | ||||||
|       fi |  | ||||||
|       case $arg in |       case $arg in | ||||||
|         '--'*)   style=$ZSH_HIGHLIGHT_STYLES[double-hyphen-option];; |         '--'*)   style=$ZSH_HIGHLIGHT_STYLES[double-hyphen-option];; | ||||||
|         '-'*)    style=$ZSH_HIGHLIGHT_STYLES[single-hyphen-option];; |         '-'*)    style=$ZSH_HIGHLIGHT_STYLES[single-hyphen-option];; | ||||||
|  | @ -243,6 +253,7 @@ _zsh_highlight_main_highlighter() | ||||||
|                    style=$ZSH_HIGHLIGHT_STYLES[commandseparator] |                    style=$ZSH_HIGHLIGHT_STYLES[commandseparator] | ||||||
|                  elif [[ $arg[1] == '<' || $arg[1] == '>' ]]; then |                  elif [[ $arg[1] == '<' || $arg[1] == '>' ]]; then | ||||||
|                    style=$ZSH_HIGHLIGHT_STYLES[redirection] |                    style=$ZSH_HIGHLIGHT_STYLES[redirection] | ||||||
|  |                    (( in_redirection=2 )) | ||||||
|                  else |                  else | ||||||
|                    if _zsh_highlight_main_highlighter_check_path; then |                    if _zsh_highlight_main_highlighter_check_path; then | ||||||
|                      style=$ZSH_HIGHLIGHT_STYLES[path] |                      style=$ZSH_HIGHLIGHT_STYLES[path] | ||||||
|  | @ -266,7 +277,7 @@ _zsh_highlight_main_highlighter() | ||||||
|     fi |     fi | ||||||
|     [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]] && highlight_glob=true |     [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]] && highlight_glob=true | ||||||
|     start_pos=$end_pos |     start_pos=$end_pos | ||||||
|     this_word=$next_word |     (( in_redirection == 0 )) && this_word=$next_word | ||||||
|   done |   done | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -35,5 +35,5 @@ expected_region_highlight=( | ||||||
|   "9 9 $ZSH_HIGHLIGHT_STYLES[redirection]" # > |   "9 9 $ZSH_HIGHLIGHT_STYLES[redirection]" # > | ||||||
|   "10 13 $ZSH_HIGHLIGHT_STYLES[path]" # /tmp |   "10 13 $ZSH_HIGHLIGHT_STYLES[path]" # /tmp | ||||||
|   "15 23 $ZSH_HIGHLIGHT_STYLES[default]" # otheruser |   "15 23 $ZSH_HIGHLIGHT_STYLES[default]" # otheruser | ||||||
|   "25 26 $ZSH_HIGHLIGHT_STYLES[command] 'issue #221'" # ls |   "25 26 $ZSH_HIGHLIGHT_STYLES[command]" # ls | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -35,5 +35,5 @@ expected_region_highlight=( | ||||||
|   "7 10 $ZSH_HIGHLIGHT_STYLES[path]" # /tmp |   "7 10 $ZSH_HIGHLIGHT_STYLES[path]" # /tmp | ||||||
|   "12 13 $ZSH_HIGHLIGHT_STYLES[single-hyphen-option] 'issue #221'" # -u |   "12 13 $ZSH_HIGHLIGHT_STYLES[single-hyphen-option] 'issue #221'" # -u | ||||||
|   "15 23 $ZSH_HIGHLIGHT_STYLES[default]" # otheruser |   "15 23 $ZSH_HIGHLIGHT_STYLES[default]" # otheruser | ||||||
|   "25 26 $ZSH_HIGHLIGHT_STYLES[command] 'issue #221'" # ls |   "25 26 $ZSH_HIGHLIGHT_STYLES[command]" # ls | ||||||
| ) | ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue