summaryrefslogtreecommitdiff
path: root/dotfiles/system/.zsh/lib/zsh-ls-colors
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-05-08 18:49:34 -0500
committerCraig Jennings <c@cjennings.net>2025-05-08 18:51:59 -0500
commit000e00871830cd15de032c80e2b62946cf19445c (patch)
tree794a7922750472bbe0e024042d6ba84f411fc3e0 /dotfiles/system/.zsh/lib/zsh-ls-colors
parentfe302606931e4bad91c4ed6df81a4403523ba780 (diff)
adding missing dotfiles and folders
- profile.d/ - bashrc - authinfo.gpg - .zsh/
Diffstat (limited to 'dotfiles/system/.zsh/lib/zsh-ls-colors')
-rw-r--r--dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE21
-rw-r--r--dotfiles/system/.zsh/lib/zsh-ls-colors/README.md114
-rwxr-xr-xdotfiles/system/.zsh/lib/zsh-ls-colors/demo65
-rw-r--r--dotfiles/system/.zsh/lib/zsh-ls-colors/ls-colors.zsh186
4 files changed, 386 insertions, 0 deletions
diff --git a/dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE b/dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE
new file mode 100644
index 0000000..940b4c2
--- /dev/null
+++ b/dotfiles/system/.zsh/lib/zsh-ls-colors/LICENSE
@@ -0,0 +1,21 @@
+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
new file mode 100644
index 0000000..7736ce6
--- /dev/null
+++ b/dotfiles/system/.zsh/lib/zsh-ls-colors/README.md
@@ -0,0 +1,114 @@
+# zsh-ls-colors
+
+![Demo screenshot](https://raw.githubusercontent.com/xPMo/zsh-ls-colors/image/demo.png)
+
+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
new file mode 100755
index 0000000..a5e468d
--- /dev/null
+++ b/dotfiles/system/.zsh/lib/zsh-ls-colors/demo
@@ -0,0 +1,65 @@
+#!/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
new file mode 100644
index 0000000..276a7bb
--- /dev/null
+++ b/dotfiles/system/.zsh/lib/zsh-ls-colors/ls-colors.zsh
@@ -0,0 +1,186 @@
+#!/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: