@@ -83,12 +83,63 @@ _zsh_highlight()
83
83
return $ret
84
84
}
85
85
86
+ # Probe the memo= feature, once.
87
+ (( ${+zsh_highlight__memo_feature} )) || {
88
+ region_highlight+=( " 0 0 fg=red, memo=zsh-syntax-highlighting" )
89
+ case ${region_highlight[-1]} in
90
+ (" 0 0 fg=red" )
91
+ # zsh 5.8 or earlier
92
+ integer -gr zsh_highlight__memo_feature=0
93
+ ;;
94
+ (" 0 0 fg=red memo=zsh-syntax-highlighting" )
95
+ # zsh 5.9 or later
96
+ integer -gr zsh_highlight__memo_feature=1
97
+ ;;
98
+ (" 0 0 fg=red, memo=zsh-syntax-highlighting" ) ;&
99
+ (* )
100
+ # We can get here in two ways:
101
+ #
102
+ # 1. When not running as a widget. In that case, $region_highlight is
103
+ # not a special variable (= one with custom getter/setter functions
104
+ # written in C) but an ordinary one, so the third case pattern matches
105
+ # and we fall through to this block. (The test suite uses this codepath.)
106
+ #
107
+ # 2. When running under a future version of zsh that will have changed
108
+ # the serialization of $region_highlight elements from their underlying
109
+ # C structs, so that none of the previous case patterns will match.
110
+ #
111
+ # In either case, fall back to a version check.
112
+ #
113
+ # The memo= feature was added to zsh in commit zsh-5.8-172-gdd6e702ee.
114
+ # The version number at the time was 5.8.0.2-dev (see Config/version.mk).
115
+ # Therefore, on 5.8.0.3 and newer the memo= feature is available.
116
+ #
117
+ # On zsh version 5.8.0.2 between the aforementioned commit and the
118
+ # first Config/version.mk bump after it (which, at the time of writing,
119
+ # is yet to come), this condition will false negative.
120
+ if is-at-least 5.8.0.3; then
121
+ integer -gr zsh_highlight__memo_feature=1
122
+ else
123
+ integer -gr zsh_highlight__memo_feature=0
124
+ fi
125
+ ;;
126
+ esac
127
+ region_highlight[-1]=()
128
+ }
129
+
130
+ # Reset region_highlight to build it from scratch
131
+ if (( zsh_highlight__memo_feature )) ; then
132
+ region_highlight=( " ${(@ )region_highlight:#* memo=zsh-syntax-highlighting* } " )
133
+ else
134
+ # Legacy codepath. Not very interoperable with other plugins (issue #418).
135
+ region_highlight=()
136
+ fi
137
+
86
138
# Remove all highlighting in isearch, so that only the underlining done by zsh itself remains.
87
139
# For details see FAQ entry 'Why does syntax highlighting not work while searching history?'.
88
140
# This disables highlighting during isearch (for reasons explained in README.md) unless zsh is new enough
89
141
# and doesn't have the pattern matching bug
90
142
if [[ $WIDGET == zle-isearch-update ]] && { $zsh_highlight__pat_static_bug || ! (( $+ ISEARCHMATCH_ACTIVE )) }; then
91
- region_highlight=()
92
143
return $ret
93
144
fi
94
145
@@ -124,9 +175,6 @@ _zsh_highlight()
124
175
# Do not highlight if there are pending inputs (copy/paste).
125
176
[[ $PENDING -gt 0 ]] && return $ret
126
177
127
- # Reset region highlight to build it from scratch
128
- region_highlight=();
129
-
130
178
{
131
179
local cache_place
132
180
local -a region_highlight_copy
@@ -245,7 +293,7 @@ _zsh_highlight_apply_zle_highlight() {
245
293
else
246
294
start=$second end=$first
247
295
fi
248
- region_highlight+=(" $start $end $region " )
296
+ region_highlight+=(" $start $end $region , memo=zsh-syntax-highlighting " )
249
297
}
250
298
251
299
@@ -285,7 +333,7 @@ _zsh_highlight_add_highlight()
285
333
shift 2
286
334
for highlight; do
287
335
if (( $+ ZSH_HIGHLIGHT_STYLES[$highlight ] )) ; then
288
- region_highlight+=(" $start $end $ZSH_HIGHLIGHT_STYLES [$highlight ]" )
336
+ region_highlight+=(" $start $end $ZSH_HIGHLIGHT_STYLES [$highlight ], memo=zsh-syntax-highlighting " )
289
337
break
290
338
fi
291
339
done
0 commit comments