-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.zsh-interactive-cd.plugin.zsh
157 lines (142 loc) · 4.06 KB
/
.zsh-interactive-cd.plugin.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
#!/usr/bin/env zsh
#
# Copyright 2017-2018 Henry Chang
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
__zic_fzf_prog() {
[ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] \
&& echo "fzf-tmux -d${FZF_TMUX_HEIGHT:-40%}" || echo "fzf"
}
__zic_matched_subdir_list() {
local dir length seg starts_with_dir
if [[ "$1" == */ ]]; then
dir="$1"
if [[ "$dir" != / ]]; then
dir="${dir: : -1}"
fi
length=$(echo -n "$dir" | wc -c)
if [ "$dir" = "/" ]; then
length=0
fi
find -L "$dir" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \
| cut -b $(( ${length} + 2 ))- | \sed '/^$/d' | while read -r line; do
if [[ "${line[1]}" == "." ]]; then
continue
fi
echo "$line"
done
else
dir=$(dirname -- "$1")
length=$(echo -n "$dir" | wc -c)
if [ "$dir" = "/" ]; then
length=0
fi
seg=$(basename -- "$1")
starts_with_dir=$( \
find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
2>/dev/null | cut -b $(( ${length} + 2 ))- | \sed '/^$/d' \
| while read -r line; do
if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
continue
fi
if [[ "$line" == "$seg"* ]]; then
echo "$line"
fi
done
)
if [ -n "$starts_with_dir" ]; then
echo "$starts_with_dir"
else
find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
2>/dev/null | cut -b $(( ${length} + 2 ))- | \sed '/^$/d' \
| while read -r line; do
if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
continue
fi
if [[ "$line" == *"$seg"* ]]; then
echo "$line"
fi
done
fi
fi
}
_zic_list_generator() {
__zic_matched_subdir_list "${(Q)@[-1]}" | sort
}
_zic_complete() {
setopt localoptions nonomatch
local l matches fzf tokens base
l=$(_zic_list_generator $@)
if [ -z "$l" ]; then
zle ${__zic_default_completion:-expand-or-complete}
return
fi
fzf=$(__zic_fzf_prog)
if [ $(echo $l | wc -l) -eq 1 ]; then
matches=${(q)l}
else
matches=$(echo $l \
| FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} \
--reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS \
--bind 'shift-tab:up,tab:down'" ${=fzf} \
| while read -r item; do
echo -n "${(q)item} "
done)
fi
matches=${matches% }
if [ -n "$matches" ]; then
tokens=(${(z)LBUFFER})
base="${(Q)@[-1]}"
if [[ "$base" != */ ]]; then
if [[ "$base" == */* ]]; then
base="$(dirname -- "$base")"
if [[ ${base[-1]} != / ]]; then
base="$base/"
fi
else
base=""
fi
fi
LBUFFER="${tokens[1]} "
if [ -n "$base" ]; then
base="${(q)base}"
if [ "${tokens[2][1]}" = "~" ]; then
base="${base/#$HOME/~}"
fi
LBUFFER="${LBUFFER}${base}"
fi
LBUFFER="${LBUFFER}${matches}/"
fi
zle redisplay
typeset -f zle-line-init >/dev/null && zle zle-line-init
}
zic-completion() {
setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
local tokens cmd
tokens=(${(z)LBUFFER})
cmd=${tokens[1]}
if [[ "$LBUFFER" =~ "^\ *cd$" ]]; then
zle ${__zic_default_completion:-expand-or-complete}
elif [ "$cmd" = cd ]; then
_zic_complete ${tokens[2,${#tokens}]/#\~/$HOME}
else
zle ${__zic_default_completion:-expand-or-complete}
fi
}
[ -z "$__zic_default_completion" ] && {
binding=$(bindkey '^I')
# $binding[(s: :w)2]
# The command substitution and following word splitting to determine the
# default zle widget for ^I formerly only works if the IFS parameter contains
# a space via $binding[(w)2]. Now it specifically splits at spaces, regardless
# of IFS.
[[ $binding =~ 'undefined-key' ]] || __zic_default_completion=$binding[(s: :w)2]
unset binding
}
zle -N zic-completion
if [ -z $zic_custom_binding ]; then
zic_custom_binding='^I'
fi
bindkey "${zic_custom_binding}" zic-completion