Browse Source

refactor(theme-and-appearance): reorganize and clean up logic (#11529)

Co-authored-by: Andrew Janke <janke@pobox.com>
Co-authored-by: Marcelo Parada <marcelo.parada@axoninsight.com>
Co-authored-by: Uy Ha <hchanuy@gmail.com>
Co-authored-by: Valentin Uveges <valentin.uveges@gmail.com>
Marc Cornellà 1 year ago
parent
commit
95d0c4b603
1 changed files with 81 additions and 54 deletions
  1. 81 54
      lib/theme-and-appearance.zsh

+ 81 - 54
lib/theme-and-appearance.zsh

@@ -1,66 +1,93 @@
-# ls colors
+# Sets color variable such as $fg, $bg, $color and $reset_color
 autoload -U colors && colors
 
-# Enable ls colors
-export LSCOLORS="Gxfxcxdxbxegedabagacad"
+# Expand variables and commands in PROMPT variables
+setopt prompt_subst
 
-# TODO organise this chaotic logic
+# Prompt function theming defaults
+ZSH_THEME_GIT_PROMPT_PREFIX="git:("   # Beginning of the git prompt, before the branch name
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"       # End of the git prompt
+ZSH_THEME_GIT_PROMPT_DIRTY="*"        # Text to display if the branch is dirty
+ZSH_THEME_GIT_PROMPT_CLEAN=""         # Text to display if the branch is clean
+ZSH_THEME_RUBY_PROMPT_PREFIX="("
+ZSH_THEME_RUBY_PROMPT_SUFFIX=")"
 
-if [[ "$DISABLE_LS_COLORS" != "true" ]]; then
-  if [[ -d "$ZSH" ]]; then
-    _test_dir="$ZSH"
-  else
-    _test_dir="."
-  fi
-  # Find the option for using colors in ls, depending on the version
-  if [[ "$OSTYPE" == netbsd* ]]; then
-    # On NetBSD, test if "gls" (GNU ls) is installed (this one supports colors);
-    # otherwise, leave ls as is, because NetBSD's ls doesn't support -G
-    gls --color -d "$_test_dir" &>/dev/null && alias ls='gls --color=tty'
-  elif [[ "$OSTYPE" == openbsd* ]]; then
-    # On OpenBSD, "gls" (ls from GNU coreutils) and "colorls" (ls from base,
-    # with color and multibyte support) are available from ports.  "colorls"
-    # will be installed on purpose and can't be pulled in by installing
-    # coreutils, so prefer it to "gls".
-    gls --color -d "$_test_dir" &>/dev/null && alias ls='gls --color=tty'
-    colorls -G -d "$_test_dir" &>/dev/null && alias ls='colorls -G'
-  elif [[ "$OSTYPE" == (darwin|freebsd)* ]]; then
-    # this is a good alias, it works by default just using $LSCOLORS
-    ls -G "$_test_dir" &>/dev/null && alias ls='ls -G'
 
-    # only use coreutils ls if there is a dircolors customization present ($LS_COLORS or .dircolors file)
-    # otherwise, gls will use the default color scheme which is ugly af
-    [[ -n "$LS_COLORS" || -f "$HOME/.dircolors" ]] && gls --color -d "$_test_dir" &>/dev/null && alias ls='gls --color=tty'
-  else
-    # For GNU ls, we use the default ls color theme. They can later be overwritten by themes.
-    if [[ -z "$LS_COLORS" ]]; then
-      (( $+commands[dircolors] )) && eval "$(dircolors -b)"
+# Use diff --color if available
+if command diff --color /dev/null{,} &>/dev/null; then
+  function diff {
+    command diff --color "$@"
+  }
+fi
+
+
+# Don't set ls coloring if disabled
+[[ "$DISABLE_LS_COLORS" != true ]] || return 0
+
+function test-ls-args {
+  local cmd="$1"          # ls, gls, colorls, ...
+  local args="${@[2,-1]}" # arguments except the first one
+  command "$cmd" "$args" /dev/null &>/dev/null
+}
+
+# Find the option for using colors in ls, depending on the version
+case "$OSTYPE" in
+  netbsd*)
+    # On NetBSD, test if `gls` (GNU ls) is installed (this one supports colors);
+    # otherwise, leave ls as is, because NetBSD's ls doesn't support -G
+    test-ls-args gls --color && alias ls='gls --color=tty'
+    ;;
+  openbsd*)
+    # On OpenBSD, `gls` (ls from GNU coreutils) and `colorls` (ls from base,
+    # with color and multibyte support) are available from ports.
+    # `colorls` will be installed on purpose and can't be pulled in by installing
+    # coreutils (which might be installed for ), so prefer it to `gls`.
+    test-ls-args gls --color && alias ls='gls --color=tty'
+    test-ls-args colorls -G && alias ls='colorls -G'
+    ;;
+  (darwin|freebsd)*)
+    # This alias works by default just using $LSCOLORS
+    test-ls-args ls -G && alias ls='ls -G'
+    # Only use GNU ls if installed and there are user defaults for $LS_COLORS,
+    # as the default coloring scheme is not very pretty
+    [[ -n "$LS_COLORS" || -f "$HOME/.dircolors" ]] \
+      && test-ls-args gls --color \
+      && alias ls='gls --color=tty'
+    ;;
+  *)
+    if test-ls-args ls --color; then
+      alias ls='ls --color=tty'
+    elif test-ls-args ls -G; then
+      alias ls='ls -G'
     fi
+    ;;
+esac
 
-    ls --color -d "$_test_dir" &>/dev/null && alias ls='ls --color=tty' || { ls -G "$_test_dir" &>/dev/null && alias ls='ls -G' }
+unfunction test-ls-args
 
-    # Take advantage of $LS_COLORS for completion as well.
-    zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
-  fi
-fi
 
-# enable diff color if possible.
-if command diff --color /dev/null /dev/null &>/dev/null; then
-  function color-diff {
-    command diff --color $@
-  }
-  alias diff="color-diff"
-  compdef _diff color-diff # compdef is already loaded by this point
-fi
+# Default coloring for BSD-based ls
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
 
-setopt prompt_subst
+# Default coloring for GNU-based ls
+if [[ -z "$LS_COLORS" ]]; then
+  # Define LS_COLORS via dircolors if available. Otherwise, set a default
+  # equivalent to LSCOLORS (generated via https://geoff.greer.fm/lscolors)
+  if (( $+commands[dircolors] )); then
+    [[ -f "$HOME/.dircolors" ]] \
+      && source <(dircolors -b "$HOME/.dircolors") \
+      || source <(dircolors -b)
+  else
+    export LS_COLORS="di=34:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=37;41:sg=30;43:tw=30;42:ow=34;42:"
+  fi
+fi
 
-[[ -n "$WINDOW" ]] && SCREEN_NO="%B$WINDOW%b " || SCREEN_NO=""
+# Take advantage of $LS_COLORS for completion as well.
+function omz_set_completion_colors {
+  zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
+  add-zsh-hook -d precmd omz_set_completion_colors
+  unfunction omz_set_completion_colors
+}
 
-# git theming default: Variables for theming the git info prompt
-ZSH_THEME_GIT_PROMPT_PREFIX="git:("         # Prefix at the very beginning of the prompt, before the branch name
-ZSH_THEME_GIT_PROMPT_SUFFIX=")"             # At the very end of the prompt
-ZSH_THEME_GIT_PROMPT_DIRTY="*"              # Text to display if the branch is dirty
-ZSH_THEME_GIT_PROMPT_CLEAN=""               # Text to display if the branch is clean
-ZSH_THEME_RUBY_PROMPT_PREFIX="("
-ZSH_THEME_RUBY_PROMPT_SUFFIX=")"
+autoload -Uz add-zsh-hook
+add-zsh-hook precmd omz_set_completion_colors