aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorromkatv <roman.perepelitsa@gmail.com>2020-01-10 23:03:04 +0300
committerromkatv <roman.perepelitsa@gmail.com>2020-01-10 23:03:04 +0300
commit07ee25a147de1321b3f1440983d8191fdf5aaed5 (patch)
treefb4222feb2028d7728a9702bbd50504be0298286
parentbbd5791aac2abc0f125dd83d2b76e159aa653c9a (diff)
add parse.zsh
-rw-r--r--internal/parse.zsh161
1 files changed, 161 insertions, 0 deletions
diff --git a/internal/parse.zsh b/internal/parse.zsh
new file mode 100644
index 00000000..4b29488a
--- /dev/null
+++ b/internal/parse.zsh
@@ -0,0 +1,161 @@
+function _p9k_skip_until() {
+ [[ -z $1 ]] && return
+ while _p9k_next_token 0; do
+ [[ $token == $~1 ]] && return
+ done
+}
+
+function _p9k_next_token() {
+ if (( $#tokens == aln[-1] )); then
+ aln[-1]=()
+ alp[-1]=()
+ fi
+
+ if (( $#tokens == alf[-1] )); then
+ alf[-1]=()
+ 1=1
+ fi
+
+ while (( $#tokens )); do
+ token=$tokens[1]
+ shift 1 tokens
+
+ if (( $+galiases[$token] )); then
+ (( aln[(eI)p$token] )) && return
+ local n=p$token s=$galiases[$token]
+ elif (( ! $1 )); then
+ return
+ elif (( $+aliases[$token] )); then
+ (( aln[(eI)p$token] )) && return
+ local n=p$token s=$aliases[$token]
+ elif [[ $token == (#b)?*.(?*) ]] && (( $+saliases[$match[1]] )); then
+ (( aln[(eI)s$match[1]] )) && return
+ local 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
+}
+
+typeset -gA _p9k_skip_token=(
+ '}' ''
+ '|' ''
+ '||' ''
+ '&' ''
+ '&&' ''
+ '|&' ''
+ '&!' ''
+ '&|' ''
+ ')' ''
+ '(' ''
+ '{' ''
+ '()' ''
+ '!' ''
+ ';' ''
+ 'if' ''
+ 'fi' ''
+ 'elif' ''
+ 'then' ''
+ 'while' ''
+ 'until' ''
+ 'do' ''
+ 'coproc' ''
+ 'nocorrect' ''
+ 'time' ''
+ '-' ''
+ 'builtin' ''
+ '[[' '\]\]'
+ '((' '\)\)'
+ 'case' '\)|esac'
+ ';;' '\)|esac'
+ ';&' '\)|esac'
+ ';|' '\)|esac'
+ '&>' '*'
+ '>' '*'
+ '>&' '*'
+ '<' '*'
+ '<&' '*'
+ '<>' '*'
+ '&>|' '*'
+ '>|' '*'
+ '&>>' '*'
+ '>>' '*'
+ '>>&' '*'
+ '&>>|' '*'
+ '>>|' '*'
+)
+
+typeset -gA _p9k_redirect=(
+ '&>' ''
+ '>' ''
+ '>&' ''
+ '<' ''
+ '<&' ''
+ '<>' ''
+ '&>|' ''
+ '>|' ''
+ '&>>' ''
+ '>>' ''
+ '>>&' ''
+ '&>>|' ''
+ '>>|' ''
+)
+
+function _p9k_extract_commands() {
+ local rcquotes
+ [[ -o rcquotes ]] && rcquotes=(-o rcquotes)
+
+ emulate -L zsh -o extended_glob -o no_nomatch $rcquotes
+
+ typeset -ga _p9k_commands=()
+ local -a aln alp alf match mbegin mend
+ [[ -o interactive_comments ]] && local tokens=(${(Z+C+)1}) || local tokens=(${(z)1})
+
+ while _p9k_next_token 1; do
+ local r=${token#<0-255>}
+ if (( $+_p9k_skip_token[$r] )); then
+ if (( $+_p9k_skip_token[$token] )); then
+ _p9k_skip_until $_p9k_skip_token[$token]
+ continue
+ fi
+ if (( $+_p9k_redirect[$r] )); then
+ _p9k_next_token 0
+ continue
+ fi
+ fi
+
+ if [[ $token == *=* ]]; then
+ local v=${(S)token/#(<->|([[:alpha:]_][[:IDENT:]]#(|'['*[^\\](\\\\)#']')))(|'+')=}
+ if (( $#v < $#token )); then
+ [[ $v == '(' ]] && _p9k_skip_until '\)'
+ continue
+ fi
+ fi
+
+ if [[ $token == *'$'* ]]; then
+ local p='<->|[[:alpha:]_][[:IDENT:]]#'
+ if [[ $token == ('$'$~p|'${'$~p'}'|'"$'$~p'"'|'"${'$~p'}"') ]]; then
+ local name=${${token##[^[:IDENT:]]}%%[^[:IDENT:]]}
+ [[ $token == *'"' ]] && local v=("${(@P)name}") || local v=(${(P)name})
+ tokens[1,0]=(${(qq)v})
+ continue
+ fi
+ fi
+
+ _p9k_commands+=${token::=${(Q)${~token}}}
+
+ # '|' '||' ';' '&' '&&' '|&' '&!' '&|' ';;' ';&' ';|' ')'
+ _p9k_skip_until '\||\|\||;|&|&&|\|&|&!|&\||;;|;&|;\||\)|}'
+ [[ $token == ';'(';'|'&'|'|') ]] && _p9k_skip_until '\)|esac'
+ done
+ true
+}