From db9913984d3e7198b9e24ae92e48bdc241a9cb32 Mon Sep 17 00:00:00 2001 From: romkatv Date: Sat, 11 Jan 2020 19:02:54 +0100 Subject: [PATCH] integrate the new command buffer parser intp p10k --- internal/p10k.zsh | 310 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 290 insertions(+), 20 deletions(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index 815ed997..70eaf8e2 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4804,6 +4804,8 @@ typeset -g _p9k__param_pat typeset -g _p9k__param_sig _p9k_init_vars() { + typeset -g _p9k__last_buffer + typeset -ga _p9k__last_commands typeset -g _p9k__last_tty typeset -gi _p9k__must_restore_prompt typeset -gi _p9k__restore_prompt_fd @@ -5237,6 +5239,288 @@ _p9k_init_params() { done } +typeset -grA __p9k_pb_cmd_skip=( + '}' '' + '|' '' + '||' '' + '&' '' + '&&' '' + '|&' '' + '&!' '' + '&|' '' + ')' '' + '(' '' + '{' '' + '()' '' + '!' '' + ';' '' + 'if' '' + 'fi' '' + 'elif' '' + 'else' '' + 'then' '' + 'while' '' + 'until' '' + 'do' '' + 'done' '' + 'esac' '' + 'end' '' + 'coproc' '' + 'nocorrect' '' + 'noglob' '' + 'time' '' + '[[' '\]\]' + '((' '\)\)' + 'case' '\)|esac' + ';;' '\)|esac' + ';&' '\)|esac' + ';|' '\)|esac' + 'foreach' '\(*\)' +) + +typeset -grA __p9k_pb_precommand=( + '-' '' + 'builtin' '' + 'command' '' + 'exec' '-[^a]#[a]' + 'nohup' '' + 'setsid' '' + 'eatmydata' '' + 'catchsegv' '' + 'pkexec' '--user' + 'doas' '-[^aCu]#[acU]' + 'nice' '-[^n]#[n]|--adjustment' + 'stdbuf' '-[^ioe]#[ioe]|--(input|output|error)' + 'sudo' '-[^aghpuUCcrtT]#[aghpuUCcrtT]|--(close-from|group|host|prompt|role|type|other-user|command-timeout|user)' +) + +typeset -grA __p9k_pb_redirect=( + '&>' '' + '>' '' + '>&' '' + '<' '' + '<&' '' + '<>' '' + '&>|' '' + '>|' '' + '&>>' '' + '>>' '' + '>>&' '' + '&>>|' '' + '>>|' '' + '<<<' '' +) + +typeset -grA __p9k_pb_term=( + '|' '' + '||' '' + ';' '' + '&' '' + '&&' '' + '|&' '' + '&!' '' + '&|' '' + ';;' '' + ';&' '' + ';|' '' + '(' '' + ')' '' + '{' '' + '}' '' + '()' '' +) + +typeset -grA __p9k_pb_term_skip=( + '()' '' + '(' '\)' + ';;' '\)|esac' + ';&' '\)|esac' + ';|' '\)|esac' +) + +# False positives: +# +# {} always {} +# +# False negatives: +# +# --------------- +# : $(x) +# --------------- +# : `x` +# --------------- +# +# Broken: +# +# --------------- +# ${x/} +# --------------- +# - -- x +# --------------- +# command -p -p x +# --------------- +# * +# --------------- +# x=$y; $x +# --------------- +# x < 0 )) || return; do + token=$tokens[1] + tokens[1]=() + if (( $+galiases[$token] )); then + (( $aln[(eI)p$token] )) && break + n=p$token + s=$galiases[$token] + elif (( e )); then + break + elif (( $+aliases[$token] )); then + (( $aln[(eI)p$token] )) && break + n=p$token + s=$aliases[$token] + elif [[ $token == (#b)?*.(?*) ]] && (( $+saliases[$match[1]] )); then + (( $aln[(eI)s$match[1]] )) && break + n=s$match[1] + s=${saliases[$match[1]]%% #} + else + break + fi + aln+=$n + alp+=$#tokens + [[ $s == *' ' ]] && alf+=$#tokens + [[ -o interactive_comments ]] && tokens[1,0]=(${(Z+C+)s}) || tokens[1,0]=(${(z)s}) + done + + case $state in + t|p*) + if (( $+__p9k_pb_term[$token] )); then + skip=$__p9k_pb_term_skip[$token] + state=${skip:+s} + [[ $token == '()' ]] || P9K_COMMANDS+=($commands) + commands=() + continue + elif [[ $state == t ]]; then + continue + fi;; + s) + if [[ $token == $~skip ]]; then + state= + fi + continue;; + *r) + state[1]= + continue;; + h) + skip=${(b)token} + state=s + continue;; + esac + + if [[ $token == '<<'(|-) ]]; then + state=h + continue + fi + + if (( $+__p9k_pb_redirect[${token#<0-255>}] )); then + state+=r + continue + fi + + if [[ $token == *'$'* ]]; then + if [[ $token == $~var ]]; then + n=${${token##[^[:IDENT:]]}%%[^[:IDENT:]]} + [[ $token == *'"' ]] && v=("${(@P)n}") || v=(${(P)n}) + tokens[1,0]=(${(qq)v}) + continue + fi + fi + + case $state in + '') + if (( $+__p9k_pb_cmd_skip[$token] )); then + skip=$__p9k_pb_cmd_skip[$token] + state=${skip:+s} + continue + fi + if [[ $token == *=* ]]; then + v=${(S)token/#(<->|([[:alpha:]_][[:IDENT:]]#(|'['*[^\\](\\\\)#']')))(|'+')=} + if (( $#v < $#token )); then + if [[ $v == '(' ]]; then + state=s + skip='\)' + fi + continue + fi + fi + : ${token::=${(Q)${~token}}};; + p) + : ${token::=${(Q)${~token}}} + case $token in + [^-]*) ;; + --) state=p1; continue;; + $~skip) state=p2; continue;; + *) continue;; + esac;; + p1) ;; + p2) + state=p + continue;; + esac + + commands+=$token + if (( $+__p9k_pb_precommand[$commands[-1]] )); then + state=p + skip=$__p9k_pb_precommand[$commands[-1]] + else + state=t + fi + done + } + + P9K_COMMANDS+=($commands) + P9K_COMMANDS=(${(u)P9K_COMMANDS:#('(('*'))'|'`'*'`'|'$'*)}) +} + function _p9k_on_widget_zle-keymap-select() { __p9k_reset_state=2; } function _p9k_on_widget_overwrite-mode() { __p9k_reset_state=2; } function _p9k_on_widget_vi-replace() { __p9k_reset_state=2; } @@ -5300,28 +5584,14 @@ function _p9k_widget_hook() { setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} (( _p9k__restore_prompt_fd )) && _p9k_restore_prompt $_p9k__restore_prompt_fd __p9k_reset_state=1 - if (( $+_p9k__last_buffer )); then - local P9K_LASTBUFFER=$_p9k__last_buffer - local P9K_LASTCURSOR=$_p9k__last_cursor - local P9K_LASTCOMMAND=$_p9k__last_command - fi - if [[ $+_p9k__last_buffer == 1 && $_p9k__last_buffer == $BUFFER ]]; then - local P9K_COMMAND=$_p9k__last_command + local -a P9K_COMMANDS + if [[ $_p9k__last_buffer == $PREBUFFER$BUFFER ]]; then + P9K_COMMANDS=($_p9k__last_commands) else - local words=("${(@z)BUFFER}") # cannot use an inline array with (A) because of bugs in old zsh - local P9K_COMMAND="${(Q)words[1]}" - if (( $+aliases[$P9K_COMMAND] )); then - if functions[_p9k_buffer_cmd]=${(q)P9K_COMMAND} 2>/dev/null; then - P9K_COMMAND="${(Q)${(Az)functions[_p9k_buffer_cmd]}[1]}" - unset 'functions[_p9k_buffer_cmd]' - else - P9K_COMMAND= - fi - fi + _p9k__last_buffer=$PREBUFFER$BUFFER + _p9k_parse_buffer $_p9k__last_buffer # 2>/dev/null + _p9k__last_commands=($P9K_COMMANDS) fi - _p9k__last_buffer=$BUFFER - _p9k__last_cursor=$CURSOR - _p9k__last_command=$P9K_COMMAND (( $+functions[p10k-on-post-widget] )) && p10k-on-post-widget "${@:2}" (( $+functions[_p9k_on_widget_$1] )) && _p9k_on_widget_$1 (( __p9k_reset_state == 2 )) && _p9k_reset_prompt