3ec04997ebc413ddc95b7c11743b525d7fc7c4ab

Author
Henry Chang <mr.changyuheng@gmail.com>
Committer
Marc Cornellà <marc.cornella@live.com>
Date

Message

Add zsh-interactive-cd plugin

Diff

This diff is truncated to protect this page.

  1diff --git a/plugins/zsh-interactive-cd/README.md b/plugins/zsh-interactive-cd/README.md
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..c8337fbc893ed385f15634c5500d64e78b939ed5
  4--- /dev/null
  5+++ b/plugins/zsh-interactive-cd/README.md
  6@@ -0,0 +1,23 @@
  7+# zsh-interactive-cd
  8+
  9+This plugin adds a fish-like interactive tab completion for the `cd` command.
 10+
 11+To use it, add `zsh-interactive-cd` to the plugins array of your zshrc file:
 12+```zsh
 13+plugins=(... zsh-interactive-cd)
 14+```
 15+
 16+![demo](https://user-images.githubusercontent.com/1441704/74360670-cb202900-4dc5-11ea-9734-f60caf726e85.gif)
 17+
 18+## Usage
 19+
 20+Press tab for completion as usual, it'll launch fzf automatically. Check fzf’s [readme](https://github.com/junegunn/fzf#search-syntax) for more search syntax usage.
 21+
 22+## Requirements
 23+
 24+This plugin requires [fzf](https://github.com/junegunn/fzf). Install it by following
 25+its [installation instructions](https://github.com/junegunn/fzf#installation).
 26+
 27+## Author
 28+
 29+[Henry Chang](https://github.com/changyuheng)
 30diff --git a/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh b/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh
 31new file mode 100644
 32index 0000000000000000000000000000000000000000..0f15aeef01f50baa0688bdf08427d9f22f9891a6
 33--- /dev/null
 34+++ b/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh
 35@@ -0,0 +1,147 @@
 36+# Copyright (c) 2017 Henry Chang
 37+
 38+__zic_fzf_prog() {
 39+  [ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] \
 40+    && echo "fzf-tmux -d${FZF_TMUX_HEIGHT:-40%}" || echo "fzf"
 41+}
 42+
 43+__zic_matched_subdir_list() {
 44+  local dir length seg starts_with_dir
 45+  if [[ "$1" == */ ]]; then
 46+    dir="$1"
 47+    if [[ "$dir" != / ]]; then
 48+      dir="${dir: : -1}"
 49+    fi
 50+    length=$(echo -n "$dir" | wc -c)
 51+    if [ "$dir" = "/" ]; then
 52+      length=0
 53+    fi
 54+    find -L "$dir" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \
 55+        | cut -b $(( ${length} + 2 ))- | sed '/^$/d' | while read -r line; do
 56+      if [[ "${line[1]}" == "." ]]; then
 57+        continue
 58+      fi
 59+      echo "$line"
 60+    done
 61+  else
 62+    dir=$(dirname -- "$1")
 63+    length=$(echo -n "$dir" | wc -c)
 64+    if [ "$dir" = "/" ]; then
 65+      length=0
 66+    fi
 67+    seg=$(basename -- "$1")
 68+    starts_with_dir=$( \
 69+      find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
 70+          2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \
 71+          | while read -r line; do
 72+        if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
 73+          continue
 74+        fi
 75+        if [[ "$line" == "$seg"* ]]; then
 76+          echo "$line"
 77+        fi
 78+      done
 79+    )
 80+    if [ -n "$starts_with_dir" ]; then
 81+      echo "$starts_with_dir"
 82+    else
 83+      find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
 84+          2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \
 85+          | while read -r line; do
 86+        if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
 87+          continue
 88+        fi
 89+        if [[ "$line" == *"$seg"* ]]; then
 90+          echo "$line"
 91+        fi
 92+      done
 93+    fi
 94+  fi
 95+}
 96+
 97+_zic_list_generator() {
 98+  __zic_matched_subdir_list "${(Q)@[-1]}" | sort
 99+}
100+
101+_zic_complete() {
102+  setopt localoptions nonomatch
103+  local l matches fzf tokens base
104+
105+  l=$(_zic_list_generator $@)
106+
107+  if [ -z "$l" ]; then
108+    zle ${__zic_default_completion:-expand-or-complete}
109+    return
110+  fi
111+
112+  fzf=$(__zic_fzf_prog)
113+
114+  if [ $(echo $l | wc -l) -eq 1 ]; then
115+    matches=${(q)l}
116+  else
117+    matches=$(echo $l \
118+        | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} \
119+          --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS \
120+          --bind 'shift-tab:up,tab:down'" ${=fzf} \
121+        | while read -r item; do
122+      echo -n "${(q)item} "
123+    done)
124+  fi
125+
126+  matches=${matches% }
127+  if [ -n "$matches" ]; then
128+    tokens=(${(z)LBUFFER})
129+    base="${(Q)@[-1]}"
130+    if [[ "$base" != */ ]]; then
131+      if [[ "$base" == */* ]]; then
132+        base="$(dirname -- "$base")"
133+        if [[ ${base[-1]} != / ]]; then
134+          base="$base/"