Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Highlight files like LS_COLORS #680

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
61 changes: 61 additions & 0 deletions docs/highlighters/files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
zsh-syntax-highlighting / highlighters / files
----------------------------------------------

This is the `files` highlighter, that highlights existing files appearing on the
command line.


### Quickstart

If you are happy with your `LS_COLORS`, simply add the following line to your
`.zshrc` after sourcing `zsh-syntax-highlighting.zsh`:

```zsh
zsh_highlight_files_extract_ls_colors
```
Comment on lines +10 to +15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please adjust this to also cater to people who don't already have LS_COLORS set?



### Configuration

Files are colored according to the associative array `ZSH_HIGHLIGHT_FILE_TYPES`
and the array `ZSH_HIGHLIGHT_FILE_PATTERNS`. The values of
`ZSH_HIGHLIGHT_FILE_TYPES` are color specifications as in
`ZSH_HIGHLIGHT_STYLES`, and the keys define which file types are highlighted
according to that style (following `LS_COLORS`):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add an example with ZSH_HIGHLIGHT_FILE_TYPES?


* `fi` - ordinary files
* `di` - directories
* `ln` - symbolic links
* `pi` - pipes
* `so` - sockets
* `bd` - block devices
* `cd` - character devices
* `or` - broken symlinks
* `ex` - executable files
* `su` - files that have the suid bit set
* `sg` - files that have the sgid bit set
* `ow` - files that are world-writable
* `tw` - files that are world-writable and sticky
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this say files or directories?

* `lp` - if set, the path component of a filename is highlighted using this style, unless it is set to `same`, in which case the path component is highlighted the same as the file

If a file would be highlighted `fi`, then it can be highlighted according to the
filename using `ZSH_HIGHLIGHT_FILE_PATTERNS` instead. This array has the form
`(glob1 style1 glob2 style2 glob3 style3 ...)`, where the globs are arbitrary
glob patterns, and the styles are color specifications. For instance, if have
`setopt extended_glob` and you write
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a missing word in this sentence, but more importantly, how can the behaviour possibly depend on the user's value of the EXTENDED_GLOB option if ${zsyh_user_options[extendedglob]} is not consulted?


```zsh
ZSH_HIGHLIGHT_FILE_PATTERNS+=('(#i)*.jpe#g' red,bold)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't that be fg=red rather than just red?

```

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.
1 change: 1 addition & 0 deletions highlighters/files/README.md
241 changes: 241 additions & 0 deletions highlighters/files/files-highlighter.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
# -*- 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

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Convert an ANSI escape sequence color into zle_highlight format (man 1 zshzle)
# Convert an ANSI escape sequence color into zle_highlight format (see zshzle(1))

Also, could you elaborate on the function's signature? What are the parameters and how is the answer returned?

_zsh_highlight_highlighter_files_ansi_to_zle()
{
local match mbegin mend seq
local var=$1; shift
for seq in "${(@s.:.)1}"; do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please just name the second parameter as well. Using $1 like this with the shift tucked away in the middle of a line is hard to read.

seq=${seq#(#b)(*)=}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works when EXTENDED_GLOB is set.

Please either document the precondition, or just have this function set that option for itself.

There are more instances of this in other functions. If instead of documenting this on every function you prefer to just document at the top of the file that all functions in this file expect EXTENDED_GLOB to be set, and then set it just at the API entry points and not in other functions, that'd be fine too.

In that case I would suggest to consider naming non-public functions with a run of two successive underscores somewhere in their name, in order to make it easier to distinguish public functions from private ones. (The main highlighter uses this distinction for some but not all functions, but then, it doesn't have entry points other than the standard ones, _predicate and _paint.)

(( $#match )) || continue
_zsh_highlight_highlighter_files_ansi_to_zle1 $seq $var\[$match[1]\]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't pass $var\[$match[1]\]; it's too obscure. Have the callee function set $REPLY and then assign from it.

unset match
done
}

_zsh_highlight_highlighter_files_ansi_to_zle1()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use less similar function names.

Please add comments.

{
local -a sgrs match
local back mbegin mend fgbg hex
integer sgr arg arg2 col r g b
local str=$1

while [ -n "$str" ]; do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while [ -n "$str" ]; do
while [[ -n "$str" ]]; do

Are you sure this loop will never be infinite?

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#;}
(( $#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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

printf -v is new in zsh 5.3.1. Unfortunately, you can't assume that it's available; use z-sy-h under rather ancient versions of zsh.

unset match
sgrs+=($fgbg=$hex) ;;
*) return 1 ;;
esac ;;
*) return 1 ;;
esac

str=$back
done

if [[ -n "$2" ]]; then
eval $2='${(j.,.)sgrs}'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just set $REPLY, per above. However, for future reference, what you tried to do here is better spelt : ${(P)2::=${(j.,.)sgrs}}. You'll need this in the caller's caller, where it passes the variable name "ls_colors" as an argument.

else
print -- ${(j.,.)sgrs}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Libraries shouldn't print.

fi
}

# Extract ZSH_HIGHLIGHT_FILE_TYPES and ZSH_HIGHLIGHT_FILE_PATTERNS from LS_COLORS
zsh_highlight_files_extract_ls_colors()
{
emulate -L zsh
setopt local_options extended_glob
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't use this setopt, so remove it (and move it into the callee, per above)?


local -A ls_colors
_zsh_highlight_highlighter_files_ansi_to_zle ls_colors $LS_COLORS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if $LS_COLORS is unset or set to an invalid value?

for key val in "${(@kv)ls_colors}"; do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is not WARN_CREATE_GLOBAL-clean.

case $key in
di|fi|ln|pi|so|bd|cd|or|ex|su|sg|ow|tw)
ZSH_HIGHLIGHT_FILE_TYPES[$key]=$val ;;
lc|rc|ec|rs|no|mi|do|st|ca|mh|cl) ;; # Recognized by LS_COLORS but not by us
*) ZSH_HIGHLIGHT_FILE_PATTERNS+=("$key" "$val") ;;
Comment on lines +115 to +116
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if it's a trivial question, but why do we handle at all values of $key that we do not recognize? What are they being added to $ZSH_HIGHLIGHT_FILE_PATTERNS for?

esac
done
}

# Perform simple filename expansion without globbing and without generating
# errors
Comment on lines +121 to +122
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't say "without generating errors"; say what kinds of errors you're trying to avoid. (And in any case, I suspect your code can still error, even if it's less likely.)

_zsh_highlight_highlighter_files_fn_expand()
{
local fn=$1
Comment on lines +123 to +125
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid abbreviations, especially undocumented ones. Keystrokes are cheap.

This goes for the function name and for the names of variables throughout.

local match expandable tail
local -a mbegin mend
if [[ $fn = (#b)(\~[^/]#)(*) ]]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the # extendedglob operator guaranteed to match greedily?

expandable=$match[1]
tail=$match[2]
# Try expanding expandable
Comment on lines +129 to +131
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? What exactly is the point of expanding just the username and nothing else? That seems to be an undefined operation, in the sense that the no guarantees whatsoever can be made on the resulting string.

(: $~expandable) >&/dev/null && expandable=$~expandable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use ${~foo}; it can execute code. See _zsh_highlight_main_highlighter_expand_path.

print -- $expandable$tail
else
print -- $fn
Comment on lines +133 to +135
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, if you print arbitrary data you have to use -r, but more importantly, don't print at all. That forks, which is expensive on some platforms. Set $REPLY and have the caller use that.

fi
}

# Whether the highlighter should be called or not.
_zsh_highlight_highlighter_files_predicate()
{
_zsh_highlight_buffer_modified
}

# Syntax highlighting function.
_zsh_highlight_highlighter_files_paint()
{
emulate -L zsh
setopt local_options extended_glob

zmodload -F zsh/stat b:zstat

local buf=$BUFFER word basename word_subst col type mode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason not to handle $PREBUFFER? What about INTERACTIVE_COMMENTS?

local -a words=(${(z)buf})
local -A statdata
integer start=0 curword=0 numwords=$#words len end

while (( curword++ < numwords )); do
col=""
word=$words[1]
words=("${(@)words:1}")
len=$#buf
buf="${buf/#[^$word[1]]#}" # strip whitespace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? Why should this do what the comment claims it would? ${word} may include whitespace.

start+=$(( len - $#buf ))
end=$(( start + $#word ))

word_subst=$(_zsh_highlight_highlighter_files_fn_expand $word)

if ! zstat -H statdata -Ls -- "$word_subst" 2>/dev/null; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the dependency. z-sy-h doesn't depend on any modules (other than zsh/zle, of course).

Would it be possible to parse ls -ld -- $foo when the zsh/stat module isn't available? Compare how the main highlighter uses the alias builtin when ${aliases} isn't available.

start=$end
buf=${buf[$#word+1,-1]}
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];;
Comment on lines +184 to +186
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if $word is a symlink whose target is a broken symlink?

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
Comment on lines +193 to +194
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't follow, actually. The case statement above isn't a complete enumeration — see, for example, https://en.wikipedia.org/wiki/Doors_%28computing%29#Overview — and you haven't checked S_ISREG().

This is repeated below.

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
Comment on lines +195 to +198
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? First of all, you didn't check whether the file is owned by uid 0 or gid 0, so the comments are simply wrong. Secondly, why do you check for S but not for s?

elif [[ $mode[9] = w ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[ow] # other-writable
elif [[ $mode[4] = x ]]; then
col=$ZSH_HIGHLIGHT_FILE_TYPES[ex] # Executable
Comment on lines +201 to +202
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about s? What about x at locations other than 4? The user might not be the owner of the file.

fi
fi

# Regular file: check file patterns
if [[ -z "$col" ]]; then
for key val in "${(@)ZSH_HIGHLIGHT_FILE_PATTERNS}"; do
if [[ $basename = $~key ]]; then
col=$val
break
fi
Comment on lines +208 to +212
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document that ordering is significant and first match wins.

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 )); then
# There is a path component
if [[ $ZSH_HIGHLIGHT_FILE_TYPES[lp] = "same" ]]; then
region_highlight+=("$start $end $col")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update for memo= support in master: 810c2dc.

else
if (( ${+ZSH_HIGHLIGHT_FILE_TYPES[lp]} )); then
region_highlight+=("$start $(( end - $#basename )) $ZSH_HIGHLIGHT_FILE_TYPES[lp]")
fi
region_highlight+=("$(( end - $#basename )) $end $col")
fi
else
region_highlight+=("$start $end $col")
fi
fi

start=$end
buf=${buf[$#word+1,-1]}
done
}

43 changes: 43 additions & 0 deletions highlighters/files/test-data/patterns1.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env zsh
# -------------------------------------------------------------------------------------------------
# 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.
# -------------------------------------------------------------------------------------------------
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
# vim: ft=zsh sw=2 ts=2 et
# -------------------------------------------------------------------------------------------------

BUFFER=$': file.tar file.tgz file.webm'

local LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you minimize the value to the smallest thing that's required for the test? Both out of general test writing principles, and because there are copyright concerns in copying such a value wholesale. (Each entry by itself is uncopyrightable, but the collection as a whole might nevertheless be copyrightable.)

Ditto in the other tests.


zsh_highlight_files_extract_ls_colors

touch file.tar file.tgz file.webm

expected_region_highlight=(
"3 10 bold,fg=1"
"12 19 bold,fg=1"
'21 29 bold,fg=5'
)
45 changes: 45 additions & 0 deletions highlighters/files/test-data/patterns2.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env zsh
# -------------------------------------------------------------------------------------------------
# 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.
# -------------------------------------------------------------------------------------------------
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
# vim: ft=zsh sw=2 ts=2 et
# -------------------------------------------------------------------------------------------------

BUFFER=$': file.tar file.tgz Makefile #file.bak# file.PgP file.flv'

ZSH_HIGHLIGHT_FILE_PATTERNS=('Makefile' 'fg=#F0BE45,bold' 'SConstruct' 'fg=#F0BE45,bold' 'CMakeLists.txt' 'fg=#F0BE45,bold' 'BUILD' 'fg=#F0BE45,bold' 'README*' 'fg=#F0BE45,bold' '(#i)*.png' 'fg=#B50769' '(#i)*.jpeg' 'fg=#B50769' '(#i)*.jpg' 'fg=#B50769' '(#i)*.gif' 'fg=#B50769' '(#i)*.bmp' 'fg=#B50769' '(#i)*.tiff' 'fg=#B50769' '(#i)*.tif' 'fg=#B50769' '(#i)*.ppm' 'fg=#B50769' '(#i)*.pgm' 'fg=#B50769' '(#i)*.pbm' 'fg=#B50769' '(#i)*.pnm' 'fg=#B50769' '(#i)*.webp' 'fg=#B50769' '(#i)*.heic' 'fg=#B50769' '(#i)*.raw' 'fg=#B50769' '(#i)*.arw' 'fg=#B50769' '(#i)*.svg' 'fg=#B50769' '(#i)*.stl' 'fg=#B50769' '(#i)*.eps' 'fg=#B50769' '(#i)*.dvi' 'fg=#B50769' '(#i)*.ps' 'fg=#B50769' '(#i)*.cbr' 'fg=#B50769' '(#i)*.jpf' 'fg=#B50769' '(#i)*.cbz' 'fg=#B50769' '(#i)*.xpm' 'fg=#B50769' '(#i)*.ico' 'fg=#B50769' '(#i)*.cr2' 'fg=#B50769' '(#i)*.orf' 'fg=#B50769' '(#i)*.nef' 'fg=#B50769' '(#i)*.avi' 'fg=#D33682' '(#i)*.flv' 'fg=#D33682' '(#i)*.m2v' 'fg=#D33682' '(#i)*.m4v' 'fg=#D33682' '(#i)*.mkv' 'fg=#D33682' '(#i)*.mov' 'fg=#D33682' '(#i)*.mp4' 'fg=#D33682' '(#i)*.mpeg' 'fg=#D33682' '(#i)*.mpg' 'fg=#D33682' '(#i)*.ogm' 'fg=#D33682' '(#i)*.ogv' 'fg=#D33682' '(#i)*.vob' 'fg=#D33682' '(#i)*.wmv' 'fg=#D33682' '(#i)*.webm' 'fg=#D33682' '(#i)*.m2ts' 'fg=#D33682' '(#i)*.aac' 'fg=#F1559C' '(#i)*.m4a' 'fg=#F1559C' '(#i)*.mp3' 'fg=#F1559C' '(#i)*.ogg' 'fg=#F1559C' '(#i)*.wma' 'fg=#F1559C' '(#i)*.mka' 'fg=#F1559C' '(#i)*.opus' 'fg=#F1559C' '(#i)*.alac' 'fg=#F1559C' '(#i)*.ape' 'fg=#F1559C' '(#i)*.flac' 'fg=#F1559C' '(#i)*.wav' 'fg=#F1559C' '(#i)*.asc' 'fg=#6A7F00' '(#i)*.enc' 'fg=#6A7F00' '(#i)*.gpg' 'fg=#6A7F00' '(#i)*.pgp' 'fg=#6A7F00' '(#i)*.sig' 'fg=#6A7F00' '(#i)*.signature' 'fg=#6A7F00' '(#i)*.pfx' 'fg=#6A7F00' '(#i)*.p12' 'fg=#6A7F00' '(#i)*.djvu' 'fg=#878AE0' '(#i)*.doc' 'fg=#878AE0' '(#i)*.docx' 'fg=#878AE0' '(#i)*.dvi' 'fg=#878AE0' '(#i)*.eml' 'fg=#878AE0' '(#i)*.eps' 'fg=#878AE0' '(#i)*.fotd' 'fg=#878AE0' '(#i)*.odp' 'fg=#878AE0' '(#i)*.odt' 'fg=#878AE0' '(#i)*.pdf' 'fg=#878AE0' '(#i)*.ppt' 'fg=#878AE0' '(#i)*.pptx' 'fg=#878AE0' '(#i)*.rtf' 'fg=#878AE0' '(#i)*.xls' 'fg=#878AE0' '(#i)*.xlsx' 'fg=#878AE0' '(#i)*.zip' 'fg=#657B83,bold' '(#i)*.tar' 'fg=#657B83,bold' '(#i)*.Z' 'fg=#657B83,bold' '(#i)*.z' 'fg=#657B83,bold' '(#i)*.gz' 'fg=#657B83,bold' '(#i)*.bz2' 'fg=#657B83,bold' '(#i)*.a' 'fg=#657B83,bold' '(#i)*.ar' 'fg=#657B83,bold' '(#i)*.7z' 'fg=#657B83,bold' '(#i)*.iso' 'fg=#657B83,bold' '(#i)*.dmg' 'fg=#657B83,bold' '(#i)*.tc' 'fg=#657B83,bold' '(#i)*.rar' 'fg=#657B83,bold' '(#i)*.par' 'fg=#657B83,bold' '(#i)*.tgz' 'fg=#657B83,bold' '(#i)*.xz' 'fg=#657B83,bold' '(#i)*.txz' 'fg=#657B83,bold' '(#i)*.lzma' 'fg=#657B83,bold' '(#i)*.deb' 'fg=#657B83,bold' '(#i)*.rpm' 'fg=#657B83,bold' '(#i)*.zst' 'fg=#657B83,bold' '*~' 'fg=#586E75' '\#*\#' 'fg=#586E75' '(#i)*.tmp' 'fg=#586E75' '(#i)*.swp' 'fg=#586E75' '(#i)*.swo' 'fg=#586E75' '(#i)*.swn' 'fg=#586E75' '(#i)*.bak' 'fg=#586E75' '(#i)*.bk' 'fg=#586E75' '(#i)*.class' 'fg=#5158A9' '(#i)*.elc' 'fg=#5158A9' '(#i)*.o' 'fg=#5158A9' '(#i)*.pyc' 'fg=#5158A9')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line breaks, please, for readability in situ and for readability of future diffs. (This affects other tests too.)

You can get them easily by running print -rC2 -- ${(qq)ZSH_HIGHLIGHT_FILE_PATTERNS}.



touch file.tar file.tgz Makefile '#file.bak#' file.PgP file.flv

expected_region_highlight=(
'3 10 fg=#657B83,bold'
'12 19 fg=#657B83,bold'
'21 28 fg=#F0BE45,bold'
'30 39 fg=#586E75'
'41 48 fg=#6A7F00'
'50 57 fg=#D33682'
)
Loading