-
Notifications
You must be signed in to change notification settings - Fork 0
/
.zshrc
291 lines (229 loc) · 8.09 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
# Order of zsh-related config files loaded in **login shell**
# 1. /etc/zshenv
# 2. {$ZDOTDIR:-$HOME}/.zshenv <- where ZDOTDIR could be defined
# 3. /etc/zprofile
# 4. {$ZDOTDIR:-$HOME}/.zprofile
# 5. /etc/zshrc
# 6. {$ZDOTDIR:-$HOME}/.zshrc
# 7. /etc/zlogin
# 8. {$ZDOTDIR:-$HOME}/.zlogin
function __echo_header() { printf "\033[37;1m%s\033[m\n" "$*"; }
function __echo_warning() { echo -e "\e[33;1mWARNING: $*\e[m"; }
function __echo_error() { echo -e "\e[31;1mERROR: $*\e[m"; }
function __exists() { type "$1" >/dev/null 2>&1; return $?; }
function __pathadd() { export PATH="$1:$PATH" }
# ==================== #
# Plugin manager #
# ==================== #
# Set the directory we want to store zinit and plugins
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
# Download Zinit, if it's not there yet
if [ ! -d "$ZINIT_HOME" ]; then
mkdir -p "$(dirname $ZINIT_HOME)"
git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
fi
# Source/Load zinit
source "${ZINIT_HOME}/zinit.zsh"
# ==================== #
# Plugins list #
# ==================== #
# Enable cache
zinit ice wait'!0' lucid cache
# Load completions
# if ls ~/.zcompdump* &> /dev/null; then
# rm ~/.zcompdump*
# fi
# autoload -U compinit
# compinit -C # skip security checking. Without -C option it'll take so long here
# compinit
autoload -Uz compinit
if [[ -n ${ZDOTDIR:-$HOME}/.zcompdump(#qN.mh+24) ]]; then
# compinit # this is too slow
compinit -C
else
compinit -C
fi
compdef -d git # Use fzf instead
zinit light Aloxaf/fzf-tab # This should be loaded after compinit and before other pulugins
zinit light zsh-users/zsh-syntax-highlighting
zinit light zsh-users/zsh-completions
# Fish-like history search pt. 1: pressing ↑ will search through history
zinit light zsh-users/zsh-history-substring-search
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND=''
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND=''
HISTORY_SUBSTRING_SEARCH_FUZZY='true'
# Fish-like history search pt. 2: the grayed out part
zinit light zsh-users/zsh-autosuggestions
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8'
# Add in snippets
zinit snippet OMZP::git
zinit snippet OMZP::sudo
zinit snippet OMZP::brew
# Completion styling
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
# set list-colors to enable filename colorizing
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
# force zsh not to show completion menu, which allows fzf-tab to capture the unambiguous prefix
zstyle ':completion:*' menu no
# zstyle ':completion:*:setopt:*' menu true select
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls --color $realpath'
zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath'
# copied from: https://github.com/Aloxaf/fzf-tab?tab=readme-ov-file#configure
# disable sort when completing `git checkout`
zstyle ':completion:*:git-checkout:*' sort false
# set descriptions format to enable group support
# NOTE: don't use escape sequences here, fzf-tab will ignore them
zstyle ':completion:*:descriptions' format '[%d]'
# preview directory's content with eza when completing cd
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
# switch group using `<` and `>`
zstyle ':fzf-tab:*' switch-group '<' '>'
# ============== #
# History #
# ============== #
HISTSIZE=100000
HISTFILE=~/.zsh_history
SAVEHIST=$HISTSIZE
HISTDUP=erase
setopt appendhistory
setopt sharehistory
setopt hist_ignore_space
setopt hist_ignore_all_dups
setopt hist_save_no_dups
setopt hist_ignore_dups
setopt hist_find_no_dups
# ==================== #
# Prompt #
# ==================== #
# Enable substitution in the prompt.
autoload -U colors && colors
# One-liner for showing all possible colors
# $ for c in {000..255}; do echo -n "\e[38;5;${c}m $c" ; [ $(($c%16)) -eq 15 ] && echo;done;echo
# Define functions for the prompt, which must be defined before starting a worker
source ${DOTFILES:-$HOME/dotfiles}/common/prompt.rc
# Allow prompt substitution
setopt prompt_subst # this allows %(...) command substitution and variable expansion in the prompt.
# Basic prompt
# BASIC_PROMPT=''
# BASIC_PROMPT+='%F{099}[%n]%f '
# BASIC_PROMPT+='%F{blue} %~%f '
# BASIC_PROMPT+='%(?.%F{green}❯ .%F{red}❯ )%f'
# PROMPT=$BASIC_PROMPT
zinit light mafredri/zsh-async
async_init
# Initialize a variable for storing git info
__GIT_PROMPT_INFO=""
# Start a worker for getting git information
async_start_worker git_worker -u -n
_git_info_callback() {
local job_name="$1"
local ret_code="$2"
local output="$3"
local exec_time="$4"
local error_output="$5"
local has_next="$6"
# Message for debugging
# echo "Callback called with output: $output" >&2
if [[ "$job_name" == "[async]" ]]; then
echo "Async error: $error_output" >&2
else
__GIT_PROMPT_INFO="$output"
# Update the prompt
zle && zle reset-prompt
fi
# Process if there are other results in buffer
if [[ "$has_next" -eq 1 ]]; then
async_process_results git_worker _git_info_callback
fi
}
# Register the callback function
async_register_callback git_worker _git_info_callback
PROMPT=''
# PROMPT+='%F{171}[%n]%f '
PROMPT+='%F{135}[%n]%f '
PROMPT+='%F{105}%m%f '
PROMPT+='%F{blue} $(__shorten_path)%f '
PROMPT+='%F{cyan}${__GIT_PROMPT_INFO}%f '
PROMPT+=$'\n'
PROMPT+='%(?.%F{green}❯ .%F{red}❯ )%f'
RPROMPT='' # No PROMPT
# Executed every time you hit the enter key
precmd() {
# Process the results of async job
async_process_results git_worker _git_info_callback
# Sync worker's current directory to the shell's one
async_worker_eval git_worker "cd $PWD"
# Get the git info in async way
async_job git_worker __update_git_info
}
# ===================== #
# Keybindings #
# ===================== #
bindkey -e # disable vi keybindings
bindkey -s '^[r' 'source ~/.zshrc^M' # option + r to run `source ~/.zshrc`
# https://gist.github.com/junegunn/f4fca918e937e6bf5bad?permalink_comment_id=2981199#gistcomment-2981199
gli() {
local filter
if [ -n $@ ] && [ -f $@ ]; then
filter="-- $@"
fi
git log \
--graph --color=always --abbrev=7 --format='%C(auto)%h %an %C(blue)%s %C(yellow)%cr' $@ | \
fzf \
--ansi --no-sort --reverse --tiebreak=index \
--preview "f() { set -- \$(echo -- \$@ | grep -o '[a-f0-9]\{7\}'); [ \$# -eq 0 ] || git show --color=always \$1 $filter; }; f {}" \
--bind "ctrl-j:down,ctrl-k:up,alt-j:preview-down,alt-k:preview-up,ctrl-f:preview-page-down,ctrl-b:preview-page-up,q:abort,ctrl-m:execute:
(grep -o '[a-f0-9]\{7\}' | head -1 |
xargs -I % sh -c 'git show --color=always % | less -R') << 'FZF-EOF'
{}
FZF-EOF" \
--preview-window=right:60% \
--height 80%
}
# https://stackoverflow.com/a/9810485
__git_files () {
_wanted files expl 'local files' _files
}
# =========== #
# Aliases #
# =========== #
source ${DOTFILES:-$HOME/dotfiles}/common/aliases.rc
alias cd="z"
# ======================== #
# Integrations and vars #
# ======================== #
# fzf installed via git
if [ "$(uname)" = "Linux" ]; then
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh || echo fzf is not installed.
fi
source <(fzf --zsh) # enable fuzzy find
eval "$(zoxide init zsh --hook prompt )" # enable zoxide
# Homebrew
if [ "$(uname)" = Darwin ]; then
if [ -x "$(command -v brew)" ]; then
eval "$(brew shellenv)"
else
__echo_error "Homebrew is not installed."
fi
fi
# Pyenv
if __exists pyenv; then
eval "$(pyenv init -)"
else
__echo_error "pyenv not found."
fi
# fzf
# Use fd (https://github.com/sharkdp/fd) for listing path candidates.
# - The first argument to the function ($1) is the base path to start traversal
# - See the source code (completion.{bash,zsh}) for the details.
_fzf_compgen_path() {
fd --hidden --exclude .git . "$1"
}
# Use fd to generate the list for directory completion
_fzf_compgen_dir() {
fd --type=d --hidden --exclude .git . "$1"
}
# fzf-git
[ -e ~/.config/fzf-git/fzf-git.sh ] && source ~/.config/fzf-git/fzf-git.sh || echo fzf-git.sh not found