-
Notifications
You must be signed in to change notification settings - Fork 0
/
.zsh-fzf.zsh
233 lines (209 loc) · 7.62 KB
/
.zsh-fzf.zsh
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
# Checkout the .fzf.zsh -> /usr/local/opt/fzf/shell/key-bindings.zsh for more info
# https://feltrac.co/environment/2020/01/18/build-your-own-shell-completion.html
# Downfalls - can't do context aware (how do I figure out the cmd line? Perhaps $@?
# More in the .zshrc-fzf
## Completion triggers with ^F
# This removes the ** requirement, so can tab on random space to get auto complete
#export FZF_COMPLETION_TRIGGER=''
# If you've ever set the trigger in the past, just removing it is not enough, need to unset
unset FZF_COMPLETION_TRIGGER
fzf-completion-notrigger() {
FZF_COMPLETION_TRIGGER='' fzf-completion
}
zle -N fzf-completion-notrigger
bindkey '^F' fzf-completion-notrigger
_fzf_complete_git_notrigger() {
FZF_COMPLETION_TRIGGER='' _fzf_complete_ssh
}
#bindkey '^I' $fzf_default_completion
#bindkey '^I' expand-or-complete
#### supported command prefixes: ####
# Most commands: files
# cd: directories
# kill: processes
# ssh, telnet: hosts
# unset, export: env vars
# unalias: aliases
## For files and directories
_fzf_compgen_path() {
#fd --hidden --follow --exclude ".git" . "$1"
rg --files --hidden --glob "!.git" "$1"
}
# Use fd to generate the list for directory completion
_fzf_compgen_dir() {
fd --type d --hidden --follow --exclude ".git" . "$1"
}
## FZF setup variables - use git ls-files cause it's way faster
git-ls-files() {
git ls-files 2> /dev/null || rg --files --hidden --glob "!.git" -M 200 2> /dev/null
}
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
#Can't use default-fzf-cmd because no functions in vim
#export FZF_DEFAULT_COMMAND='default-fzf-cmd'
exists rg && export FZF_DEFAULT_COMMAND='rg --files --hidden --glob "!.git" 2> /dev/null'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
#export FZF_CTRL_T_COMMAND='default-fzf-cmd'
export FZF_DEFAULT_OPTS="--height 60% --keep-right --reverse --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort' --preview-window down:60%:wrap --bind 'up:preview-up,down:preview-down,ctrl-d:preview-page-down,ctrl-u:preview-page-up,ctrl-f:half-page-down,ctrl-b:half-page-up,ctrl-e:toggle-preview'"
export FZF_CTRL_T_OPTS="--preview 'preview-unknown {}'"
export FZF_COMPLETION_OPTS="$FZF_CTRL_T_OPTS"
# Support alt-c for changing directory
bindkey "ç" fzf-cd-widget
fzf-preview-window-calc() {
if [ "$COLUMNS" -gt 160 ]; then
echo "right:60%"
else
echo "down:60%"
fi
}
fzf-dir() {
_fzf_compgen_dir . |
fzf-down --ansi --multi --no-sort --preview-window down:50% \
--preview 'tree -C {} | head -'$LINES
}
fzf-dir-widget() {
local result=$(fzf-dir | join-lines)
zle reset-prompt
LBUFFER+=$result
}
zle -N fzf-dir-widget
bindkey '^e^e' fzf-dir-widget
bindkey -r "^E"
fzf-git-ls-files() {
git ls-files | fzf
}
fzf-git-ls-files-widget() {
local result=$(fzf-git-ls-files | join-lines)
zle reset-prompt
LBUFFER+=$result
}
zle -N fzf-git-ls-files-widget
bindkey '^e^s' fzf-git-ls-files-widget
fzf-yank-history-widget() {
local selected num
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
selected=( $(fc -rl 1 |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
local ret=$?
echo ${selected:1} | pbcopy
echo yanked "'"${selected:1}"'"
# if [ -n "$selected" ]; then
# num=$selected[1]
# if [ -n "$num" ]; then
# zle vi-fetch-history -n $num
# fi
# fi
zle reset-prompt
return $ret
}
zle -N fzf-yank-history-widget
bindkey '^Y' fzf-yank-history-widget
# Tmux buffer action - get filepaths
fzf-tmux-filepaths-widget() {
local result=$(tmux_paths.js | fzf-down --ansi --multi --no-sort \
--preview 'preview-unknown {}' | join-lines)
zle reset-prompt
LBUFFER+=$result
}
zle -N fzf-tmux-filepaths-widget
bindkey '^e^t' fzf-tmux-filepaths-widget
# (EXPERIMENTAL) Advanced customization of fzf options via _fzf_comprun function
# - The first argument to the function is the name of the command.
# - You should make sure to pass the rest of the arguments to fzf.
_fzf_comprun() {
local command=$1
shift
case "$command" in
cd) fzf "$@" --preview 'tree -C {} | head -200' ;;
export|unset) fzf "$@" --preview "eval 'echo \$'{}" ;;
ssh) fzf "$@" --preview 'dig {}' ;;
# I tried aliases, didn't seem to work, not sure why - guessing it's not pulling the context (subshell?)
*) fzf "$@" ;;
esac
}
## Git shortcuts
# Initial copy from:
# https://gist.github.com/junegunn/8b572b8d4b5eddd8b85e5f4d40f17236
# https://junegunn.kr/2016/07/fzf-git/
is_in_git_repo() {
git rev-parse HEAD > /dev/null 2>&1
}
fzf-down() {
fzf --height 90% "$@" --border --preview-window "$(fzf-preview-window-calc)"
}
fzf_gf() {
is_in_git_repo || return
git -c color.status=always status --short 2> /dev/null |
fzf-down -m --ansi --nth 2..,.. \
--preview '(git diff --color=always -- {-1} 2> /dev/null | sed 1,4d) | head -500' |
cut -c4- | sed 's/.* -> //'
}
# same as gf, but with files changed since merge-base
fzf_gg() {
is_in_git_repo || return
git du --name-only --relative=$(git rev-parse --show-prefix) 2> /dev/null |
fzf-down -m --ansi \
--preview '(git diff --color=always "$(git merge-base HEAD $(git upstream))" -- {-1} 2> /dev/null | sed 1,4d) | head -500'
}
fzf_gb() {
is_in_git_repo || return
git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)' |
fzf-down --ansi --multi --no-sort --preview-window right:70% \
--preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" {} | head -'$LINES |
sed 's#^remotes/##'
}
# Shouldn't really be here, but convenient
fzf_gz() {
is_in_git_repo || return
echo "$(fastpass info)" | perl -pe 's/\/\.\.\.//g' | cut -c 1- | rargs -d, git ls-files {0} |
fzf-down -m --ansi \
--preview 'preview-unknown {}'
}
fzf_gm() {
is_in_git_repo || return
git for-each-ref --sort=-committerdate refs/{heads,remotes} --format='%(refname:short)' |
fzf-down --ansi --multi --no-sort --preview-window right:70% \
--preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" {} | head -'$LINES |
sed 's#^remotes/##'
}
fzf_gt() {
is_in_git_repo || return
git tag --sort -version:refname |
fzf-down --multi --preview-window right:70% \
--preview 'git show --color=always {} | head -'$LINES
}
fzf_gh() {
is_in_git_repo || return
# --graph is slow on large repos
# git log --date=short --format="%C(green)%C(bold)%cd %C(auto)%h%d %s (%an)" --graph --color=always |
git log --date=short --format="%C(green)%C(bold)%cd %C(auto)%h%d %s (%an)" --color=always |
fzf-down --ansi --no-sort --reverse --multi --bind 'ctrl-s:toggle-sort' \
--header 'Press CTRL-S to toggle sort' \
--preview 'grep -o "[a-f0-9]\{7,\}" <<< {} | xargs git show --color=always | head -'$LINES |
grep -o "[a-f0-9]\{7,\}"
}
fzf_gr() {
is_in_git_repo || return
git remote -v | awk '{print $1 "\t" $2}' | uniq |
fzf-down --tac \
--preview 'git log --oneline --graph --date=short --pretty="format:%C(auto)%cd %h%d %s" {1} | head -200' |
cut -d$'\t' -f1
}
join-lines() {
local item
while read item; do
echo -n "${(q)item} "
done
}
bind-git-helper() {
local c
for c in $@; do
eval "fzf-g$c-widget() { local result=\$(fzf_g$c | join-lines); zle reset-prompt; LBUFFER+=\$result }"
eval "zle -N fzf-g$c-widget"
eval "bindkey '^g^$c' fzf-g$c-widget"
done
}
# Remove default
bindkey -r "^G"
# Files, with Untracked files, merGebase diff files, Branches, reMote branches, Tags, Remotes, commit Hashes
bind-git-helper f g b m t r h z
unset -f bind-git-helper