diff options
Diffstat (limited to 'dotfiles/system/.zsh/lib')
| -rw-r--r-- | dotfiles/system/.zsh/lib/-ftb-colorize | 34 | ||||
| -rwxr-xr-x | dotfiles/system/.zsh/lib/-ftb-fzf | 102 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/-ftb-generate-complist | 113 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/-ftb-generate-header | 35 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/-ftb-generate-query | 36 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/ftb-switch-group | 38 | ||||
| -rwxr-xr-x | dotfiles/system/.zsh/lib/ftb-tmux-popup | 83 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE | 21 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/zsh-ls-colors/README.md | 114 | ||||
| -rwxr-xr-x | dotfiles/system/.zsh/lib/zsh-ls-colors/demo | 65 | ||||
| -rw-r--r-- | dotfiles/system/.zsh/lib/zsh-ls-colors/ls-colors.zsh | 186 |
11 files changed, 0 insertions, 827 deletions
diff --git a/dotfiles/system/.zsh/lib/-ftb-colorize b/dotfiles/system/.zsh/lib/-ftb-colorize deleted file mode 100644 index 3b1909b..0000000 --- a/dotfiles/system/.zsh/lib/-ftb-colorize +++ /dev/null @@ -1,34 +0,0 @@ -#!/hint/zsh -emulate -L zsh -o cbases -o octalzeroes - -local REPLY -local -a reply stat lstat - -# fzf-tab-lscolors::match-by $1 lstat follow -zstat -A lstat -L -- $1 -# follow symlink -(( lstat[3] & 0170000 )) && zstat -A stat -- $1 2>/dev/null - -fzf-tab-lscolors::from-mode "$1" "$lstat[3]" $stat[3] -# fall back to name -[[ -z $REPLY ]] && fzf-tab-lscolors::from-name $1 - -# If this is a symlink -if [[ -n $lstat[14] ]]; then - local sym_color=$REPLY - local rsv_color=$REPLY - local rsv=$lstat[14] - # If this is not a broken symlink - if [[ -e $rsv ]]; then - # fzf-tab-lscolors::match-by $rsv stat - zstat -A stat -- $rsv - fzf-tab-lscolors::from-mode $rsv $stat[3] - # fall back to name - [[ -z $REPLY ]] && fzf-tab-lscolors::from-name $rsv - rsv_color=$REPLY - fi - dpre=$'\033[0m\033['$sym_color'm' - dsuf+=$'\033[0m -> \033['$rsv_color'm'$rsv -else - dpre=$'\033[0m\033['$REPLY'm' -fi diff --git a/dotfiles/system/.zsh/lib/-ftb-fzf b/dotfiles/system/.zsh/lib/-ftb-fzf deleted file mode 100755 index 19adf04..0000000 --- a/dotfiles/system/.zsh/lib/-ftb-fzf +++ /dev/null @@ -1,102 +0,0 @@ -#!/hint/zsh - -local tmp_dir=${TMPPREFIX:-/tmp/zsh}-fzf-tab-$USER -[[ -d $tmp_dir ]] || command mkdir $tmp_dir - -local ftb_preview_init=" -zmodload zsh/mapfile -local -a _ftb_compcap=(\"\${(@f)mapfile[$tmp_dir/compcap.$$]}\") -local -a _ftb_groups=(\"\${(@f)mapfile[$tmp_dir/groups.$$]}\") -local bs=\$'\2' -# get descriptoin -export desc=\${\${\"\$(<{f})\"%\$'\0'*}#*\$'\0'} -# get ctxt for current completion -local -A ctxt=(\"\${(@0)\${_ftb_compcap[(r)\${(b)desc}\$bs*]#*\$bs}}\") -# get group -if (( \$+ctxt[group] )); then - export group=\$_ftb_groups[\$ctxt[group]] -fi -# get original word -export word=\${(Q)ctxt[word]} -# get real path if it is file -if (( \$+ctxt[realdir] )); then - export realpath=\${ctxt[realdir]}\$word -fi -" -local binds=tab:down,btab:up,change:top,ctrl-space:toggle -local fzf_command fzf_flags fzf_preview debug_command tmp switch_group fzf_pad -local ret=0 - --ftb-zstyle -s fzf-command fzf_command || fzf_command=fzf --ftb-zstyle -a fzf-bindings tmp && binds+=,${(j:,:)tmp} --ftb-zstyle -a fzf-flags fzf_flags --ftb-zstyle -s fzf-preview fzf_preview --ftb-zstyle -a switch-group switch_group || switch_group=(F1 F2) --ftb-zstyle -s fzf-pad fzf_pad || fzf_pad=2 - --ftb-zstyle -a debug-command debug_command && { - ${(eX)debug_command} $fzf_flags - return -} - -print -rl -- $_ftb_compcap > $tmp_dir/compcap.$$ -print -rl -- $_ftb_groups > $tmp_dir/groups.$$ -print -r -- ${ftb_preview_init/{f}/\$1} > $tmp_dir/ftb_preview_init.$$ - -binds=${binds//{_FTB_INIT_}/. $tmp_dir/ftb_preview_init.$$ {f} $'\n'} - -local -i header_lines=$#_ftb_headers -local -i lines=$(( $#_ftb_compcap + fzf_pad + header_lines )) -local reload_command="$commands[zsh] -f $FZF_TAB_HOME/lib/ftb-switch-group $$ $header_lines $tmp_dir" - -# detect if we will use tmux popup -local use_tmux_popup=0 -if [[ $fzf_command == "ftb-tmux-popup" ]]; then - use_tmux_popup=1 -fi - -if (( ! use_tmux_popup )); then - # fzf will cause the current line to refresh, so move the cursor down. - echoti cud1 >/dev/tty - # reset cursor before call fzf - echoti cnorm >/dev/tty 2>/dev/null -fi - -cat > $tmp_dir/completions.$$ - -local dd='gdd' -if (( ${+commands[$dd]} == 0 )) ; then - dd='dd' -fi -if (( ${+commands[$dd]} == 0 )) ; then - dd='true' # nop if dd is not installed -fi - -_ftb_query="${_ftb_query}$(command "$dd" bs=1G count=1 status=none iflag=nonblock < /dev/tty 2>/dev/null)" || true - -$fzf_command \ - --ansi \ - --bind=$binds \ - --bind="${switch_group[1]}:reload($reload_command -1),${switch_group[2]}:reload($reload_command 1)" \ - --color=hl:$(( header_lines == 0 ? 188 : 255 )) \ - --cycle \ - --delimiter='\x00' \ - --expect=$continuous_trigger,$print_query,$accept_line \ - --header-lines=$header_lines \ - --height=${FZF_TMUX_HEIGHT:=$(( lines > LINES / 3 * 2 ? LINES / 3 * 2 : lines ))} \ - --layout=reverse \ - --multi \ - --nth=2,3 \ - --print-query \ - --query=$_ftb_query \ - --tiebreak=begin \ - ${fzf_preview:+--preview=$ftb_preview_init$fzf_preview} \ - $fzf_flags < $tmp_dir/completions.$$ || ret=$? - -if (( ! use_tmux_popup )); then - echoti civis >/dev/tty 2>/dev/null - echoti cuu1 >/dev/tty -fi - -command rm $tmp_dir/*.$$ 2>/dev/null -return $ret diff --git a/dotfiles/system/.zsh/lib/-ftb-generate-complist b/dotfiles/system/.zsh/lib/-ftb-generate-complist deleted file mode 100644 index 42dd033..0000000 --- a/dotfiles/system/.zsh/lib/-ftb-generate-complist +++ /dev/null @@ -1,113 +0,0 @@ -#!/hint/zsh - -local dsuf dpre k _v filepath first_word show_group default_color prefix bs=$'\b' -local -a list_colors group_colors tcandidates reply match mbegin mend -local -i same_word=1 colorful=0 -local -Ua duplicate_groups=() -local -A word_map=() - -(( $#_ftb_compcap == 0 )) && return - --ftb-zstyle -s show-group show_group || show_group=full --ftb-zstyle -s default-color default_color || default_color=$'\x1b[37m' --ftb-zstyle -s prefix prefix || { - zstyle -m ':completion:*:descriptions' format '*' && prefix='·' -} --ftb-zstyle -a group-colors group_colors || group_colors=($_ftb_group_colors) -zstyle -a ":completion:$_ftb_curcontext" list-colors list_colors - -# init colorize -if (( $+builtins[fzf-tab-candidates-generate] )); then - fzf-tab-candidates-generate -i list_colors -else - local -A namecolors=(${(@s:=:)${(@s.:.)list_colors}:#[[:alpha:]][[:alpha:]]=*}) - local -A modecolors=(${(@Ms:=:)${(@s.:.)list_colors}:#[[:alpha:]][[:alpha:]]=*}) - (( $#namecolors == 0 && $#modecolors == 0 )) && list_colors=() -fi - -if (( $#_ftb_groups == 1 )); then - -ftb-zstyle -m single-group prefix || prefix='' - -ftb-zstyle -m single-group color || group_colors=("$default_color") -fi - -if (( $+builtins[fzf-tab-candidates-generate] )); then - fzf-tab-candidates-generate -else - for k _v in "${(@ps:\2:)_ftb_compcap}"; do - local -A v=("${(@0)_v}") - [[ $v[word] == ${first_word:=$v[word]} ]] || same_word=0 - - # add character and color to describe the type of the files - dsuf='' dpre='' - if (( $+v[realdir] )); then - filepath=$v[realdir]${(Q)v[word]} - if [[ -d $filepath ]]; then - dsuf=/ - fi - # add color and resolve symlink if have list-colors - # detail: http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcomplist-Module - if (( $#list_colors )) && [[ -a $filepath || -L $filepath ]]; then - -ftb-colorize $filepath - colorful=1 - elif [[ -L $filepath ]]; then - dsuf=@ - fi - if [[ $options[list_types] == off ]]; then - dsuf='' - fi - fi - - # add color to description if they have group index - if (( $+v[group] )); then - local color=$group_colors[$v[group]] - # add a hidden group index at start of string to keep group order when sorting - # first group index is for builtin sort, sencond is for GNU sort - tcandidates+=$v[group]$'\b'$color$prefix$dpre$'\0'$v[group]$'\b'$k$'\0'$dsuf - else - tcandidates+=$default_color$dpre$'\0'$k$'\0'$dsuf - fi - - # check group with duplicate member - if [[ $show_group == brief ]]; then - if (( $+word_map[$v[word]] && $+v[group] )); then - duplicate_groups+=$v[group] # add this group - duplicate_groups+=$word_map[$v[word]] # add previous group - fi - word_map[$v[word]]=$v[group] - fi - done -fi - -(( same_word )) && tcandidates[2,-1]=() - -# sort and remove sort group or other index -zstyle -T ":completion:$_ftb_curcontext" sort -if (( $? != 1 )); then - if (( colorful )); then - # if enable list_colors, we should skip the first field - if [[ ${commands[sort]:A:t} != (|busybox*) ]]; then - # this is faster but doesn't work if `find` is from busybox - tcandidates=(${(f)"$(command sort -u -t '\0' -k 2 <<< ${(pj:\n:)tcandidates})"}) - else - # slower but portable - tcandidates=(${(@o)${(@)tcandidates:/(#b)([^$'\0']#)$'\0'(*)/$match[2]$'\0'$match[1]}}) - tcandidates=(${(@)tcandidates/(#b)(*)$'\0'([^$'\0']#)/$match[2]$'\0'$match[1]}) - fi - else - tcandidates=("${(@o)tcandidates}") - fi -fi -typeset -gUa _ftb_complist=("${(@)tcandidates//[0-9]#$bs}") - -# hide needless group -if (( $#_ftb_groups )); then - local i to_hide indexs=({1..$#_ftb_groups}) - case $show_group in - brief) to_hide=(${indexs:|duplicate_groups}) ;; - none) to_hide=($indexs) ;; - esac - for i in $to_hide; do - # NOTE: _ftb_groups is unique array - _ftb_groups[i]="__hide__$i" - done -fi diff --git a/dotfiles/system/.zsh/lib/-ftb-generate-header b/dotfiles/system/.zsh/lib/-ftb-generate-header deleted file mode 100644 index a54fee1..0000000 --- a/dotfiles/system/.zsh/lib/-ftb-generate-header +++ /dev/null @@ -1,35 +0,0 @@ -#!/hint/zsh - -typeset -ga _ftb_headers=() -local i tmp group_colors -local -i mlen=0 len=0 - -if (( $#_ftb_groups == 1 )) && { ! -ftb-zstyle -m single-group "header" }; then - return -fi - -# calculate the max column width -for i in $_ftb_groups; do - (( $#i > mlen )) && mlen=$#i -done -mlen+=1 - --ftb-zstyle -a group-colors group_colors || group_colors=($_ftb_group_colors) - -for (( i=1; i<=$#_ftb_groups; i++ )); do - [[ $_ftb_groups[i] == "__hide__"* ]] && continue - - if (( len + $#_ftb_groups[i] > COLUMNS - 5 )); then - _ftb_headers+=$tmp - tmp='' && len=0 - fi - if (( len + mlen > COLUMNS - 5 )); then - # the last column doesn't need padding - _ftb_headers+=$tmp$group_colors[i]$_ftb_groups[i]$'\033[00m' - tmp='' && len=0 - else - tmp+=$group_colors[i]${(r:$mlen:)_ftb_groups[i]}$'\033[00m' - len+=$mlen - fi -done -(( $#tmp )) && _ftb_headers+=$tmp diff --git a/dotfiles/system/.zsh/lib/-ftb-generate-query b/dotfiles/system/.zsh/lib/-ftb-generate-query deleted file mode 100644 index 87ebb75..0000000 --- a/dotfiles/system/.zsh/lib/-ftb-generate-query +++ /dev/null @@ -1,36 +0,0 @@ -#!/hint/zsh - -local key qtype tmp query_string -typeset -g _ftb_query= --ftb-zstyle -a query-string query_string || query_string=(prefix input first) -for qtype in $query_string; do - if [[ $qtype == prefix ]]; then - # find the longest common prefix among descriptions - local -a keys=(${_ftb_compcap%$'\2'*}) - tmp=$keys[1] - local MATCH match mbegin mend prefix=(${(s::)tmp}) - for key in ${keys:1}; do - (( $#tmp )) || break - [[ $key == $tmp* ]] && continue - # interpose characters from the current common prefix and $key and see how - # many pairs of equal characters we get at the start of the resulting string - [[ ${(j::)${${(s::)key[1,$#tmp]}:^prefix}} =~ '^(((.)\3)*)' ]] - # truncate common prefix and maintain loop invariant: ${(s::)tmp} == $prefix - tmp[$#MATCH/2+1,-1]="" - prefix[$#MATCH/2+1,-1]=() - done - elif [[ $qtype == input ]]; then - local fv=${_ftb_compcap[1]#*$'\2'} - local -A v=("${(@0)fv}") - tmp=$v[PREFIX] - if (( $RBUFFER[(i)$v[SUFFIX]] != 1 )); then - tmp=${tmp/%$v[SUFFIX]} - fi - tmp=${${tmp#$v[hpre]}#$v[apre]} - fi - if (( $query_string[(I)longest] )); then - (( $#tmp > $#_ftb_query )) && _ftb_query=$tmp - elif [[ -n $tmp ]]; then - _ftb_query=$tmp && break - fi -done diff --git a/dotfiles/system/.zsh/lib/ftb-switch-group b/dotfiles/system/.zsh/lib/ftb-switch-group deleted file mode 100644 index 8d06956..0000000 --- a/dotfiles/system/.zsh/lib/ftb-switch-group +++ /dev/null @@ -1,38 +0,0 @@ -#!/hint/zsh -emulate -L zsh -o extended_glob - -zmodload zsh/mapfile - -# receive arguments -local pid=$1 header_lines=$2 tmp_dir=$3 offset=$@[-1] - -# read completion list -local -a list=(${(f)mapfile[$tmp_dir/completions.$pid]}) - -# get total group count -if (( $#list > 10000 )); then - local -Ua total=(${(f)"$(print -l ${list:$header_lines} | grep -a -oP '^\x1b\[[0-9;]*m')"}) -else - local -Ua total=(${(M)${list:$header_lines}#$'\x1b['[0-9;]#*m}) -fi - -# get current group index, start from 2 -local current=2 -if [[ -f $tmp_dir/current-group.$pid ]]; then - current=$(( $(<$tmp_dir/current-group.$pid) + offset )) -fi -(( current > $#total )) && current=1 -(( current == 0 )) && current=$#total -echo $current > $tmp_dir/current-group.$pid - -# print headers -if (( header_lines != 0 )); then - print -l ${list[1,header_lines]/${total[current]}/$'\x1b[1m'} -fi - -# print current group -if (( $#list > 10000 )); then - print -l ${list:$header_lines} | grep -a -F "${total[current]}" -else - print -l ${(M)${list:$header_lines}:#${total[current]}*} -fi diff --git a/dotfiles/system/.zsh/lib/ftb-tmux-popup b/dotfiles/system/.zsh/lib/ftb-tmux-popup deleted file mode 100755 index 7e74d3c..0000000 --- a/dotfiles/system/.zsh/lib/ftb-tmux-popup +++ /dev/null @@ -1,83 +0,0 @@ -#!/hint/zsh -# Show results with tmux popup -# Example usage: -# zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup -# zstyle ':fzf-tab:*' popup-pad 0 0 -# It can also be used as a standalone tool, like: -# ls | ftb-tmux-popup -emulate -L zsh -o extended_glob - -# import min -autoload -Uz zmathfunc -zmathfunc - -: ${tmp_dir:=${TMPPREFIX:-/tmp/zsh}-fzf-tab-$USER} - -# fallback to fzf if it is not running in tmux -if (( ! $+TMUX_PANE )); then - fzf $@ - return -fi - -local ret=0 - -local -a fzf_opts=($@) -fzf_opts=(${${fzf_opts/--height*}/--layout*}) - -# get position of cursor and size of window -local -a tmp=($(command tmux display-message -p "#{pane_top} #{cursor_y} #{pane_left} #{cursor_x} #{window_height} #{window_width}")) -local cursor_y=$((tmp[1] + tmp[2])) cursor_x=$((tmp[3] + tmp[4])) window_height=$tmp[5] window_width=$tmp[6] - -# if not called by fzf-tab -if (( ! $+IN_FZF_TAB )); then - [[ -d $tmp_dir ]] || mkdir -p $tmp_dir - cat > $tmp_dir/completions.$$ -fi - -local text REPLY comp_lines comp_length length popup_pad - -zstyle -a ":fzf-tab:$_ftb_curcontext" popup-pad popup_pad || popup_pad=(0 0) - -# get the size of content, note we should remove all ANSI color code -comp_lines=$(( ${#${(f)mapfile[$tmp_dir/completions.$$]}} + $popup_pad[2] )) -if (( comp_lines <= 500 )); then - comp_length=0 - for line in ${(f)mapfile[$tmp_dir/completions.$$]}; do - length=${(m)#${(S)line//$'\x1b['[0-9]#*m}} - (( length >= comp_length )) && comp_length=$length - done -else - # FIXME: can't get the correct width of CJK characters. - comp_length=$(command sed 's/\x1b\[[0-9;]*m//g;s/\x00//g' $tmp_dir/completions.$$ | command awk 'length > max_length { max_length = length; } END { print max_length }') -fi -comp_length=$(( comp_length + $popup_pad[1] )) - -local popup_height popup_y popup_width popup_x - -# calculate the popup height and y position -if (( cursor_y * 2 > window_height )); then - # show above the cursor - popup_height=$(( min(comp_lines + 4, cursor_y) )) - popup_y=$cursor_y -else - # show below the cursor - popup_height=$(( min(comp_lines + 4, window_height - cursor_y) )) - popup_y=$(( cursor_y + popup_height + 1 )) - fzf_opts+=(--layout=reverse) -fi - -# calculate the popup width and x position -popup_width=$(( min(comp_length + 5, window_width) )) -popup_x=$(( cursor_x + popup_width > window_width ? window_width - popup_width : cursor_x )) - -echo -E "$commands[fzf] ${(qq)fzf_opts[@]} < $tmp_dir/completions.$$ > $tmp_dir/result-$$" > $tmp_dir/fzf-$$ -{ - tmux popup -x $popup_x -y $popup_y \ - -w $popup_width -h $popup_height \ - -d $PWD -E ". $tmp_dir/fzf-$$" || ret=$? - echo -E "$(<$tmp_dir/result-$$)" -} always { - command rm $tmp_dir/*-$$ - (( $+IN_FZF_TAB )) || command rm $tmp_dir/completions.$$ -} -return $ret diff --git a/dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE b/dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE deleted file mode 100644 index 940b4c2..0000000 --- a/dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Gamma - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dotfiles/system/.zsh/lib/zsh-ls-colors/README.md b/dotfiles/system/.zsh/lib/zsh-ls-colors/README.md deleted file mode 100644 index 7736ce6..0000000 --- a/dotfiles/system/.zsh/lib/zsh-ls-colors/README.md +++ /dev/null @@ -1,114 +0,0 @@ -# zsh-ls-colors - - - -A zsh library to use `LS_COLORS` in scripts or other plugins. - -For a simple demo, see the `demo` script in this repo. - -For more advanced usage, -instructions are located at top of the source files for `from-mode` and `from-name`. -If a use case isn't adequately covered, -please open an issue! - -## Using zsh-ls-colors in a plugin - -You can use this as a submodule or a subtree. - -### submodule: - -```sh -# Add (only once) -git submodule add git://github.com/xPMo/zsh-ls-colors.git ls-colors -git commit -m 'Add ls-colors as submodule' - -# Update -cd ls-colors -git fetch -git checkout origin/master -cd .. -git commit ls-colors -m 'Update ls-colors to latest' -``` - -### Subtree: - -```sh -# Initial add -git subtree add --prefix=ls-colors/ --squash -m 'Add ls-colors as a subtree' \ - git://github.com/xPMo/zsh-ls-colors.git master - -# Update -git subtree pull --prefix=ls-colors/ --squash -m 'Update ls-colors to latest' \ - git://github.com/xPMo/zsh-ls-colors.git master - - -# Or, after adding a remote: -git remote add ls-colors git://github.com/xPMo/zsh-ls-colors.git - -# Initial add -git subtree add --prefix=ls-colors/ --squash -m 'Add ls-colors as a subtree' ls-colors master - -# Update -git subtree pull --prefix=ls-colors/ --squash -m 'Update ls-colors to latest' ls-colors master -``` - -### Function namespacing - -Since functions are a public namespace, -this plugin allows you to customize the preifix for your plugin: - -```zsh -# load functions as my-lscolors::{init,match-by,from-name,from-mode} -source ${0:h}/ls-colors/ls-colors.zsh my-lscolors -``` - -### Parameter namespacing - -While indirect parameter expansion exists with `${(P)var}`, -it doesn't play nicely with array parameters. - -There are multiple strategies to prevent unnecessary re-parsing: - -```zsh -# Call once when loading. -# Pollutes global namespace but prevents re-parsing -ls-color::init -``` - -```zsh -# Don't call init at all and only use ::match-by. -# Doesn't pollute global namespace but reparses LS_COLORS on every call -ls-color::match-by $file lstat -``` - -```zsh -# Initialize within a scope with local parameters. -# Best for not polluting global namespace when multiple filenames need to be parsed. -(){ - local -A namecolors modecolors - ls-color::init - - for arg; do - ... - done -} -``` - -```zsh -# Serialize: -typeset -g LS_COLORS_CACHE_FILE=$(mktemp) -(){ - local -A namecolors modecolors - ls-color::init - typeset -p modecolors namecolors >| $LS_COLORS_CACHE_FILE - zcompile $LS_COLORS_CACHE_FILE -} - -my-function(){ - local -A namecolors modecolors - source $LS_COLORS_CACHE_FILE - - ... -} -``` - diff --git a/dotfiles/system/.zsh/lib/zsh-ls-colors/demo b/dotfiles/system/.zsh/lib/zsh-ls-colors/demo deleted file mode 100755 index a5e468d..0000000 --- a/dotfiles/system/.zsh/lib/zsh-ls-colors/demo +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env zsh -# set $0 (ref: zdharma.org/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html#zero-handling) -0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" -0="${${(M)0:#/*}:-$PWD/$0}" - -# load library functions -source ls-colors.zsh '' - -# to name the functions with a different namespace -# call source with a different argument -#source my-plugin::ls - -# init (sets modecolors and namecolors) -# You have options. Either you can pollute global namespace: -ls-color::init -# Or you can have ::match-by re-parse colors on every call -: # (do nothing) -# Or if you have multiple calls, you can parse colors once for a scope: -(){ - local -A modecolors namecolors - ls-color::init - - for arg; do - ls-color::match-by $arg lstat - : do something else - done -} - - -# colors can also be added for other globs after init as well: -namecolors[*.md]='01' # bold markdown files - -# EXTENDED_GLOB is enabled when matching, so things like this are possible: -namecolors[(#i)(*/|)license(|.*)]='04' # underline LICENSE, or license.txt, or similar - -local file reply -# color each file in the argument list -for file; do - ls-color::match-by $file all - # point to symlink resolution if it exists - print '\e['$reply[1]'m'$file'\e[0m'${reply[2]:+' → \e['$reply[3]'m'$reply[2]'\e[0m'} -done - -# ======================= -# Alternate manual method: -for file; do - ls-color::match-by $file lstat follow - if [[ $reply[2] ]]; then - # This is a symlink - symlink_color=$reply[1] - # If broken, use link color for destination - resolved_color=$reply[1] - resolved=$reply[2] - if [[ -e $file ]]; then - # Not broken, update destination color - ls-color::match-by $file stat - resolved_color=$reply[1] - fi - print '\e['$symlink_color'm'$file'\e[0m → \e['$resolved_color'm'$resolved'\e[0m' - else - # This is not a symlink - print '\e['$reply[1]'m'$file'\e[0m' - fi -done - diff --git a/dotfiles/system/.zsh/lib/zsh-ls-colors/ls-colors.zsh b/dotfiles/system/.zsh/lib/zsh-ls-colors/ls-colors.zsh deleted file mode 100644 index 276a7bb..0000000 --- a/dotfiles/system/.zsh/lib/zsh-ls-colors/ls-colors.zsh +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env zsh - -# set the prefix for all functions -local pfx=${1:-'ls-color'} - -# {{{ From mode -# Usage: -# $1: filename -# $2: The value of struct stat st_mode -# If empty, modecolors lookup will be skipped -# $3: (If symlink) The value of struct stat st_mode -# for the target of $1's symlink. If unset, -# interpret as a broken link. -# Sets REPLY to the console code -${pfx}::from-mode () { - - emulate -L zsh - setopt cbases octalzeroes extendedglob - - [[ -z $2 ]] && return 1 - - local -i reg=0 - local -a codes - - local -i st_mode=$(($2)) - # See man 7 inode for more info - # file type - case $(( st_mode & 0170000 )) in - $(( 0140000 )) ) codes=( $modecolors[so] ) ;; - $(( 0120000 )) ) # symlink, special handling - if ! (($+3)); then - REPLY=$modecolors[or] - elif [[ $modecolors[ln] = target ]]; then - "$0" "$1" "${@:3}" - else - REPLY=$modecolors[ln] - fi - return - ;; - $(( 0100000 )) ) codes=( ); reg=1 ;; # regular file - $(( 0060000 )) ) codes=( $modecolors[bd] ) ;; - $(( 0040000 )) ) codes=( $modecolors[di] ) ;; - $(( 0020000 )) ) codes=( $modecolors[cd] ) ;; - $(( 0010000 )) ) codes=( $modecolors[pi] ) ;; - esac - - # setuid/setgid/sticky/other-writable - (( st_mode & 04000 )) && codes+=( $modecolors[su] ) - (( st_mode & 02000 )) && codes+=( $modecolors[sg] ) - (( ! reg )) && case $(( st_mode & 01002 )) in - # sticky - $(( 01000 )) ) codes+=( $modecolors[st] ) ;; - # other-writable - $(( 00002 )) ) codes+=( $modecolors[ow] ) ;; - # other-writable and sticky - $(( 01002 )) ) codes+=( $modecolors[tw] ) ;; - esac - - # executable - if (( ! $#codes )); then - (( st_mode & 0111 )) && codes+=( $modecolors[ex] ) - fi - - # return nonzero if no matching code - [[ ${REPLY::=${(j:;:)codes}} ]] -} # }}} -# {{{ From name -# Usage: -# $1: filename -# -# Sets REPLY to the console code -${pfx}::from-name () { - - emulate -L zsh - setopt extendedglob - - # Return non-zero if no keys match - [[ ${REPLY::=$namecolors[(k)$1]} ]] -} # }}} -# {{{ Init -# WARNING: initializes namecolors and modecolors in global scope -${pfx}::init () { - emulate -L zsh - - # Use $1 if provided, otherwise use LS_COLORS - # Use LSCOLORS on BSD - local LS_COLORS=${1:-${LS_COLORS:-$LSCOLORS}} - - # read in LS_COLORS - typeset -gA namecolors=(${(@s:=:)${(@s.:.)LS_COLORS}:#[[:alpha:]][[:alpha:]]=*}) - typeset -gA modecolors=(${(@Ms:=:)${(@s.:.)LS_COLORS}:#[[:alpha:]][[:alpha:]]=*}) -} -# }}} -# {{{ Match by -# Usage: -# $1: filename -# Optional (must be $2): g[lobal]: Use existing stat | lstat in parent scope -# ${@:2}: Append to reply: -# - l[stat] : Look up using lstat (don't follow symlink), if empty match name -# - s[tat] : Look up using stat (do follow symlink), if empty match name -# - n[ame] : Only match name -# - f[ollow]: Get resolution path of symlink -# - L[stat] : Same as above but don't match name -# - S[tat] : Same as above but don't match name -# - a[ll] : If a broken symlink: lstat follow lstat -# : If a symlink : lstat follow stat -# : Otherwise : lstat -# - A[ll] : If a broken symlink: Lstat follow Lstat -# : If a symlink : Lstat follow Stat -# : Otherwise : Lstat -# -# or returns non-zero -${pfx}::match-by () { - emulate -L zsh - setopt extendedglob cbases octalzeroes - - local arg REPLY name=$1 pfx=${0%::match-by} - shift - - # init in local scope if not using global params - if ! [[ -v namecolors && -v modecolors ]]; then - local -A namecolors modecolors - ${pfx}::init - fi - - if [[ ${1:l} = (g|global) ]]; then - shift - else - local -a stat lstat - declare -ga reply=() - fi - - zmodload -F zsh/stat b:zstat - for arg; do - case ${arg[1]:l} in - n|name) - ${pfx}::from-name $name - reply+=("$REPLY") - ;; - l|lstat) - (($#lstat)) || zstat -A lstat -L $name || return 1 - if ((lstat[3] & 0170000 )); then - # follow symlink - (($#stat)) || zstat -A stat $name 2>/dev/null - fi - ${pfx}::from-mode "$name" "$lstat[3]" $stat[3] - if [[ $REPLY || ${2[1]} = L ]]; then - reply+=("$REPLY") - else # fall back to name - "$0" "$name" g n - fi - ;; - s|stat) - (($#stat)) || zstat -A stat $name || return 1 - ${pfx}::from-mode $name $stat[3] - reply+=("$REPLY") - if [[ $REPLY || ${arg[1]} = S ]]; then - reply+=("$REPLY") - else # fall back to name - "$0" "$name" g n - fi - ;; - f|follow) - (($#lstat)) || zstat -A lstat -L $name || return 1 - reply+=("$lstat[14]") - ;; - a|all) - # Match case - "$0" "$name" g ${${${arg[1]%a}:+L}:-l} - # won't append if empty - reply+=($lstat[14]) - # $stat[14] will be empty if not a symlink - if [[ $lstat[14] ]]; then - if [[ -e $name ]]; then - "$0" "$name" g ${${${arg[1]%a}:+S}:-s} - else - reply+=($reply[-2]) - fi - fi - ;; - *) return 2 ;; - esac - done -} -# }}} -# vim: set foldmethod=marker: |
