Added copyright boilerplate and fixed indentation

This commit is contained in:
Joe Rabinoff 2020-02-04 10:25:34 -05:00
parent 22362e02f7
commit c432451c20
2 changed files with 212 additions and 164 deletions

View File

@ -17,10 +17,11 @@ zsh_highlight_files_extract_ls_colors
### Configuration ### Configuration
Files are colored according to the associative arrays `ZSH_HIGHLIGHT_FILE_TYPES` Files are colored according to the associative array `ZSH_HIGHLIGHT_FILE_TYPES`
and `ZSH_HIGHLIGHT_FILE_PATTERNS`. The values of `ZSH_HIGHLIGHT_FILE_TYPES` are and the array `ZSH_HIGHLIGHT_FILE_PATTERNS`. The values of
color specifications as in `ZSH_HIGHLIGHT_STYLES`, and the keys define which `ZSH_HIGHLIGHT_FILE_TYPES` are color specifications as in
file types are highlighted according to that style (following `LS_COLORS`): `ZSH_HIGHLIGHT_STYLES`, and the keys define which file types are highlighted
according to that style (following `LS_COLORS`):
* `fi` - ordinary files * `fi` - ordinary files
* `di` - directories * `di` - directories
@ -38,12 +39,23 @@ file types are highlighted according to that style (following `LS_COLORS`):
* `lp` - if set, the path-component of a filename is highlighted using this style * `lp` - if set, the path-component of a filename is highlighted using this style
If a file would be highlighted `fi`, then it can be highlighted according to the If a file would be highlighted `fi`, then it can be highlighted according to the
filename using `ZSH_HIGHLIGHT_FILE_PATTERNS` instead. The keys of this filename using `ZSH_HIGHLIGHT_FILE_PATTERNS` instead. This array has the form
associative array are arbitrary glob patterns; the values are color `(glob1 style1 glob2 style2 glob3 style3 ...)`, where the globs are arbitrary
specifications. For instance, if have `setopt extended_glob` and you write glob patterns, and the styles are color specifications. For instance, if have
`setopt extended_glob` and you write
```zsh ```zsh
ZSH_HIGHLIGHT_FILE_PATTERNS[(#i)*.jpe#g]=red,bold ZSH_HIGHLIGHT_FILE_PATTERNS+=('(#i)*.jpe#g' red,bold)
``` ```
then the files `foo.jpg` and `bar.jPeG` will be colored red and bold. then the files `foo.jpg` and `bar.jPeG` will be colored red and bold.
### Limitations
This highlighter makes no attempt to determine if a word is in command position.
Hence if you run the command `cat foo` and you happen to have a directory named
`cat` in the current directory, then the highlighter will highlight `cat`
according to `ZSH_HIGHLIGHT_FILE_TYPES[di]` and not
`ZSH_HIGHLIGHT_STYLES[command]` (assuming you load the `files` highlighter after
the `main` one). Likewise with aliases, reserved words, etc.

View File

@ -1,192 +1,228 @@
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
# -------------------------------------------------------------------------------------------------
# Copyright (c) 2020 zsh-syntax-highlighting contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted
# provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this list of conditions
# and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice, this list of
# conditions and the following disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
# may be used to endorse or promote products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# -------------------------------------------------------------------------------------------------
# vim: ft=zsh sw=2 ts=2 et
# -------------------------------------------------------------------------------------------------
# Highlighter for zsh-syntax-highlighting that highlights filenames # Highlighter for zsh-syntax-highlighting that highlights filenames
typeset -gA ZSH_HIGHLIGHT_FILE_TYPES ZSH_HIGHLIGHT_FILE_PATTERNS typeset -gA ZSH_HIGHLIGHT_FILE_TYPES
typeset -ga ZSH_HIGHLIGHT_FILE_PATTERNS
# Convert an ANSI escape sequence color into zle_highlight format (man 1 zshzle) # Convert an ANSI escape sequence color into zle_highlight format (man 1 zshzle)
_zsh_highlight_highlighter_files_ansi_to_zle() { _zsh_highlight_highlighter_files_ansi_to_zle()
local match mbegin mend seq {
local var=$1; shift local match mbegin mend seq
for seq in "${(@s.:.)1}"; do local var=$1; shift
seq=${seq#(#b)(*)=} for seq in "${(@s.:.)1}"; do
(( $#match )) || continue seq=${seq#(#b)(*)=}
_zsh_highlight_highlighter_files_ansi_to_zle1 $seq $var\[$match[1]\] (( $#match )) || continue
done _zsh_highlight_highlighter_files_ansi_to_zle1 $seq $var\[$match[1]\]
done
} }
_zsh_highlight_highlighter_files_ansi_to_zle1() { _zsh_highlight_highlighter_files_ansi_to_zle1()
emulate -L zsh {
setopt local_options extended_glob emulate -L zsh
setopt local_options extended_glob
local -a sgrs match local -a sgrs match
local back mbegin mend fgbg hex local back mbegin mend fgbg hex
integer sgr arg arg2 col r g b integer sgr arg arg2 col r g b
local str=$1 local str=$1
while [ -n "$str" ]; do while [ -n "$str" ]; do
back=${str##(#b)([[:digit:]]##)} back=${str##(#b)([[:digit:]]##)}
back=${back#;}
(( $#match )) || return 1
sgr=$match; unset match
case $sgr in
0) ;;
1) sgrs+=(bold) ;;
4) sgrs+=(underline) ;;
7) sgrs+=(standout) ;;
<30-37>) sgrs+=(fg=$(( $sgr - 30 ))) ;;
<40-47>) sgrs+=(bg=$(( $sgr - 40 ))) ;;
38|48)
(( sgr == 38 )) && fgbg=fg || fgbg=bg
# 38;5;n means paletted color
# 38;2;r;g;b means truecolor
back=${back##(#b)([[:digit:]]##)}
back=${back#;} back=${back#;}
(( $#match )) || return 1 (( $#match )) || return 1
arg=$match; unset match
case $arg in
5) back=${back##(#b)([[:digit:]]##)}
back=${back#;}
(( $#match )) || return 1
arg2=$match; unset match
sgrs+=($fgbg=$arg2) ;;
2) back=${back##(#b)([[:digit:]]##);([[:digit:]]##);([[:digit:]]##)}
back=${back#;}
(( $#match == 3 )) || return 1
printf -v hex \#%02X%02X%02X $match
unset match
sgrs+=($fgbg=$hex) ;;
*) return 1 ;;
esac ;;
*) return 1 ;;
esac
sgr=$match; unset match str=$back
case $sgr in done
0) ;;
1) sgrs+=(bold) ;;
4) sgrs+=(underline) ;;
7) sgrs+=(standout) ;;
<30-37>) sgrs+=(fg=$(( $sgr - 30 ))) ;;
<40-47>) sgrs+=(bg=$(( $sgr - 40 ))) ;;
38|48)
(( sgr == 38 )) && fgbg=fg || fgbg=bg
# 38;5;n means paletted color
# 38;2;r;g;b means truecolor
back=${back##(#b)([[:digit:]]##)}
back=${back#;}
(( $#match )) || return 1
arg=$match; unset match
case $arg in
5) back=${back##(#b)([[:digit:]]##)}
back=${back#;}
(( $#match )) || return 1
arg2=$match; unset match
sgrs+=($fgbg=$arg2) ;;
2) back=${back##(#b)([[:digit:]]##);([[:digit:]]##);([[:digit:]]##)}
back=${back#;}
(( $#match == 3 )) || return 1
printf -v hex \#%02X%02X%02X $match
unset match
sgrs+=($fgbg=$hex) ;;
*) return 1 ;;
esac ;;
*) return 1 ;;
esac
str=$back if [[ -n "$2" ]]; then
done eval $2='${(j.,.)sgrs}'
else
if [[ -n "$2" ]]; then print -- ${(j.,.)sgrs}
eval $2='${(j.,.)sgrs}' fi
else
print -- ${(j.,.)sgrs}
fi
} }
# Extract ZSH_HIGHLIGHT_FILE_TYPES and ZSH_HIGHLIGHT_FILE_PATTERNS from LS_COLORS # Extract ZSH_HIGHLIGHT_FILE_TYPES and ZSH_HIGHLIGHT_FILE_PATTERNS from LS_COLORS
zsh_highlight_files_extract_ls_colors() { zsh_highlight_files_extract_ls_colors()
local -A ls_colors {
_zsh_highlight_highlighter_files_ansi_to_zle ls_colors $LS_COLORS local -A ls_colors
for key val in ${(kv)ls_colors}; do _zsh_highlight_highlighter_files_ansi_to_zle ls_colors $LS_COLORS
case $key in for key val in ${(kv)ls_colors}; do
di|fi|ln|pi|so|bd|cd|or|ex|su|sg|ow|tw) case $key in
ZSH_HIGHLIGHT_FILE_TYPES[$key]=$val ;; di|fi|ln|pi|so|bd|cd|or|ex|su|sg|ow|tw)
*) ZSH_HIGHLIGHT_FILE_PATTERNS[$key]=$val ;; ZSH_HIGHLIGHT_FILE_TYPES[$key]=$val ;;
esac *) ZSH_HIGHLIGHT_FILE_PATTERNS+=($key $val) ;;
done esac
done
} }
# Perform simple filename expansion without globbing and without generating # Perform simple filename expansion without globbing and without generating
# errors # errors
_zsh_highlight_highlighter_files_fn_expand() { _zsh_highlight_highlighter_files_fn_expand()
local fn=$1 {
local match expandable tail local fn=$1
local -a mbegin mend local match expandable tail
if [[ $fn = (#b)(\~[^/]#)(*) ]]; then local -a mbegin mend
expandable=$match[1] if [[ $fn = (#b)(\~[^/]#)(*) ]]; then
tail=$match[2] expandable=$match[1]
# Try expanding expandable tail=$match[2]
(: $~expandable) >&/dev/null && expandable=$~expandable # Try expanding expandable
print -- $expandable$tail (: $~expandable) >&/dev/null && expandable=$~expandable
else print -- $expandable$tail
print -- $fn else
fi print -- $fn
fi
} }
# Whether the highlighter should be called or not. # Whether the highlighter should be called or not.
_zsh_highlight_highlighter_files_predicate() { _zsh_highlight_highlighter_files_predicate()
_zsh_highlight_buffer_modified {
_zsh_highlight_buffer_modified
} }
# Syntax highlighting function. # Syntax highlighting function.
_zsh_highlight_highlighter_files_paint() { _zsh_highlight_highlighter_files_paint()
emulate -L zsh {
setopt localoptions extended_glob emulate -L zsh
setopt localoptions extended_glob
zmodload -F zsh/stat b:zstat zmodload -F zsh/stat b:zstat
local buf=$BUFFER word basename word_subst col type mode local buf=$BUFFER word basename word_subst col type mode
local -a words=(${(z)buf}) local -a words=(${(z)buf})
local -A statdata local -A statdata
integer start=0 curword=0 numwords=$#words len end integer start=0 curword=0 numwords=$#words len end
while (( curword++ < numwords )); do while (( curword++ < numwords )); do
col="" col=""
word=$words[1] word=$words[1]
words=("${(@)words:1}") words=("${(@)words:1}")
len=$#buf len=$#buf
buf="${buf/#[^$word[1]]#}" # strip whitespace buf="${buf/#[^$word[1]]#}" # strip whitespace
start+=$(( len - $#buf )) start+=$(( len - $#buf ))
end=$(( start + $#word )) end=$(( start + $#word ))
word_subst=$(_zsh_highlight_highlighter_files_fn_expand $word) word_subst=$(_zsh_highlight_highlighter_files_fn_expand $word)
if ! zstat -H statdata -Ls -- "$word_subst" 2>/dev/null; then if ! zstat -H statdata -Ls -- "$word_subst" 2>/dev/null; then
start=$end start=$end
buf=${buf[$#word+1,-1]} buf=${buf[$#word+1,-1]}
continue continue
fi
mode=$statdata[mode]
type=$mode[1]
basename=$word:t
[[ $word[-1] = '/' ]] && basename=$basename/
# Color by file type
case $type in
d) [[ ${mode[9,10]} = wt ]] \
&& col=$ZSH_HIGHLIGHT_FILE_TYPES[tw] \
|| col=$ZSH_HIGHLIGHT_FILE_TYPES[di];;
l) [[ -e "$word_subst" ]] \
&& col=$ZSH_HIGHLIGHT_FILE_TYPES[ln] \
|| col=$ZSH_HIGHLIGHT_FILE_TYPES[or];;
p) col=$ZSH_HIGHLIGHT_FILE_TYPES[pi];;
b) col=$ZSH_HIGHLIGHT_FILE_TYPES[bd];;
c) col=$ZSH_HIGHLIGHT_FILE_TYPES[cd];;
s) col=$ZSH_HIGHLIGHT_FILE_TYPES[so];;
esac
# Regular file: more special cases
if [[ -z "$col" ]]; then
if [[ $mode[4] = s ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[su] # setuid root
elif [[ $mode[7] = s ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[sg] # setgid root
elif [[ $mode[4] = x ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[ex] # Executable
fi
fi
# Regular file: check file patterns
if [[ -z "$col" ]]; then
for key val in ${(kv)ZSH_HIGHLIGHT_FILE_PATTERNS}; do
if [[ $basename = $~key ]]; then
col=$val
break
fi fi
mode=$statdata[mode] done
type=$mode[1] fi
basename=$word:t
[[ $word[-1] = '/' ]] && basename=$basename/
# Color by file type # Just a regular file
case $type in if [[ -z "$col" ]]; then
d) [[ ${mode[9,10]} = wt ]] \ col=$ZSH_HIGHLIGHT_FILE_TYPES[fi]
&& col=$ZSH_HIGHLIGHT_FILE_TYPES[tw] \ fi
|| col=$ZSH_HIGHLIGHT_FILE_TYPES[di];;
l) [[ -e "$word_subst" ]] \
&& col=$ZSH_HIGHLIGHT_FILE_TYPES[ln] \
|| col=$ZSH_HIGHLIGHT_FILE_TYPES[or];;
p) col=$ZSH_HIGHLIGHT_FILE_TYPES[pi];;
b) col=$ZSH_HIGHLIGHT_FILE_TYPES[bd];;
c) col=$ZSH_HIGHLIGHT_FILE_TYPES[cd];;
s) col=$ZSH_HIGHLIGHT_FILE_TYPES[so];;
esac
# Regular file: more special cases if [[ -n "$col" ]]; then
if [[ -z "$col" ]]; then if (( end > start + $#basename && ${+ZSH_HIGHLIGHT_FILE_TYPES[lp]} )); then
if [[ $mode[4] = s ]]; then region_highlight+=("$start $(( end - $#basename )) $ZSH_HIGHLIGHT_FILE_TYPES[lp]")
col=$ZSH_HIGHLIGHT_FILE_TYPES[su] # setuid root fi
elif [[ $mode[7] = s ]]; then region_highlight+=("$(( end - $#basename )) $end $col")
col=$ZSH_HIGHLIGHT_FILE_TYPES[sg] # setgid root fi
elif [[ $mode[4] = x ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[ex] # Executable
fi
fi
# Regular file: check file patterns start=$end
if [[ -z "$col" ]]; then buf=${buf[$#word+1,-1]}
for key val in ${(kv)ZSH_HIGHLIGHT_FILE_PATTERNS}; do done
if [[ $basename = $~key ]]; then
col=$val
break
fi
done
fi
# Just a regular file
if [[ -z "$col" ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[fi]
fi
if [[ -n "$col" ]]; then
if (( end > start + $#basename && ${+ZSH_HIGHLIGHT_FILE_TYPES[lp]} )); then
region_highlight+=("$start $(( end - $#basename )) $ZSH_HIGHLIGHT_FILE_TYPES[lp]")
fi
region_highlight+=("$(( end - $#basename )) $end $col")
fi
start=$end
buf=${buf[$#word+1,-1]}
done
} }