-
Notifications
You must be signed in to change notification settings - Fork 6
/
.zshrc
300 lines (245 loc) Β· 10.5 KB
/
.zshrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# Josh Dick's .zshrc <https://joshdick.net>
# *** MISC ***
# Clear out and reset PATH in case .zshrc is sourced multiple times in one session (while making changes)
# Do this before anything else so that this file can override any default settings that may be in /etc/profile
export PATH=$(env -i bash --login --norc -c 'echo $PATH')
# Test whether a given command exists
# Adapted from <http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script/3931779#3931779>
function command_exists() {
hash "$1" &> /dev/null
}
# *** ZSH-SPECIFIC SETTINGS ***
HISTFILE=~/.zsh_history
HISTSIZE=1000
SAVEHIST=1000
setopt autocd beep nomatch prompt_subst correct inc_append_history interactivecomments share_history
unsetopt notify
zstyle :compinstall filename "$HOME/.zshrc"
autoload -Uz compinit && compinit
autoload -U colors && colors # Enable colors in prompt
# *** ZSH KEYBOARD SETTINGS ***
# Adapted from <http://zshwiki.org/home/zle/bindkeys#reading_terminfo<Paste>>
# create a zkbd compatible hash;
# to add other keys to this hash, see: man 5 terminfo
typeset -g -A key
key[Home]="$terminfo[khome]"
key[End]="$terminfo[kend]"
key[Insert]="$terminfo[kich1]"
key[Backspace]="$terminfo[kbs]"
key[Delete]="$terminfo[kdch1]"
key[Up]="$terminfo[kcuu1]"
key[Down]="$terminfo[kcud1]"
key[Left]="$terminfo[kcub1]"
key[Right]="$terminfo[kcuf1]"
key[PageUp]="$terminfo[kpp]"
key[PageDown]="$terminfo[knp]"
# setup key accordingly
[[ -n "$key[Home]" ]] && bindkey -- "$key[Home]" beginning-of-line
[[ -n "$key[End]" ]] && bindkey -- "$key[End]" end-of-line
[[ -n "$key[Insert]" ]] && bindkey -- "$key[Insert]" overwrite-mode
[[ -n "$key[Backspace]" ]] && bindkey -- "$key[Backspace]" backward-delete-char
[[ -n "$key[Delete]" ]] && bindkey -- "$key[Delete]" delete-char
[[ -n "$key[Up]" ]] && bindkey -- "$key[Up]" up-line-or-history
[[ -n "$key[Down]" ]] && bindkey -- "$key[Down]" down-line-or-history
[[ -n "$key[Left]" ]] && bindkey -- "$key[Left]" backward-char
[[ -n "$key[Right]" ]] && bindkey -- "$key[Right]" forward-char
[[ -n "$key[PageUp]" ]] && bindkey -- "$key[PageUp]" history-beginning-search-backward
[[ -n "$key[PageDown]" ]] && bindkey -- "$key[PageDown]" history-beginning-search-forward
# Finally, make sure the terminal is in application mode, when zle is
# active. Only then are the values from $terminfo valid.
if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
function zle-line-init () {
echoti smkx
}
function zle-line-finish () {
echoti rmkx
}
zle -N zle-line-init
zle -N zle-line-finish
fi
# *** PROMPT FORMATTING ***
# Echoes a username/host string when connected over SSH (empty otherwise)
ssh_info() {
[[ "$SSH_CONNECTION" != '' ]] && echo "%(!.%{$fg[red]%}.%{$fg[yellow]%})%n%{$reset_color%}@%{$fg[green]%}%m%{$reset_color%}:" || echo ""
}
# Echoes information about Git repository status when inside a Git repository
git_info() {
# Exit if not inside a Git repository
! git rev-parse --is-inside-work-tree > /dev/null 2>&1 && return
# Git branch/tag, or name-rev if on detached head
local GIT_LOCATION=${$(git symbolic-ref -q HEAD || git name-rev --name-only --no-undefined --always HEAD)#(refs/heads/|tags/)}
local AHEAD="%{$fg[red]%}β‘NUM%{$reset_color%}"
local BEHIND="%{$fg[cyan]%}β£NUM%{$reset_color%}"
local MERGING="%{$fg[magenta]%}β‘οΈ%{$reset_color%}"
local UNTRACKED="%{$fg[red]%}β%{$reset_color%}"
local MODIFIED="%{$fg[yellow]%}β%{$reset_color%}"
local STAGED="%{$fg[green]%}β%{$reset_color%}"
local -a DIVERGENCES
local -a FLAGS
local NUM_AHEAD="$(git log --oneline @{u}.. 2> /dev/null | wc -l | tr -d ' ')"
if [ "$NUM_AHEAD" -gt 0 ]; then
DIVERGENCES+=( "${AHEAD//NUM/$NUM_AHEAD}" )
fi
local NUM_BEHIND="$(git log --oneline ..@{u} 2> /dev/null | wc -l | tr -d ' ')"
if [ "$NUM_BEHIND" -gt 0 ]; then
DIVERGENCES+=( "${BEHIND//NUM/$NUM_BEHIND}" )
fi
local GIT_DIR="$(git rev-parse --git-dir 2> /dev/null)"
if [ -n $GIT_DIR ] && test -r $GIT_DIR/MERGE_HEAD; then
FLAGS+=( "$MERGING" )
fi
if [[ -n $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then
FLAGS+=( "$UNTRACKED" )
fi
if ! git diff --quiet 2> /dev/null; then
FLAGS+=( "$MODIFIED" )
fi
if ! git diff --cached --quiet 2> /dev/null; then
FLAGS+=( "$STAGED" )
fi
local -a GIT_INFO
GIT_INFO+=( "%{$fg[cyan]%}Β±" )
[[ ${#DIVERGENCES[@]} -ne 0 ]] && GIT_INFO+=( "${(j::)DIVERGENCES}" )
[[ ${#FLAGS[@]} -ne 0 ]] && GIT_INFO+=( "${(j::)FLAGS}" )
GIT_INFO+=( "%{$fg[cyan]%}$GIT_LOCATION%{$reset_color%}" )
echo "${(j: :)GIT_INFO}"
}
# Use β― as the non-root prompt character; # for root
# Change the prompt character color if the last command had a nonzero exit code
PS1="
\$(ssh_info)%{$fg[magenta]%}%~%u \$(git_info)
%(?.%{$fg[blue]%}.%{$fg[red]%})%(!.#.β―)%{$reset_color%} "
# *** HOMEBREW ***
if [ -f /opt/homebrew/bin/brew ]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
HOMEBREW_PREFIX="$(brew --prefix)"
fi
if command_exists brew; then
# Assume Git was installed via Homebrew, and that the Git configuration below
# should use Homebrew-provided locations instead of the defaults below
GIT_BASH_COMPLETION_SOURCE="$HOMEBREW_PREFIX/etc/bash_completion.d/git-completion.bash"
GIT_ZSH_COMPLETION_SOURCE="$HOMEBREW_PREFIX/share/zsh/site-functions/_git"
GIT_DIFF_HIGHLIGHT_PATH="$HOMEBREW_PREFIX/share/git-core/contrib/diff-highlight"
else
# Locations of the Git completion files for Arch Linux as of Git 1.8.1
GIT_BASH_COMPLETION_SOURCE=/usr/share/git/completion/git-completion.bash
GIT_ZSH_COMPLETION_SOURCE=/usr/share/git/completion/git-completion.zsh
GIT_DIFF_HIGHLIGHT_PATH=~/.bin/diff-highlight-script
fi
# Set up diff-highlight
export PATH="$GIT_DIFF_HIGHLIGHT_PATH:$PATH"
# *** ZSH PLUGINS ***
# <https://github.com/zsh-users/zsh-syntax-highlighting>
. ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
# <https://github.com/zsh-users/zsh-history-substring-search>
. ~/.zsh/zsh-history-substring-search/zsh-history-substring-search.zsh
# Bind up and down keys for zsh-history-substring-search
[[ -n "$key[Up]" ]] && bindkey -- "$key[Up]" history-substring-search-up
[[ -n "$key[Down]" ]] && bindkey -- "$key[Down]" history-substring-search-down
# <https://github.com/atuinsh/atuin>
if command_exists atuin; then
eval "$(atuin init zsh --disable-up-arrow)"
fi
# <https://github.com/junegunn/fzf>
. ~/.fzf.zsh
# Configure fzf to use `rg` or `ag` if available instead of `find`,
# since both are faster than `find` and have better filtering (.gitignore, node_modules, etc.)
# For use with fzf's Vim plugin(s).
if command_exists rg; then
export FZF_DEFAULT_COMMAND='rg --smart-case --files --follow --no-ignore-vcs --hidden --glob "!{node_modules/*,.git/*}"'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
elif command_exists ag; then
export FZF_DEFAULT_COMMAND='ag -g ""'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
fi
# Catppuccin Mocha theme for fzf, with transparent background
# <https://github.com/catppuccin/fzf>
export FZF_DEFAULT_OPTS=" \
--color=bg+:#313244,bg:-1,spinner:#f5e0dc,hl:#f38ba8 \
--color=fg:#cdd6f4,header:#f38ba8,info:#cba6f7,pointer:#f5e0dc \
--color=marker:#f5e0dc,fg+:#cdd6f4,prompt:#cba6f7,hl+:#f38ba8"
# *** FUNCTIONS AND ALIASES ***
. ~/.zsh/functions.zsh
. ~/.zsh/aliases.zsh
# *** ENVIRONMENT ***
# Include any machine-specific configuration if it exists
test -e ~/.localrc && . ~/.localrc
# Editor - See if vim lives around these parts, otherwise fall back to nano
if command_exists nvim && [[ ! $(nvim --version | grep "NVIM v") =~ "0.7" ]]; then
export EDITOR=nvim
export VISUAL=nvim
elif command_exists vim; then
export EDITOR=vim
export VISUAL=vim
else
export EDITOR=nano
export VISUAL=nano
fi
export GIT_EDITOR="$HOME/.bin/git_editor"
export PAGER=less
# gpg-agent
if command_exists gpgconf; then
export GPG_TTY=$(tty)
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi
fi
# Emulate pgrep if we're on OS X
if ! command_exists pgrep; then
alias pgrep=poorgrep
fi
# Emulate tree if we're on OS X
if ! command_exists tree; then
alias tree=poortree
fi
# LSCOLORS - Default except for normal directories (first character) to replace hard-to-read blue
# For details, see manpage for ls
export LSCOLORS=Gxfxcxdxbxegedabagacad
# Attempt to set up Git completion for zsh as documented inside git-completion.zsh
if [ -r "$GIT_BASH_COMPLETION_SOURCE" ] && [ -r "$GIT_ZSH_COMPLETION_SOURCE" ]; then
zstyle ':completion:*:*:git:*' script $GIT_BASH_COMPLETION_SOURCE
# If it doesn't already exist, create a symlink to the zsh completion file as ~/.zsh/completion/_git.
# If the file was copied via sync_home and isn't actually a symlink, it will be replaced with a symlink.
[ ! -h ~/.zsh/completion/_git ] && mkdir -p ~/.zsh/completion && rm -f ~/.zsh/completion/_git && ln -s $GIT_ZSH_COMPLETION_SOURCE ~/.zsh/completion/_git
# Add the ~/.zsh/completion directory to fpath so zsh can find it.
fpath=(~/.zsh/completion $fpath)
fi
# <https://github.com/nodenv/nodenv>
# Initialize nodenv if it's installed (it may be installed via Homebrew)
NODENV_BIN_DIR="$HOME/.nodenv/bin"
test -d "$NODENV_BIN_DIR" && export PATH="$NODENV_BIN_DIR:$PATH"
if command_exists nodenv; then
eval "$(nodenv init -)"
fi
# <https://github.com/rbenv/rbenv>
# Initialize rbenv if it's installed (it may be installed via Homebrew)
RBENV_BIN_DIR="$HOME/.rbenv/bin"
test -d "$RBENV_BIN_DIR" && export PATH="$RBENV_BIN_DIR:$PATH"
if command_exists rbenv; then
eval "$(rbenv init -)"
fi
# Initialize a default Python virtualenv if one is configured in ~/.localrc
# (VIRTUALENV_ACTIVATOR should point to ./bin/activate)
if [ -n "$VIRTUALENV_ACTIVATOR" -a -r "$VIRTUALENV_ACTIVATOR" ]; then
VIRTUAL_ENV_DISABLE_PROMPT=1 . "$VIRTUALENV_ACTIVATOR"
fi
# Initialize the "personal bin"
. ~/.bin/bin_init.zsh
# When connecting via ssh, always [re]attach to a terminal manager
# Adapted from code found at <http://involution.com/2004/11/17/1-32/> (now offline)
if command_exists tmux && [ -z $TMUX ]; then
if [ "$SSH_TTY" != "" -a "$TERM" -a "$TERM" != "screen" -a "$TERM" != "dumb" ]; then
pgrep tmux
# $? is the exit code of pgrep; 0 means there was a result (tmux is already running)
if [ $? -eq 0 ]; then
tmux -u attach -d
else
tmux -u
fi
fi
fi
# ALL GLORY TO THE HYPNOTOAD
if command_exists cowsay && command_exists fortune; then
fortune | cowsay -f ~/.hypnotoad.cow -W 60
fi