From f9c95b2ef34bddd5f7bf7ab487d0cc762f622f30 Mon Sep 17 00:00:00 2001 From: m0viefreak Date: Tue, 29 Mar 2016 21:50:46 +0200 Subject: [PATCH 1/3] 'driver': Widget binding: Support binding unbound zle hooks If a special zle-* hook is currently unbound, there is no entry in $widgets. Support that case by adding a new case branch. --- zsh-syntax-highlighting.zsh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/zsh-syntax-highlighting.zsh b/zsh-syntax-highlighting.zsh index e49e5a8..2f6c842 100644 --- a/zsh-syntax-highlighting.zsh +++ b/zsh-syntax-highlighting.zsh @@ -235,8 +235,10 @@ _zsh_highlight_bind_widgets() } # Override ZLE widgets to make them invoke _zsh_highlight. + local -U widgets_to_bind + widgets_to_bind=(${${(k)widgets}:#(.*|orig-*|run-help|which-command|beep|set-local-history|yank)}) local cur_widget - for cur_widget in ${${(k)widgets}:#(.*|orig-*|run-help|which-command|beep|set-local-history|yank)}; do + for cur_widget in $widgets_to_bind; do case $widgets[$cur_widget] in # Already rebound event: do nothing. @@ -262,6 +264,10 @@ _zsh_highlight_bind_widgets() builtin) eval "_zsh_highlight_widget_${(q)cur_widget}() { _zsh_highlight_call_widget .${(q)cur_widget} -- \"\$@\" }" zle -N $cur_widget _zsh_highlight_widget_$cur_widget;; + # Special zle-* hook that is currently not bound at all: Bind to z-sy-h driectly. + '') eval "_zsh_highlight_widget_${(q)cur_widget}() { :; _zsh_highlight }" + zle -N $cur_widget _zsh_highlight_widget_$cur_widget;; + # Default: unhandled case. *) echo "zsh-syntax-highlighting: unhandled ZLE widget '$cur_widget'" >&2 ;; esac From 8dfe7b091015b468933a298e0781e7478aac7392 Mon Sep 17 00:00:00 2001 From: m0viefreak Date: Tue, 29 Mar 2016 21:56:57 +0200 Subject: [PATCH 2/3] 'driver': Always bind zle-line-finish and use it instead of accept-* Special handling for cursor imprint or partial path highlighting is needed in more cases than accept-*. For example when accepting a line from isearch, no accept-* widget is invoked. The proper way is to use zle-line-finish. Trumps #259. Fixes #284. --- highlighters/cursor/cursor-highlighter.zsh | 7 +++---- highlighters/main/main-highlighter.zsh | 7 +++---- highlighters/main/test-data/path_prefix2.zsh | 2 +- zsh-syntax-highlighting.zsh | 6 ++++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/highlighters/cursor/cursor-highlighter.zsh b/highlighters/cursor/cursor-highlighter.zsh index aa70f55..13479b9 100644 --- a/highlighters/cursor/cursor-highlighter.zsh +++ b/highlighters/cursor/cursor-highlighter.zsh @@ -34,15 +34,14 @@ # Whether the cursor highlighter should be called or not. _zsh_highlight_cursor_highlighter_predicate() { - # accept-* may trigger removal of cursor highlighting - [[ $WIDGET == accept-* ]] || - _zsh_highlight_cursor_moved + # remove cursor highlighting when the line is finished + [[ $WIDGET == zle-line-finish ]] || _zsh_highlight_cursor_moved } # Cursor highlighting function. _zsh_highlight_cursor_highlighter() { - [[ $WIDGET == accept-* ]] && return + [[ $WIDGET == zle-line-finish ]] && return _zsh_highlight_add_highlight $CURSOR $(( $CURSOR + 1 )) cursor } diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index 540e05b..e477246 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -62,9 +62,8 @@ # Whether the highlighter should be called or not. _zsh_highlight_main_highlighter_predicate() { - # accept-* may trigger removal of path_prefix highlighting - [[ $WIDGET == accept-* ]] || - _zsh_highlight_buffer_modified + # may need to remove path_prefix highlighting when the line ends + [[ $WIDGET == zle-line-finish ]] || _zsh_highlight_buffer_modified } # Helper to deal with tokens crossing line boundaries. @@ -595,7 +594,7 @@ _zsh_highlight_main_highlighter_check_path() # If this word ends the buffer, check if it's the prefix of a valid path. if [[ ${BUFFER[1]} != "-" && ${#BUFFER} == $end_pos ]] && - [[ $WIDGET != accept-* ]]; then + [[ $WIDGET != zle-line-finish ]]; then local -a tmp tmp=( ${expanded_path}*(N) ) (( $#tmp > 0 )) && REPLY=path_prefix && return 0 diff --git a/highlighters/main/test-data/path_prefix2.zsh b/highlighters/main/test-data/path_prefix2.zsh index ffe50cd..501928a 100644 --- a/highlighters/main/test-data/path_prefix2.zsh +++ b/highlighters/main/test-data/path_prefix2.zsh @@ -31,7 +31,7 @@ # Related to path_prefix.zsh BUFFER='ls /bin/s' -WIDGET=accept-line +WIDGET=zle-line-finish expected_region_highlight=( "4 9 default" # /bin/s diff --git a/zsh-syntax-highlighting.zsh b/zsh-syntax-highlighting.zsh index 2f6c842..0626bd1 100644 --- a/zsh-syntax-highlighting.zsh +++ b/zsh-syntax-highlighting.zsh @@ -237,6 +237,12 @@ _zsh_highlight_bind_widgets() # Override ZLE widgets to make them invoke _zsh_highlight. local -U widgets_to_bind widgets_to_bind=(${${(k)widgets}:#(.*|orig-*|run-help|which-command|beep|set-local-history|yank)}) + + # Always wrap special zle-line-finish widget. This is needed to decide if the + # current line ends and special highlighting logic needs to be applied. + # E.g. remove cursor imprint, don't highlight partial paths, ... + widgets_to_bind+=(zle-line-finish) + local cur_widget for cur_widget in $widgets_to_bind; do case $widgets[$cur_widget] in From 56b81a9b66524ce7e99adbd8105e6b5bd2af6a1f Mon Sep 17 00:00:00 2001 From: m0viefreak Date: Tue, 29 Mar 2016 22:13:46 +0200 Subject: [PATCH 3/3] 'driver': Don't highlight in isearch zsh version 5.2 and lower don't support ISEARCHMATCH_ACTIE and we are unable to re-apply zle_highlight on top. Therefore it is impossible to see the underlined matched area. Since that information is more important, completely disable highlighting in isearch in that case. To do that, we need to make sure we are actually called when something changes in isearch. Trumps #257. --- README.md | 9 +++++++++ zsh-syntax-highlighting.zsh | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/README.md b/README.md index ac8beaf..e52f776 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,15 @@ custom widgets have been created (i.e., after all `zle -N` calls and after running `compinit`). Widgets created later will work, but will not update the syntax highlighting. +### Why does syntax highlighting not work while searching history? + +In `zsh` versions before 5.3 is not possible for `zsh-syntax-highlighting.zsh` +to know if an incremental search is currently active and that matched parts of the +buffer should be underlined (or otherwise highlighted). Therefore, it is not possible +for `zsh-syntax-highlighting.zsh` to apply syntax highlighting and to underline the +matched part of the search. While searching the history, the latter is more important, +so syntax highlighting is disabled in this case. + ### How are new releases announced? There is currently no "push" announcements channel. However, the following diff --git a/zsh-syntax-highlighting.zsh b/zsh-syntax-highlighting.zsh index 0626bd1..0e275f9 100644 --- a/zsh-syntax-highlighting.zsh +++ b/zsh-syntax-highlighting.zsh @@ -58,6 +58,14 @@ _zsh_highlight() # Store the previous command return code to restore it whatever happens. local ret=$? + # Remove all highlighting in isearch, so that only the underlining done by zsh itself remains. + # For details see FAQ entry 'Why does syntax highlighting not work while searching history?' + # and http://www.zsh.org/mla/users/2016/msg00415.html. + if [[ $WIDGET == zle-isearch-update ]]; then + region_highlight=() + return $ret + fi + setopt localoptions warncreateglobal setopt localoptions noksharrays local REPLY # don't leak $REPLY into global scope @@ -243,6 +251,10 @@ _zsh_highlight_bind_widgets() # E.g. remove cursor imprint, don't highlight partial paths, ... widgets_to_bind+=(zle-line-finish) + # Always wrap special zle-isearch-update widget to be notified of updates in isearch. + # This is needed because we need to disable highlighting in that case. + widgets_to_bind+=(zle-isearch-update) + local cur_widget for cur_widget in $widgets_to_bind; do case $widgets[$cur_widget] in