*highlight: Set of optimizations, also logic changes (commandseparator)

parse -oo, before:

Running time: 2.2680830000
num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)  350        2260,37     6,46  100,00%   1679,94     4,80   74,32%  -hsmw-highlight-process
 2) 2800         358,98     0,13   15,88%    358,98     0,13   15,88%  -hsmw-highlight-string
 3) 2450          87,01     0,04    3,85%     87,01     0,04    3,85%  -hsmw-highlight-check-path
 4) 1400          72,33     0,05    3,20%     72,33     0,05    3,20%  (anon)
 5) 1400          42,94     0,03    1,90%     42,94     0,03    1,90%  -hsmw-highlight-main-type
 6)  350          10,27     0,03    0,45%     10,27     0,03    0,45%  -hsmw-highlight-stack-pop
 7)  350           8,91     0,03    0,39%      8,91     0,03    0,39%  -hsmw-highlight-path-separators
 8)    1           0,02     0,02    0,00%      0,02     0,02    0,00%  -hsmw-highlight-init

parse -oo, after:

Running time: 2.0801330000
num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)  350        2072,44     5,92  100,00%   1586,54     4,53   76,55%  -hsmw-highlight-process
 2) 2800         341,85     0,12   16,49%    341,85     0,12   16,49%  -hsmw-highlight-string
 3) 2450          83,71     0,03    4,04%     83,71     0,03    4,04%  -hsmw-highlight-check-path
 4) 1400          42,58     0,03    2,05%     42,58     0,03    2,05%  -hsmw-highlight-main-type
 5)  350           9,69     0,03    0,47%      9,69     0,03    0,47%  -hsmw-highlight-stack-pop
 6)  350           8,07     0,02    0,39%      8,07     0,02    0,39%  -hsmw-highlight-path-separators
 7)    1           0,01     0,01    0,00%      0,01     0,01    0,00%  -hsmw-highlight-init
This commit is contained in:
Sebastian Gniazdowski 2016-10-25 13:58:01 +02:00
parent 8ff58ae0ec
commit c87d9acd8f

View file

@ -167,9 +167,10 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
## Variable declarations and initializations
local start_pos=0 end_pos highlight_glob=true arg style
local in_array_assignment=false # true between 'a=(' and the matching ')'
typeset -a __HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR
typeset -a __HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS
typeset -a __HSMW_HIGHLIGHT_TOKENS_CONTROL_FLOW
typeset -a __HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR
integer arg_type=0 # Can be 0, 1, 2 or 3 - look up ^
local -a options_to_set # used in callees
local buf="$1"
integer len="${#buf}"
@ -181,14 +182,6 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
fi
unset path_dirs_was_set
__HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR=(
'|' '||' ';' '&' '&&'
'|&'
'&!' '&|'
# ### 'case' syntax, but followed by a pattern, not by a command
# ';;' ';&' ';|'
)
__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS=(
'builtin' 'command' 'exec' 'nocorrect' 'noglob'
'pkexec' # immune to #121 because it's usually not passed --option flags
@ -212,7 +205,16 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
'!' # reserved word; unrelated to $histchars[1]
)
__HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR=(
'|' '||' ';' '&' '&&'
'|&'
'&!' '&|'
# ### 'case' syntax, but followed by a pattern, not by a command
# ';;' ';&' ';|'
)
local -a match mbegin mend
local MATCH; integer MBEGIN MEND
# State machine
#
@ -305,6 +307,8 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
integer offset=$(( ${proc_buf[(i)$needle]} - 1 ))
(( start_pos += offset ))
(( end_pos = start_pos + $#arg ))
arg_type=3
else
integer offset=0
if [[ "$proc_buf" = (#b)(#s)(([[:space:]]|\\[[:space:]])##)* ]]; then
@ -313,6 +317,16 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
fi
((start_pos+=offset))
((end_pos=start_pos+${#arg}))
if [[ -n ${__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS[(r)$arg]} ]]; then
arg_type=1
elif [[ -n ${__HSMW_HIGHLIGHT_TOKENS_CONTROL_FLOW[(r)$arg]} ]]; then
arg_type=2
elif [[ -n ${__HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR[(r)$arg]} ]]; then
arg_type=3
else
arg_type=0
fi
fi
proc_buf="${proc_buf[offset + $#arg + 1,len]}"
@ -343,10 +357,8 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
if (( this_word & BIT_sudo_opt )) && [[ $arg != -* ]]; then
(( this_word = this_word ^ BIT_sudo_opt ))
fi
fi
# Parse the sudo command line
if (( ! in_redirection )); then
# Parse the sudo command line
if (( this_word & BIT_sudo_opt )); then
case "$arg" in
# Flag that requires an argument
@ -376,7 +388,7 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
style=reserved-word # de facto a reserved word, although not de jure
(( next_word = BIT_start ))
elif (( this_word & BIT_start )) && (( in_redirection == 0 )); then # $arg is the command word
if [[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]]; then
if (( arg_type == 1 )); then
style=precommand
elif [[ "$arg" = "sudo" ]]; then
style=precommand
@ -384,23 +396,20 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
(( next_word = next_word | BIT_sudo_opt ))
(( next_word = next_word | BIT_start ))
else
: ${expanded_path::=${(Q)~arg}}
-hsmw-highlight-main-type $expanded_path
() {
# Special-case: command word is '$foo', like that, without braces or anything.
#
# That's not entirely correct --- if the parameter's value happens to be a reserved
# word, the parameter expansion will be highlighted as a reserved word --- but that
# incorrectness is outweighed by the usability improvement of permitting the use of
# parameters that refer to commands, functions, and builtins.
local MATCH; integer MBEGIN MEND
if [[ $REPLY == none ]] && (( ${+parameters} )) &&
[[ ${arg[1]} == \$ ]] && [[ ${arg:1} = (#m)([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##) ]] &&
(( ${+parameters[${MATCH}]} ))
then
-hsmw-highlight-main-type ${(P)MATCH}
fi
}
# Special-case: command word is '$foo', like that, without braces or anything.
#
# That's not entirely correct --- if the parameter's value happens to be a reserved
# word, the parameter expansion will be highlighted as a reserved word --- but that
# incorrectness is outweighed by the usability improvement of permitting the use of
# parameters that refer to commands, functions, and builtins.
if [[ ${arg[1]} == \$ ]] && (( ${+parameters} )) && [[ ${arg:1} = (#m)([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##) ]] &&
(( ${+parameters[${MATCH}]} ))
then
-hsmw-highlight-main-type ${(P)MATCH}
else
: ${expanded_path::=${(Q)~arg}}
-hsmw-highlight-main-type $expanded_path
fi
case $REPLY in
reserved) # reserved word
style=reserved-word
@ -435,7 +444,7 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
style=alias
-hsmw-highlight-resolve-alias $arg
local alias_target="$REPLY"
[[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$alias_target"} && -z ${(M)__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]] && __HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS+=($arg)
[[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$alias_target"} && "$arg_type" != "1" ]] && __HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS+=($arg)
fi
}
;;
@ -457,7 +466,7 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
style=history-expansion
elif [[ $arg[0,1] == $histchars[2,2] ]]; then
style=history-expansion
elif [[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then
elif (( arg_type == 3 )); then
if (( this_word & BIT_regular )); then
# This highlights empty commands (semicolon follows nothing) as an error.
# Zsh accepts them, though.
@ -508,9 +517,7 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
;;
esac
fi
fi
if (( ! already_added )) && [[ $style == unknown-token ]] && # not handled by the 'command word' codepath
{ (( in_redirection )) || (( this_word & BIT_regular )) || (( this_word & BIT_sudo_opt )) || (( this_word & BIT_sudo_arg )) }
elif { (( in_redirection )) || (( this_word & BIT_regular )) || (( this_word & BIT_sudo_opt )) || (( this_word & BIT_sudo_arg )) }
then # $arg is a non-command word
case $arg in
$'\x29') # subshell or end of array assignment
@ -561,17 +568,12 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
'`'*) style=back-quoted-argument;;
[*?]*|*[^\\][*?]*)
$highlight_glob && style=globbing || style=default;;
*) if false; then
elif [[ $arg = $'\x7d' ]] && $right_brace_is_recognised_everywhere; then
*) if [[ $arg = $'\x7d' ]] && $right_brace_is_recognised_everywhere; then
# was handled by the $'\x7d' case above
elif [[ $arg[0,1] = $histchars[0,1] ]] && (( $#arg[0,2] == 2 )); then
style=history-expansion
elif [[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then
if (( this_word & BIT_regular )); then
elif (( arg_type == 3 )); then
style=commandseparator
else
style=unknown-token
fi
elif (( in_redirection == 2 )); then
style=redirection
else
@ -589,7 +591,7 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
[[ "${HSMW_HIGHLIGHT_STYLES[$style]}" != "none" ]] && reply+=("$start_pos $end_pos ${HSMW_HIGHLIGHT_STYLES[$style]}")
[[ $style == path || $style == path_prefix ]] && -hsmw-highlight-path-separators
fi
if [[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then
if (( arg_type == 3 )); then
if [[ $arg == ';' ]] && $in_array_assignment; then
# literal newline inside an array assignment
(( next_word = BIT_regular ))
@ -597,9 +599,9 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
(( next_word = BIT_start ))
highlight_glob=true
fi
elif [[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_CONTROL_FLOW:#"$arg"} ]] && (( this_word & BIT_start )); then
elif (( arg_type == 2 )) && (( this_word & BIT_start )); then
(( next_word = BIT_start ))
elif [[ -n ${(M)__HSMW_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]] && (( this_word & BIT_start )); then
elif (( arg_type == 1 )) && (( this_word & BIT_start )); then
(( next_word = BIT_start ))
elif [[ $arg == "repeat" ]] && (( this_word & BIT_start )); then
# skip the repeat-count word
@ -617,7 +619,7 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
if (( in_redirection == 0 )); then
# This is the default/common codepath.
(( this_word = next_word ))
else
#else
# Stall $this_word.
fi
done
@ -689,8 +691,6 @@ typeset -gA HSMW_HIGHLIGHT_STYLES
# Highlight special chars inside dollar-quoted strings
-hsmw-highlight-dollar-string()
{
local -a match mbegin mend
local MATCH; integer MBEGIN MEND
local i j k style
local AA
integer c