|
|
- # -*- mode: sh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
- # -------------------------------------------------------------------------------------------------
- # Copyright (c) 2010-2016 zsh-syntax-highlighting contributors
- # Copyright (c) 2016-2019 Sebastian Gniazdowski (modifications)
- # All rights reserved.
- #
- # The only licensing for this file follows.
- #
- # Redistribution and use in source and binary forms, with or without modification, are permitted
- # provided that the following conditions are met:
- #
- # * Redistributions of source code must retain the above copyright notice, this list of conditions
- # and the following disclaimer.
- # * Redistributions in binary form must reproduce the above copyright notice, this list of
- # conditions and the following disclaimer in the documentation and/or other materials provided
- # with the distribution.
- # * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
- # may be used to endorse or promote products derived from this software without specific prior
- # written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- # -------------------------------------------------------------------------------------------------
-
- typeset -gA __fast_highlight_main__command_type_cache FAST_BLIST_PATTERNS
- typeset -g FAST_WORK_DIR
- : ${FAST_WORK_DIR:=$FAST_BASE_DIR}
- FAST_WORK_DIR=${~FAST_WORK_DIR}
- () {
- emulate -L zsh -o extendedglob
- local -A map
- map=( "XDG:" "${XDG_CONFIG_HOME:-$HOME/.config}/fsh/"
- "LOCAL:" "/usr/local/share/fsh/"
- "HOME:" "$HOME/.fsh/"
- "OPT:" "/opt/local/share/fsh/"
- )
- FAST_WORK_DIR=${${FAST_WORK_DIR/(#m)(#s)(XDG|LOCAL|HOME|OPT):(#c0,1)/${map[${MATCH%:}:]}}%/}
- }
-
- # Define default styles. You can set this after loading the plugin in
- # Zshrc and use 256 colors via numbers, like: fg=150
- typeset -gA FAST_HIGHLIGHT_STYLES
- if [[ -e $FAST_WORK_DIR/current_theme.zsh ]]; then
- source $FAST_WORK_DIR/current_theme.zsh
- else
- # built-in theme
- zstyle :plugin:fast-syntax-highlighting theme default
- : ${FAST_HIGHLIGHT_STYLES[default]:=none}
- : ${FAST_HIGHLIGHT_STYLES[unknown-token]:=fg=red,bold}
- : ${FAST_HIGHLIGHT_STYLES[reserved-word]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[subcommand]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[alias]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[suffix-alias]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[global-alias]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[builtin]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[function]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[command]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[precommand]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[commandseparator]:=none}
- : ${FAST_HIGHLIGHT_STYLES[hashed-command]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[path]:=fg=magenta}
- : ${FAST_HIGHLIGHT_STYLES[path-to-dir]:=fg=magenta,underline}
- : ${FAST_HIGHLIGHT_STYLES[path_pathseparator]:=}
- : ${FAST_HIGHLIGHT_STYLES[globbing]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[globbing-ext]:=fg=13}
- : ${FAST_HIGHLIGHT_STYLES[history-expansion]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[single-hyphen-option]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[double-hyphen-option]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[back-quoted-argument]:=none}
- : ${FAST_HIGHLIGHT_STYLES[single-quoted-argument]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[double-quoted-argument]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[dollar-quoted-argument]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[back-or-dollar-double-quoted-argument]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[back-dollar-quoted-argument]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[assign]:=none}
- : ${FAST_HIGHLIGHT_STYLES[redirection]:=none}
- : ${FAST_HIGHLIGHT_STYLES[comment]:=fg=black,bold}
- : ${FAST_HIGHLIGHT_STYLES[variable]:=fg=113}
- : ${FAST_HIGHLIGHT_STYLES[mathvar]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[mathnum]:=fg=magenta}
- : ${FAST_HIGHLIGHT_STYLES[matherr]:=fg=red}
- : ${FAST_HIGHLIGHT_STYLES[assign-array-bracket]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-variable]:=none}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-operator]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-number]:=fg=magenta}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-separator]:=fg=yellow,bold}
- : ${FAST_HIGHLIGHT_STYLES[here-string-tri]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[here-string-text]:=bg=18}
- : ${FAST_HIGHLIGHT_STYLES[here-string-var]:=fg=cyan,bg=18}
- : ${FAST_HIGHLIGHT_STYLES[case-input]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[case-parentheses]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[case-condition]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[paired-bracket]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[bracket-level-1]:=fg=green,bold}
- : ${FAST_HIGHLIGHT_STYLES[bracket-level-2]:=fg=yellow,bold}
- : ${FAST_HIGHLIGHT_STYLES[bracket-level-3]:=fg=cyan,bold}
- : ${FAST_HIGHLIGHT_STYLES[single-sq-bracket]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[double-sq-bracket]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[double-paren]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[correct-subtle]:=fg=12}
- : ${FAST_HIGHLIGHT_STYLES[incorrect-subtle]:=fg=red}
- : ${FAST_HIGHLIGHT_STYLES[subtle-separator]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[subtle-bg]:=bg=18}
- : ${FAST_HIGHLIGHT_STYLES[secondary]:=free}
- fi
-
- # This can overwrite some of *_STYLES fields
- [[ -r $FAST_WORK_DIR/theme_overlay.zsh ]] && source $FAST_WORK_DIR/theme_overlay.zsh
-
- typeset -gA __FAST_HIGHLIGHT_TOKEN_TYPES
-
- __FAST_HIGHLIGHT_TOKEN_TYPES=(
-
- # Precommand
-
- 'builtin' 1
- 'command' 1
- 'exec' 1
- 'nocorrect' 1
- 'noglob' 1
- 'pkexec' 1 # immune to #121 because it's usually not passed --option flags
-
- # Control flow
- # Tokens that, at (naively-determined) "command position", are followed by
- # a de jure command position. All of these are reserved words.
-
- $'\x7b' 2 # block '{'
- $'\x28' 2 # subshell '('
- '()' 2 # anonymous function
- 'while' 2
- 'until' 2
- 'if' 2
- 'then' 2
- 'elif' 2
- 'else' 2
- 'do' 2
- 'time' 2
- 'coproc' 2
- '!' 2 # reserved word; unrelated to $histchars[1]
-
- # Command separators
-
- '|' 3
- '||' 3
- ';' 3
- '&' 3
- '&&' 3
- '|&' 3
- '&!' 3
- '&|' 3
- # ### 'case' syntax, but followed by a pattern, not by a command
- # ';;' ';&' ';|'
- )
-
- # A hash instead of multiple globals
- typeset -gA FAST_HIGHLIGHT
-
- # Brackets highlighter active by default
- : ${FAST_HIGHLIGHT[use_brackets]:=1}
-
- FAST_HIGHLIGHT+=(
- chroma-fast-theme →chroma/-fast-theme.ch
- chroma-alias →chroma/-alias.ch
- chroma-autoload →chroma/-autoload.ch
- chroma-autorandr →chroma/-autorandr.ch
- chroma-docker →chroma/-docker.ch
- chroma-example →chroma/-example.ch
- chroma-ionice →chroma/-ionice.ch
- chroma-make →chroma/-make.ch
- chroma-nice →chroma/-nice.ch
- chroma-nmcli →chroma/-nmcli.ch
- chroma-node →chroma/-node.ch
- chroma-perl →chroma/-perl.ch
- chroma-printf →chroma/-printf.ch
- chroma-ruby →chroma/-ruby.ch
- chroma-scp →chroma/-scp.ch
- chroma-ssh →chroma/-ssh.ch
-
- chroma-git →chroma/main-chroma.ch%git
- chroma-hub →chroma/-hub.ch
- chroma-lab →chroma/-lab.ch
- chroma-svn →chroma/-subversion.ch
- chroma-svnadmin →chroma/-subversion.ch
- chroma-svndumpfilter →chroma/-subversion.ch
-
- chroma-egrep →chroma/-grep.ch
- chroma-fgrep →chroma/-grep.ch
- chroma-grep →chroma/-grep.ch
-
- chroma-awk →chroma/-awk.ch
- chroma-gawk →chroma/-awk.ch
- chroma-mawk →chroma/-awk.ch
-
- chroma-source →chroma/-source.ch
- chroma-. →chroma/-source.ch
-
- chroma-bash →chroma/-sh.ch
- chroma-fish →chroma/-sh.ch
- chroma-sh →chroma/-sh.ch
- chroma-zsh →chroma/-sh.ch
-
- chroma-whatis →chroma/-whatis.ch
- chroma-man →chroma/-whatis.ch
-
- chroma-- →chroma/-precommand.ch
- chroma-xargs →chroma/-precommand.ch
- chroma-nohup →chroma/-precommand.ch
- chroma-strace →chroma/-precommand.ch
- chroma-ltrace →chroma/-precommand.ch
-
- chroma-hg →chroma/-subcommand.ch
- chroma-cvs →chroma/-subcommand.ch
- chroma-pip →chroma/-subcommand.ch
- chroma-pip2 →chroma/-subcommand.ch
- chroma-pip3 →chroma/-subcommand.ch
- chroma-gem →chroma/-subcommand.ch
- chroma-bundle →chroma/-subcommand.ch
- chroma-yard →chroma/-subcommand.ch
- chroma-cabal →chroma/-subcommand.ch
- chroma-npm →chroma/-subcommand.ch
- chroma-nvm →chroma/-subcommand.ch
- chroma-yarn →chroma/-subcommand.ch
- chroma-brew →chroma/-subcommand.ch
- chroma-port →chroma/-subcommand.ch
- chroma-yum →chroma/-subcommand.ch
- chroma-dnf →chroma/-subcommand.ch
- chroma-tmux →chroma/-subcommand.ch
- chroma-pass →chroma/-subcommand.ch
- chroma-aws →chroma/-subcommand.ch
- chroma-apt →chroma/-subcommand.ch
- chroma-apt-get →chroma/-subcommand.ch
- chroma-apt-cache →chroma/-subcommand.ch
- chroma-aptitude →chroma/-subcommand.ch
- chroma-keyctl →chroma/-subcommand.ch
- chroma-systemctl →chroma/-subcommand.ch
- chroma-asciinema →chroma/-subcommand.ch
- chroma-ipfs →chroma/-subcommand.ch
- chroma-zinit →chroma/main-chroma.ch%zinit
- chroma-aspell →chroma/-subcommand.ch
- chroma-bspc →chroma/-subcommand.ch
- chroma-cryptsetup →chroma/-subcommand.ch
- chroma-diskutil →chroma/-subcommand.ch
- chroma-exercism →chroma/-subcommand.ch
- chroma-gulp →chroma/-subcommand.ch
- chroma-i3-msg →chroma/-subcommand.ch
- chroma-openssl →chroma/-subcommand.ch
- chroma-solargraph →chroma/-subcommand.ch
- chroma-subliminal →chroma/-subcommand.ch
- chroma-svnadmin →chroma/-subcommand.ch
- chroma-travis →chroma/-subcommand.ch
- chroma-udisksctl →chroma/-subcommand.ch
- chroma-xdotool →chroma/-subcommand.ch
- chroma-zmanage →chroma/-subcommand.ch
- chroma-zsystem →chroma/-subcommand.ch
- chroma-zypper →chroma/-subcommand.ch
-
- chroma-fpath+=\( →chroma/-fpath_peq.ch
- chroma-fpath=\( →chroma/-fpath_peq.ch
- chroma-FPATH+= →chroma/-fpath_peq.ch
- chroma-FPATH= →chroma/-fpath_peq.ch
- #chroma-which →chroma/-which.ch
- #chroma-vim →chroma/-vim.ch
- )
-
- if [[ $OSTYPE == darwin* ]] {
- noglob unset FAST_HIGHLIGHT[chroma-man] FAST_HIGHLIGHT[chroma-whatis]
- }
-
- # Assignments seen, to know if math parameter exists
- typeset -gA FAST_ASSIGNS_SEEN
-
- # Exposing tokens found on command position,
- # for other scripts to process
- typeset -ga ZLAST_COMMANDS
-
- # Get the type of a command.
- #
- # Uses the zsh/parameter module if available to avoid forks, and a
- # wrapper around 'type -w' as fallback.
- #
- # Takes a single argument.
- #
- # The result will be stored in REPLY.
- -fast-highlight-main-type() {
- REPLY=$__fast_highlight_main__command_type_cache[(e)$1]
- [[ -z $REPLY ]] && {
-
- if zmodload -e zsh/parameter; then
- if (( $+aliases[(e)$1] )); then
- REPLY=alias
- elif (( ${+galiases[(e)$1]} )); then
- REPLY="global alias"
- elif (( $+functions[(e)$1] )); then
- REPLY=function
- elif (( $+builtins[(e)$1] )); then
- REPLY=builtin
- elif (( $+commands[(e)$1] )); then
- REPLY=command
- elif (( $+saliases[(e)${1##*.}] )); then
- REPLY='suffix alias'
- elif (( $reswords[(Ie)$1] )); then
- REPLY=reserved
- # zsh 5.2 and older have a bug whereby running 'type -w ./sudo' implicitly
- # runs 'hash ./sudo=/usr/local/bin/./sudo' (assuming /usr/local/bin/sudo
- # exists and is in $PATH). Avoid triggering the bug, at the expense of
- # falling through to the $() below, incurring a fork. (Issue #354.)
- #
- # The second disjunct mimics the isrelative() C call from the zsh bug.
- elif [[ $1 != */* || ${+ZSH_ARGZERO} = "1" ]] && ! builtin type -w -- $1 >/dev/null 2>&1; then
- REPLY=none
- fi
- fi
-
- [[ -z $REPLY ]] && REPLY="${$(LC_ALL=C builtin type -w -- $1 2>/dev/null)##*: }"
-
- [[ $REPLY = "none" ]] && {
- [[ -n ${FAST_BLIST_PATTERNS[(k)${${(M)1:#/*}:-$PWD/$1}]} ]] || {
- [[ -d $1 ]] && REPLY="dirpath" || {
- for cdpath_dir in $cdpath; do
- [[ -d $cdpath_dir/$1 ]] && { REPLY="dirpath"; break; }
- done
- }
- }
- }
-
- __fast_highlight_main__command_type_cache[(e)$1]=$REPLY
-
- }
- }
-
- # Below are variables that must be defined in outer
- # scope so that they are reachable in *-process()
- -fast-highlight-fill-option-variables() {
- if [[ -o ignore_braces ]] || eval '[[ -o ignore_close_braces ]] 2>/dev/null'; then
- FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=0
- else
- FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=1
- fi
-
- if [[ -o path_dirs ]]; then
- FAST_HIGHLIGHT[path_dirs_was_set]=1
- else
- FAST_HIGHLIGHT[path_dirs_was_set]=0
- fi
-
- if [[ -o multi_func_def ]]; then
- FAST_HIGHLIGHT[multi_func_def]=1
- else
- FAST_HIGHLIGHT[multi_func_def]=0
- fi
-
- if [[ -o interactive_comments ]]; then
- FAST_HIGHLIGHT[ointeractive_comments]=1
- else
- FAST_HIGHLIGHT[ointeractive_comments]=0
- fi
- }
-
- # Main syntax highlighting function.
- -fast-highlight-process()
- {
- emulate -L zsh
- setopt extendedglob bareglobqual nonomatch typesetsilent
-
- [[ $CONTEXT == "select" ]] && return 0
-
- (( FAST_HIGHLIGHT[path_dirs_was_set] )) && setopt PATH_DIRS
- (( FAST_HIGHLIGHT[ointeractive_comments] )) && local interactive_comments= # _set_ to empty
-
- # Variable declarations and initializations
- # in_array_assignment true between 'a=(' and the matching ')'
- # braces_stack: "R" for round, "Q" for square, "Y" for curly
- # _mybuf, cdpath_dir are used in sub-functions
- local _start_pos=$3 _end_pos __start __end highlight_glob=1 __arg __style in_array_assignment=0 MATCH expanded_path braces_stack __buf=$1$2 _mybuf __workbuf cdpath_dir active_command alias_target _was_double_hyphen=0 __nul=$'\0' __tmp
- # __arg_type can be 0, 1, 2 or 3, i.e. precommand, control flow, command separator
- # __idx and _end_idx are used in sub-functions
- # for this_word and next_word look below at commented integers and at state machine description
- integer __arg_type=0 MBEGIN MEND in_redirection __len=${#__buf} __PBUFLEN=${#1} already_added offset __idx _end_idx this_word=1 next_word=0 __pos __asize __delimited=0 itmp iitmp
- local -a match mbegin mend __inputs __list
-
- # This comment explains the numbers:
- # BIT_for - word after reserved-word-recognized `for'
- # BIT_afpcmd - word after a precommand that can take options, like `command' and `exec'
- # integer BIT_start=1 BIT_regular=2 BIT_sudo_opt=4 BIT_sudo_arg=8 BIT_always=16 BIT_for=32 BIT_afpcmd=64
- # integer BIT_chroma=8192
-
- integer BIT_case_preamble=512 BIT_case_item=1024 BIT_case_nempty_item=2048 BIT_case_code=4096
-
- # Braces stack
- # T - typeset, local, etc.
-
- # State machine
- #
- # The states are:
- # - :__start: Command word
- # - :sudo_opt: A leading-dash option to sudo (such as "-u" or "-i")
- # - :sudo_arg: The argument to a sudo leading-dash option that takes one,
- # when given as a separate word; i.e., "foo" in "-u foo" (two
- # words) but not in "-ufoo" (one word).
- # - :regular: "Not a command word", and command delimiters are permitted.
- # Mainly used to detect premature termination of commands.
- # - :always: The word 'always' in the «{ foo } always { bar }» syntax.
- #
- # When the kind of a word is not yet known, $this_word / $next_word may contain
- # multiple states. For example, after "sudo -i", the next word may be either
- # another --flag or a command name, hence the state would include both :__start:
- # and :sudo_opt:.
- #
- # 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:/}
- # 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 --- that is, the value of $this_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. Thus, upon reaching the next word (the one that follows
- # the redirection operator and target), $this_word will still contain values
- # appropriate for the word immediately following the word that preceded the
- # redirection operator.
- #
- # The "the previous word was a redirection operator" state is not communicated
- # to the next iteration via $next_word/$this_word as usual, but via
- # $in_redirection. The value of $next_word from the iteration that processed
- # the operator is discarded.
- #
-
- # Command exposure for other scripts
- ZLAST_COMMANDS=()
- # Restart observing of assigns
- FAST_ASSIGNS_SEEN=()
- # Restart function's gathering
- FAST_HIGHLIGHT[chroma-autoload-elements]=""
- # Restart FPATH elements gathering
- FAST_HIGHLIGHT[chroma-fpath_peq-elements]=""
- # Restart svn zinit's ICE gathering
- FAST_HIGHLIGHT[chroma-zinit-ice-elements-svn]=0
- FAST_HIGHLIGHT[chroma-zinit-ice-elements-id-as]=""
-
- [[ -n $ZCALC_ACTIVE ]] && {
- _start_pos=0; _end_pos=__len; __arg=$__buf
- -fast-highlight-math-string
- return 0
- }
-
- # Processing buffer
- local proc_buf=$__buf needle
- for __arg in ${interactive_comments-${(z)__buf}} \
- ${interactive_comments+${(zZ+c+)__buf}}; do
-
- # Initialize $next_word to its default value?
- (( in_redirection = in_redirection > 0 ? in_redirection - 1 : in_redirection ));
- (( next_word = (in_redirection == 0) ? 2 : next_word )) # else Stall $next_word.
- (( next_word = next_word | (this_word & (BIT_case_code|8192)) ))
-
- # If we have a good delimiting construct just ending, and '{'
- # occurs, then respect this and go for alternate syntax, i.e.
- # treat '{' (\x7b) as if it's on command position
- [[ $__arg = '{' && $__delimited = 2 ]] && { (( this_word = (this_word & ~2) | 1 )); __delimited=0; }
-
- __asize=${#__arg}
-
- # Reset state of working variables
- already_added=0
- __style=${FAST_THEME_NAME}unknown-token
- (( this_word & 1 )) && { in_array_assignment=0; [[ $__arg == 'noglob' ]] && highlight_glob=0; }
-
- # Compute the new $_start_pos and $_end_pos, skipping over whitespace in $__buf.
- if [[ $__arg == ';' ]] ; then
- braces_stack=${braces_stack#T}
- __delimited=0
-
- # Both ; and \n are rendered as a ";" (SEPER) by the ${(z)..} flag.
- needle=$';\n'
- [[ $proc_buf = (#b)[^$needle]#([$needle]##)* ]] && offset=${mbegin[1]}-1
- (( _start_pos += offset ))
- (( _end_pos = _start_pos + __asize ))
-
- # Prepare next loop cycle
- (( this_word & BIT_case_item )) || { (( in_array_assignment )) && (( this_word = 2 | (this_word & BIT_case_code) )) || { (( this_word = 1 | (this_word & BIT_case_code) )); highlight_glob=1; }; }
- in_redirection=0
-
- # Chance to highlight ';'
- [[ ${proc_buf[offset+1]} != $'\n' ]] && {
- [[ ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}commandseparator]} != "none" ]] && \
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}commandseparator]}")
- }
-
- proc_buf=${proc_buf[offset + __asize + 1,__len]}
- _start_pos=$_end_pos
- continue
- else
- offset=0
- if [[ $proc_buf = (#b)(#s)(([[:space:]]|\\[[:space:]])##)* ]]; then
- # The first, outer parenthesis
- offset=${mend[1]}
- fi
- (( _start_pos += offset ))
- (( _end_pos = _start_pos + __asize ))
-
- # No-hit will result in value 0
- __arg_type=${__FAST_HIGHLIGHT_TOKEN_TYPES[$__arg]}
- fi
-
- (( this_word & 1 )) && ZLAST_COMMANDS+=( $__arg );
-
- proc_buf=${proc_buf[offset + __asize + 1,__len]}
-
- # Handle the INTERACTIVE_COMMENTS option.
- #
- # We use the (Z+c+) flag so the entire comment is presented as one token in $__arg.
- if [[ -n ${interactive_comments+'set'} && $__arg == ${histchars[3]}* ]]; then
- if (( this_word & 3 )); then
- __style=${FAST_THEME_NAME}comment
- else
- __style=${FAST_THEME_NAME}unknown-token # prematurely terminated
- fi
- # ADD
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- _start_pos=$_end_pos
- continue
- fi
-
- # Redirection?
- [[ $__arg == (<0-9>|)(\<|\>)* && $__arg != (\<|\>)$'\x28'* && $__arg != "<<<" ]] && \
- in_redirection=2
-
- # Special-case the first word after 'sudo'.
- if (( ! in_redirection )); then
- (( this_word & 4 )) && [[ $__arg != -* ]] && (( this_word = this_word ^ 4 ))
-
- # Parse the sudo command line
- if (( this_word & 4 )); then
- case $__arg in
- # Flag that requires an argument
- '-'[Cgprtu])
- (( this_word = this_word & ~1 ))
- (( next_word = 8 | (this_word & BIT_case_code) ))
- ;;
- # This prevents misbehavior with sudo -u -otherargument
- '-'*)
- (( this_word = this_word & ~1 ))
- (( next_word = next_word | 1 | 4 ))
- ;;
- esac
- elif (( this_word & 8 )); then
- (( next_word = next_word | 4 | 1 ))
- elif (( this_word & 64 )); then
- [[ $__arg = -[pvV-]## && $active_command = "command" ]] && (( this_word = (this_word & ~1) | 2, next_word = (next_word | 65) & ~2 ))
- [[ $__arg = -[cla-]## && $active_command = "exec" ]] && (( this_word = (this_word & ~1) | 2, next_word = (next_word | 65) & ~2 ))
- [[ $__arg = \{[a-zA-Z_][a-zA-Z0-9_]#\} && $active_command = "exec" ]] && {
- # Highlight {descriptor} passed to exec
- (( this_word = (this_word & ~1) | 2, next_word = (next_word | 65) & ~2 ))
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}exec-descriptor]}")
- already_added=1
- }
- fi
- fi
-
- (( this_word & 8192 )) && {
- __list=( ${(z@)${aliases[$active_command]:-${active_command##*/}}##[[:space:]]#(command|builtin|exec|noglob|nocorrect|pkexec)[[:space:]]#} )
- ${${FAST_HIGHLIGHT[chroma-${__list[1]}]}%\%*} ${(M)FAST_HIGHLIGHT[chroma-${__list[1]}]%\%*} 0 "$__arg" $_start_pos $_end_pos 2>/dev/null && continue
- }
-
- (( this_word & 1 )) && {
- # !in_redirection needed particularly for exec {A}>b {C}>d
- (( !in_redirection )) && active_command=$__arg
- _mybuf=${${aliases[$active_command]:-${active_command##*/}}##[[:space:]]#(command|builtin|exec|noglob|nocorrect|pkexec)[[:space:]]#}
- [[ "$_mybuf" = (#b)(FPATH+(#c0,1)=)* ]] && _mybuf="${match[1]} ${(j: :)${(s,:,)${_mybuf#FPATH+(#c0,1)=}}}"
- [[ -n ${FAST_HIGHLIGHT[chroma-${_mybuf%% *}]} ]] && {
- __list=( ${(z@)_mybuf} )
- if (( ${#__list} > 1 )) || [[ $active_command != $_mybuf ]]; then
- __style=${FAST_THEME_NAME}alias
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
-
- ${${FAST_HIGHLIGHT[chroma-${__list[1]}]}%\%*} ${(M)FAST_HIGHLIGHT[chroma-${__list[1]}]%\%*} 1 "${__list[1]}" "-100000" $_end_pos 2>/dev/null || \
- (( this_word = next_word, next_word = 2 ))
-
- for _mybuf in "${(@)__list[2,-1]}"; do
- (( next_word = next_word | (this_word & (BIT_case_code|8192)) ))
- ${${FAST_HIGHLIGHT[chroma-${__list[1]}]}%\%*} ${(M)FAST_HIGHLIGHT[chroma-${__list[1]}]%\%*} 0 "$_mybuf" "-100000" $_end_pos 2>/dev/null || \
- (( this_word = next_word, next_word = 2 ))
- done
-
- # This might have been done multiple times in chroma, but
- # as _end_pos doesn't change, it can be done one more time
- _start_pos=$_end_pos
-
- continue
- else
- ${${FAST_HIGHLIGHT[chroma-${__list[1]}]}%\%*} ${(M)FAST_HIGHLIGHT[chroma-${__list[1]}]%\%*} 1 "$__arg" $_start_pos $_end_pos 2>/dev/null && continue
- fi
- } || (( 1 ))
- }
-
- expanded_path=""
-
- # The Great Fork: is this a command word? Is this a non-command word?
- if (( this_word & 16 )) && [[ $__arg == 'always' ]]; then
- # try-always construct
- __style=${FAST_THEME_NAME}reserved-word # de facto a reserved word, although not de jure
- (( next_word = 1 | (this_word & BIT_case_code) ))
- elif (( (this_word & 1) && (in_redirection == 0) )) || [[ $braces_stack = T* ]]; then # T - typedef, etc.
- if (( __arg_type == 1 )); then
- __style=${FAST_THEME_NAME}precommand
- [[ $__arg = "command" || $__arg = "exec" ]] && (( next_word = next_word | 64 ))
- elif [[ $__arg = (sudo|doas) ]]; then
- __style=${FAST_THEME_NAME}precommand
- (( next_word = (next_word & ~2) | 4 | 1 ))
- else
- _mybuf=${${(Q)__arg}#\"}
- if (( ${+parameters} )) && \
- [[ $_mybuf = (#b)(*)(*)\$([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##)(*) || \
- $_mybuf = (#b)(*)(*)\$\{([a-zA-Z_][a-zA-Z0-9_:-]#|[0-9]##)(*) ]] && \
- (( ${+parameters[${match[3]%%:-*}]} ))
- then
- -fast-highlight-main-type ${match[1]}${match[2]}${(P)match[3]%%:-*}${match[4]#\}}
- elif [[ $braces_stack = T* ]]; then # T - typedef, etc.
- REPLY=none
- else
- : ${expanded_path::=${~_mybuf}}
- -fast-highlight-main-type $expanded_path
- fi
-
- case $REPLY in
- reserved) # reserved word
- [[ $__arg = "[[" ]] && __style=${FAST_THEME_NAME}double-sq-bracket || __style=${FAST_THEME_NAME}reserved-word
- if [[ $__arg == $'\x7b' ]]; then # Y - '{'
- braces_stack='Y'$braces_stack
-
- elif [[ $__arg == $'\x7d' && $braces_stack = Y* ]]; then # Y - '}'
- # We're at command word, so no need to check right_brace_is_recognised_everywhere
- braces_stack=${braces_stack#Y}
- __style=${FAST_THEME_NAME}reserved-word
- (( next_word = next_word | 16 ))
-
- elif [[ $__arg == "[[" ]]; then # A - [[
- braces_stack='A'$braces_stack
-
- # Counting complex brackets (for brackets-highlighter): 1. [[ as command
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN + 1 )) )
- elif [[ $__arg == "for" ]]; then
- (( next_word = next_word | 32 )) # BIT_for
-
- elif [[ $__arg == "case" ]]; then
- (( next_word = BIT_case_preamble ))
-
- elif [[ $__arg = (typeset|declare|local|float|integer|export|readonly) ]]; then
- braces_stack='T'$braces_stack
- fi
- ;;
- 'suffix alias') __style=${FAST_THEME_NAME}suffix-alias;;
- 'global alias') __style=${FAST_THEME_NAME}global-alias;;
-
- alias)
- if [[ $__arg = ?*'='* ]]; then
- # The so called (by old code) "insane_alias"
- __style=${FAST_THEME_NAME}unknown-token
- else
- __style=${FAST_THEME_NAME}alias
- (( ${+aliases} )) && alias_target=${aliases[$__arg]} || alias_target="${"$(alias -- $__arg)"#*=}"
- [[ ${__FAST_HIGHLIGHT_TOKEN_TYPES[$alias_target]} = "1" && $__arg_type != "1" ]] && __FAST_HIGHLIGHT_TOKEN_TYPES[$__arg]="1"
- fi
- ;;
-
- builtin) [[ $__arg = "[" ]] && {
- __style=${FAST_THEME_NAME}single-sq-bracket
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) )
- } || __style=${FAST_THEME_NAME}builtin
- # T - typeset, etc. mode
- [[ $__arg = (typeset|declare|local|float|integer|export|readonly) ]] && braces_stack='T'$braces_stack
- [[ $__arg = eval ]] && (( next_word = next_word | 256 ))
- ;;
-
- function) __style=${FAST_THEME_NAME}function;;
-
- command) __style=${FAST_THEME_NAME}command;;
-
- hashed) __style=${FAST_THEME_NAME}hashed-command;;
-
- dirpath) __style=${FAST_THEME_NAME}path-to-dir;;
-
- none) # Assign?
- if [[ $__arg == [a-zA-Z_][a-zA-Z0-9_]#(|\[[^\]]#\])(|[^\]]#\])(|[+])=* || $__arg == [0-9]##(|[+])=* || ( $braces_stack = T* && ${__arg_type} != 3 ) ]] {
- __style=${FAST_THEME_NAME}assign
- FAST_ASSIGNS_SEEN[${__arg%%=*}]=1
-
- # Handle array assignment
- [[ $__arg = (#b)*=(\()*(\))* || $__arg = (#b)*=(\()* ]] && {
- (( __start=_start_pos-__PBUFLEN+${mbegin[1]}-1, __end=__start+1, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}assign-array-bracket]}")
- # Counting complex brackets (for brackets-highlighter): 2. ( in array assign
- _FAST_COMPLEX_BRACKETS+=( $__start )
- (( mbegin[2] >= 1 )) && {
- (( __start=_start_pos-__PBUFLEN+${mbegin[2]}-1, __end=__start+1, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}assign-array-bracket]}")
- # Counting complex brackets (for brackets-highlighter): 3a. ) in array assign
- _FAST_COMPLEX_BRACKETS+=( $__start )
- } || in_array_assignment=1
- } || { [[ ${braces_stack[1]} != 'T' ]] && (( next_word = (next_word | 1) & ~2 )); }
-
- # Handle no-string highlight, string "/' highlight, math mode highlight
- local ctmp="\"" dtmp="'"
- itmp=${__arg[(i)$ctmp]}-1 iitmp=${__arg[(i)$dtmp]}-1
- integer jtmp=${__arg[(b:itmp+2:i)$ctmp]} jjtmp=${__arg[(b:iitmp+2:i)$dtmp]}
- (( itmp < iitmp && itmp <= __asize - 1 )) && (( jtmp > __asize && (jtmp = __asize), 1 > 0 )) && \
- (( __start=_start_pos-__PBUFLEN+itmp, __end=_start_pos-__PBUFLEN+jtmp, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-quoted-argument]}") && \
- { itmp=${__arg[(i)=]}; __arg=${__arg[itmp,__asize]}; (( _start_pos += itmp - 1 ));
- -fast-highlight-string; (( _start_pos = _start_pos - itmp + 1, 1 > 0 )); } || \
- {
- (( iitmp <= __asize - 1 )) && (( jjtmp > __asize && (jjtmp = __asize), 1 > 0 )) && \
- (( __start=_start_pos-__PBUFLEN+iitmp, __end=_start_pos-__PBUFLEN+jjtmp, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}single-quoted-argument]}")
- } || \
- {
- itmp=${__arg[(i)=]}; __arg=${__arg[itmp,__asize]}; (( _start_pos += itmp - 1 ));
- [[ ${__arg[2,4]} = '$((' ]] && { -fast-highlight-math-string;
- (( __start=_start_pos-__PBUFLEN+2, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 4. $(( in assign argument
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- (( jtmp = ${__arg[(I)\)\)]}-1, jtmp > 0 )) && {
- (( __start=_start_pos-__PBUFLEN+jtmp, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 5. )) in assign argument
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- }
- } || -fast-highlight-string;
- (( _start_pos = _start_pos - itmp + 1, 1 > 0 ))
- }
-
- } elif [[ $__arg = ${histchars[1]}* && -n ${__arg[2]} ]] {
- __style=${FAST_THEME_NAME}history-expansion
-
- } elif [[ $__arg == ${histchars[2]}* ]] {
- __style=${FAST_THEME_NAME}history-expansion
-
- } elif (( __arg_type == 3 )) {
- # This highlights empty commands (semicolon follows nothing) as an error.
- # Zsh accepts them, though.
- (( this_word & 3 )) && __style=${FAST_THEME_NAME}commandseparator
-
- } elif [[ $__arg[1,2] == '((' ]] {
- # Arithmetic evaluation.
- #
- # Note: prior to zsh-5.1.1-52-g4bed2cf (workers/36669), the ${(z)...}
- # splitter would only output the '((' token if the matching '))' had
- # been typed. Therefore, under those versions of zsh, BUFFER="(( 42"
- # would be highlighted as an error until the matching "))" are typed.
- #
- # We highlight just the opening parentheses, as a reserved word; this
- # is how [[ ... ]] is highlighted, too.
-
- # ADD
- (( __start=_start_pos-__PBUFLEN, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- already_added=1
-
- # Counting complex brackets (for brackets-highlighter): 6. (( as command
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
-
- -fast-highlight-math-string
-
- # ADD
- [[ $__arg[-2,-1] == '))' ]] && {
- (( __start=_end_pos-__PBUFLEN-2, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- (( __delimited = __delimited ? 2 : __delimited ))
-
- # Counting complex brackets (for brackets-highlighter): 7. )) for as-command ((
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- }
-
- } elif [[ $__arg == '()' ]] {
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN + 1 )) )
- # anonymous function
- __style=${FAST_THEME_NAME}reserved-word
- } elif [[ $__arg == $'\x28' ]] {
- # subshell '(', stack: letter 'R'
- __style=${FAST_THEME_NAME}reserved-word
- braces_stack='R'$braces_stack
-
- } elif [[ $__arg == $'\x29' ]] {
- # ')', stack: letter 'R' for subshell
- [[ $braces_stack = R* ]] && { braces_stack=${braces_stack#R}; __style=${FAST_THEME_NAME}reserved-word; }
-
- } elif (( this_word & 14 )) {
- __style=${FAST_THEME_NAME}default
-
- } elif [[ $__arg = (';;'|';&'|';|') ]] && (( this_word & BIT_case_code )) {
- (( next_word = (next_word | BIT_case_item) & ~(BIT_case_code+3) ))
- __style=${FAST_THEME_NAME}default
-
- } elif [[ $__arg = \$\([^\(]* ]] {
- already_added=1
- }
- ;;
- *)
- # ADD
- # (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end commandtypefromthefuture-$REPLY")
- already_added=1
- ;;
- esac
- fi
- # in_redirection || BIT_regular || BIT_sudo_opt || BIT_sudo_arg
- elif (( in_redirection + this_word & 14 ))
- then # $__arg is a non-command word
- case $__arg in
- ']]')
- # A - [[
- [[ $braces_stack = A* ]] && {
- __style=${FAST_THEME_NAME}double-sq-bracket
- (( __delimited = __delimited ? 2 : __delimited ))
- # Counting complex brackets (for brackets-highlighter): 8a. ]] for as-command [[
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- } || {
- [[ $braces_stack = *A* ]] && {
- __style=${FAST_THEME_NAME}unknown-token
- # Counting complex brackets (for brackets-highlighter): 8b. ]] for as-command [[
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- } || __style=${FAST_THEME_NAME}default
- }
- braces_stack=${braces_stack#A}
- ;;
- ']')
- __style=${FAST_THEME_NAME}single-sq-bracket
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) )
- ;;
- $'\x28')
- # '(' inside [[
- __style=${FAST_THEME_NAME}reserved-word
- braces_stack='R'$braces_stack
- ;;
- $'\x29') # ')' - subshell or end of array assignment
- if (( in_array_assignment )); then
- in_array_assignment=0
- (( next_word = next_word | 1 ))
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}assign-array-bracket]}")
- already_added=1
- # Counting complex brackets (for brackets-highlighter): 3b. ) in array assign
- _FAST_COMPLEX_BRACKETS+=( $__start )
- elif [[ $braces_stack = R* ]]; then
- braces_stack=${braces_stack#R}
- __style=${FAST_THEME_NAME}reserved-word
- # Zsh doesn't tokenize final ) if it's just single ')',
- # but logically what's below is correct, so it is kept
- # in case Zsh will be changed / fixed, etc.
- elif [[ $braces_stack = F* ]]; then
- __style=${FAST_THEME_NAME}builtin
- fi
- ;;
- $'\x28\x29') # '()' - possibly a function definition
- # || false # TODO: or if the previous word was a command word
- (( FAST_HIGHLIGHT[multi_func_def] )) && (( next_word = next_word | 1 ))
- __style=${FAST_THEME_NAME}reserved-word
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN + 1 )) )
- # Remove possible annoying unknown-token __style, or misleading function __style
- reply[-1]=()
- __fast_highlight_main__command_type_cache[$active_command]="function"
- ;;
- '--'*) [[ $__arg == "--" ]] && { _was_double_hyphen=1; __style=${FAST_THEME_NAME}double-hyphen-option; } || {
- (( !_was_double_hyphen )) && {
- [[ "$__arg" = (#b)(--[a-zA-Z0-9_]##)=(*) ]] && {
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-hyphen-option]}")
- (( __start=_start_pos-__PBUFLEN+1+mend[1], __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}optarg-${${${(M)match[2]:#<->}:+number}:-string}]}")
- already_added=1
- } || __style=${FAST_THEME_NAME}double-hyphen-option
- } || __style=${FAST_THEME_NAME}default
- }
- ;;
- '-'*) (( !_was_double_hyphen )) && __style=${FAST_THEME_NAME}single-hyphen-option || __style=${FAST_THEME_NAME}default;;
- \$\'*)
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}dollar-quoted-argument]}")
- -fast-highlight-dollar-string
- already_added=1
- ;;
- [\"\']*|[^\"\\]##([\\][\\])#\"*|[^\'\\]##([\\][\\])#\'*)
- # 256 is eval-mode
- if (( this_word & 256 )) && [[ $__arg = [\'\"]* ]]; then
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}recursive-base]}")
- if [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]} ]]; then
- __idx=1
- _mybuf=$FAST_THEME_NAME
- FAST_THEME_NAME=${${${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]}:t:r}#(XDG|LOCAL|HOME|OPT):}
- (( ${+FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}default]} )) || source $FAST_WORK_DIR/secondary_theme.zsh
- else
- __idx=0
- fi
- (( _start_pos-__PBUFLEN >= 0 )) && \
- -fast-highlight-process "$PREBUFFER" "${${__arg%[\'\"]}#[\'\"]}" $(( _start_pos + 1 ))
- (( __idx )) && FAST_THEME_NAME=$_mybuf
- already_added=1
- else
- [[ $__arg = *([^\\][\#][\#]|"(#b)"|"(#B)"|"(#m)"|"(#c")* && $highlight_glob -ne 0 ]] && \
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}globbing-ext]}")
- # Reusing existing vars, treat this code like C++ STL
- # header, full of underscores and unhelpful var names
- itmp=0 __workbuf=$__arg __tmp="" cdpath_dir=$__arg
- while [[ $__workbuf = (#b)[^\"\'\\]#(([\"\'])|[\\](*))(*) ]]; do
- [[ -n ${match[3]} ]] && {
- itmp+=${mbegin[1]}
- # Optionally skip 1 quoted char
- [[ $__tmp = \' ]] && __workbuf=${match[3]} || { itmp+=1; __workbuf=${match[3]:1}; }
- } || {
- itmp+=${mbegin[1]}
- __workbuf=${match[4]}
- # Toggle quoting
- [[ ( ${match[1]} = \" && $__tmp != \' ) || ( ${match[1]} = \' && $__tmp != \" ) ]] && {
- [[ $__tmp = [\"\'] ]] && {
- # End of quoting
- (( __start=_start_pos-__PBUFLEN+iitmp-1, __end=_start_pos-__PBUFLEN+itmp, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}${${${__tmp#\'}:+double-quoted-argument}:-single-quoted-argument}]}")
- already_added=1
-
- [[ $__tmp = \" ]] && {
- __arg=${cdpath_dir[iitmp+1,itmp-1]}
- (( _start_pos += iitmp - 1 + 1 ))
- -fast-highlight-string
- (( _start_pos = _start_pos - iitmp + 1 - 1 ))
- }
- # The end-of-quoting proper algorithm action
- __tmp=
- } || {
- # Beginning of quoting
- iitmp=itmp
- # The beginning-of-quoting proper algorithm action
- __tmp=${match[1]}
- }
- }
- }
- done
- [[ $__tmp = [\"\'] ]] && {
- (( __start=_start_pos-__PBUFLEN+iitmp-1, __end=_start_pos-__PBUFLEN+__asize, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}${${${__tmp#\'}:+double-quoted-argument}:-single-quoted-argument}]}")
- already_added=1
-
- [[ $__tmp = \" ]] && {
- __arg=${cdpath_dir[iitmp+1,__asize]}
- (( _start_pos += iitmp - 1 + 1 ))
- -fast-highlight-string
- (( _start_pos = _start_pos - iitmp + 1 - 1 ))
- }
- }
- fi
- ;;
- \$\(\(*)
- already_added=1
- -fast-highlight-math-string
- # ADD
- (( __start=_start_pos-__PBUFLEN+1, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 9. $(( as argument
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- # ADD
- [[ $__arg[-2,-1] == '))' ]] && (( __start=_end_pos-__PBUFLEN-2, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 10. )) for as-argument $((
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- ;;
- '`'*)
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}back-quoted-argument]}")
- if [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]} ]]; then
- __idx=1
- _mybuf=$FAST_THEME_NAME
- FAST_THEME_NAME=${${${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]}:t:r}#(XDG|LOCAL|HOME|OPT):}
- (( ${+FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}default]} )) || source $FAST_WORK_DIR/secondary_theme.zsh
- else
- __idx=0
- fi
- (( _start_pos-__PBUFLEN >= 0 )) && \
- -fast-highlight-process "$PREBUFFER" "${${__arg%[\`]}#[\`]}" $(( _start_pos + 1 ))
- (( __idx )) && FAST_THEME_NAME=$_mybuf
- already_added=1
- ;;
- '((') # 'F' - (( after for
- (( this_word & 32 )) && {
- braces_stack='F'$braces_stack
- __style=${FAST_THEME_NAME}double-paren
- # Counting complex brackets (for brackets-highlighter): 11. (( as for-syntax
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- # This is set after __arg_type == 2, and also here,
- # when another alternate-syntax capable command occurs
- __delimited=1
- }
- ;;
- '))') # 'F' - (( after for
- [[ $braces_stack = F* ]] && {
- braces_stack=${braces_stack#F}
- __style=${FAST_THEME_NAME}double-paren
- # Counting complex brackets (for brackets-highlighter): 12. )) as for-syntax
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- (( __delimited = __delimited ? 2 : __delimited ))
- }
- ;;
- '<<<')
- (( next_word = (next_word | 128) & ~3 ))
- [[ ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-tri]} != "none" ]] && (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-tri]}")
- already_added=1
- ;;
- *) # F - (( after for
- if [[ $braces_stack = F* ]]; then
- -fast-highlight-string
- _mybuf=$__arg
- __idx=_start_pos
- while [[ $_mybuf = (#b)[^a-zA-Z\{\$]#([a-zA-Z][a-zA-Z0-9]#)(*) ]]; do
- (( __start=__idx-__PBUFLEN+${mbegin[1]}-1, __end=__idx-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-variable]}")
- __idx+=${mend[1]}
- _mybuf=${match[2]}
- done
-
- _mybuf=$__arg
- __idx=_start_pos
- while [[ $_mybuf = (#b)[^+\<\>=:\*\|\&\^\~-]#([+\<\>=:\*\|\&\^\~-]##)(*) ]]; do
- (( __start=__idx-__PBUFLEN+${mbegin[1]}-1, __end=__idx-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-operator]}")
- __idx+=${mend[1]}
- _mybuf=${match[2]}
- done
-
- _mybuf=$__arg
- __idx=_start_pos
- while [[ $_mybuf = (#b)[^0-9]#([0-9]##)(*) ]]; do
- (( __start=__idx-__PBUFLEN+${mbegin[1]}-1, __end=__idx-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-number]}")
- __idx+=${mend[1]}
- _mybuf=${match[2]}
- done
-
- if [[ $__arg = (#b)[^\;]#(\;)[\ ]# ]]; then
- (( __start=_start_pos-__PBUFLEN+${mbegin[1]}-1, __end=_start_pos-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-separator]}")
- fi
-
- already_added=1
- elif [[ $__arg = *([^\\][\#][\#]|"(#b)"|"(#B)"|"(#m)"|"(#c")* ]]; then
- (( highlight_glob )) && __style=${FAST_THEME_NAME}globbing-ext || __style=${FAST_THEME_NAME}default
- elif [[ $__arg = ([*?]*|*[^\\][*?]*) ]]; then
- (( highlight_glob )) && __style=${FAST_THEME_NAME}globbing || __style=${FAST_THEME_NAME}default
- elif [[ $__arg = \$* ]]; then
- __style=${FAST_THEME_NAME}variable
- elif [[ $__arg = $'\x7d' && $braces_stack = Y* && ${FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]} = "1" ]]; then
- # right brace, i.e. $'\x7d' == '}'
- # Parsing rule: # {
- #
- # Additionally, `tt(})' is recognized in any position if neither the
- # tt(IGNORE_BRACES) option nor the tt(IGNORE_CLOSE_BRACES) option is set."""
- braces_stack=${braces_stack#Y}
- __style=${FAST_THEME_NAME}reserved-word
- (( next_word = next_word | 16 ))
- elif [[ $__arg = (';;'|';&'|';|') ]] && (( this_word & BIT_case_code )); then
- (( next_word = (next_word | BIT_case_item) & ~(BIT_case_code+3) ))
- __style=${FAST_THEME_NAME}default
- elif [[ $__arg = ${histchars[1]}* && -n ${__arg[2]} ]]; then
- __style=${FAST_THEME_NAME}history-expansion
- elif (( __arg_type == 3 )); then
- __style=${FAST_THEME_NAME}commandseparator
- elif (( in_redirection == 2 )); then
- __style=${FAST_THEME_NAME}redirection
- elif (( ${+galiases[(e)$__arg]} )); then
- __style=${FAST_THEME_NAME}global-alias
- else
- if [[ ${FAST_HIGHLIGHT[no_check_paths]} != 1 ]]; then
- if [[ ${FAST_HIGHLIGHT[use_async]} != 1 ]]; then
- if -fast-highlight-check-path noasync; then
- # ADD
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- already_added=1
-
- # TODO: path separators, optimize and add to async code-path
- [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path_pathseparator]} && ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path]} != ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path_pathseparator]} ]] && {
- for (( __pos = _start_pos; __pos <= _end_pos; __pos++ )) ; do
- # ADD
- [[ ${__buf[__pos]} == "/" ]] && (( __start=__pos-__PBUFLEN, __start >= 0 )) && reply+=("$(( __start - 1 )) $__start ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path_pathseparator]}")
- done
- }
- else
- __style=${FAST_THEME_NAME}default
- fi
- else
- if [[ -z ${FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}]} || $(( EPOCHSECONDS - FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}-born-at] )) -gt 8 ]]; then
- if [[ $LASTWIDGET != *-or-beginning-search ]]; then
- exec {PCFD}< <(-fast-highlight-check-path; sleep 5)
- command sleep 0
- FAST_HIGHLIGHT[path-queue]+=";$_start_pos $_end_pos;"
- is-at-least 5.0.6 && __pos=1 || __pos=0
- zle -F ${${__pos:#0}:+-w} $PCFD fast-highlight-check-path-handler
- already_added=1
- else
- __style=${FAST_THEME_NAME}default
- fi
- elif [[ ${FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}]%D} -eq 1 ]]; then
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path${${(M)FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}]%D}:+-to-dir}]}")
- already_added=1
- else
- __style=${FAST_THEME_NAME}default
- fi
- fi
- else
- __style=${FAST_THEME_NAME}default
- fi
- fi
- ;;
- esac
- elif (( this_word & 128 ))
- then
- (( next_word = (next_word | 2) & ~129 ))
- [[ ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-text]} != "none" ]] && (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-text]}")
- -fast-highlight-string ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-var]:#none}
- already_added=1
- elif (( this_word & (BIT_case_preamble + BIT_case_item) ))
- then
- if (( this_word & BIT_case_preamble )); then
- [[ $__arg = "in" ]] && {
- __style=${FAST_THEME_NAME}reserved-word
- (( next_word = BIT_case_item ))
- } || {
- __style=${FAST_THEME_NAME}case-input
- (( next_word = BIT_case_preamble ))
- }
- else
- if (( this_word & BIT_case_nempty_item == 0 )) && [[ $__arg = "esac" ]]; then
- (( next_word = 1 ))
- __style=${FAST_THEME_NAME}reserved-word
- elif [[ $__arg = (\(*\)|\)|\() ]]; then
- [[ $__arg = *\) ]] && (( next_word = BIT_case_code | 1 )) || (( next_word = BIT_case_item | BIT_case_nempty_item ))
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) )
- (( ${#__arg} > 1 )) && {
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos+${#__arg}-1-__PBUFLEN )) )
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}case-parentheses]}")
- (( __start=_start_pos+1-__PBUFLEN, __end=_end_pos-1-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}case-condition]}")
- already_added=1
- } || {
- __style=${FAST_THEME_NAME}case-parentheses
- }
- else
- (( next_word = BIT_case_item | BIT_case_nempty_item ))
- __style=${FAST_THEME_NAME}case-condition
- fi
- fi
- fi
- if [[ $__arg = (#b)*'#'(([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])|([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F]))* || $__arg = (#b)*'rgb('(([0-9a-fA-F][0-9a-fA-F](#c0,1)),([0-9a-fA-F][0-9a-fA-F](#c0,1)),([0-9a-fA-F][0-9a-fA-F](#c0,1)))* ]]; then
- if [[ -n $match[2] ]]; then
- if [[ $match[2] = ?? || $match[3] = ?? || $match[4] = ?? ]]; then
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end bg=#${(l:2::0:)match[2]}${(l:2::0:)match[3]}${(l:2::0:)match[4]}")
- else
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end bg=#$match[2]$match[3]$match[4]")
- fi
- else
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end bg=#$match[5]$match[6]$match[7]")
- fi
- already_added=1
- fi
-
- # ADD
- (( already_added == 0 )) && [[ ${FAST_HIGHLIGHT_STYLES[$__style]} != "none" ]] && (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
-
- if (( (__arg_type == 3) && ((this_word & (BIT_case_preamble|BIT_case_item)) == 0) )); then
- if [[ $__arg == ';' ]] && (( in_array_assignment )); then
- # literal newline inside an array assignment
- (( next_word = 2 | (next_word & BIT_case_code) ))
- elif [[ -n ${braces_stack[(r)A]} ]]; then
- # 'A' in stack -> inside [[ ... ]]
- (( next_word = 2 | (next_word & BIT_case_code) ))
- else
- braces_stack=${braces_stack#T}
- (( next_word = 1 | (next_word & BIT_case_code) ))
- highlight_glob=1
- # A new command means that we should not expect that alternate
- # syntax will occur (this is also in the ';' short-path), but
- # || and && mean going down just 1 step, not all the way to 0
- [[ $__arg != ("||"|"&&") ]] && __delimited=0 || (( __delimited = __delimited == 2 ? 1 : __delimited ))
- fi
- elif (( ( (__arg_type == 1) || (__arg_type == 2) ) && (this_word & 1) )); then # (( __arg_type == 1 || __arg_type == 2 )) && (( this_word & 1 ))
- __delimited=1
- (( next_word = 1 | (next_word & (64 | BIT_case_code)) ))
- elif [[ $__arg == "repeat" ]] && (( this_word & 1 )); then
- __delimited=1
- # skip the repeat-count word
- in_redirection=2
- # The redirection mechanism assumes $this_word describes the word
- # following the redirection. Make it so.
- #
- # That word can be a command word with shortloops (`repeat 2 ls`)
- # or a command separator (`repeat 2; ls` or `repeat 2; do ls; done`).
- #
- # The repeat-count word will be handled like a redirection target.
- (( this_word = 3 ))
- fi
- _start_pos=$_end_pos
- # This is the default/common codepath.
- (( this_word = in_redirection == 0 ? next_word : this_word )) #else # Stall $this_word.
- done
-
- # Do we have whole buffer? I.e. start at zero
- [[ $3 != 0 ]] && return 0
-
- # The loop overwrites ")" with "x", except those from $( ) substitution
- #
- # __pos: current nest level, starts from 0
- # __workbuf: copy of __buf, with limit on 250 characters
- # __idx: index in whole command line buffer
- # __list: list of coordinates of ) which shouldn't be ovewritten
- _mybuf=${__buf[1,250]} __workbuf=$_mybuf __idx=0 __pos=0 __list=()
-
- while [[ $__workbuf = (#b)[^\(\)]#([\(\)])(*) ]]; do
- if [[ ${match[1]} == \( ]]; then
- __arg=${_mybuf[__idx+${mbegin[1]}-1,__idx+${mbegin[1]}-1+2]}
- [[ $__arg = '$('[^\(] ]] && __list+=( $__pos )
- [[ $__arg = '$((' ]] && _mybuf[__idx+${mbegin[1]}-1]=x
- # Increase parenthesis level
- __pos+=1
- else
- # Decrease parenthesis level
- __pos=__pos-1
- [[ -z ${__list[(r)$__pos]} ]] && [[ $__pos -gt 0 ]] && _mybuf[__idx+${mbegin[1]}]=x
- fi
- __idx+=${mbegin[2]}-1
- __workbuf=${match[2]}
- done
-
- # Run on fake buffer with replaced parentheses: ")" into "x"
- if [[ "$_mybuf" = *$__nul* ]]; then
- # Try to avoid conflict with the \0, however
- # we have to split at *some* character - \7
- # is ^G, so one cannot have null and ^G at
- # the same time on the command line
- __nul=$'\7'
- fi
-
- __inputs=( ${(ps:$__nul:)${(S)_mybuf//(#b)*\$\(([^\)]#)(\)|(#e))/${mbegin[1]};${mend[1]}${__nul}}%$__nul*} )
- if [[ "${__inputs[1]}" != "$_mybuf" && -n "${__inputs[1]}" ]]; then
- if [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]} ]]; then
- __idx=1
- __tmp=$FAST_THEME_NAME
- FAST_THEME_NAME=${${${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]}:t:r}#(XDG|LOCAL|HOME|OPT):}
- (( ${+FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}default]} )) || source $FAST_WORK_DIR/secondary_theme.zsh
- else
- __idx=0
- fi
- for _mybuf in $__inputs; do
- (( __start=${_mybuf%%;*}-__PBUFLEN-1, __end=${_mybuf##*;}-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${__tmp}recursive-base]}")
- # Pass authentic buffer for recursive analysis
- -fast-highlight-process "$PREBUFFER" "${__buf[${_mybuf%%;*},${_mybuf##*;}]}" $(( ${_mybuf%%;*} - 1 ))
- done
- # Restore theme
- (( __idx )) && FAST_THEME_NAME=$__tmp
- fi
-
- return 0
- }
-
- -fast-highlight-check-path()
- {
- (( _start_pos-__PBUFLEN >= 0 )) || \
- { [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"; return 1; }
- [[ $1 != "noasync" ]] && {
- print -r -- ${sysparams[pid]}
- # This is to fill cache
- print -r -- $__arg
- }
-
- : ${expanded_path:=${(Q)~__arg}}
- [[ -n ${FAST_BLIST_PATTERNS[(k)${${(M)expanded_path:#/*}:-$PWD/$expanded_path}]} ]] && { [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"; return 1; }
-
- [[ -z $expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"; return 1; }
- [[ -d $expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos ${_end_pos}D" || __style=${FAST_THEME_NAME}path-to-dir; return 0; }
- [[ -e $expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos $_end_pos" || __style=${FAST_THEME_NAME}path; return 0; }
-
- # Search the path in CDPATH, only for CD command
- [[ $active_command = "cd" ]] && for cdpath_dir in $cdpath; do
- [[ -d $cdpath_dir/$expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos ${_end_pos}D" || __style=${FAST_THEME_NAME}path-to-dir; return 0; }
- [[ -e $cdpath_dir/$expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos $_end_pos" || __style=${FAST_THEME_NAME}path; return 0; }
- done
-
- # It's not a path.
- [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"
- return 1
- }
-
- -fast-highlight-check-path-handler() {
- local IFS=$'\n' pid PCFD=$1 line stripped val
- integer idx
-
- if read -r -u $PCFD pid; then
- if read -r -u $PCFD val; then
- if read -r -u $PCFD line; then
- stripped=${${line#- }%D}
- FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}-born-at]=$EPOCHSECONDS
- idx=${${FAST_HIGHLIGHT[path-queue]}[(I)$stripped]}
- (( idx > 0 )) && {
- if [[ $line != -* ]]; then
- FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}]="1${(M)line%D}"
- region_highlight+=("${line%% *} ${${line##* }%D} ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path${${(M)line%D}:+-to-dir}]}")
- else
- FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}]=0
- fi
- val=${FAST_HIGHLIGHT[path-queue]}
- val[idx-1,idx+${#stripped}]=""
- FAST_HIGHLIGHT[path-queue]=$val
- [[ ${FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}]%D} = 1 && ${#val} -le 27 ]] && zle -R
- }
- fi
- fi
- kill -9 $pid 2>/dev/null
- fi
-
- zle -F -w ${PCFD}
- exec {PCFD}<&-
- }
-
- zle -N -- fast-highlight-check-path-handler -fast-highlight-check-path-handler
-
- # Highlight special blocks inside double-quoted strings
- #
- # The while [[ ... ]] pattern is logically ((A)|(B)|(C)|(D)|(E))(*), where:
- # - A matches $var[abc]
- # - B matches ${(...)var[abc]}
- # - C matches $
- # - D matches \$ or \" or \'
- # - E matches \*
- #
- # and the first condition -n ${match[7] uses D to continue searching when
- # backslash-something (not ['"$]) is occured.
- #
- # $1 - additional style to glue-in to added style
- -fast-highlight-string()
- {
- (( _start_pos-__PBUFLEN >= 0 )) || return 0
- _mybuf=$__arg
- __idx=_start_pos
-
- # 7 8
- while [[ $_mybuf = (#b)[^\$\\]#((\$(#B)([#+^=~](#c1,2))(#c0,1)(#B)([a-zA-Z_:][a-zA-Z0-9_:]#|[0-9]##)(#b)(\[[^\]]#\])(#c0,1))|(\$[{](#B)([#+^=~](#c1,2))(#c0,1)(#b)(\([a-zA-Z0-9_:@%#]##\))(#c0,1)[a-zA-Z0-9_:#]##(\[[^\]]#\])(#c0,1)[}])|\$|[\\][\'\"\$]|[\\](*))(*) ]]; do
- [[ -n ${match[7]} ]] && {
- # Skip following char – it is quoted. Choice is
- # made to not highlight such quoting
- __idx+=${mbegin[1]}+1
- _mybuf=${match[7]:1}
- } || {
- __idx+=${mbegin[1]}-1
- _end_idx=__idx+${mend[1]}-${mbegin[1]}+1
- _mybuf=${match[8]}
-
- # ADD
- (( __start=__idx-__PBUFLEN, __end=_end_idx-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${${1:+$1}:-${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}back-or-dollar-double-quoted-argument]}}")
-
- __idx=_end_idx
- }
- done
- return 0
- }
-
- # Highlight math and non-math context variables inside $(( )) and (( ))
- #
- # The while [[ ... ]] pattern is logically ((A)|(B)|(C)|(D))(*), where:
- # - A matches $var[abc]
- # - B matches ${(...)var[abc]}
- # - C matches $
- # - D matches words [a-zA-Z]## (variables)
- #
- # Parameters used: _mybuf, __idx, _end_idx, __style
- -fast-highlight-math-string()
- {
- (( _start_pos-__PBUFLEN >= 0 )) || return 0
- _mybuf=$__arg
- __idx=_start_pos
-
- # 7
- while [[ $_mybuf = (#b)[^\$_a-zA-Z0-9]#((\$(#B)(+|)(#B)([a-zA-Z_:][a-zA-Z0-9_:]#|[0-9]##)(#b)(\[[^\]]##\])(#c0,1))|(\$[{](#B)(+|)(#b)(\([a-zA-Z0-9_:@%#]##\))(#c0,1)[a-zA-Z0-9_:#]##(\[[^\]]##\])(#c0,1)[}])|\$|[a-zA-Z_][a-zA-Z0-9_]#|[0-9]##)(*) ]]; do
- __idx+=${mbegin[1]}-1
- _end_idx=__idx+${mend[1]}-${mbegin[1]}+1
- _mybuf=${match[7]}
-
- [[ ${match[1]} = [0-9]* ]] && __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}mathnum]} || {
- [[ ${match[1]} = [a-zA-Z_]* ]] && {
- [[ ${+parameters[${match[1]}]} = 1 || ${FAST_ASSIGNS_SEEN[${match[1]}]} = 1 ]] && \
- __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}mathvar]} || \
- __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}matherr]}
- } || {
- [[ ${match[1]} = "$"* ]] && {
- match[1]=${match[1]//[\{\}+]/}
- if [[ ${match[1]} = "$" || ${FAST_ASSIGNS_SEEN[${match[1]:1}]} = 1 ]] || \
- { eval "[[ -n \${(P)\${match[1]:1}} ]]" } 2>> /dev/null; then
- __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}back-or-dollar-double-quoted-argument]}
- else
- __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}matherr]}
- fi
- }
- }
- }
-
- # ADD
- [[ $__style != "none" && -n $__style ]] && (( __start=__idx-__PBUFLEN, __end=_end_idx-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end $__style")
-
- __idx=_end_idx
- done
- }
-
- # Highlight special chars inside dollar-quoted strings
- -fast-highlight-dollar-string()
- {
- (( _start_pos-__PBUFLEN >= 0 )) || return 0
- local i j k __style
- local AA
- integer c
-
- # Starting dollar-quote is at 1:2, so __start parsing at offset 3 in the string.
- for (( i = 3 ; i < _end_pos - _start_pos ; i += 1 )) ; do
- (( j = i + _start_pos - 1 ))
- (( k = j + 1 ))
-
- case ${__arg[$i]} in
- "\\") __style=${FAST_THEME_NAME}back-dollar-quoted-argument
- for (( c = i + 1 ; c <= _end_pos - _start_pos ; c += 1 )); do
- [[ ${__arg[$c]} != ([0-9xXuUa-fA-F]) ]] && break
- done
- AA=$__arg[$i+1,$c-1]
- # Matching for HEX and OCT values like \0xA6, \xA6 or \012
- if [[ "$AA" == (#m)(#s)(x|X)[0-9a-fA-F](#c1,2)
- || "$AA" == (#m)(#s)[0-7](#c1,3)
- || "$AA" == (#m)(#s)u[0-9a-fA-F](#c1,4)
- || "$AA" == (#m)(#s)U[0-9a-fA-F](#c1,8)
- ]]; then
- (( k += MEND ))
- (( i += MEND ))
- else
- if (( __asize > i+1 )) && [[ $__arg[i+1] == [xXuU] ]]; then
- # \x not followed by hex digits is probably an error
- __style=${FAST_THEME_NAME}unknown-token
- fi
- (( k += 1 )) # Color following char too.
- (( i += 1 )) # Skip parsing the escaped char.
- fi
- ;;
- *) continue ;;
-
- esac
- # ADD
- (( __start=j-__PBUFLEN, __end=k-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- done
- }
-
- -fast-highlight-init() {
- _FAST_COMPLEX_BRACKETS=()
- __fast_highlight_main__command_type_cache=()
- }
-
- typeset -ga FSH_LIST
- -fsh_sy_h_shappend() {
- FSH_LIST+=( "$(( $1 - 1 ));;$(( $2 ))" )
- }
-
- functions -M fsh_sy_h_append 2 2 -fsh_sy_h_shappend 2>/dev/null
-
- # vim:ft=zsh:sw=2:sts=2
|