e7420736db0e09fd6057ae9ecaea815966619a3d

Author
Robby Russell <robby@planetargon.com>
Committer
Robby Russell <robby@planetargon.com>
Date

Message

Merge pull request #2510 from pavoljuhas/master

Add scd plugin for smart change of directory.

Diff

This diff is truncated to protect this page.

  1diff --git a/plugins/scd/README.md b/plugins/scd/README.md
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..197cea50a45df926f924e10c8cd6647d50b7a5e0
  4--- /dev/null
  5+++ b/plugins/scd/README.md
  6@@ -0,0 +1,122 @@
  7+# scd - smart change of directory
  8+
  9+Define `scd` shell function for changing to any directory with
 10+a few keystrokes.
 11+
 12+`scd` keeps history of the visited directories, which serves as an index of
 13+the known paths.  The directory index is updated after every `cd` command in
 14+the shell and can be also filled manually by running `scd -a`.  To switch to
 15+some directory, `scd` needs few fragments of the desired path to match with
 16+the index.  A selection menu is displayed in case of several matches, with a
 17+preference given to recently visited paths.  `scd` can create permanent
 18+directory aliases, which appear as named directories in zsh session.
 19+
 20+## INSTALLATION
 21+
 22+For oh-my-zsh, add `scd` to the `plugins` array in the ~/.zshrc file as in the
 23+[template file](../../templates/zshrc.zsh-template#L45).
 24+
 25+Besides zsh, `scd` can be used with *bash*, *dash* or *tcsh*
 26+shells and is also available as [Vim](http://www.vim.org/) plugin and
 27+[IPython](http://ipython.org/) extension.  For installation details, see
 28+https://github.com/pavoljuhas/smart-change-directory.
 29+
 30+## SYNOPSIS
 31+
 32+```sh
 33+scd [options] [pattern1 pattern2 ...]
 34+```
 35+
 36+## OPTIONS
 37+
 38+<dl><dt>
 39+-a, --add</dt><dd>
 40+  add specified directories to the directory index.</dd><dt>
 41+
 42+--unindex</dt><dd>
 43+  remove specified directories from the index.</dd><dt>
 44+
 45+-r, --recursive</dt><dd>
 46+  apply options <em>--add</em> or <em>--unindex</em> recursively.</dd><dt>
 47+
 48+--alias=ALIAS</dt><dd>
 49+  create alias for the current or specified directory and save it to
 50+  <em>~/.scdalias.zsh</em>.</dd><dt>
 51+
 52+--unalias</dt><dd>
 53+  remove ALIAS definition for the current or specified directory from
 54+  <em>~/.scdalias.zsh</em>.</dd><dt>
 55+
 56+--list</dt><dd>
 57+  show matching directories and exit.</dd><dt>
 58+
 59+-v, --verbose</dt><dd>
 60+  display directory rank in the selection menu.</dd><dt>
 61+
 62+-h, --help</dt><dd>
 63+  display this options summary and exit.</dd>
 64+</dl>
 65+
 66+## Examples
 67+
 68+```sh
 69+# Index recursively some paths for the very first run
 70+scd -ar ~/Documents/
 71+
 72+# Change to a directory path matching "doc"
 73+scd doc
 74+
 75+# Change to a path matching all of "a", "b" and "c"
 76+scd a b c
 77+
 78+# Change to a directory path that ends with "ts"
 79+scd "ts(#e)"
 80+
 81+# Show selection menu and ranking of 20 most likely directories
 82+scd -v
 83+
 84+# Alias current directory as "xray"
 85+scd --alias=xray
 86+
 87+# Jump to a previously defined aliased directory
 88+scd xray
 89+```
 90+
 91+# FILES
 92+
 93+<dl><dt>
 94+~/.scdhistory</dt><dd>
 95+    time-stamped index of visited directories.</dd><dt>
 96+
 97+~/.scdalias.zsh</dt><dd>
 98+    scd-generated definitions of directory aliases.</dd>
 99+</dl>
100+
101+# ENVIRONMENT
102+
103+<dl><dt>
104+SCD_HISTFILE</dt><dd>
105+    path to the scd index file (by default ~/.scdhistory).</dd><dt>
106diff --git a/plugins/scd/scd b/plugins/scd/scd
107new file mode 100755
108index 0000000000000000000000000000000000000000..1567d2736cf8f4fb9582dc35dfc97b2bace9d0c9
109--- /dev/null
110+++ b/plugins/scd/scd
111@@ -0,0 +1,353 @@
112+#!/bin/zsh -f
113+
114+emulate -L zsh
115+local EXIT=return
116+if [[ $(whence -w $0) == *:' 'command ]]; then
117+    emulate -R zsh
118+    local RUNNING_AS_COMMAND=1
119+    EXIT=exit
120+fi
121+
122+local DOC='scd -- smart change to a recently used directory
123+usage: scd [options] [pattern1 pattern2 ...]
124+Go to a directory path that contains all fixed string patterns.  Prefer
125+recently visited directories and directories with patterns in their tail
126+component.  Display a selection menu in case of multiple matches.
127+
128+Options:
129+  -a, --add         add specified directories to the directory index
130+  --unindex         remove specified directories from the index
131+  -r, --recursive   apply options --add or --unindex recursively
132+  --alias=ALIAS     create alias for the current or specified directory and
133+                    store it in ~/.scdalias.zsh
134+  --unalias         remove ALIAS definition for the current or specified
135+                    directory from ~/.scdalias.zsh
136+  --list            show matching directories and exit
137+  -v, --verbose     display directory rank in the selection menu
138+  -h, --help        display this message and exit
139+'
140+
141+local SCD_HISTFILE=${SCD_HISTFILE:-${HOME}/.scdhistory}
142+local SCD_HISTSIZE=${SCD_HISTSIZE:-5000}
143+local SCD_MENUSIZE=${SCD_MENUSIZE:-20}
144+local SCD_MEANLIFE=${SCD_MEANLIFE:-86400}
145+local SCD_THRESHOLD=${SCD_THRESHOLD:-0.005}
146+local SCD_SCRIPT=${RUNNING_AS_COMMAND:+$SCD_SCRIPT}
147+local SCD_ALIAS=~/.scdalias.zsh
148+
149+local ICASE a d m p i tdir maxrank threshold
150+local opt_help opt_add opt_unindex opt_recursive opt_verbose
151+local opt_alias opt_unalias opt_list
152+local -A drank dalias
153+local dmatching
154+local last_directory
155+
156+setopt extendedhistory extendedglob noautonamedirs brace_ccl
157+
158+# If SCD_SCRIPT is defined make sure the file exists and is empty.
159+# This removes any previous old commands.
160+[[ -n "$SCD_SCRIPT" ]] && [[ -s $SCD_SCRIPT || ! -f $SCD_SCRIPT ]] && (
161+    umask 077
162+    : >| $SCD_SCRIPT
163+)
164+
165+# process command line options
166+zmodload -i zsh/zutil
167+zmodload -i zsh/datetime
168+zparseopts -D -- a=opt_add -add=opt_add -unindex=opt_unindex \
169+    r=opt_recursive -recursive=opt_recursive \
170+    -alias:=opt_alias -unalias=opt_unalias -list=opt_list \
171+    v=opt_verbose -verbose=opt_verbose h=opt_help -help=opt_help \
172+    || $EXIT $?
173+
174+if [[ -n $opt_help ]]; then
175+    print $DOC
176+    $EXIT
177+fi
178+
179+# load directory aliases if they exist
180+[[ -r $SCD_ALIAS ]] && source $SCD_ALIAS
181+
182+# works faster than the (:a) modifier and is compatible with zsh 4.2.6
183+_scd_Y19oug_abspath() {
184+    set -A $1 ${(ps:\0:)"$(
185+        unfunction -m "*"; shift
186+        for d; do
187+            cd $d && print -Nr -- $PWD && cd $OLDPWD
188+        done
189+        )"}
190+}
191+
192+# define directory alias
193+if [[ -n $opt_alias ]]; then
194+    if [[ -n $1 && ! -d $1 ]]; then
195+        print -u2 "'$1' is not a directory."
196+        $EXIT 1
197+    fi
198+    a=${opt_alias[-1]#=}
199+    _scd_Y19oug_abspath d ${1:-$PWD}
200+    # alias in the current shell, update alias file if successful
201+    hash -d -- $a=$d &&
202+    (
203+        umask 077
204+        hash -dr
205+        [[ -r $SCD_ALIAS ]] && source $SCD_ALIAS
206+        hash -d -- $a=$d
207+        hash -dL >| $SCD_ALIAS
208+    )
209+    $EXIT $?
210+fi
211diff --git a/plugins/scd/scd.plugin.zsh b/plugins/scd/scd.plugin.zsh
212new file mode 100644
213index 0000000000000000000000000000000000000000..0197c53a170227363c085d1a5fc585d5be92af11
214--- /dev/null
215+++ b/plugins/scd/scd.plugin.zsh
216@@ -0,0 +1,19 @@
217+## The scd script should autoload as a shell function.
218+autoload scd
219+
220+
221+## If the scd function exists, define a change-directory-hook function
222+## to record visited directories in the scd index.
223+if [[ ${+functions[scd]} == 1 ]]; then
224+    scd_chpwd_hook() { scd --add $PWD }
225+    autoload add-zsh-hook
226+    add-zsh-hook chpwd scd_chpwd_hook
227+fi
228+
229+
230+## Allow scd usage with unquoted wildcard characters such as "*" or "?".
231+alias scd='noglob scd'
232+
233+
234+## Load the directory aliases created by scd if any.
235+if [[ -s ~/.scdalias.zsh ]]; then source ~/.scdalias.zsh; fi