typeset -gA _p9k_skip_token=( '}' '' '|' '' '||' '' '&' '' '&&' '' '|&' '' '&!' '' '&|' '' ')' '' '(' '' '{' '' '()' '' '!' '' ';' '' 'if' '' 'fi' '' 'elif' '' 'else' '' 'then' '' 'while' '' 'until' '' 'do' '' 'done' '' 'esac' '' 'end' '' 'coproc' '' 'nocorrect' '' 'time' '' '-' '' 'builtin' '' # this is wrong as it will cause alias expansion '[[' '\]\]' '((' '\)\)' 'case' '\)|esac' ';;' '\)|esac' ';&' '\)|esac' ';|' '\)|esac' '&>' '*' '>' '*' '>&' '*' '<' '*' '<&' '*' '<>' '*' '&>|' '*' '>|' '*' '&>>' '*' '>>' '*' '>>&' '*' '&>>|' '*' '>>|' '*' '<<<' '*' 'foreach' '\(*\)' ) typeset -gA _p9k_redirect=( '&>' '' '>' '' '>&' '' '<' '' '<&' '' '<>' '' '&>|' '' '>|' '' '&>>' '' '>>' '' '>>&' '' '&>>|' '' '>>|' '' '<<<' '' ) typeset -gA _p9k_term=( '|' '' '||' '' ';' '' '&' '' '&&' '' '|&' '' '&!' '' '&|' '' ';;' '' ';&' '' ';|' '' '(' '' ')' '' '{' '' '}' '' '()' '' ) typeset -gA _p9k_skip_arg=( ';;' '\)|esac' ';&' '\)|esac' ';|' '\)|esac' '(' '\)' '()' '' ) function _p9k_next_token() { if (( $#tokens == aln[-1] )); then aln[-1]=() alp[-1]=() if (( $#tokens == alf[-1] )); then alf[-1]=() (( e = 0 )) else (( e = 1 )) fi else (( e = 1 )) fi while (( $#tokens )); do token=$tokens[1] shift 1 tokens if (( $+galiases[$token] )); then (( $aln[(eI)p$token] )) && return n=p$token s=$galiases[$token] elif (( e )); then return elif (( $+aliases[$token] )); then (( $aln[(eI)p$token] )) && return n=p$token s=$aliases[$token] elif [[ $token == (#b)?*.(?*) ]] && (( $+saliases[$match[1]] )); then (( $aln[(eI)s$match[1]] )) && return n=s$match[1] s=${saliases[$match[1]]%% #} else return 0 fi aln+=$n alp+=$#tokens [[ $s == *' ' ]] && alf+=$#tokens [[ -o interactive_comments ]] && tokens[1,0]=(${(Z+C+)s}) || tokens[1,0]=(${(z)s}) done token= return 1 } # False positives: # # {} always {} # # False negatives: # # --------------- # : $(x) # --------------- # : `x` # --------------- # # Broken: # # --------------- # ${x/} # --------------- # * # --------------- # x=$y; $x # --------------- # x <} if (( $+_p9k_skip_token[$r] )); then if (( $+_p9k_skip_token[$token] )); then skip=$_p9k_skip_token[$token] continue fi if (( $+_p9k_redirect[$r] )); then skip='*' continue fi fi if [[ $token == *=* ]]; then v=${(S)token/#(<->|([[:alpha:]_][[:IDENT:]]#(|'['*[^\\](\\\\)#']')))(|'+')=} if (( $#v < $#token )); then [[ $v == '(' ]] && skip='\)' continue fi fi if [[ $token == *'$'* ]]; then if [[ $token == $~id ]]; then n=${${token##[^[:IDENT:]]}%%[^[:IDENT:]]} [[ $token == *'"' ]] && v=("${(@P)n}") || v=(${(P)name}) tokens[1,0]=(${(qq)v}) continue fi fi commands+=${:-${(Q)${~token}}} skip=']' done _p9k_commands+=($commands) _p9k_commands=(${(u)_p9k_commands:#('(('*'))'|'`'*'`'|'$'*)}) }