Compare commits

...

20 Commits

Author SHA1 Message Date
Daniel Shahaf
b08d508cd8 driver: Fix a bug that prevented subsequent, third-party zle-line-pre-redraw hooks from running.
Without this patch, `_zsh_highlight` was invoked by add-zle-hook-widget
with `$?` being non-zero (see add-zle-hook-widget:48-52).  Since
`_zsh_highlight` preserves `$?` from its caller's point of view,
add-zle-hook-widget saw a non-zero exit code from `_zsh_highlight` and
did not run any the remaining zle-line-pre-redraw hooks.

See https://github.com/zsh-users/zsh-syntax-highlighting/issues/579#issuecomment-623576907.
2020-05-04 16:45:21 +00:00
Matthew Martin
8d4c6355e6 driver: Do not pass widget arguments to _zsh_highlight
This avoids a bug in zsh 4.3.12 and prior which affects passing
arguments to an anonymous function.
2018-10-13 21:55:45 -05:00
Daniel Shahaf
56ba7f082d driver: Clarify comment. No functional change. 2018-10-12 12:35:34 -05:00
Matthew Martin
2cbb3fb24e driver: Allow for -U in autoloaded function definition 2018-10-12 12:35:34 -05:00
Matthew Martin
f265ef0b9a driver: Use idiomatic module check 2018-10-12 12:35:34 -05:00
Daniel Shahaf
d0fb0df4ff driver: Make the shadowing $WIDGET read only. 2018-10-12 12:35:34 -05:00
Daniel Shahaf
f665eec230 driver: Avoid a fork in the common case.
Found-by: Matthew Martin
2018-10-12 12:35:34 -05:00
Daniel Shahaf
a868b6942e test harness: Actually test the new code.
Currently, without zsh/zle loaded, the tests silently fall back to the
5.2-and-earlier codepath; see:
.
    https://github.com/zsh-users/zsh-syntax-highlighting/pull/356#issuecomment-243651251
2018-10-12 12:35:34 -05:00
Daniel Shahaf
b5249f17ab driver: Rewrite without a state variable
Suggested-by: m0viefreak
2018-10-12 12:35:32 -05:00
Daniel Shahaf
d2594c1157 noop: Make a whitespace-only change to reduce noise in the next commit. 2018-10-12 12:31:12 -05:00
Daniel Shahaf
66ae59eccc docs: Rewrap. 2018-10-12 12:31:12 -05:00
Daniel Shahaf
1651137f5c docs: Update FAQ answer per changes on this branch. 2018-10-12 12:31:12 -05:00
Daniel Shahaf
d4ab7e51d2 redo _zsh_highlight__function_callable_p 2018-10-12 12:31:12 -05:00
Daniel Shahaf
38477f2a3d driver: Use a different way of checking whether add-zle-hook-widget is present.
Based on code by Bart Schaefer (reference within).

Tested with zsh 5.0.7-5 (debian package) and with 5b4cbcc842c6 (39158,
5.3-to-be of today).
2018-10-12 12:31:12 -05:00
Daniel Shahaf
d98622dcd0 changelog: Use a more specific link. 2018-10-12 12:31:12 -05:00
Daniel Shahaf
04fd6bbf53 changelog: Note the effect of fixing #245/#90 and an alternative. 2018-10-12 12:31:12 -05:00
Daniel Shahaf
30c6e70394 driver: Pass zle-line-finish arguments on to _zsh_highlight.
(Currently a noop)
2018-10-12 12:31:12 -05:00
Daniel Shahaf
74a27de70d driver: Hook zle-line-finish.
Compare issue #288.
2018-10-12 12:31:10 -05:00
Daniel Shahaf
85e62a8171 driver: Reimplement using 'add-zle-hook-widget zle-line-pre-redraw'
This feature will be released in zsh 5.3.  Older zsh's will use the existing
codepath.
2018-10-12 12:30:23 -05:00
Daniel Shahaf
aed99f6a3e wrappers: Reimplement using Mikachu's zle-line-pre-redraw hook (workers/36650). 2018-10-11 22:04:02 -05:00
6 changed files with 175 additions and 59 deletions

View File

@ -39,11 +39,23 @@ FAQ
### Why must `zsh-syntax-highlighting.zsh` be sourced at the end of the `.zshrc` file? ### Why must `zsh-syntax-highlighting.zsh` be sourced at the end of the `.zshrc` file?
`zsh-syntax-highlighting.zsh` wraps ZLE widgets. It must be sourced after all zsh-syntax-highlighting works by hooking into the Zsh Line Editor (ZLE) and
custom widgets have been created (i.e., after all `zle -N` calls and after computing syntax highlighting for the command-line buffer as it stands at the
running `compinit`). Widgets created later will work, but will not update the time z-sy-h's hook is invoked.
In zsh 5.2 and older,
`zsh-syntax-highlighting.zsh` hooks into ZLE by wrapping ZLE widgets. It must
be sourced after all custom widgets have been created (i.e., after all `zle -N`
calls and after running `compinit`) in order to be able to wrap all of them.
Widgets created after z-sy-h is sourced will work, but will not update the
syntax highlighting. syntax highlighting.
In zsh 5.3 and newer,
zsh-syntax-highlighting uses the `add-zle-hook-widget` facility to install
a `zle-line-pre-redraw` hook. Hooks are run in order of registration,
therefore, z-sy-h must be sourced (and register its hook) after anything else
that adds hooks that modify the command-line buffer.
### Does syntax highlighting work during incremental history search? ### Does syntax highlighting work during incremental history search?
Highlighting the command line during an incremental history search (by default bound to Highlighting the command line during an incremental history search (by default bound to

View File

@ -292,6 +292,28 @@ in this area.
(0a9b347483ae) (0a9b347483ae)
# Changes in version 0.5.0
## Incompatible changes:
- An unsuccessful completion (a <kbd>⮀ Tab</kbd> press that doesn't change the
command line) no longer causes highlighting to be lost. Visual feedback can
alternatively be achieved by setting the `format` zstyle under the `warnings`
tag, for example,
zstyle ':completion:*:warnings' format '%F{red}No matches%f'
Refer to the [description of the `format` style in `zshcompsys(1)`]
[zshcompsys-Standard-Styles-format].
(#90, part of #245, XXXXXXXXXXXX)
[zshcompsys-Standard-Styles]: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Standard-Styles
[zshcompsys-Standard-Styles-format]: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#index-format_002c-completion-style
# Changes in version 0.4.1 # Changes in version 0.4.1
## Fixes: ## Fixes:

View File

@ -31,6 +31,9 @@
emulate -LR zsh emulate -LR zsh
setopt localoptions extendedglob setopt localoptions extendedglob
# Required for add-zle-hook-widget.
zmodload zsh/zle
# Argument parsing. # Argument parsing.
if (( $# != 3 )) || [[ $1 == -* ]]; then if (( $# != 3 )) || [[ $1 == -* ]]; then
print -r -- >&2 "$0: usage: $0 BUFFER HIGHLIGHTER BASENAME" print -r -- >&2 "$0: usage: $0 BUFFER HIGHLIGHTER BASENAME"

View File

@ -31,6 +31,9 @@
setopt NO_UNSET WARN_CREATE_GLOBAL setopt NO_UNSET WARN_CREATE_GLOBAL
# Required for add-zle-hook-widget.
zmodload zsh/zle
# Check an highlighter was given as argument. # Check an highlighter was given as argument.
[[ -n "$1" ]] || { [[ -n "$1" ]] || {
echo >&2 "Bail out! You must provide the name of a valid highlighter as argument." echo >&2 "Bail out! You must provide the name of a valid highlighter as argument."

View File

@ -29,6 +29,9 @@
# ------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------
# Required for add-zle-hook-widget.
zmodload zsh/zle
# Check an highlighter was given as argument. # Check an highlighter was given as argument.
[[ -n "$1" ]] || { [[ -n "$1" ]] || {
echo >&2 "Bail out! You must provide the name of a valid highlighter as argument." echo >&2 "Bail out! You must provide the name of a valid highlighter as argument."

View File

@ -49,6 +49,52 @@ if true; then
fi fi
fi fi
# This function takes a single argument F and returns True iff F is an autoload stub.
_zsh_highlight__function_is_autoload_stub_p() {
if zmodload -e zsh/parameter; then
#(( ${+functions[$1]} )) &&
[[ "$functions[$1]" == *"builtin autoload -X"* ]]
else
#[[ $(type -wa -- "$1") == *'function'* ]] &&
[[ "${${(@f)"$(which -- "$1")"}[2]}" == $'\t'$histchars[3]' undefined' ]]
fi
# Do nothing here: return the exit code of the if.
}
# Return True iff the argument denotes a function name.
_zsh_highlight__is_function_p() {
if zmodload -e zsh/parameter; then
(( ${+functions[$1]} ))
else
[[ $(type -wa -- "$1") == *'function'* ]]
fi
}
# This function takes a single argument F and returns True iff F denotes the
# name of a callable function. A function is callable if it is fully defined
# or if it is marked for autoloading and autoloading it at the first call to it
# will succeed. In particular, if a function has been marked for autoloading
# but is not available in $fpath, then this function will return False therefor.
#
# See users/21671 http://www.zsh.org/cgi-bin/mla/redirect?USERNUMBER=21671
_zsh_highlight__function_callable_p() {
if _zsh_highlight__is_function_p "$1" &&
! _zsh_highlight__function_is_autoload_stub_p "$1"
then
# Already fully loaded.
return 0 # true
else
# "$1" is either an autoload stub, or not a function at all.
#
# Use a subshell to avoid affecting the calling shell.
#
# We expect 'autoload +X' to return non-zero if it fails to fully load
# the function.
( autoload -U +X -- "$1" 2>/dev/null )
return $?
fi
}
# ------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------
# Core highlighting update system # Core highlighting update system
# ------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------
@ -290,9 +336,35 @@ _zsh_highlight_call_widget()
_zsh_highlight _zsh_highlight
} }
# Rebind all ZLE widgets to make them invoke _zsh_highlights. if _zsh_highlight__function_callable_p add-zle-hook-widget
_zsh_highlight_bind_widgets() then
{ autoload -U add-zle-hook-widget
_zsh_highlight__zle-line-finish() {
# Reset $WIDGET since the 'main' highlighter depends on it.
#
# Since $WIDGET is declared by zle as read-only in this function's scope,
# a nested function is required in order to shadow its built-in value;
# see "User-defined widgets" in zshall.
() {
local -h -r WIDGET=zle-line-finish
_zsh_highlight
}
}
_zsh_highlight__zle-line-pre-redraw() {
# Set $? to 0 for _zsh_highlight. Without this, subsequent
# zle-line-pre-redraw hooks won't run, since add-zle-hook-widget happens to
# call us with $? == 1 in the common case.
true && _zsh_highlight "$@"
}
_zsh_highlight_bind_widgets(){}
if [[ -o zle ]]; then
add-zle-hook-widget zle-line-pre-redraw _zsh_highlight__zle-line-pre-redraw
add-zle-hook-widget zle-line-finish _zsh_highlight__zle-line-finish
fi
else
# Rebind all ZLE widgets to make them invoke _zsh_highlights.
_zsh_highlight_bind_widgets()
{
setopt localoptions noksharrays setopt localoptions noksharrays
typeset -F SECONDS typeset -F SECONDS
local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once
@ -355,7 +427,8 @@ _zsh_highlight_bind_widgets()
fi fi
esac esac
done done
} }
fi
# Load highlighters from directory. # Load highlighters from directory.
# #