main: Recurse into backtick command substitutions
This commit is contained in:
		
							parent
							
								
									c40c72c386
								
							
						
					
					
						commit
						9db393309e
					
				|  | @ -1084,21 +1084,67 @@ _zsh_highlight_main_highlighter_highlight_dollar_quote() | ||||||
|   REPLY=$i |   REPLY=$i | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # Highlight backtick subshells | # Highlight backtick substitutions | ||||||
| _zsh_highlight_main_highlighter_highlight_backtick() | _zsh_highlight_main_highlighter_highlight_backtick() | ||||||
| { | { | ||||||
|   local arg1=$1 i=$1 q=\` style |   # buf is the contents of the backticks with a layer of backslashes removed. | ||||||
|  |   # last is the index of arg for the start of the string to be copied into buf. | ||||||
|  |   #     It is either one past the beginning backtick or one past the last backslash. | ||||||
|  |   # offset is a count of consumed \ (the delta between buf and arg). | ||||||
|  |   # offsets is an array indexed by buf offset of when the delta between buf and arg changes. | ||||||
|  |   #     It is sparse, so search backwards to the last value | ||||||
|  |   # unclosed is an array of one highlight to append to reply if this back-quoted-argument | ||||||
|  |   #     is closed and there is an unclosed back-quoted-argument in buf. | ||||||
|  |   local buf highlight style=back-quoted-argument-unclosed | ||||||
|  |   local -i arg1=$1 end_ i=$1 last offset=0 start subshell_has_end=0 | ||||||
|  |   local -a highlight_zone highlights offsets unclosed | ||||||
|   reply=() |   reply=() | ||||||
|   while i=$arg[(ib:i+1:)$q]; [[ $arg[i-1] == '\' && $i -lt $(( end_pos - start_pos )) ]]; do done |  | ||||||
| 
 | 
 | ||||||
|   if [[ $arg[i] == '`' ]]; then |   last=$(( arg1 + 1 )) | ||||||
|     style=back-quoted-argument |   # Remove one layer of backslashes and find the end | ||||||
|   else |   while i=$arg[(ib:i+1:)[\\\\\`]]; do # find the next \ or ` | ||||||
|     # If unclosed, i points past the end |     if (( i > end_pos - start_pos )); then | ||||||
|  |       buf=$buf$arg[last,i] | ||||||
|  |       offsets[i-arg1-offset]='' # So we never index past the end | ||||||
|       (( i-- )) |       (( i-- )) | ||||||
|     style=back-quoted-argument-unclosed |       subshell_has_end=$(( has_end && (start_pos + i == len) )) | ||||||
|  |       break | ||||||
|     fi |     fi | ||||||
|   reply=($(( start_pos + arg1 - 1 )) $(( start_pos + i )) $style) | 
 | ||||||
|  |     if [[ $arg[i] == '\' ]]; then | ||||||
|  |       (( i++ )) | ||||||
|  |       # POSIX XCU 2.6.3 | ||||||
|  |       if [[ $arg[i] == ('$'|'`'|'\') ]]; then | ||||||
|  |         buf=$buf$arg[last,i-2] | ||||||
|  |         (( offset++ )) | ||||||
|  |         # offsets is relative to buf, so adjust by -arg1 | ||||||
|  |         offsets[i-arg1-offset]=$offset | ||||||
|  |       else | ||||||
|  |         buf=$buf$arg[last,i-1] | ||||||
|  |       fi | ||||||
|  |     else # it's an unquoted ` and this is the end | ||||||
|  |       style=back-quoted-argument | ||||||
|  |       buf=$buf$arg[last,i-1] | ||||||
|  |       offsets[i-arg1-offset]='' # So we never index past the end | ||||||
|  |       break | ||||||
|  |     fi | ||||||
|  |     last=$i | ||||||
|  |   done | ||||||
|  | 
 | ||||||
|  |   _zsh_highlight_main_highlighter_highlight_list 0 '' $subshell_has_end $buf | ||||||
|  | 
 | ||||||
|  |   # Munge the reply to account for removed backslashes | ||||||
|  |   for start end_ highlight in $reply; do | ||||||
|  |     start=$(( start_pos + arg1 + start + offsets[(Rb:start:)?*] )) | ||||||
|  |     end_=$(( start_pos + arg1 + end_ + offsets[(Rb:end_:)?*] )) | ||||||
|  |     highlights+=($start $end_ $highlight) | ||||||
|  |     if [[ $highlight == back-quoted-argument-unclosed && $style == back-quoted-argument ]]; then | ||||||
|  |       # An inner backtick command substitution is unclosed, but this level is closed | ||||||
|  |       unclosed=($(( start_pos + i - 1)) $(( start_pos + i )) unknown-token) | ||||||
|  |     fi | ||||||
|  |   done | ||||||
|  | 
 | ||||||
|  |   reply=($(( start_pos + arg1 - 1 )) $(( start_pos + i )) $style $highlights $unclosed) | ||||||
|   REPLY=$i |   REPLY=$i | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -27,16 +27,25 @@ | ||||||
| # vim: ft=zsh sw=2 ts=2 et | # vim: ft=zsh sw=2 ts=2 et | ||||||
| # ------------------------------------------------------------------------------------------------- | # ------------------------------------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| # 42 is in the command position in a nested subshell. |  | ||||||
| BUFFER='echo `echo \`42\`` "is `echo equal` to" `echo 6 times 9' | BUFFER='echo `echo \`42\`` "is `echo equal` to" `echo 6 times 9' | ||||||
| 
 | 
 | ||||||
| expected_region_highlight=( | expected_region_highlight=( | ||||||
|   "1 4 builtin" # echo |   "1 4 builtin" # echo | ||||||
|   "6 18 default" # `echo \`42\`` |   "6 18 default" # `echo \`42\`` | ||||||
|   "6 18 back-quoted-argument" # `echo \`42\`` |   "6 18 back-quoted-argument" # `echo \`42\`` | ||||||
|  |   "7 10 builtin" # echo | ||||||
|  |   "12 17 default" # \`42\` | ||||||
|  |   "12 17 back-quoted-argument" # \`42\` | ||||||
|  |   "14 15 unknown-token" # 42 | ||||||
|   "20 39 default" # "is `echo equal` to" |   "20 39 default" # "is `echo equal` to" | ||||||
|   "20 39 double-quoted-argument" # "is `echo equal` to" |   "20 39 double-quoted-argument" # "is `echo equal` to" | ||||||
|   "24 35 back-quoted-argument" # `echo equal` |   "24 35 back-quoted-argument" # `echo equal` | ||||||
|  |   "25 28 builtin" # echo | ||||||
|  |   "30 34 default" # equal | ||||||
|   "41 55 default" # `echo 6 times 9 |   "41 55 default" # `echo 6 times 9 | ||||||
|   "41 55 back-quoted-argument-unclosed" # `echo 6 times 9 |   "41 55 back-quoted-argument-unclosed" # `echo 6 times 9 | ||||||
|  |   "42 45 builtin" # echo | ||||||
|  |   "47 47 default" # 6 | ||||||
|  |   "49 53 default" # times | ||||||
|  |   "55 55 default" # 9 | ||||||
| ) | ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue