Add theme off support and preserve defaulting behavior.

This commit is contained in:
Andrew Janke 2015-04-03 16:13:51 -04:00
commit ecb1fd91c8

View file

@ -45,6 +45,13 @@ else
SCREEN_NO="" SCREEN_NO=""
fi fi
# Theme and appearance
#
# Support for OMZ theming.
#
# This provides two public (user-facing) functions, theme() and lstheme(), for working
# with themes interactively.
# OMZ themes use promptsubst, so make sure it's on # OMZ themes use promptsubst, so make sure it's on
setopt prompt_subst setopt prompt_subst
@ -64,6 +71,7 @@ _OMZ_DEBUG_BLACKLISTED_THEMES=(agnoster dstufft dogenpunk fino fino-time half-li
# theme random - load a random theme # theme random - load a random theme
# theme <n> - load a theme by index (where <n> is an integer) # theme <n> - load a theme by index (where <n> is an integer)
# theme next - load the next theme in the list of defined themes # theme next - load the next theme in the list of defined themes
# theme off - unload theme and return to zsh appearance defaults
# #
# If no argument is given, `theme random` is the default behavior. # If no argument is given, `theme random` is the default behavior.
# #
@ -96,12 +104,35 @@ function theme() {
elif [[ $1 =~ '^[0-9]+$' ]]; then elif [[ $1 =~ '^[0-9]+$' ]]; then
# Select theme by index # Select theme by index
_omz_theme_n $1 _omz_theme_n $1
elif [[ $1 == "off" ]]; then
# Turn theming off
_omz_unload_theme
else else
# Main case: load named theme # Main case: load named theme
_omz_load_theme $1 _omz_load_theme $1
fi fi
} }
# List available themes by name
#
# The list will always be in sorted order, so you can index in to it.
# Themes in the "blacklist" are still included in lstheme, because they're
# still eligible for direct reference by explicit name or index, and that
# keeps the order stable.
function lstheme() {
local themes x theme_dir
themes=()
for theme_dir ($ZSH_CUSTOM $ZSH_CUSTOM/themes $ZSH/themes); do
if [[ -d $theme_dir ]]; then
themes+=($(_omz_lstheme_dir $theme_dir))
fi
done
themes=(${(ou)themes})
echo ${(F)themes}
}
function _omz_load_theme() { function _omz_load_theme() {
local name=$1 local name=$1
local theme_dir found local theme_dir found
@ -121,18 +152,17 @@ function _omz_load_theme() {
# Loads a theme by index # Loads a theme by index
# #
# Usage: # _omz_theme_n <n> - loads theme at given index
# themen - advance to the next theme # _omz_theme_n next - loads the next theme from the list of defined themes
# themen next - advance to the next theme
# themen <n> - load theme number <n>
# #
# Loads a theme selected by index into list of defined themes, instead of by # Loads a theme selected by index into list of defined themes, instead of by
# name. This is to make it easy to cycle through all the themes for debugging # name. This is to make it easy to cycle through all the themes for debugging
# or browsing purposes. # or browsing purposes.
# #
# If called without an argument, it just advances to the next theme in the list # If called without an argument, it just advances to the next theme in the list
# after the currently loaded theme.
# #
# `themen next` will ignore themes in the ZSH_BLACKLISTED_THEMES variable. # `_omz_theme_n next` will ignore themes in the ZSH_BLACKLISTED_THEMES parameter.
function _omz_theme_n() { function _omz_theme_n() {
# Numeric index argument: select theme by index # Numeric index argument: select theme by index
local themes n name n_themes blacklist local themes n name n_themes blacklist
@ -147,6 +177,9 @@ function _omz_theme_n() {
# from themes list to keep indexes stable # from themes list to keep indexes stable
blacklist=($(_omz_theme_blacklist)) blacklist=($(_omz_theme_blacklist))
while [[ ${blacklist[(i)${themes[n]}]} -le ${#blacklist} ]]; do while [[ ${blacklist[(i)${themes[n]}]} -le ${#blacklist} ]]; do
if [[ $ZSH_THEME_DEBUG == 'true' ]]; then
echo "[oh-my-zsh]: Skipping blacklisted theme ${themes[n]}"
fi
(( n = n % n_themes + 1 )) (( n = n % n_themes + 1 ))
done done
else else
@ -172,10 +205,9 @@ function _omz_theme_n() {
# This operates by "reference", so caller should pass in names of the input # This operates by "reference", so caller should pass in names of the input
# parameters, not their values. # parameters, not their values.
# #
# Implementation note: the input variables may not be named "omz_asd_a", "omz_asd_b", # Implementation note: the input variables may not be named "_omz_asd_a", "_omz_asd_b",
# or "omz_asd_out_name". # or "_omz_asd_out_name", due to dynamic scoping conflicts. And you cannot use the
# due to dynamic scoping conflicts. And you cannot use the numeric parameters ($1, $2, etc) # numeric parameters ($1, $2, etc) as inputs.
# as inputs.
# #
# Example: # Example:
# #
@ -186,18 +218,18 @@ function _omz_theme_n() {
# After the function call, $c will contain (foo baz). # After the function call, $c will contain (foo baz).
# #
function _omz_array_setdiff() { function _omz_array_setdiff() {
local omz_asd_a omz_asd_b omz_asd_out_name local _omz_asd_a _omz_asd_b _omz_asd_out_name
omz_asd_out_name=$1 _omz_asd_out_name=$1
omz_asd_a=(${(P)2}) _omz_asd_a=(${(P)2})
omz_asd_b=(${(P)3}) _omz_asd_b=(${(P)3})
local my_out item local my_out item
my_out=() my_out=()
for item (${omz_asd_a}); do for item (${_omz_asd_a}); do
if [[ ${omz_asd_b[(i)$item]} -gt ${#omz_asd_b} ]]; then if [[ ${_omz_asd_b[(i)$item]} -gt ${#_omz_asd_b} ]]; then
my_out+=($item) my_out+=($item)
fi fi
done done
set -A $omz_asd_out_name $my_out set -A $_omz_asd_out_name $my_out
} }
@ -314,26 +346,61 @@ function _omz_source_theme_file() {
source $1 source $1
} }
# Resets all theme settings to their default state # Unloads the OMZ theme from this session, by unsetting theme-related
# (To the extent that we know what themes do, that is.) # parameters, removing installed hook functions, and restoring prompt parameters
# This will reset all variables used by the core OMZ *_prompt_info functions. # to their default ZSH values
# It will also remove any hook functions installed by the current theme, if it function _omz_unload_theme() {
# was loaded by the theme() function # Unload hook functions
function _omz_reset_theme() { if [[ -n $_OMZ_THEME_CHPWD_FUNCTIONS ]]; then
# Prompts #echo Removing chpwd hooks: $_OMZ_THEME_CHPWD_FUNCTIONS
PROMPT="%n@%m:%~%# " _omz_array_setdiff chpwd_functions chpwd_functions _OMZ_THEME_CHPWD_FUNCTIONS
PROMPT2='%_> ' fi
PROMPT3='?# ' if [[ -n $_OMZ_THEME_PRECMD_FUNCTIONS ]]; then
PROMPT4='+%N:%i> ' #echo Removing precmd hooks: $_OMZ_THEME_PRECMD_FUNCTIONS
unset RPROMPT RPROMPT2 _omz_array_setdiff precmd_functions precmd_functions _OMZ_THEME_PRECMD_FUNCTIONS
fi
if [[ -n $_OMZ_THEME_PREEXEC_FUNCTIONS ]]; then
#echo Removing preexec hooks: $_OMZ_THEME_PREEXEC_FUNCTIONS
_omz_array_setdiff preexec_functions preexec_functions _OMZ_THEME_PREEXEC_FUNCTIONS
fi
# This assumes that all ZSH_THEME_<aspect>_* variables are owned by # This assumes that all ZSH_THEME_<aspect>_* variables are owned by
# OMZ theming, and can be reset en masse # OMZ theming, and can be reset en masse
# All the commented-out variables are there to serve as a list of things # All the commented-out variables are there to serve as a list of things
# that are used by theme support and could be given default values # that are used by theme support and could be given default values
# git_prompt_info variables
unset -m 'ZSH_THEME_GIT_PROMPT_*' unset -m 'ZSH_THEME_GIT_PROMPT_*'
unset -m 'ZSH_THEME_NVM_PROMPT_*'
unset -m 'ZSH_THEME_RVM_PROMPT_*'
unset -m 'ZSH_THEME_SVN_PROMPT_*'
# Reset prompts to default ZSH values (values found in ZSH reference manual)
PROMPT='%m%# '
PROMPT2='%_> '
PROMPT3='?# '
PROMPT4='+%N:%i> '
SPROMPT="zsh: correct '%R' to '%r' [nyae]?"
unset RPROMPT RPROMPT2
unset ZSH_THEME
}
# Resets all theme settings to their OMZ default state
# (To the extent that we know what themes do, that is.)
# This will reset all variables used by the core OMZ *_prompt_info functions.
# It will also remove any hook functions installed by the current theme, if it
# was loaded by the theme() function
function _omz_reset_theme() {
_omz_unload_theme
_omz_apply_theme_defaults
}
# Adds OMZ default values that differ from ZSH defaults
function _omz_apply_theme_defaults() {
# Prompts
PROMPT="%n@%m:%~%# "
# git_prompt_info variables
ZSH_THEME_GIT_PROMPT_PREFIX="git:(" # Prefix at the very beginning of the prompt, before the branch name 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_SUFFIX=")" # At the very end of the prompt
#ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX= #ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX=
@ -356,59 +423,20 @@ function _omz_reset_theme() {
#ZSH_THEME_GIT_PROMPT_DIVERGED= #ZSH_THEME_GIT_PROMPT_DIVERGED=
#ZSH_THEME_GIT_PROMPT_UNTRACKED= #ZSH_THEME_GIT_PROMPT_UNTRACKED=
# nvm_prompt_info variables # nvm_prompt_info variables
unset -m 'ZSH_THEME_NVM_PROMPT_*'
#ZSH_THEME_NVM_PROMPT_PREFIX= #ZSH_THEME_NVM_PROMPT_PREFIX=
#ZSH_THEME_NVM_PROMPT_SUFFIX= #ZSH_THEME_NVM_PROMPT_SUFFIX=
# rvm_prompt_info variables # rvm_prompt_info variables
unset -m 'ZSH_THEME_RVM_PROMPT_*'
#ZSH_THEME_RVM_PROMPT_PREFIX= #ZSH_THEME_RVM_PROMPT_PREFIX=
#ZSH_THEME_RVM_PROMPT_SUFFIX= #ZSH_THEME_RVM_PROMPT_SUFFIX=
#ZSH_THEME_RVM_PROMPT_OPTIONS= #ZSH_THEME_RVM_PROMPT_OPTIONS=
# svn_prompt_info variables # svn_prompt_info variables
unset -m 'ZSH_THEME_SVN_PROMPT_*'
#ZSH_THEME_SVN_PROMPT_CLEAN #ZSH_THEME_SVN_PROMPT_CLEAN
#ZSH_THEME_SVN_PROMPT_DIRTY #ZSH_THEME_SVN_PROMPT_DIRTY
#ZSH_THEME_SVN_PROMPT_PREFIX #ZSH_THEME_SVN_PROMPT_PREFIX
#ZSH_THEME_SVN_PROMPT_SUFFIX #ZSH_THEME_SVN_PROMPT_SUFFIX
# Hook functions
if [[ -n $_OMZ_THEME_CHPWD_FUNCTIONS ]]; then
#echo Removing chpwd hooks: $_OMZ_THEME_CHPWD_FUNCTIONS
#chpwd_functions=(${chpwd_functions:|_OMZ_THEME_CHPWD_FUNCTIONS})
_omz_array_setdiff chpwd_functions chpwd_functions _OMZ_THEME_CHPWD_FUNCTIONS
fi
if [[ -n $_OMZ_THEME_PRECMD_FUNCTIONS ]]; then
#echo Removing precmd hooks: $_OMZ_THEME_PRECMD_FUNCTIONS
#precmd_functions=(${precmd_functions:|_OMZ_THEME_PRECMD_FUNCTIONS})
_omz_array_setdiff precmd_functions precmd_functions _OMZ_THEME_PRECMD_FUNCTIONS
fi
if [[ -n $_OMZ_THEME_PREEXEC_FUNCTIONS ]]; then
#echo Removing preexec hooks: $_OMZ_THEME_PREEXEC_FUNCTIONS
#preexec_functions=(${preexec_functions:|_OMZ_THEME_PREEXEC_FUNCTIONS})
_omz_array_setdiff preexec_functions preexec_functions _OMZ_THEME_PREEXEC_FUNCTIONS
fi
} }
# List available themes by name
#
# The list will always be in sorted order, so you can index in to it.
# Themes in the "blacklist" are still included in lstheme, because they're
# still eligible for direct reference by explicit name or index, and that
# keeps the order stable.
function lstheme() {
local themes x theme_dir
themes=()
for theme_dir ($ZSH_CUSTOM $ZSH_CUSTOM/themes $ZSH/themes); do
if [[ -d $theme_dir ]]; then
themes+=($(_omz_lstheme_dir $theme_dir))
fi
done
themes=(${(ou)themes})
echo ${(F)themes}
}
# List themes defined in a given dir # List themes defined in a given dir
function _omz_lstheme_dir() { function _omz_lstheme_dir() {
ls $1 | grep '.zsh-theme$' | sed 's,\.zsh-theme$,,' ls $1 | grep '.zsh-theme$' | sed 's,\.zsh-theme$,,'
@ -460,3 +488,40 @@ function _omz_theme_show_prompt_key {
done done
} }
# Set to true to enable debugging output for theme functions
# Note that this can cause unstable behavior, especially with these themes:
# agnoster dstufft
ZSH_THEME_DEBUG=${ZSH_THEME_DEBUG:-false}
# These themes are known to interact badly with our debugging support
_OMZ_DEBUG_BLACKLISTED_THEMES=(agnoster dstufft dogenpunk fino fino-time half-life \
kolo peepcode smt steeef suvash zhann)
# Configure and enable ls colors
autoload -U colors && colors
export LSCOLORS="Gxfxcxdxbxegedabagacad"
if [[ $DISABLE_LS_COLORS != "true" ]]; then
# Find the option for using colors in ls, depending on the version: Linux or BSD
if [[ "$(uname -s)" == "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 . &>/dev/null 2>&1 && alias ls='gls --color=tty'
elif [[ "$(uname -s)" == "OpenBSD" ]]; then
# On OpenBSD, test if "colorls" is installed (this one supports colors);
# otherwise, leave ls as is, because OpenBSD's ls doesn't support -G
colorls -G -d . &>/dev/null 2>&1 && alias ls='colorls -G'
else
ls --color -d . &>/dev/null 2>&1 && alias ls='ls --color=tty' || alias ls='ls -G'
fi
fi
if [[ -n $WINDOW ]]; then
SCREEN_NO="%B$WINDOW%b "
else
SCREEN_NO=""
fi
# OMZ themes use promptsubst, so make sure it's on
setopt prompt_subst
# Apply theming defaults, regardless of whether a specific theme is loaded
_omz_apply_theme_defaults