|
|
- # Update ZLE buffer syntax highlighting.
- #
- # Invokes each highlighter that needs updating.
- # This function is supposed to be called whenever the ZLE state changes.
- _zsh_highlight_internal()
- {
- emulate -L zsh
- setopt localoptions warncreateglobal nobashrematch
- local REPLY # don't leak $REPLY into global scope
-
- # Do not highlight if there are more than 300 chars in the buffer. It's most
- # likely a pasted command or a huge list of files in that case..
- [[ -n ${ZSH_HIGHLIGHT_MAXLENGTH:-} ]] && [[ $#BUFFER -gt $ZSH_HIGHLIGHT_MAXLENGTH ]] && return
-
- # Do not highlight if there are pending inputs (copy/paste).
- [[ $PENDING -gt 0 ]] && return
-
- {
- local cache_place
- local -a region_highlight_copy
-
- # Select which highlighters in ZSH_HIGHLIGHT_HIGHLIGHTERS need to be invoked.
- local highlighter; for highlighter in $ZSH_HIGHLIGHT_HIGHLIGHTERS; do
-
- # eval cache place for current highlighter and prepare it
- cache_place="_zsh_highlight__highlighter_${highlighter}_cache"
- typeset -ga ${cache_place}
-
- # If highlighter needs to be invoked
- if ! type "_zsh_highlight_highlighter_${highlighter}_predicate" >&/dev/null; then
- echo "zsh-syntax-highlighting: warning: disabling the ${(qq)highlighter} highlighter as it has not been loaded" >&2
- # TODO: use ${(b)} rather than ${(q)} if supported
- ZSH_HIGHLIGHT_HIGHLIGHTERS=( ${ZSH_HIGHLIGHT_HIGHLIGHTERS:#${highlighter}} )
- elif "_zsh_highlight_highlighter_${highlighter}_predicate"; then
-
- # save a copy, and cleanup region_highlight
- region_highlight_copy=("${region_highlight[@]}")
- region_highlight=()
-
- # Execute highlighter and save result
- {
- "_zsh_highlight_highlighter_${highlighter}_paint"
- } always {
- : ${(AP)cache_place::="${region_highlight[@]}"}
- }
-
- # Restore saved region_highlight
- region_highlight=("${region_highlight_copy[@]}")
-
- fi
-
- # Use value form cache if any cached
- region_highlight+=("${(@P)cache_place}")
-
- done
-
- # Re-apply zle_highlight settings
-
- # region
- () {
- (( REGION_ACTIVE )) || return
- integer min max
- if (( MARK > CURSOR )) ; then
- min=$CURSOR max=$MARK
- else
- min=$MARK max=$CURSOR
- fi
- if (( REGION_ACTIVE == 1 )); then
- [[ $KEYMAP = vicmd ]] && (( max++ ))
- elif (( REGION_ACTIVE == 2 )); then
- local needle=$'\n'
- # CURSOR and MARK are 0 indexed between letters like region_highlight
- # Do not include the newline in the highlight
- (( min = ${BUFFER[(Ib:min:)$needle]} ))
- (( max = ${BUFFER[(ib:max:)$needle]} - 1 ))
- fi
- _zsh_highlight_apply_zle_highlight region standout "$min" "$max"
- }
-
- # yank / paste (zsh-5.1.1 and newer)
- (( $+YANK_ACTIVE )) && (( YANK_ACTIVE )) && _zsh_highlight_apply_zle_highlight paste standout "$YANK_START" "$YANK_END"
-
- # isearch
- (( $+ISEARCHMATCH_ACTIVE )) && (( ISEARCHMATCH_ACTIVE )) && _zsh_highlight_apply_zle_highlight isearch underline "$ISEARCHMATCH_START" "$ISEARCHMATCH_END"
-
- # suffix
- (( $+SUFFIX_ACTIVE )) && (( SUFFIX_ACTIVE )) && _zsh_highlight_apply_zle_highlight suffix bold "$SUFFIX_START" "$SUFFIX_END"
-
- } always {
- typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER="$BUFFER"
- typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=$CURSOR
- }
- }
-
- # Apply highlighting based on entries in the zle_highlight array.
- # This function takes four arguments:
- # 1. The exact entry (no patterns) in the zle_highlight array:
- # region, paste, isearch, or suffix
- # 2. The default highlighting that should be applied if the entry is unset
- # 3. and 4. Two integer values describing the beginning and end of the
- # range. The order does not matter.
- _zsh_highlight_apply_zle_highlight() {
- local entry="$1" default="$2"
- integer first="$3" second="$4"
-
- # read the relevant entry from zle_highlight
- #
- # ### In zsh≥5.0.8 we'd use ${(b)entry}, but we support older zsh's, so we don't
- # ### add (b). The only effect is on the failure mode for callers that violate
- # ### the precondition.
- local region="${zle_highlight[(r)${entry}:*]-}"
-
- if [[ -z "$region" ]]; then
- # entry not specified at all, use default value
- region=$default
- else
- # strip prefix
- region="${region#${entry}:}"
-
- # no highlighting when set to the empty string or to 'none'
- if [[ -z "$region" ]] || [[ "$region" == none ]]; then
- return
- fi
- fi
-
- integer start end
- if (( first < second )); then
- start=$first end=$second
- else
- start=$second end=$first
- fi
- region_highlight+=("$start $end $region, memo=zsh-syntax-highlighting")
- }
-
- _zsh_highlight_internal "$@"
|