Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

692 wiersze
27 KiB

minor: Fix WARN_CREATE_GLOBAL warnings issued by zsh 5.1.1-dev-0. The following warnings are issued by zsh as of zsh-workers/37018 (commit de9effbce601 to zsh itself): _zsh_highlight_main_highlighter_highlight_dollar_string:17: array parameter match created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: array parameter mbegin created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: array parameter mend created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: numeric parameter parameter MBEGIN created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: numeric parameter parameter MEND created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: scalar parameter MATCH created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_string:11: array parameter match created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: array parameter mbegin created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: array parameter mend created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: numeric parameter parameter MBEGIN created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: numeric parameter parameter MEND created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: scalar parameter MATCH created globally in function _zsh_highlight_main_highlighter_highlight_string
9 lat temu
minor: Fix WARN_CREATE_GLOBAL warnings issued by zsh 5.1.1-dev-0. The following warnings are issued by zsh as of zsh-workers/37018 (commit de9effbce601 to zsh itself): _zsh_highlight_main_highlighter_highlight_dollar_string:17: array parameter match created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: array parameter mbegin created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: array parameter mend created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: numeric parameter parameter MBEGIN created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: numeric parameter parameter MEND created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_dollar_string:17: scalar parameter MATCH created globally in function _zsh_highlight_main_highlighter_highlight_dollar_string _zsh_highlight_main_highlighter_highlight_string:11: array parameter match created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: array parameter mbegin created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: array parameter mend created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: numeric parameter parameter MBEGIN created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: numeric parameter parameter MEND created globally in function _zsh_highlight_main_highlighter_highlight_string _zsh_highlight_main_highlighter_highlight_string:11: scalar parameter MATCH created globally in function _zsh_highlight_main_highlighter_highlight_string
9 lat temu
  1. # -------------------------------------------------------------------------------------------------
  2. # Copyright (c) 2010-2016 zsh-syntax-highlighting contributors
  3. # All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without modification, are permitted
  6. # provided that the following conditions are met:
  7. #
  8. # * Redistributions of source code must retain the above copyright notice, this list of conditions
  9. # and the following disclaimer.
  10. # * Redistributions in binary form must reproduce the above copyright notice, this list of
  11. # conditions and the following disclaimer in the documentation and/or other materials provided
  12. # with the distribution.
  13. # * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
  14. # may be used to endorse or promote products derived from this software without specific prior
  15. # written permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  18. # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  19. # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  20. # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  23. # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  24. # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. # -------------------------------------------------------------------------------------------------
  26. # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
  27. # vim: ft=zsh sw=2 ts=2 et
  28. # -------------------------------------------------------------------------------------------------
  29. # Define default styles.
  30. : ${ZSH_HIGHLIGHT_STYLES[default]:=none}
  31. : ${ZSH_HIGHLIGHT_STYLES[unknown-token]:=fg=red,bold}
  32. : ${ZSH_HIGHLIGHT_STYLES[reserved-word]:=fg=yellow}
  33. : ${ZSH_HIGHLIGHT_STYLES[alias]:=fg=green}
  34. : ${ZSH_HIGHLIGHT_STYLES[suffix-alias]:=fg=green,underline}
  35. : ${ZSH_HIGHLIGHT_STYLES[builtin]:=fg=green}
  36. : ${ZSH_HIGHLIGHT_STYLES[function]:=fg=green}
  37. : ${ZSH_HIGHLIGHT_STYLES[command]:=fg=green}
  38. : ${ZSH_HIGHLIGHT_STYLES[precommand]:=fg=green,underline}
  39. : ${ZSH_HIGHLIGHT_STYLES[commandseparator]:=none}
  40. : ${ZSH_HIGHLIGHT_STYLES[hashed-command]:=fg=green}
  41. : ${ZSH_HIGHLIGHT_STYLES[path]:=underline}
  42. : ${ZSH_HIGHLIGHT_STYLES[path_prefix]:=underline}
  43. : ${ZSH_HIGHLIGHT_STYLES[globbing]:=fg=blue}
  44. : ${ZSH_HIGHLIGHT_STYLES[history-expansion]:=fg=blue}
  45. : ${ZSH_HIGHLIGHT_STYLES[single-hyphen-option]:=none}
  46. : ${ZSH_HIGHLIGHT_STYLES[double-hyphen-option]:=none}
  47. : ${ZSH_HIGHLIGHT_STYLES[back-quoted-argument]:=none}
  48. : ${ZSH_HIGHLIGHT_STYLES[single-quoted-argument]:=fg=yellow}
  49. : ${ZSH_HIGHLIGHT_STYLES[double-quoted-argument]:=fg=yellow}
  50. : ${ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]:=fg=yellow}
  51. : ${ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]:=fg=cyan}
  52. : ${ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]:=fg=cyan}
  53. : ${ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]:=fg=cyan}
  54. : ${ZSH_HIGHLIGHT_STYLES[assign]:=none}
  55. : ${ZSH_HIGHLIGHT_STYLES[redirection]:=none}
  56. : ${ZSH_HIGHLIGHT_STYLES[comment]:=fg=black,bold}
  57. # Whether the highlighter should be called or not.
  58. _zsh_highlight_main_highlighter_predicate()
  59. {
  60. # accept-* may trigger removal of path_prefix highlighting
  61. [[ $WIDGET == accept-* ]] ||
  62. _zsh_highlight_buffer_modified
  63. }
  64. # Helper to deal with tokens crossing line boundaries.
  65. _zsh_highlight_main_add_region_highlight() {
  66. integer start=$1 end=$2
  67. shift 2
  68. # The calculation was relative to $PREBUFFER$BUFFER, but region_highlight is
  69. # relative to $BUFFER.
  70. (( start -= $#PREBUFFER ))
  71. (( end -= $#PREBUFFER ))
  72. (( end < 0 )) && return # having end<0 would be a bug
  73. (( start < 0 )) && start=0 # having start<0 is normal with e.g. multiline strings
  74. _zsh_highlight_add_highlight $start $end "$@"
  75. }
  76. # Get the type of a command.
  77. #
  78. # Uses the zsh/parameter module if available to avoid forks, and a
  79. # wrapper around 'type -w' as fallback.
  80. #
  81. # Takes a single argument.
  82. #
  83. # The result will be stored in REPLY.
  84. _zsh_highlight_main__type() {
  85. if (( $+_zsh_highlight_main__command_type_cache )); then
  86. REPLY=$_zsh_highlight_main__command_type_cache[(e)$1]
  87. if [[ -n "$REPLY" ]]; then
  88. return
  89. fi
  90. fi
  91. if (( $#options_to_set )); then
  92. setopt localoptions $options_to_set;
  93. fi
  94. unset REPLY
  95. if zmodload -e zsh/parameter; then
  96. if (( $+aliases[(e)$1] )); then
  97. REPLY=alias
  98. elif (( $+saliases[(e)${1##*.}] )); then
  99. REPLY='suffix alias'
  100. elif (( $reswords[(Ie)$1] )); then
  101. REPLY=reserved
  102. elif (( $+functions[(e)$1] )); then
  103. REPLY=function
  104. elif (( $+builtins[(e)$1] )); then
  105. REPLY=builtin
  106. elif (( $+commands[(e)$1] )); then
  107. REPLY=command
  108. elif ! builtin type -w -- $1 >/dev/null 2>&1; then
  109. REPLY=none
  110. fi
  111. fi
  112. if ! (( $+REPLY )); then
  113. REPLY="${$(LC_ALL=C builtin type -w -- $1 2>/dev/null)#*: }"
  114. fi
  115. if (( $+_zsh_highlight_main__command_type_cache )); then
  116. _zsh_highlight_main__command_type_cache[(e)$1]=$REPLY
  117. fi
  118. }
  119. # Check whether the first argument is a redirection operator token.
  120. # Report result via the exit code.
  121. _zsh_highlight_main__is_redirection() {
  122. # A redirection operator token:
  123. # - starts with an optional single-digit number;
  124. # - then, has a '<' or '>' character;
  125. # - is not a process substitution [<(...) or >(...)].
  126. [[ $1 == (<0-9>|)(\<|\>)* ]] && [[ $1 != (\<|\>)$'\x28'* ]]
  127. }
  128. # Resolve alias.
  129. #
  130. # Takes a single argument.
  131. #
  132. # The result will be stored in REPLY.
  133. _zsh_highlight_main__resolve_alias() {
  134. if zmodload -e zsh/parameter; then
  135. REPLY=${aliases[$arg]}
  136. else
  137. REPLY="${"$(alias -- $arg)"#*=}"
  138. fi
  139. }
  140. # Main syntax highlighting function.
  141. _zsh_highlight_main_highlighter()
  142. {
  143. ## Before we even 'emulate -L', we must test a few options that would reset.
  144. if [[ -o interactive_comments ]]; then
  145. local interactive_comments= # set to empty
  146. fi
  147. if [[ -o path_dirs ]]; then
  148. integer path_dirs_was_set=1
  149. else
  150. integer path_dirs_was_set=0
  151. fi
  152. emulate -L zsh
  153. setopt localoptions extendedglob bareglobqual
  154. # At the PS3 prompt and in vared, highlight nothing.
  155. #
  156. # (We can't check this in _zsh_highlight_main_highlighter_predicate because
  157. # if the predicate returns false, the previous value of region_highlight
  158. # would be reused.)
  159. if [[ $CONTEXT == (select|vared) ]]; then
  160. return
  161. fi
  162. ## Variable declarations and initializations
  163. local start_pos=0 end_pos highlight_glob=true arg style
  164. local in_array_assignment=false # true between 'a=(' and the matching ')'
  165. typeset -a ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR
  166. typeset -a ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS
  167. typeset -a ZSH_HIGHLIGHT_TOKENS_CONTROL_FLOW
  168. local -a options_to_set # used in callees
  169. local buf="$PREBUFFER$BUFFER"
  170. integer len="${#buf}"
  171. if (( path_dirs_was_set )); then
  172. options_to_set+=( PATH_DIRS )
  173. fi
  174. unset path_dirs_was_set
  175. ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR=(
  176. '|' '||' ';' '&' '&&'
  177. '|&'
  178. '&!' '&|'
  179. # ### 'case' syntax, but followed by a pattern, not by a command
  180. # ';;' ';&' ';|'
  181. )
  182. ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS=(
  183. 'builtin' 'command' 'exec' 'nocorrect' 'noglob'
  184. 'pkexec' # immune to #121 because it's usually not passed --option flags
  185. )
  186. # Tokens that, at (naively-determined) "command position", are followed by
  187. # a de jure command position. All of these are reserved words.
  188. ZSH_HIGHLIGHT_TOKENS_CONTROL_FLOW=(
  189. $'\x7b' # block
  190. $'\x28' # subshell
  191. '()' # anonymous function
  192. 'while'
  193. 'until'
  194. 'if'
  195. 'then'
  196. 'elif'
  197. 'else'
  198. 'do'
  199. 'time'
  200. 'coproc'
  201. '!' # reserved word; unrelated to $histchars[1]
  202. )
  203. # State machine
  204. #
  205. # The states are:
  206. # - :start: Command word
  207. # - :sudo_opt: A leading-dash option to sudo (such as "-u" or "-i")
  208. # - :sudo_arg: The argument to a sudo leading-dash option that takes one,
  209. # when given as a separate word; i.e., "foo" in "-u foo" (two
  210. # words) but not in "-ufoo" (one word).
  211. # - :regular: "Not a command word", and command delimiters are permitted.
  212. # Mainly used to detect premature termination of commands.
  213. #
  214. # When the kind of a word is not yet known, $this_word / $next_word may contain
  215. # multiple states. For example, after "sudo -i", the next word may be either
  216. # another --flag or a command name, hence the state would include both :start:
  217. # and :sudo_opt:.
  218. #
  219. # The tokens are always added with both leading and trailing colons to serve as
  220. # word delimiters (an improvised array); [[ $x == *:foo:* ]] and x=${x//:foo:/}
  221. # will DTRT regardless of how many elements or repetitions $x has..
  222. #
  223. # Handling of redirections: upon seeing a redirection token, we must stall
  224. # the current state --- that is, the value of $this_word --- for two iterations
  225. # (one for the redirection operator, one for the word following it representing
  226. # the redirection target). Therefore, we set $in_redirection to 2 upon seeing a
  227. # redirection operator, decrement it each iteration, and stall the current state
  228. # when it is non-zero. Thus, upon reaching the next word (the one that follows
  229. # the redirection operator and target), $this_word will still contain values
  230. # appropriate for the word immediately following the word that preceded the
  231. # redirection operator.
  232. #
  233. # The "the previous word was a redirection operator" state is not communicated
  234. # to the next iteration via $next_word/$this_word as usual, but via
  235. # $in_redirection. The value of $next_word from the iteration that processed
  236. # the operator is discarded.
  237. #
  238. local this_word=':start:' next_word
  239. integer in_redirection
  240. # Processing buffer
  241. local proc_buf="$buf"
  242. for arg in ${interactive_comments-${(z)buf}} \
  243. ${interactive_comments+${(zZ+c+)buf}}; do
  244. if (( in_redirection )); then
  245. (( --in_redirection ))
  246. fi
  247. if (( in_redirection == 0 )); then
  248. # Initialize $next_word to its default value.
  249. next_word=':regular:'
  250. else
  251. # Stall $next_word.
  252. fi
  253. # $already_added is set to 1 to disable adding an entry to region_highlight
  254. # for this iteration. Currently, that is done for "" and $'' strings,
  255. # which add the entry early so escape sequences within the string override
  256. # the string's color.
  257. integer already_added=0
  258. if [[ $this_word == *':start:'* ]]; then
  259. in_array_assignment=false
  260. if [[ $arg == 'noglob' ]]; then
  261. highlight_glob=false
  262. fi
  263. fi
  264. # advance $start_pos, skipping over whitespace in $buf.
  265. if [[ $arg == ';' ]] ; then
  266. # We're looking for either a semicolon or a newline, whichever comes
  267. # first. Both of these are rendered as a ";" (SEPER) by the ${(z)..}
  268. # flag.
  269. #
  270. # We can't use the (Z+n+) flag because that elides the end-of-command
  271. # token altogether, so 'echo foo\necho bar' (two commands) becomes
  272. # indistinguishable from 'echo foo echo bar' (one command with three
  273. # words for arguments).
  274. local needle=$'[;\n]'
  275. integer offset=$(( ${proc_buf[(i)$needle]} - 1 ))
  276. (( start_pos += offset ))
  277. (( end_pos = start_pos + $#arg ))
  278. else
  279. integer offset=$(((len-start_pos)-${#${proc_buf##([[:space:]]|\\[[:space:]])#}}))
  280. ((start_pos+=offset))
  281. ((end_pos=$start_pos+${#arg}))
  282. fi
  283. # Above `if` computes new start_pos and end_pos.
  284. # Here we compute new proc_buf. We advance it
  285. # (chop off characters from the beginning)
  286. # beyond what end_pos points to, by skipping
  287. # as many characters as end_pos was advanced.
  288. #
  289. # end_pos was advanced by $offset (via start_pos)
  290. # and by $#arg. Note the `start_pos=$end_pos`
  291. # below.
  292. #
  293. # As for the [,len]. We could use [,len-start_pos+offset]
  294. # here, but to make it easier on eyes, we use len and
  295. # rely on the fact that Zsh simply handles that. The
  296. # length of proc_buf is len-start_pos+offset because
  297. # we're chopping it to match current start_pos, so its
  298. # length matches the previous value of start_pos.
  299. #
  300. # Why [,-1] is slower than [,length] isn't clear.
  301. proc_buf="${proc_buf[offset + $#arg + 1,len]}"
  302. if [[ -n ${interactive_comments+'set'} && $arg[1] == $histchars[3] ]]; then
  303. if [[ $this_word == *(':regular:'|':start:')* ]]; then
  304. style=comment
  305. else
  306. style=unknown-token # prematurely terminated
  307. fi
  308. _zsh_highlight_main_add_region_highlight $start_pos $end_pos $style
  309. already_added=1
  310. continue
  311. fi
  312. # Parse the sudo command line
  313. if (( ! in_redirection )); then
  314. if [[ $this_word == *':sudo_opt:'* ]]; then
  315. case "$arg" in
  316. # Flag that requires an argument
  317. '-'[Cgprtu]) this_word=${this_word//:start:/};
  318. next_word=':sudo_arg:';;
  319. # This prevents misbehavior with sudo -u -otherargument
  320. '-'*) this_word=${this_word//:start:/};
  321. next_word+=':start:';
  322. next_word+=':sudo_opt:';;
  323. *) ;;
  324. esac
  325. elif [[ $this_word == *':sudo_arg:'* ]]; then
  326. next_word+=':sudo_opt:'
  327. next_word+=':start:'
  328. fi
  329. fi
  330. if [[ $this_word == *':start:'* ]] && (( in_redirection == 0 )); then # $arg is the command word
  331. if [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]]; then
  332. style=precommand
  333. elif [[ "$arg" = "sudo" ]]; then
  334. style=precommand
  335. next_word=${next_word//:regular:/}
  336. next_word+=':sudo_opt:'
  337. next_word+=':start:'
  338. else
  339. _zsh_highlight_main_highlighter_expand_path $arg
  340. local expanded_arg="$REPLY"
  341. _zsh_highlight_main__type ${expanded_arg}
  342. local res="$REPLY"
  343. () {
  344. # Special-case: command word is '$foo', like that, without braces or anything.
  345. #
  346. # That's not entirely correct --- if the parameter's value happens to be a reserved
  347. # word, the parameter expansion will be highlighted as a reserved word --- but that
  348. # incorrectness is outweighed by the usability improvement of permitting the use of
  349. # parameters that refer to commands, functions, and builtins.
  350. local -a match mbegin mend
  351. local MATCH; integer MBEGIN MEND
  352. if [[ $res == none ]] && (( ${+parameters} )) &&
  353. [[ ${arg[1]} == \$ ]] && [[ ${arg:1} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+)$ ]]; then
  354. _zsh_highlight_main__type ${(P)MATCH}
  355. res=$REPLY
  356. fi
  357. }
  358. case $res in
  359. reserved) style=reserved-word;;
  360. 'suffix alias') style=suffix-alias;;
  361. alias) () {
  362. integer insane_alias
  363. case $arg in
  364. # Issue #263: aliases with '=' on their LHS.
  365. #
  366. # There are three cases:
  367. #
  368. # - Unsupported, breaks 'alias -L' output, but invokable:
  369. ('='*) :;;
  370. # - Unsupported, not invokable:
  371. (*'='*) insane_alias=1;;
  372. # - The common case:
  373. (*) :;;
  374. esac
  375. if (( insane_alias )); then
  376. style=unknown-token
  377. else
  378. style=alias
  379. _zsh_highlight_main__resolve_alias $arg
  380. local alias_target="$REPLY"
  381. [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$alias_target"} && -z ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]] && ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS+=($arg)
  382. fi
  383. }
  384. ;;
  385. builtin) style=builtin;;
  386. function) style=function;;
  387. command) style=command;;
  388. hashed) style=hashed-command;;
  389. none) if _zsh_highlight_main_highlighter_check_assign; then
  390. style=assign
  391. if [[ $arg[-1] == '(' ]]; then
  392. in_array_assignment=true
  393. else
  394. # assignment to a scalar parameter.
  395. # (For array assignments, the command doesn't start until the ")" token.)
  396. next_word+=':start:'
  397. fi
  398. elif [[ $arg[0,1] = $histchars[0,1] ]] && (( $#arg[0,2] == 2 )); then
  399. style=history-expansion
  400. elif [[ $arg[0,1] == $histchars[2,2] ]]; then
  401. style=history-expansion
  402. elif [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then
  403. if [[ $this_word == *':regular:'* ]]; then
  404. # This highlights empty commands (semicolon follows nothing) as an error.
  405. # Zsh accepts them, though.
  406. style=commandseparator
  407. else
  408. style=unknown-token
  409. fi
  410. elif _zsh_highlight_main__is_redirection $arg; then
  411. # A '<' or '>', possibly followed by a digit
  412. style=redirection
  413. (( in_redirection=2 ))
  414. elif [[ $arg[1,2] == '((' ]]; then
  415. # Arithmetic evaluation.
  416. #
  417. # Note: prior to zsh-5.1.1-52-g4bed2cf (workers/36669), the ${(z)...}
  418. # splitter would only output the '((' token if the matching '))' had
  419. # been typed. Therefore, under those versions of zsh, BUFFER="(( 42"
  420. # would be highlighted as an error until the matching "))" are typed.
  421. #
  422. # We highlight just the opening parentheses, as a reserved word; this
  423. # is how [[ ... ]] is highlighted, too.
  424. style=reserved-word
  425. _zsh_highlight_main_add_region_highlight $start_pos $((start_pos + 2)) $style
  426. already_added=1
  427. if [[ $arg[-2,-1] == '))' ]]; then
  428. _zsh_highlight_main_add_region_highlight $((end_pos - 2)) $end_pos $style
  429. already_added=1
  430. fi
  431. elif [[ $arg == '()' || $arg == $'\x28' ]]; then
  432. # anonymous function
  433. # subshell
  434. style=reserved-word
  435. else
  436. if _zsh_highlight_main_highlighter_check_path; then
  437. style=$REPLY
  438. else
  439. style=unknown-token
  440. fi
  441. fi
  442. ;;
  443. *) _zsh_highlight_main_add_region_highlight commandtypefromthefuture-$res
  444. already_added=1
  445. ;;
  446. esac
  447. fi
  448. else # $arg is a non-command word
  449. case $arg in
  450. $'\x29') # subshell or end of array assignment
  451. if $in_array_assignment; then
  452. style=assign
  453. in_array_assignment=false
  454. else
  455. style=reserved-word
  456. fi;;
  457. $'\x7d') style=reserved-word;; # block
  458. '--'*) style=double-hyphen-option;;
  459. '-'*) style=single-hyphen-option;;
  460. "'"*) style=single-quoted-argument;;
  461. '"'*) style=double-quoted-argument
  462. _zsh_highlight_main_add_region_highlight $start_pos $end_pos $style
  463. _zsh_highlight_main_highlighter_highlight_string
  464. already_added=1
  465. ;;
  466. \$\'*) style=dollar-quoted-argument
  467. _zsh_highlight_main_add_region_highlight $start_pos $end_pos $style
  468. _zsh_highlight_main_highlighter_highlight_dollar_string
  469. already_added=1
  470. ;;
  471. '`'*) style=back-quoted-argument;;
  472. [*?]*|*[^\\][*?]*)
  473. $highlight_glob && style=globbing || style=default;;
  474. *) if false; then
  475. elif [[ $arg[0,1] = $histchars[0,1] ]] && (( $#arg[0,2] == 2 )); then
  476. style=history-expansion
  477. elif [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then
  478. if [[ $this_word == *':regular:'* ]]; then
  479. style=commandseparator
  480. else
  481. style=unknown-token
  482. fi
  483. elif _zsh_highlight_main__is_redirection $arg; then
  484. style=redirection
  485. (( in_redirection=2 ))
  486. else
  487. if _zsh_highlight_main_highlighter_check_path; then
  488. style=$REPLY
  489. else
  490. style=default
  491. fi
  492. fi
  493. ;;
  494. esac
  495. fi
  496. (( already_added )) || _zsh_highlight_main_add_region_highlight $start_pos $end_pos $style
  497. if [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then
  498. next_word=':start:'
  499. highlight_glob=true
  500. elif
  501. [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_CONTROL_FLOW:#"$arg"} && $this_word == *':start:'* ]] ||
  502. [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} && $this_word == *':start:'* ]]; then
  503. next_word=':start:'
  504. elif [[ $arg == "repeat" && $this_word == *':start:'* ]]; then
  505. # skip the repeat-count word
  506. in_redirection=2
  507. # The redirection mechanism assumes $this_word describes the word
  508. # following the redirection. Make it so.
  509. #
  510. # The repeat-count word will be handled like a redirection target.
  511. this_word=':start:'
  512. fi
  513. start_pos=$end_pos
  514. (( in_redirection == 0 )) && this_word=$next_word
  515. done
  516. }
  517. # Check if $arg is variable assignment
  518. _zsh_highlight_main_highlighter_check_assign()
  519. {
  520. setopt localoptions extended_glob
  521. [[ $arg == [[:alpha:]_][[:alnum:]_]#(|\[*\])(|[+])=* ]]
  522. }
  523. # Check if $arg is a path.
  524. # If yes, return 0 and in $REPLY the style to use.
  525. # Else, return non-zero (and the contents of $REPLY is undefined).
  526. _zsh_highlight_main_highlighter_check_path()
  527. {
  528. _zsh_highlight_main_highlighter_expand_path $arg;
  529. local expanded_path="$REPLY"
  530. REPLY=path
  531. [[ -z $expanded_path ]] && return 1
  532. [[ -e $expanded_path ]] && return 0
  533. # Search the path in CDPATH
  534. local cdpath_dir
  535. for cdpath_dir in $cdpath ; do
  536. [[ -e "$cdpath_dir/$expanded_path" ]] && return 0
  537. done
  538. # If dirname($arg) doesn't exist, neither does $arg.
  539. [[ ! -e ${expanded_path:h} ]] && return 1
  540. # If this word ends the buffer, check if it's the prefix of a valid path.
  541. if [[ ${BUFFER[1]} != "-" && ${#BUFFER} == $end_pos ]] &&
  542. [[ $WIDGET != accept-* ]]; then
  543. local -a tmp
  544. tmp=( ${expanded_path}*(N) )
  545. (( $#tmp > 0 )) && REPLY=path_prefix && return 0
  546. fi
  547. # It's not a path.
  548. return 1
  549. }
  550. # Highlight special chars inside double-quoted strings
  551. _zsh_highlight_main_highlighter_highlight_string()
  552. {
  553. setopt localoptions noksharrays
  554. local -a match mbegin mend
  555. local MATCH; integer MBEGIN MEND
  556. local i j k style
  557. # Starting quote is at 1, so start parsing at offset 2 in the string.
  558. for (( i = 2 ; i < end_pos - start_pos ; i += 1 )) ; do
  559. (( j = i + start_pos - 1 ))
  560. (( k = j + 1 ))
  561. case "$arg[$i]" in
  562. '$' ) style=dollar-double-quoted-argument
  563. # Look for an alphanumeric parameter name.
  564. if [[ ${arg:$i} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+) ]] ; then
  565. (( k += $#MATCH )) # highlight the parameter name
  566. (( i += $#MATCH )) # skip past it
  567. elif [[ ${arg:$i} =~ ^[{]([A-Za-z_][A-Za-z0-9_]*|[0-9]+)[}] ]] ; then
  568. (( k += $#MATCH )) # highlight the parameter name and braces
  569. (( i += $#MATCH )) # skip past it
  570. else
  571. continue
  572. fi
  573. ;;
  574. "\\") style=back-double-quoted-argument
  575. if [[ \\\`\"\$ == *$arg[$i+1]* ]]; then
  576. (( k += 1 )) # Color following char too.
  577. (( i += 1 )) # Skip parsing the escaped char.
  578. else
  579. continue
  580. fi
  581. ;;
  582. *) continue ;;
  583. esac
  584. _zsh_highlight_main_add_region_highlight $j $k $style
  585. done
  586. }
  587. # Highlight special chars inside dollar-quoted strings
  588. _zsh_highlight_main_highlighter_highlight_dollar_string()
  589. {
  590. setopt localoptions noksharrays
  591. local -a match mbegin mend
  592. local MATCH; integer MBEGIN MEND
  593. local i j k style
  594. local AA
  595. integer c
  596. # Starting dollar-quote is at 1:2, so start parsing at offset 3 in the string.
  597. for (( i = 3 ; i < end_pos - start_pos ; i += 1 )) ; do
  598. (( j = i + start_pos - 1 ))
  599. (( k = j + 1 ))
  600. case "$arg[$i]" in
  601. "\\") style=back-dollar-quoted-argument
  602. for (( c = i + 1 ; c <= end_pos - start_pos ; c += 1 )); do
  603. [[ "$arg[$c]" != ([0-9xXuUa-fA-F]) ]] && break
  604. done
  605. AA=$arg[$i+1,$c-1]
  606. # Matching for HEX and OCT values like \0xA6, \xA6 or \012
  607. if [[ "$AA" =~ "^(x|X)[0-9a-fA-F]{1,2}"
  608. || "$AA" =~ "^[0-7]{1,3}"
  609. || "$AA" =~ "^u[0-9a-fA-F]{1,4}"
  610. || "$AA" =~ "^U[0-9a-fA-F]{1,8}"
  611. ]]; then
  612. (( k += $#MATCH ))
  613. (( i += $#MATCH ))
  614. else
  615. if (( $#arg > $i+1 )) && [[ $arg[$i+1] == [xXuU] ]]; then
  616. # \x not followed by hex digits is probably an error
  617. style=unknown-token
  618. fi
  619. (( k += 1 )) # Color following char too.
  620. (( i += 1 )) # Skip parsing the escaped char.
  621. fi
  622. ;;
  623. *) continue ;;
  624. esac
  625. _zsh_highlight_main_add_region_highlight $j $k $style
  626. done
  627. }
  628. # Called with a single positional argument.
  629. # Perform filename expansion (tilde expansion) on the argument and set $REPLY to the expanded value.
  630. #
  631. # Does not perform filename generation (globbing).
  632. _zsh_highlight_main_highlighter_expand_path()
  633. {
  634. (( $# == 1 )) || echo "zsh-syntax-highlighting: BUG: _zsh_highlight_main_highlighter_expand_path: called without argument" >&2
  635. # The $~1 syntax normally performs filename generation, but not when it's on the right-hand side of ${x:=y}.
  636. setopt localoptions nonomatch
  637. unset REPLY
  638. : ${REPLY:=${(Q)~1}}
  639. }
  640. # -------------------------------------------------------------------------------------------------
  641. # Main highlighter initialization
  642. # -------------------------------------------------------------------------------------------------
  643. _zsh_highlight_main__precmd_hook() {
  644. _zsh_highlight_main__command_type_cache=()
  645. }
  646. autoload -U add-zsh-hook
  647. if add-zsh-hook precmd _zsh_highlight_main__precmd_hook 2>/dev/null; then
  648. # Initialize command type cache
  649. typeset -gA _zsh_highlight_main__command_type_cache
  650. else
  651. echo 'zsh-syntax-highlighting: Failed to load add-zsh-hook. Some speed optimizations will not be used.' >&2
  652. # Make sure the cache is unset
  653. unset _zsh_highlight_main__command_type_cache
  654. fi