blob: ee810e2298beffd9a8021ef96f4bccaa98635547 [file] [log] [blame]
Erich Smith3e76d672012-05-07 09:56:36 -04001#!/usr/bin/env sh
2
3# Fasd (this file) can be sourced or executed by any POSIX compatible shell.
4
5# Fasd is originally written based on code from z (https://github.com/rupa/z)
6# by rupa deadwyler under the WTFPL license. Most if not all of the code has
7# been rewritten.
8
9# Copyright (C) 2011, 2012 by Wei Dai. All rights reserved.
10#
11# Permission is hereby granted, free of charge, to any person obtaining
12# a copy of this software and associated documentation files (the
13# "Software"), to deal in the Software without restriction, including
14# without limitation the rights to use, copy, modify, merge, publish,
15# distribute, sublicense, and/or sell copies of the Software, and to
16# permit persons to whom the Software is furnished to do so, subject to
17# the following conditions:
18#
19# The above copyright notice and this permission notice shall be included
20# in all copies or substantial portions of the Software.
21#
22# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30fasd() {
31
32 case "$1" in
33 --init)
34 shift
35 while [ "$1" ]; do
36 case $1 in
37 env)
38 { # source rc files if present
39 [ -s "/etc/fasdrc" ] && . "/etc/fasdrc"
40 [ -s "$HOME/.fasdrc" ] && . "$HOME/.fasdrc"
41
42 # set default options
43 [ -z "$_FASD_DATA" ] && _FASD_DATA="$HOME/.fasd"
44 [ -z "$_FASD_BLACKLIST" ] && _FASD_BLACKLIST="--help"
45 [ -z "$_FASD_SHIFT" ] && _FASD_SHIFT="sudo busybox"
46 [ -z "$_FASD_IGNORE" ] && _FASD_IGNORE="fasd cd ls echo"
47 [ -z "$_FASD_SINK" ] && _FASD_SINK=/dev/null
48 [ -z "$_FASD_TRACK_PWD" ] && _FASD_TRACK_PWD=1
49 [ -z "$_FASD_MAX" ] && _FASD_MAX=2000
50 [ -z "$_FASD_BACKENDS" ] && _FASD_BACKENDS=native
51
52 if [ -z "$_FASD_AWK" ]; then
53 # awk preferences
54 local awk; for awk in mawk gawk original-awk nawk awk; do
55 $awk "" && _FASD_AWK=$awk && break
56 done
57 fi
58 } >> "${_FASD_SINK:-/dev/null}" 2>&1
59 ;;
60
61 auto) cat <<EOS
62{ if compctl; then # zsh
63 eval "\$(fasd --init posix-alias zsh-hook zsh-ccomp zsh-ccomp-install \
64 zsh-wcomp zsh-wcomp-install)"
65 elif complete; then # bash
66 eval "\$(fasd --init posix-alias bash-hook bash-ccomp bash-ccomp-install)"
67 else # posix shell
68 eval "\$(fasd --init posix-alias posix-hook)"
69 fi
70} >> "$_FASD_SINK" 2>&1
71
72EOS
73 ;;
74
75 posix-alias) cat <<EOS
76alias a='fasd -a'
77alias s='fasd -si'
78alias sd='fasd -sid'
79alias sf='fasd -sif'
80alias d='fasd -d'
81alias f='fasd -f'
82# function to execute built-in cd
83fasd_cd() { [ \$# -gt 1 ] && cd "\$(fasd -e echo "\$@")" || fasd "\$@"; }
84alias z='fasd_cd -d'
85
86EOS
87 ;;
88
89 zsh-hook) cat <<EOS
90# add zsh hook
91_fasd_preexec() {
92 { eval "fasd --proc \$(fasd --sanitize \$3)"; } >> "$_FASD_SINK" 2>&1
93}
94autoload -U add-zsh-hook
95add-zsh-hook preexec _fasd_preexec
96
97EOS
98 ;;
99
100 bash-hook) cat <<EOS
101# add bash hook
102echo \$PROMPT_COMMAND | grep -v -q "fasd --proc" && \
103 PROMPT_COMMAND='eval "fasd --proc \$(fasd --sanitize \$(history 1 | \
104 sed -e "s/^[ ]*[0-9]*[ ]*//"))" >> "$_FASD_SINK" 2>&1;'"\$PROMPT_COMMAND"
105
106EOS
107 ;;
108
109 posix-hook) cat <<EOS
110_fasd_ps1_func() {
111 { eval "fasd --proc \$(fasd --sanitize \
112 \$(fc -nl -0 | sed -n '\$s/\s*\(.*\)/\1/p'))"; } >> "$_FASD_SINK" 2>&1
113}
114echo "\$PS1" | grep -v -q "_fasd_ps1_func" && \
115export PS1="\\\$(_fasd_ps1_func)\$PS1"
116
117EOS
118 ;;
119
120 zsh-ccomp) cat <<EOS
121# zsh command mode completion
122_fasd_zsh_cmd_complete() {
123 local compl
124 read -c compl
125 compstate[insert]=menu # no expand
126 reply=(\${(f)"\$(fasd --complete "\$compl")"})
127}
128
129EOS
130 ;;
131
132 zsh-wcomp) cat <<EOS
133# zsh word mode completion
134_fasd_zsh_word_complete() {
135 [ "\$2" ] && local _fasd_cur="\$2"
136 [ -z "\$_fasd_cur" ] && local _fasd_cur="\${words[CURRENT]}"
137 local fnd="\${_fasd_cur//,/ }"
138 local typ=\${1:-e}
139 fasd --query \$typ \$fnd | sort -nr | sed 's/^[0-9.]*[ ]*//' | \
140 while read line; do
141 compadd -U -V fasd "\$line"
142 done
143 compstate[insert]=menu # no expand
144}
145_fasd_zsh_word_complete_f() { _fasd_zsh_word_complete f ; }
146_fasd_zsh_word_complete_d() { _fasd_zsh_word_complete d ; }
147_fasd_zsh_word_complete_trigger() {
148 local _fasd_cur="\${words[CURRENT]}"
149 eval \$(fasd --word-complete-trigger _fasd_zsh_word_complete \$_fasd_cur)
150}
151# define zle widgets
152zle -C fasd-complete 'menu-select' _fasd_zsh_word_complete
153zle -C fasd-complete-f 'menu-select' _fasd_zsh_word_complete_f
154zle -C fasd-complete-d 'menu-select' _fasd_zsh_word_complete_d
155
156EOS
157 ;;
158
159 zsh-ccomp-install) cat <<EOS
160# enbale command mode completion
161compctl -U -K _fasd_zsh_cmd_complete -V fasd -x 'C[-1,-*e],s[-]n[1,e]' -c - \
162 'c[-1,-A][-1,-D]' -f -- fasd fasd_cd
163
164EOS
165 ;;
166
167 zsh-wcomp-install) cat <<EOS
168# enable word mode completion
169zstyle ':completion:*' completer _complete _ignored \
170 _fasd_zsh_word_complete_trigger
171
172EOS
173 ;;
174
175 bash-ccomp) cat <<EOS
176# bash command mode completion
177_fasd_bash_cmd_complete() {
178 # complete command after "-e"
179 local cur=\${COMP_WORDS[COMP_CWORD]}
180 [[ \${COMP_WORDS[COMP_CWORD-1]} == -*e ]] && \
181 COMPREPLY=( \$(compgen -A command \$cur) ) && return
182 # complete using default readline complete after "-A" or "-D"
183 case \${COMP_WORDS[COMP_CWORD-1]} in
184 -A|-D) COMPREPLY=( \$(compgen -o default \$cur) ) && return
185 esac
186 # get completion results using expanded aliases
187 local RESULT=\$( fasd -q --complete "\$(alias -p \$COMP_WORDS \
188 2>> "$_FASD_SINK" | sed -n "\\\$s/^.*'\(.*\)'/\1/p") \${COMP_LINE#* }" )
189 IFS=\$'\n' COMPREPLY=( \$RESULT )
190}
191_fasd_bash_hook_cmd_complete() {
192 for cmd in \$*; do
193 complete -F _fasd_bash_cmd_complete \$cmd
194 done
195}
196
197EOS
198 ;;
199
200 bash-wcomp) cat <<EOS
201# bash word mode completion
202_fasd_bash_word_complete() {
203 [ "\$2" ] && local _fasd_cur="\$2"
204 [ "\$_fasd_cur" ] || local _fasd_cur="\${COMP_WORDS[COMP_CWORD]}"
205 local typ=\${1:-e}
206 local fnd="\${_fasd_cur//,/ }"
207 local RESULT=\$(fasd -q --query \$typ \$fnd | sed 's/^[0-9.]*[ ]*//')
208 IFS=\$'\n' COMPREPLY=( \$RESULT )
209} >> "$_FASD_SINK" 2>&1
210_fasd_bash_word_complete_trigger() {
211 [ "\$_fasd_cur" ] || local _fasd_cur="\${COMP_WORDS[COMP_CWORD]}"
212 eval "\$(fasd --word-complete-trigger _fasd_bash_word_complete \$_fasd_cur)"
213} >> "$_FASD_SINK" 2>&1
214_fasd_bash_word_complete_wrap() {
215 local _fasd_cur="\${COMP_WORDS[COMP_CWORD]}"
216 _fasd_bash_word_complete_trigger
217 local z=\${COMP_WORDS[0]}
218 # try original comp func
219 [ "\$COMPREPLY" ] || eval "\$( echo "\$_FASD_BASH_COMPLETE_P" | \
220 sed -n "/ \$z\$/"'s/.*-F \(.*\) .*/\1/p' )"
221 # fall back on original complete options
222 local cmd="\$(echo "\$_FASD_BASH_COMPLETE_P" | \
223 sed -n "/ \$z\$/"'s/complete/compgen/') \$_fasd_cur"
224 [ "\$COMPREPLY" ] || COMPREPLY=( \$(eval \$cmd) )
225} >> "$_FASD_SINK" 2>&1
226
227EOS
228 ;;
229
230 bash-ccomp-install) cat <<EOS
231# enable bash command mode completion
232_fasd_bash_hook_cmd_complete fasd a s d f sd sf z
233
234EOS
235 ;;
236
237 bash-wcomp-install) cat <<EOS
238_FASD_BASH_COMPLETE_P="\$(complete -p)"
239for cmd in \$(complete -p | awk '{print \$NF}' | tr '\n' ' '); do
240 complete -o default -o bashdefault -F _fasd_bash_word_complete_wrap \$cmd
241done
242# enable word mode completion as default completion
243complete -o default -o bashdefault -D -F _fasd_bash_word_complete_trigger \
244 >> "$_FASD_SINK" 2>&1
245
246EOS
247 ;;
248 esac; shift
249 done
250 ;;
251
252 --init-alias)
253 fasd --init posix-alias
254 ;;
255
256 --init-zsh)
257 fasd --init zsh-hook zsh-ccomp zsh-ccomp-install zsh-wcomp zsh-wcomp-install
258 ;;
259
260 --init-bash)
261 fasd --init bash-hook bash-ccomp bash-ccomp-install
262 ;;
263
264 --init-posix)
265 fasd --init posix-hook
266 ;;
267
268 # if "$_fasd_cur" is a query, then eval all the arguments
269 --word-complete-trigger)
270 shift; [ "$2" ] && local _fasd_cur="$2" || return
271 case "$_fasd_cur" in
272 ,*) echo "$1" e "$_fasd_cur";;
273 f,*) echo "$1" f "${_fasd_cur#?}";;
274 d,*) echo "$1" d "${_fasd_cur#?}";;
275 *,,) echo "$1" e "$_fasd_cur";;
276 *,,f) echo "$1" f "${_fasd_cur%?}";;
277 *,,d) echo "$1" d "${_fasd_cur%?}";;
278 esac
279 ;;
280
281 --sanitize)
282 shift; echo "$@" | \
283 sed 's/\([^\]\)$([^ ]*\([^)]*\)))*/\1\2/g;s/\([^\]\)[|&;<>$`]\{1,\}/\1 /g'
284 ;;
285
286 --proc) shift # process commands
287 # stop if we don't own ~/.fasd (we're another user but our ENV is still set)
288 [ -f "$_FASD_DATA" -a ! -O "$_FASD_DATA" ] && return
289
290 # make zsh do word splitting for the for loop to work
291 [ "$ZSH_VERSION" ] && emulate sh && setopt localoptions
292
293 # blacklists
294 local each; for each in $_FASD_BLACKLIST; do
295 case " $* " in *\ $each\ *) return;; esac
296 done
297
298 # shifts
299 while true; do
300 case " $_FASD_SHIFT " in
301 *\ $1\ *) shift;;
302 *) break
303 esac
304 done
305
306 # ignores
307 case " $_FASD_IGNORE " in
308 *\ $1\ *) return
309 esac
310
311 shift; fasd --add "$@" # add all arguments except command
312 ;;
313
314 --add|-A) shift # add entries
315 # find all valid path arguments, convert them to simplest absolute form
316 local paths="$(while [ "$1" ]; do
317 [ -e "$1" ] && echo "$1"; shift
318 done | sed '/^[^/]/s@^@'"$PWD"'/@
319 s@/\.\.$@/\.\./@;s@/\(\./\)\{1,\}@/@g;: 0;s@[^/][^/]*//*\.\./@/@;t 0
320 s@^/*\.\./@/@;s@//*@/@g;s@/\.\{0,1\}$@@;s@^$@/@' | tr '\n' '|')"
321
322 # add current pwd if the option is set
323 [ "$_FASD_TRACK_PWD" = "1" -a "$PWD" != "$HOME" ] && paths="$paths|$PWD"
324
325 [ -z "${paths##\|}" ] && return # stop if we have nothing to add
326
327 # maintain the file
328 local tempfile
329 tempfile="$(mktemp "$_FASD_DATA".XXXXXX)" || return
330 $_FASD_AWK -v list="$paths" -v now="$(date +%s)" -v max="$_FASD_MAX" -F"|" '
331 BEGIN {
332 split(list, files, "|")
333 for(i in files) {
334 path = files[i]
335 if(path == "") continue
336 paths[path] = path # array for checking
337 rank[path] = 1
338 time[path] = now
339 }
340 }
341 $2 >= 1 {
342 if($1 in paths) {
343 rank[$1] = $2 + 1
344 time[$1] = now
345 } else {
346 rank[$1] = $2
347 time[$1] = $3
348 }
349 count += $2
350 }
351 END {
352 if(count > max)
353 for(i in rank) print i "|" 0.9*rank[i] "|" time[i] # aging
354 else
355 for(i in rank) print i "|" rank[i] "|" time[i]
356 }' "$_FASD_DATA" 2>> "$_FASD_SINK" >| "$tempfile"
357 if [ $? -ne 0 -a -f "$_FASD_DATA" ]; then
358 env rm -f "$tempfile"
359 else
360 env mv -f "$tempfile" "$_FASD_DATA"
361 fi
362 ;;
363
364 --delete|-D) shift # delete entries
365 # turn valid arguments into entry-deleting sed commands
366 local sed_cmd="$(while [ "$1" ]; do echo "$1"; shift; done | \
367 sed '/^[^/]/s@^@'"$PWD"'/@;s@/\.\.$@/\.\./@;s@/\(\./\)\{1,\}@/@g
368 : 0;s@[^/][^/]*//*\.\./@/@;t 0;s@^/*\.\./@/@;s@//*@/@g;s@/\.\{0,1\}$@@
369 s@^$@/@;s@\([.[/*^$]\)@\\\1@g;s@^\(.*\)$@/^\1|/d@')"
370
371 # maintain the file
372 local tempfile
373 tempfile="$(mktemp "$_FASD_DATA".XXXXXX)" || return
374
375 sed -e "$sed_cmd" "$_FASD_DATA" 2>> "$_FASD_SINK" >| "$tempfile"
376
377 if [ $? -ne 0 -a -f "$_FASD_DATA" ]; then
378 env rm -f "$tempfile"
379 else
380 env mv -f "$tempfile" "$_FASD_DATA"
381 fi
382 ;;
383
384 --query) shift # query the db, --query [$typ ["$fnd" [$mode [$quote]]]]
385 [ -f "$_FASD_DATA" ] || return # no db yet
386 [ "$1" ] && local typ="$1"
387 [ "$2" ] && local fnd="$2"
388 [ "$3" ] && local mode="$3"
389 [ "$4" ] && local quote="$4"
390 [ "$quote" ] && local qts='"\""' || local qts=
391
392 # make zsh do word spliting for the for loop to work
393 [ "$ZSH_VERSION" ] && emulate sh && setopt localoptions
394
395 # cat all backends
396 local each _fasd_data; for each in $_FASD_BACKENDS; do
397 _fasd_data="$_fasd_data
398$(fasd --backend $each)"
399 done
400 [ "$_fasd_data" ] || _fasd_data="$(cat "$_FASD_DATA")"
401
402 # set mode specific code for calculating the prior
403 case $mode in
404 rank) local prior='times[i]';;
405 recent) local prior='sqrt(100000/(1+t-la[i]))';;
406 *) local prior='times[i] * frecent(la[i])';;
407 esac
408
409 # query the database
410 echo "$_fasd_data" | while read line; do
411 [ -${typ:-e} "${line%%\|*}" ] && echo "$line"
412 done | $_FASD_AWK -v t="$(date +%s)" -v q="$fnd" -F"|" '
413 function frecent(time) {
414 dx = t-time
415 if( dx < 3600 ) return 6
416 if( dx < 86400 ) return 4
417 if( dx < 604800 ) return 2
418 return 1
419 }
420 function likelihood(pattern, path) {
421 m = gsub("/+", "/", path)
422 r = 1
423 for(i in pattern) {
424 tmp = path
425 gsub(".*" pattern[i], "", tmp)
426 n = gsub("/+", "/", tmp)
427 if(n == m)
428 return 0
429 else if(n == 0)
430 r *= 20 # F
431 else
432 r *= 1 - (n / m)
433 }
434 return r
435 }
436 BEGIN {
437 split(q, pattern, " ")
438 for(i in pattern) pattern_lower[i] = tolower(pattern[i]) # nocase
439 }
440 {
441 if(!wcase[$1]) {
442 times[$1] = $2
443 la[$1] = $3
444 wcase[$1] = likelihood(pattern, $1)
445 if(!cx) nocase[$1] = likelihood(pattern_lower, tolower($1))
446 } else {
447 times[$1] += $2
448 if($3 > la[$1]) la[$1] = $3
449 }
450 cx = cx || wcase[$1]
451 ncx = ncx || nocase[$1]
452 }
453 END {
454 if(cx) {
455 for(i in wcase) {
456 if(wcase[i])
457 printf "%-10s %s\n", '"$prior"' * wcase[i], '"$qts"' i '"$qts"'
458 }
459 } else if(ncx) {
460 for(i in nocase) {
461 if(nocase[i])
462 printf "%-10s %s\n", '"$prior"' * nocase[i], '"$qts"' i '"$qts"'
463 }
464 }
465 }' - 2>> "$_FASD_SINK"
466 ;;
467
468 --backend)
469 case $2 in
470 native) cat "$_FASD_DATA";;
471 viminfo)
472 local t="$(date +%s)"
473 < "$HOME/.viminfo" sed -n '/^>/{s@~@'"$HOME"'@;p}' | \
474 while IFS=" " read line; do
475 t=$((t-60)); echo "${line#??}|1|$t"
476 done
477 ;;
478 recently-used)
479 tr -d '\n' < "$HOME/.local/share/recently-used.xbel" | \
480 sed 's@file:/@\n@g;s@count="@\n@g' | sed '1d;s/".*$//' | \
481 tr '\n' '|' | sed 's@|/@\n@g' | $_FASD_AWK -F'|' '{
482 sum = 0
483 for( i=2; i<=NF; i++ ) sum += $i
484 print $1 "|" sum
485 }'
486 ;;
487 *) eval "$2";;
488 esac
489 ;;
490
491 *) # parsing logic and processing
492 local fnd last _FASD_BACKENDS="$_FASD_BACKENDS" _fasd_data
493 while [ "$1" ]; do case "$1" in
494 --complete) [ "$2" = "--" ] && shift; set -- $(echo $2); local lst=1 r=r;;
495 --query|--add|--delete|-A|-D) fasd "$@"; return $?;;
496 --version) echo "0.5.4"; return 0;;
497 --) while [ "$2" ]; do shift; fnd="$fnd$1 "; last="$1"; done;;
498 -*) local o="${1#-}"; while [ "$o" ]; do case "$o" in
499 s*) local show=1;;
500 l*) local lst=1;;
501 i*) local interactive=1 show=1;;
502 r*) local mode=rank;;
503 t*) local mode=recent;;
504 e*) o="${o#?}"; if [ "$o" ]; then # there are characters after "-e"
505 local exec="$o" # anything after "-e"
506 else # use the next argument
507 local exec="${2:?"-e: Argument needed "}"
508 shift
509 fi; break;;
510 b*) o="${o#?}"; if [ "$o" ]; then
511 _FASD_BACKENDS="$o"
512 else
513 _FASD_BACKENDS="${2:?"-b: Argument needed"}"
514 shift
515 fi; break;;
516 B*) o="${o#?}"; if [ "$o" ]; then
517 _FASD_BACKENDS="$_FASD_BACKENDS $o"
518 else
519 _FASD_BACKENDS="$_FASD_BACKENDS ${2:?"-B: Argument needed"}"
520 shift
521 fi; break;;
522 a*) local typ=e;;
523 d*) local typ=d;;
524 f*) local typ=f;;
525 q*) local quote=1;;
526 h*) echo "fasd [options] [query ...]
527[f|a|s|d|z] [opions] [query ...]
528 options:
529 -s show list of files with their ranks
530 -l list paths only
531 -i interactive mode
532 -e <cmd> set command to execute on the result file
533 -b <name> only use <name> backend
534 -b <name> add additional backend <name>
535 -a match files and directories
536 -d match directories only
537 -f match files only
538 -r match by rank only
539 -t match by recent access only
540 -h show a brief help message
541
542fasd [-A|-D] [paths ...]
543 -A add paths
544 -D delete paths" >&2; return;;
545 esac; o="${o#?}"; done;;
546 *) fnd="$fnd $1"; last="$1";;
547 esac; shift; done
548
549 # if we hit enter on a completion just execute
550 case "$last" in
551 # completions will always start with /
552 /*) [ -z "$show$lst" -a -${typ:-e} "$last" -a "$exec" ] \
553 && eval $exec "\"$last\"" && return;;
554 esac
555
556 local result
557 result="$(fasd --query 2>> "$_FASD_SINK")" # query the database
558 [ $? -gt 0 ] && return
559 if [ "$interactive" ] || [ "$exec" -a -z "$fnd$lst$show" -a -t 1 ]; then
560 result="$(echo "$result" | sort -nr)"
561 echo "$result" | sed = | sed 'N;s/\n/ /' | sort -nr >&2; printf "> " >&2
562 local i; read i; [ 0 -lt "${i:-0}" ] 2>> "$_FASD_SINK" || return 1
563 result="$(echo "$result" | sed -n "${i:-1}"'s/^[0-9.]*[ ]*//p')"
564 if [ "$result" ]; then
565 fasd --add "$result"; eval ${exec:-echo} "\"$result\""
566 fi
567 elif [ "$lst" ]; then
568 echo "$result" | sort -n${r} | sed 's/^[0-9.]*[ ]*//'
569 elif [ "$show" ]; then
570 echo "$result" | sort -n
571 elif [ "$fnd" -a "$exec" ]; then # exec
572 result="$(echo "$result" | sort -n | sed -n '$s/^[0-9.]*[ ]*//p')"
573 fasd --add "$result"; eval $exec "\"$result\""
574 elif [ "$fnd" -a ! -t 1 ]; then # echo if output is not terminal
575 result="$(echo "$result" | sort -n | sed -n '$s/^[0-9.]*[ ]*//p')"
576 fasd --add "$result"; echo "$result"
577 else # no args, show
578 echo "$result" | sort -n
579 fi
580
581 esac
582}
583
584fasd --init env
585
586case $- in
Erich Smith65ea1e92012-05-12 21:04:19 -0400587 *i*) cite about-plugin
588 about-plugin 'navigate "frecently" used files and directories'
Erich Smith3e76d672012-05-07 09:56:36 -0400589 eval "$(fasd --init auto)"
590 ;;
591 *) # assume being executed as an executable
592 if [ -x "$_FASD_SHELL" -a -z "$_FASD_SET" ]; then
593 _FASD_SET=1 exec $_FASD_SHELL "$0" "$@"
594 else
595 fasd "$@"
596 fi
597esac
598