1 # Copyright (c) 2017 Henry Chang
4 [ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] \
5 && echo "fzf-tmux -d${FZF_TMUX_HEIGHT:-40%}" || echo "fzf"
8 __zic_matched_subdir_list() {
9 local dir length seg starts_with_dir
10 if [[ "$1" == */ ]]; then
12 if [[ "$dir" != / ]]; then
15 length=$(echo -n "$dir" | wc -c)
16 if [ "$dir" = "/" ]; then
19 find -L "$dir" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \
20 | cut -b $(( ${length} + 2 ))- | sed '/^$/d' | while read -r line; do
21 if [[ "${line[1]}" == "." ]]; then
27 dir=$(dirname -- "$1")
28 length=$(echo -n "$dir" | wc -c)
29 if [ "$dir" = "/" ]; then
32 seg=$(basename -- "$1")
34 find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
35 2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \
36 | while read -r line; do
37 if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
40 if [[ "$line" == "$seg"* ]]; then
45 if [ -n "$starts_with_dir" ]; then
46 echo "$starts_with_dir"
48 find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
49 2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \
50 | while read -r line; do
51 if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
54 if [[ "$line" == *"$seg"* ]]; then
62 _zic_list_generator() {
63 __zic_matched_subdir_list "${(Q)@[-1]}" | sort
67 setopt localoptions nonomatch
68 local l matches fzf tokens base
70 l=$(_zic_list_generator $@)
73 zle ${__zic_default_completion:-expand-or-complete}
79 if [ $(echo $l | wc -l) -eq 1 ]; then
83 | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} \
84 --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS \
85 --bind 'shift-tab:up,tab:down'" ${=fzf} \
86 | while read -r item; do
92 if [ -n "$matches" ]; then
93 tokens=(${(z)LBUFFER})
95 if [[ "$base" != */ ]]; then
96 if [[ "$base" == */* ]]; then
97 base="$(dirname -- "$base")"
98 if [[ ${base[-1]} != / ]]; then
105 LBUFFER="${tokens[1]} "
106 if [ -n "$base" ]; then
108 if [ "${tokens[2][1]}" = "~" ]; then
109 base="${base/#$HOME/~}"
111 LBUFFER="${LBUFFER}${base}"
113 LBUFFER="${LBUFFER}${matches}/"
116 typeset -f zle-line-init >/dev/null && zle zle-line-init
120 setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
123 tokens=(${(z)LBUFFER})
126 if [[ "$LBUFFER" =~ "^\ *cd$" ]]; then
127 zle ${__zic_default_completion:-expand-or-complete}
128 elif [ "$cmd" = cd ]; then
129 _zic_complete ${tokens[2,${#tokens}]/#\~/$HOME}
131 zle ${__zic_default_completion:-expand-or-complete}
135 [ -z "$__zic_default_completion" ] && {
136 binding=$(bindkey '^I')
138 # The command substitution and following word splitting to determine the
139 # default zle widget for ^I formerly only works if the IFS parameter contains
140 # a space via $binding[(w)2]. Now it specifically splits at spaces, regardless
142 [[ $binding =~ 'undefined-key' ]] || __zic_default_completion=$binding[(s: :w)2]
146 zle -N zic-completion
147 bindkey -M emacs '^I' zic-completion
148 bindkey -M viins '^I' zic-completion