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=""
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
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 <n> - load a theme by index (where <n> is an integer)
# 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.
#
@ -96,12 +104,35 @@ function theme() {
elif [[ $1 =~ '^[0-9]+$' ]]; then
# Select theme by index
_omz_theme_n $1
elif [[ $1 == "off" ]]; then
# Turn theming off
_omz_unload_theme
else
# Main case: load named theme
_omz_load_theme $1
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() {
local name=$1
local theme_dir found
@ -121,18 +152,17 @@ function _omz_load_theme() {
# Loads a theme by index
#
# Usage:
# themen - advance to the next theme
# themen next - advance to the next theme
# themen <n> - load theme number <n>
# _omz_theme_n <n> - loads theme at given index
# _omz_theme_n next - loads the next theme from the list of defined themes
#
# 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
# or browsing purposes.
#
# 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() {
# Numeric index argument: select theme by index
local themes n name n_themes blacklist
@ -147,6 +177,9 @@ function _omz_theme_n() {
# from themes list to keep indexes stable
blacklist=($(_omz_theme_blacklist))
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 ))
done
else
@ -172,10 +205,9 @@ function _omz_theme_n() {
# This operates by "reference", so caller should pass in names of the input
# parameters, not their values.
#
# Implementation note: the input variables may not be named "omz_asd_a", "omz_asd_b",
# or "omz_asd_out_name".
# due to dynamic scoping conflicts. And you cannot use the numeric parameters ($1, $2, etc)
# as inputs.
# Implementation note: the input variables may not be named "_omz_asd_a", "_omz_asd_b",
# or "_omz_asd_out_name", due to dynamic scoping conflicts. And you cannot use the
# numeric parameters ($1, $2, etc) as inputs.
#
# Example:
#
@ -186,18 +218,18 @@ function _omz_theme_n() {
# After the function call, $c will contain (foo baz).
#
function _omz_array_setdiff() {
local omz_asd_a omz_asd_b omz_asd_out_name
omz_asd_out_name=$1
omz_asd_a=(${(P)2})
omz_asd_b=(${(P)3})
local _omz_asd_a _omz_asd_b _omz_asd_out_name
_omz_asd_out_name=$1
_omz_asd_a=(${(P)2})
_omz_asd_b=(${(P)3})
local my_out item
my_out=()
for item (${omz_asd_a}); do
if [[ ${omz_asd_b[(i)$item]} -gt ${#omz_asd_b} ]]; then
for item (${_omz_asd_a}); do
if [[ ${_omz_asd_b[(i)$item]} -gt ${#_omz_asd_b} ]]; then
my_out+=($item)
fi
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
}
# Resets all theme settings to their 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() {
# Prompts
PROMPT="%n@%m:%~%# "
PROMPT2='%_> '
PROMPT3='?# '
PROMPT4='+%N:%i> '
unset RPROMPT RPROMPT2
# Unloads the OMZ theme from this session, by unsetting theme-related
# parameters, removing installed hook functions, and restoring prompt parameters
# to their default ZSH values
function _omz_unload_theme() {
# Unload hook functions
if [[ -n $_OMZ_THEME_CHPWD_FUNCTIONS ]]; then
#echo Removing chpwd hooks: $_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
_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
# OMZ theming, and can be reset en masse
# 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
# git_prompt_info variables
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_SUFFIX=")" # At the very end of the prompt
#ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX=
@ -356,59 +423,20 @@ function _omz_reset_theme() {
#ZSH_THEME_GIT_PROMPT_DIVERGED=
#ZSH_THEME_GIT_PROMPT_UNTRACKED=
# nvm_prompt_info variables
unset -m 'ZSH_THEME_NVM_PROMPT_*'
#ZSH_THEME_NVM_PROMPT_PREFIX=
#ZSH_THEME_NVM_PROMPT_SUFFIX=
# rvm_prompt_info variables
unset -m 'ZSH_THEME_RVM_PROMPT_*'
#ZSH_THEME_RVM_PROMPT_PREFIX=
#ZSH_THEME_RVM_PROMPT_SUFFIX=
#ZSH_THEME_RVM_PROMPT_OPTIONS=
# svn_prompt_info variables
unset -m 'ZSH_THEME_SVN_PROMPT_*'
#ZSH_THEME_SVN_PROMPT_CLEAN
#ZSH_THEME_SVN_PROMPT_DIRTY
#ZSH_THEME_SVN_PROMPT_PREFIX
#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
function _omz_lstheme_dir() {
ls $1 | grep '.zsh-theme$' | sed 's,\.zsh-theme$,,'
@ -460,3 +488,40 @@ function _omz_theme_show_prompt_key {
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