Skip to content

Commit

Permalink
'main': Use zsh/parameter instead of type -w
Browse files Browse the repository at this point in the history
If possible, try to use the zsh/parameter module to get
information about a shell words.

This avoids subshells and is a huge speed improvement
on systems such as cygwin.

Note 1:
$commands does not know about PATH_DIRS. So in case
PATH_DIRS is set, 'type -w' is still used if nothing
else matches.

Note 2:
zsh/parameter can't distinguish between 'command' and
'hashed'. Adjusted the test for that case to XFAIL.

The ideal solution would be if whence had an option to
put the result in REPLY instead of printing it to stdout.
  • Loading branch information
m0vie committed May 13, 2016
1 parent 61f4325 commit 12b879c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
61 changes: 43 additions & 18 deletions highlighters/main/main-highlighter.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,39 @@ _zsh_highlight_main_add_region_highlight() {
_zsh_highlight_add_highlight $start $end "$@"
}

# Wrapper around 'type -w'.
# Get the type of a command.
#
# Takes a single argument and outputs the output of 'type -w $1'.
# Uses the zsh/parameter module if available to avoid forks, and a
# wrapper around 'type -w' as fallback.
#
# NOTE: This runs 'setopt', but that should be safe since it'll only ever be
# called inside a $(...) subshell, so the effects will be local.
# Takes a single argument.
#
# The result will be stored in REPLY.
_zsh_highlight_main__type() {
if (( $#options_to_set )); then
setopt localoptions $options_to_set;
fi
LC_ALL=C builtin type -w -- $1 2>/dev/null
unset REPLY
if zmodload -e zsh/parameter; then
if (( $+aliases[(e)$1] )); then
REPLY=alias
elif (( $+saliases[(e)${1##*.}] )); then
REPLY='suffix alias'
elif (( $reswords[(Ie)$1] )); then
REPLY=reserved
elif (( $+functions[(e)$1] )); then
REPLY=function
elif (( $+builtins[(e)$1] )); then
REPLY=builtin
elif (( $+commands[(e)$1] )); then
REPLY=command
elif ! builtin type -w -- $1 >/dev/null 2>&1; then
REPLY=none
fi
fi
if ! (( $+REPLY )); then
REPLY="${$(LC_ALL=C builtin type -w -- $1 2>/dev/null)#*: }"
fi
}

# Check whether the first argument is a redirection operator token.
Expand Down Expand Up @@ -329,7 +351,8 @@ _zsh_highlight_main_highlighter()
else
_zsh_highlight_main_highlighter_expand_path $arg
local expanded_arg="$REPLY"
local res="$(_zsh_highlight_main__type ${expanded_arg})"
_zsh_highlight_main__type ${expanded_arg}
local res="$REPLY"
() {
# Special-case: command word is '$foo', like that, without braces or anything.
#
Expand All @@ -339,17 +362,16 @@ _zsh_highlight_main_highlighter()
# parameters that refer to commands, functions, and builtins.
local -a match mbegin mend
local MATCH; integer MBEGIN MEND
if [[ $res == *': none' ]] && (( ${+parameters} )) &&
if [[ $res == none ]] && (( ${+parameters} )) &&
[[ ${arg[1]} == \$ ]] && [[ ${arg:1} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+)$ ]]; then
res="$(_zsh_highlight_main__type ${(P)MATCH})"
_zsh_highlight_main__type ${(P)MATCH}
res=$REPLY
fi
}
case $res in
*': reserved') style=reserved-word;;
*': suffix alias')
style=suffix-alias
;;
*': alias') () {
reserved) style=reserved-word;;
'suffix alias') style=suffix-alias;;
alias) () {
integer insane_alias
case $arg in
# Issue #263: aliases with '=' on their LHS.
Expand All @@ -373,11 +395,11 @@ _zsh_highlight_main_highlighter()
fi
}
;;
*': builtin') style=builtin;;
*': function') style=function;;
*': command') style=command;;
*': hashed') style=hashed-command;;
*) if _zsh_highlight_main_highlighter_check_assign; then
builtin) style=builtin;;
function) style=function;;
command) style=command;;
hashed) style=hashed-command;;
none) if _zsh_highlight_main_highlighter_check_assign; then
style=assign
if [[ $arg[-1] == '(' ]]; then
in_array_assignment=true
Expand Down Expand Up @@ -431,6 +453,9 @@ _zsh_highlight_main_highlighter()
fi
fi
;;
*) _zsh_highlight_main_add_region_highlight commandtypefromthefuture-$res
already_added=1
;;
esac
fi
else # $arg is a non-command word
Expand Down
2 changes: 1 addition & 1 deletion highlighters/main/test-data/hashed-command.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ hash zsh_syntax_highlighting_hash=/doesnotexist
BUFFER='zsh_syntax_highlighting_hash'

expected_region_highlight=(
"1 28 hashed-command"
"1 28 hashed-command 'zsh/parameter cannot distinguish between hashed and command'"
)

0 comments on commit 12b879c

Please sign in to comment.