I've replaced near all if [[ ]] calls with [[ ]] in zsh-syntax-highlighting's main-highlighter.zsh, and no performance was gained. So unless there's a tight loop, if [[ doesn't slow down when compared to [[ alone. BTW. Running attached parse.zsh on toparse.zsh with zsh-5.2 in shebang produces following difference in generated region_highlight, to /bin/zsh (OS X 5.0.8): 439c439 < 3878 3885 fg=yellow --- > 3878 3885 fg=green The same difference for 5.1.1, 5.1. Zsh-5.0.8-dev-0 doesn't produce the difference, and 5.0.8-dev-1 produces it, so apparently that's where the difference starts appearing, compared to OS X 5.0.8 /bin/zsh. Best regards, Sebastian Gniazdowski
diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index 6df671e..8a0d68d 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -92,9 +92,7 @@ _zsh_highlight_main_add_region_highlight() { _zsh_highlight_main__type() { if (( $+_zsh_highlight_main__command_type_cache )); then REPLY=$_zsh_highlight_main__command_type_cache[(e)$1] - if [[ -n "$REPLY" ]]; then - return - fi + [[ -n "$REPLY" ]] && return fi if (( $#options_to_set )); then setopt localoptions $options_to_set; @@ -289,15 +287,13 @@ _zsh_highlight_highlighter_main_paint() # the string's color. integer already_added=0 style=unknown-token - if [[ $this_word == *':start:'* ]]; then + [[ $this_word == *':start:'* ]] && { in_array_assignment=false - if [[ $arg == 'noglob' ]]; then - highlight_glob=false - fi - fi + [[ $arg == 'noglob' ]] && highlight_glob=false + } # Compute the new $start_pos and $end_pos, skipping over whitespace in $buf. - if [[ $arg == ';' ]] ; then + [[ $arg == ';' ]] && { # We're looking for either a semicolon or a newline, whichever comes # first. Both of these are rendered as a ";" (SEPER) by the ${(z)..} # flag. @@ -310,11 +306,11 @@ _zsh_highlight_highlighter_main_paint() integer offset=$(( ${proc_buf[(i)$needle]} - 1 )) (( start_pos += offset )) (( end_pos = start_pos + $#arg )) - else + } || { integer offset=$(((len-start_pos)-${#${proc_buf##([[:space:]]|\\[[:space:]])#}})) ((start_pos+=offset)) ((end_pos=$start_pos+${#arg})) - fi + } # Compute the new $proc_buf. We advance it # (chop off characters from the beginning) @@ -338,33 +334,23 @@ _zsh_highlight_highlighter_main_paint() # 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[1] == $histchars[3] ]]; then - if [[ $this_word == *(':regular:'|':start:')* ]]; then - style=comment - else - style=unknown-token # prematurely terminated - fi + [[ -n ${interactive_comments+'set'} && $arg[1] == $histchars[3] ]] && { + [[ $this_word == *(':regular:'|':start:')* ]] && style=comment || style=unknown-token # prematurely terminated _zsh_highlight_main_add_region_highlight $start_pos $end_pos $style already_added=1 continue - fi + } # Analyse the current word. - if _zsh_highlight_main__is_redirection $arg ; then - # A '<' or '>', possibly followed by a digit - in_redirection=2 - fi + # A '<' or '>', possibly followed by a digit + _zsh_highlight_main__is_redirection $arg && in_redirection=2 # Special-case the first word after 'sudo'. - if (( ! in_redirection )); then - if [[ $this_word == *':sudo_opt:'* ]] && [[ $arg != -* ]]; then - this_word=${this_word//:sudo_opt:/} - fi - fi + (( ! in_redirection )) && [[ $this_word == *':sudo_opt:'* ]] && [[ $arg != -* ]] && this_word=${this_word//:sudo_opt:/} # Parse the sudo command line - if (( ! in_redirection )); then - if [[ $this_word == *':sudo_opt:'* ]]; then + (( ! in_redirection )) && { + [[ $this_word == *':sudo_opt:'* ]] && { case "$arg" in # Flag that requires an argument '-'[Cgprtu]) this_word=${this_word//:start:/}; @@ -375,22 +361,21 @@ _zsh_highlight_highlighter_main_paint() next_word+=':sudo_opt:';; *) ;; esac - elif [[ $this_word == *':sudo_arg:'* ]]; then - next_word+=':sudo_opt:' - next_word+=':start:' - fi - fi + } || { + [[ $this_word == *':sudo_arg:'* ]] && next_word+=':sudo_opt:' && next_word+=':start:' + } + } # The Great Fork: is this a command word? Is this a non-command word? - if [[ $this_word == *':start:'* ]] && (( in_redirection == 0 )); then # $arg is the command word - if [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]]; then - style=precommand - elif [[ "$arg" = "sudo" ]]; then + [[ $this_word == *':start:'* ]] && (( in_redirection == 0 )) && { + [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]] && { style=precommand - next_word=${next_word//:regular:/} - next_word+=':sudo_opt:' - next_word+=':start:' - else + } || { [[ "$arg" = "sudo" ]] && { + style=precommand + next_word=${next_word//:regular:/} + next_word+=':sudo_opt:' + next_word+=':start:' + } || { _zsh_highlight_main_highlighter_expand_path $arg local expanded_arg="$REPLY" _zsh_highlight_main__type ${expanded_arg} @@ -404,13 +389,10 @@ _zsh_highlight_highlighter_main_paint() # parameters that refer to commands, functions, and builtins. local -a match mbegin mend local MATCH; integer MBEGIN MEND - if [[ $res == none ]] && (( ${+parameters} )) && - [[ ${arg[1]} == \$ ]] && [[ ${arg:1} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+)$ ]] && - (( ${+parameters[${MATCH}]} )) - then + [[ $res == none ]] && (( ${+parameters} )) && [[ ${arg[1]} == \$ ]] && [[ ${arg:1} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+)$ ]] && (( ${+parameters[${MATCH}]} )) && { _zsh_highlight_main__type ${(P)MATCH} res=$REPLY - fi + } } case $res in reserved) style=reserved-word;; @@ -429,14 +411,12 @@ _zsh_highlight_highlighter_main_paint() # - The common case: (*) :;; esac - if (( insane_alias )); then - style=unknown-token - else + (( insane_alias )) && style=unknown-token || { style=alias _zsh_highlight_main__resolve_alias $arg local alias_target="$REPLY" [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$alias_target"} && -z ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} ]] && ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS+=($arg) - fi + } } ;; builtin) style=builtin;; @@ -457,13 +437,9 @@ _zsh_highlight_highlighter_main_paint() elif [[ $arg[0,1] == $histchars[2,2] ]]; then style=history-expansion elif [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then - if [[ $this_word == *':regular:'* ]]; then + [[ $this_word == *':regular:'* ]] && style=commandseparator || style=unknown-token # This highlights empty commands (semicolon follows nothing) as an error. # Zsh accepts them, though. - style=commandseparator - else - style=unknown-token - fi elif (( in_redirection == 2 )); then style=redirection elif [[ $arg[1,2] == '((' ]]; then @@ -479,31 +455,26 @@ _zsh_highlight_highlighter_main_paint() style=reserved-word _zsh_highlight_main_add_region_highlight $start_pos $((start_pos + 2)) $style already_added=1 - if [[ $arg[-2,-1] == '))' ]]; then + [[ $arg[-2,-1] == '))' ]] && { _zsh_highlight_main_add_region_highlight $((end_pos - 2)) $end_pos $style already_added=1 - fi + } elif [[ $arg == '()' || $arg == $'\x28' ]]; then # anonymous function # subshell style=reserved-word else - if _zsh_highlight_main_highlighter_check_path; then - style=$REPLY - else - style=unknown-token - fi + _zsh_highlight_main_highlighter_check_path && style=$REPLY || style=unknown-token fi ;; *) _zsh_highlight_main_add_region_highlight $start_pos $end_pos commandtypefromthefuture-$res already_added=1 ;; esac - fi - fi - if (( ! already_added )) && [[ $style == unknown-token ]] && # not handled by the 'command word' codepath - { (( in_redirection )) || [[ $this_word == *':regular:'* ]] || [[ $this_word == *':sudo_opt:'* ]] || [[ $this_word == *':sudo_arg:'* ]] } - then # $arg is a non-command word + } + } + } + (( ! already_added )) && [[ $style == unknown-token ]] && { (( in_redirection )) || [[ $this_word == *':regular:'* ]] || [[ $this_word == *':sudo_opt:'* ]] || [[ $this_word == *':sudo_arg:'* ]] } && { case $arg in $'\x29') # subshell or end of array assignment if $in_array_assignment; then @@ -534,35 +505,27 @@ _zsh_highlight_highlighter_main_paint() elif [[ $arg[0,1] = $histchars[0,1] ]] && (( $#arg[0,2] == 2 )); then style=history-expansion elif [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then - if [[ $this_word == *':regular:'* ]]; then - style=commandseparator - else - style=unknown-token - fi + [[ $this_word == *':regular:'* ]] && style=commandseparator || style=unknown-token elif (( in_redirection == 2 )); then style=redirection else - if _zsh_highlight_main_highlighter_check_path; then - style=$REPLY - else - style=default - fi + _zsh_highlight_main_highlighter_check_path && style=$REPLY || style=default fi ;; esac - fi + } if ! (( already_added )); then _zsh_highlight_main_add_region_highlight $start_pos $end_pos $style [[ $style == path || $style == path_prefix ]] && _zsh_highlight_main_highlighter_highlight_path_separators fi - if [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]]; then + [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_COMMANDSEPARATOR:#"$arg"} ]] && { next_word=':start:' highlight_glob=true - elif - [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_CONTROL_FLOW:#"$arg"} && $this_word == *':start:'* ]] || - [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} && $this_word == *':start:'* ]]; then + } || { + [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_CONTROL_FLOW:#"$arg"} && $this_word == *':start:'* ]] || + [[ -n ${(M)ZSH_HIGHLIGHT_TOKENS_PRECOMMANDS:#"$arg"} && $this_word == *':start:'* ]] && { next_word=':start:' - elif [[ $arg == "repeat" && $this_word == *':start:'* ]]; then + } || { [[ $arg == "repeat" && $this_word == *':start:'* ]] && { # skip the repeat-count word in_redirection=2 # The redirection mechanism assumes $this_word describes the word @@ -573,14 +536,11 @@ _zsh_highlight_highlighter_main_paint() # # The repeat-count word will be handled like a redirection target. this_word=':start::regular:' - fi + } +} + } start_pos=$end_pos - if (( in_redirection == 0 )); then - # This is the default/common codepath. - this_word=$next_word - else - # Stall $this_word. - fi + (( in_redirection == 0 )) && this_word=$next_word done } @@ -598,9 +558,7 @@ _zsh_highlight_main_highlighter_highlight_path_separators() style_pathsep=${style}_pathseparator [[ -z "$ZSH_HIGHLIGHT_STYLES[$style_pathsep]" || "$ZSH_HIGHLIGHT_STYLES[$style]" == "$ZSH_HIGHLIGHT_STYLES[$style_pathsep]" ]] && return 0 for (( pos = start_pos; $pos <= end_pos; pos++ )) ; do - if [[ $BUFFER[pos] == / ]]; then - _zsh_highlight_main_add_region_highlight $((pos - 1)) $pos $style_pathsep - fi + [[ $BUFFER[pos] == / ]] && _zsh_highlight_main_add_region_highlight $((pos - 1)) $pos $style_pathsep done } @@ -628,12 +586,11 @@ _zsh_highlight_main_highlighter_check_path() [[ ! -d ${expanded_path:h} ]] && return 1 # If this word ends the buffer, check if it's the prefix of a valid path. - if [[ ${BUFFER[1]} != "-" && ${#BUFFER} == $end_pos ]] && - [[ $WIDGET != zle-line-finish ]]; then + [[ ${BUFFER[1]} != "-" && ${#BUFFER} == $end_pos ]] && [[ $WIDGET != zle-line-finish ]] && { local -a tmp tmp=( ${expanded_path}*(N) ) (( $#tmp > 0 )) && REPLY=path_prefix && return 0 - fi + } # It's not a path. return 1 @@ -653,23 +610,21 @@ _zsh_highlight_main_highlighter_highlight_string() case "$arg[$i]" in '$' ) style=dollar-double-quoted-argument # Look for an alphanumeric parameter name. - if [[ ${arg:$i} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+) ]] ; then + [[ ${arg:$i} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+) ]] && { (( k += $#MATCH )) # highlight the parameter name (( i += $#MATCH )) # skip past it - elif [[ ${arg:$i} =~ ^[{]([A-Za-z_][A-Za-z0-9_]*|[0-9]+)[}] ]] ; then - (( k += $#MATCH )) # highlight the parameter name and braces - (( i += $#MATCH )) # skip past it - else - continue - fi + } || { + [[ ${arg:$i} =~ ^[{]([A-Za-z_][A-Za-z0-9_]*|[0-9]+)[}] ]] && { + (( k += $#MATCH )) # highlight the parameter name and braces + (( i += $#MATCH )) # skip past it + } || continue + } ;; "\\") style=back-double-quoted-argument - if [[ \\\`\"\$ == *$arg[$i+1]* ]]; then + [[ \\\`\"\$ == *$arg[$i+1]* ]] && { (( k += 1 )) # Color following char too. (( i += 1 )) # Skip parsing the escaped char. - else - continue - fi + } || continue ;; *) continue ;; @@ -698,21 +653,18 @@ _zsh_highlight_main_highlighter_highlight_dollar_string() done AA=$arg[$i+1,$c-1] # Matching for HEX and OCT values like \0xA6, \xA6 or \012 - if [[ "$AA" =~ "^(x|X)[0-9a-fA-F]{1,2}" + [[ "$AA" =~ "^(x|X)[0-9a-fA-F]{1,2}" || "$AA" =~ "^[0-7]{1,3}" || "$AA" =~ "^u[0-9a-fA-F]{1,4}" || "$AA" =~ "^U[0-9a-fA-F]{1,8}" - ]]; then + ]] && { (( k += $#MATCH )) (( i += $#MATCH )) - else - if (( $#arg > $i+1 )) && [[ $arg[$i+1] == [xXuU] ]]; then - # \x not followed by hex digits is probably an error - style=unknown-token - fi + } || { + (( $#arg > $i+1 )) && [[ $arg[$i+1] == [xXuU] ]] && style=unknown-token (( k += 1 )) # Color following char too. (( i += 1 )) # Skip parsing the escaped char. - fi + } ;; *) continue ;;
Attachment:
parse.zsh
Description: Binary data
Attachment:
toparse.zsh
Description: Binary data