mirror of
https://github.com/zsh-users/zsh-syntax-highlighting.git
synced 2025-02-06 09:55:31 +08:00
driver: Split out autoloadable part of _zsh_highlight
This commit is contained in:
parent
b62aeb6168
commit
f45b29d9c6
135
_zsh_highlight_internal
Normal file
135
_zsh_highlight_internal
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# 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 "$@"
|
@ -37,6 +37,7 @@ builtin unalias -m '[^+]*'
|
|||||||
|
|
||||||
# Set $0 to the expected value, regardless of functionargzero.
|
# Set $0 to the expected value, regardless of functionargzero.
|
||||||
0=${(%):-%N}
|
0=${(%):-%N}
|
||||||
|
fpath+=(${0:P:h})
|
||||||
if true; then
|
if true; then
|
||||||
# $0 is reliable
|
# $0 is reliable
|
||||||
typeset -g ZSH_HIGHLIGHT_VERSION=$(<"${0:A:h}"/.version)
|
typeset -g ZSH_HIGHLIGHT_VERSION=$(<"${0:A:h}"/.version)
|
||||||
@ -210,136 +211,9 @@ _zsh_highlight()
|
|||||||
fi
|
fi
|
||||||
typeset -r zsyh_user_options
|
typeset -r zsyh_user_options
|
||||||
|
|
||||||
emulate -L zsh
|
_zsh_highlight_internal
|
||||||
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
|
return ret
|
||||||
# likely a pasted command or a huge list of files in that case..
|
|
||||||
[[ -n ${ZSH_HIGHLIGHT_MAXLENGTH:-} ]] && [[ $#BUFFER -gt $ZSH_HIGHLIGHT_MAXLENGTH ]] && return $ret
|
|
||||||
|
|
||||||
# Do not highlight if there are pending inputs (copy/paste).
|
|
||||||
[[ $PENDING -gt 0 ]] && return $ret
|
|
||||||
|
|
||||||
{
|
|
||||||
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"
|
|
||||||
|
|
||||||
|
|
||||||
return $ret
|
|
||||||
|
|
||||||
|
|
||||||
} 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")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -561,6 +435,8 @@ _zsh_highlight_load_highlighters()
|
|||||||
# Setup
|
# Setup
|
||||||
# -------------------------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
autoload -Uz _zsh_highlight_internal
|
||||||
|
|
||||||
# Try binding widgets.
|
# Try binding widgets.
|
||||||
_zsh_highlight_bind_widgets || {
|
_zsh_highlight_bind_widgets || {
|
||||||
print -r -- >&2 'zsh-syntax-highlighting: failed binding ZLE widgets, exiting.'
|
print -r -- >&2 'zsh-syntax-highlighting: failed binding ZLE widgets, exiting.'
|
||||||
|
Loading…
Reference in New Issue
Block a user