├── INSTALL.md ├── LICENSE ├── Makefile ├── README.md ├── fasd ├── fasd.1 └── fasd.1.md /INSTALL.md: -------------------------------------------------------------------------------- 1 | Fasd is a self-contained posix shell script that can be either sourced or 2 | executed. A Makefile is provided to install `fasd` and `fasd.1` to desired 3 | places. 4 | 5 | 6 | System-wide install: 7 | 8 | make install 9 | 10 | Install to $HOME: 11 | 12 | PREFIX=$HOME make install 13 | 14 | Or alternatively you can just copy `fasd` to anywhere you like. 15 | 16 | To get fasd working in a shell, some initialization code must be run. Put the 17 | line below in your shell rc. 18 | 19 | eval "$(fasd --init auto)" 20 | 21 | This will setup a command hook that executes on every command and advanced tab 22 | completion for zsh and bash. 23 | 24 | If you want more control over what gets into your shell environment, you can 25 | pass customized set of arguments to `fasd --init`. 26 | 27 | zsh-hook # define _fasd_preexec and add it to zsh preexec array 28 | zsh-ccomp # zsh command mode completion definitions 29 | zsh-ccomp-install # setup command mode completion for zsh 30 | zsh-wcomp # zsh word mode completion definitions 31 | zsh-wcomp-install # setup word mode completion for zsh 32 | bash-hook # add hook code to bash $PROMPT_COMMAND 33 | bash-ccomp # bash command mode completion definitions 34 | bash-ccomp-install # setup command mode completion for bash 35 | posix-alias # define alias that applies to all posix shells 36 | posix-hook # setup $PS1 hook for shells that's posix compatible 37 | tcsh-alias # define aliases for tcsh 38 | tcsh-hook # setup tcsh precmd alias 39 | 40 | Example for a minimal zsh setup (no tab completion): 41 | 42 | eval "$(fasd --init posix-alias zsh-hook)" 43 | 44 | Note that this method will slightly increase your shell start-up time, since 45 | calling binaries has overhead. You can cache fasd init code if you want minimal 46 | overhead. Example code for bash (to be put into .bashrc): 47 | 48 | fasd_cache="$HOME/.fasd-init-bash" 49 | if [ "$(command -v fasd)" -nt "$fasd_cache" -o ! -s "$fasd_cache" ]; then 50 | fasd --init posix-alias bash-hook bash-ccomp bash-ccomp-install >| "$fasd_cache" 51 | fi 52 | source "$fasd_cache" 53 | unset fasd_cache 54 | 55 | Optionally, if you can also source `fasd` if you want `fasd` to be a shell 56 | function instead of an executable. 57 | 58 | You can tweak initialization code. For instance, if you want to use "c" 59 | instead of "z" to do directory jumping. You run the code below: 60 | 61 | # function to execute built-in cd 62 | fasd_cd() { 63 | if [ $# -le 1 ]; then 64 | fasd "$@" 65 | else 66 | local _fasd_ret="$(fasd -e echo "$@")" 67 | [ -z "$_fasd_ret" ] && return 68 | [ -d "$_fasd_ret" ] && cd "$_fasd_ret" || echo "$_fasd_ret" 69 | fi 70 | } 71 | alias c='fasd_cd -d' # `-d' option present for bash completion 72 | 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011, 2012 by Wei Dai. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX?= /usr/local 2 | BINDIR?= ${PREFIX}/bin 3 | MANDIR?= ${PREFIX}/share/man 4 | INSTALL?= install 5 | INSTALLDIR= ${INSTALL} -d 6 | INSTALLBIN= ${INSTALL} -m 755 7 | INSTALLMAN= ${INSTALL} -m 644 8 | 9 | all: fasd.1 10 | 11 | uninstall: 12 | rm -f ${DESTDIR}${BINDIR}/fasd 13 | rm -f ${DESTDIR}${MANDIR}/man1/fasd.1 14 | 15 | install: 16 | ${INSTALLDIR} ${DESTDIR}${BINDIR} 17 | ${INSTALLBIN} fasd ${DESTDIR}${BINDIR} 18 | ${INSTALLDIR} ${DESTDIR}${MANDIR}/man1 19 | ${INSTALLMAN} fasd.1 ${DESTDIR}${MANDIR}/man1 20 | 21 | man: fasd.1 22 | 23 | fasd.1: fasd.1.md 24 | pandoc -s -w man fasd.1.md -o fasd.1 25 | 26 | .PHONY: all install uninstall man 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fasd 2 | 3 | Fasd (pronounced similar to "fast") is a command-line productivity booster. 4 | Fasd offers quick access to files and directories for POSIX shells. It is 5 | inspired by tools like [autojump](https://github.com/joelthelion/autojump), 6 | [z](http://github.com/rupa/z) and [v](https://github.com/rupa/v). Fasd keeps 7 | track of files and directories you have accessed, so that you can quickly 8 | reference them in the command line. 9 | 10 | The name fasd comes from the default suggested aliases `f`(files), 11 | `a`(files/directories), `s`(show/search/select), `d`(directories). 12 | 13 | Fasd ranks files and directories by "frecency," that is, by both "frequency" and 14 | "recency." The term "frecency" was first coined by Mozilla and used in Firefox 15 | ([link](https://developer.mozilla.org/en/The_Places_frecency_algorithm)). 16 | 17 | # Introduction 18 | 19 | If you use your shell to navigate and launch applications, fasd can help you do 20 | it more efficiently. With fasd, you can open files regardless of which 21 | directory you are in. Just with a few key strings, fasd can find a "frecent" 22 | file or directory and open it with command you specify. Below are some 23 | hypothetical situations, where you can type in the command on the left and fasd 24 | will "expand" your command into the right side. Pretty magic, huh? 25 | 26 | ``` 27 | v def conf => vim /some/awkward/path/to/type/default.conf 28 | j abc => cd /hell/of/a/awkward/path/to/get/to/abcdef 29 | m movie => mplayer /whatever/whatever/whatever/awesome_movie.mp4 30 | o eng paper => xdg-open /you/dont/remember/where/english_paper.pdf 31 | vim `f rc lo` => vim /etc/rc.local 32 | vim `f rc conf` => vim /etc/rc.conf 33 | ``` 34 | 35 | Fasd comes with some useful aliases by default: 36 | 37 | ```sh 38 | alias a='fasd -a' # any 39 | alias s='fasd -si' # show / search / select 40 | alias d='fasd -d' # directory 41 | alias f='fasd -f' # file 42 | alias sd='fasd -sid' # interactive directory selection 43 | alias sf='fasd -sif' # interactive file selection 44 | alias z='fasd_cd -d' # cd, same functionality as j in autojump 45 | alias zz='fasd_cd -d -i' # cd with interactive selection 46 | ``` 47 | 48 | Fasd will smartly detect when to display a list of files or just the best 49 | match. For instance, when you call fasd in a subshell with some search 50 | parameters, fasd will only return the best match. This enables you to do: 51 | 52 | ```sh 53 | mv update.html `d www` 54 | cp `f mov` . 55 | ``` 56 | 57 | # Install 58 | 59 | Fasd is available in various package managers. Please check 60 | [the wiki page](https://github.com/clvv/fasd/wiki/Installing-via-Package-Managers) 61 | for an up-to-date list. 62 | 63 | You can also manually obtain a copy of fasd. 64 | 65 | Download fasd 1.0.1 from GitHub: 66 | [zip](https://github.com/clvv/fasd/zipball/1.0.1), 67 | [tar.gz](https://github.com/clvv/fasd/tarball/1.0.1). 68 | 69 | Fasd is a self-contained POSIX shell script that can be either sourced or 70 | executed. A Makefile is provided to install `fasd` and `fasd.1` to desired 71 | places. 72 | 73 | System-wide install: 74 | 75 | make install 76 | 77 | Install to $HOME: 78 | 79 | PREFIX=$HOME make install 80 | 81 | Or alternatively you can just copy `fasd` to anywhere you like (preferably 82 | under some directory in `$PATH`). 83 | 84 | To get fasd working in a shell, some initialization code must be run. Put the 85 | line below in your shell rc. 86 | 87 | ```sh 88 | eval "$(fasd --init auto)" 89 | ``` 90 | 91 | This will setup a command hook that executes on every command and advanced tab 92 | completion for zsh and bash. 93 | 94 | If you want more control over what gets into your shell environment, you can 95 | pass customized set of arguments to `fasd --init`. 96 | 97 | ``` 98 | zsh-hook # define _fasd_preexec and add it to zsh preexec array 99 | zsh-ccomp # zsh command mode completion definitions 100 | zsh-ccomp-install # setup command mode completion for zsh 101 | zsh-wcomp # zsh word mode completion definitions 102 | zsh-wcomp-install # setup word mode completion for zsh 103 | bash-hook # add hook code to bash $PROMPT_COMMAND 104 | bash-ccomp # bash command mode completion definitions 105 | bash-ccomp-install # setup command mode completion for bash 106 | posix-alias # define aliases that applies to all posix shells 107 | posix-hook # setup $PS1 hook for shells that's posix compatible 108 | tcsh-alias # define aliases for tcsh 109 | tcsh-hook # setup tcsh precmd alias 110 | ``` 111 | 112 | Example for a minimal zsh setup (no tab completion): 113 | 114 | ```sh 115 | eval "$(fasd --init posix-alias zsh-hook)" 116 | ``` 117 | 118 | Note that this method will slightly increase your shell start-up time, since 119 | calling binaries has overhead. You can cache fasd init code if you want minimal 120 | overhead. Example code for bash (to be put into .bashrc): 121 | 122 | ```sh 123 | fasd_cache="$HOME/.fasd-init-bash" 124 | if [ "$(command -v fasd)" -nt "$fasd_cache" -o ! -s "$fasd_cache" ]; then 125 | fasd --init posix-alias bash-hook bash-ccomp bash-ccomp-install >| "$fasd_cache" 126 | fi 127 | source "$fasd_cache" 128 | unset fasd_cache 129 | ``` 130 | 131 | Optionally, if you can also source `fasd` if you want `fasd` to be a shell 132 | function instead of an executable. 133 | 134 | You can tweak initialization code. For instance, if you want to use "c" 135 | instead of "z" to do directory jumping, you can use the alias below: 136 | 137 | ```sh 138 | alias c='fasd_cd -d' 139 | # `-d` option present for bash completion 140 | # function fasd_cd is defined in posix-alias 141 | ``` 142 | 143 | After you first installed fasd, open some files (with any program) or `cd` 144 | around in your shell. Then try some examples below. 145 | 146 | # Examples 147 | 148 | ```sh 149 | f foo # list frecent files matching foo 150 | a foo bar # list frecent files and directories matching foo and bar 151 | f js$ # list frecent files that ends in js 152 | f -e vim foo # run vim on the most frecent file matching foo 153 | mplayer `f bar` # run mplayer on the most frecent file matching bar 154 | z foo # cd into the most frecent directory matching foo 155 | open `sf pdf` # interactively select a file matching pdf and launch `open` 156 | ``` 157 | 158 | You should add your own aliases to fully utilize the power of fasd. Here are 159 | some examples to get you started: 160 | 161 | ```sh 162 | alias v='f -e vim' # quick opening files with vim 163 | alias m='f -e mplayer' # quick opening files with mplayer 164 | alias o='a -e xdg-open' # quick opening files with xdg-open 165 | ``` 166 | 167 | If you're using bash, you have to call `_fasd_bash_hook_cmd_complete` to make 168 | completion work. For instance: 169 | 170 | _fasd_bash_hook_cmd_complete v m j o 171 | 172 | You could select an entry in the list of matching files. 173 | 174 | # Matching 175 | 176 | Fasd has three matching modes: default, case-insensitive, and fuzzy. 177 | 178 | For a given set of queries (the set of command-line arguments passed to fasd), 179 | a path is a match if and only if: 180 | 181 | 1. Queries match the path *in order*. 182 | 2. The last query matches the *last segment* of the path. 183 | 184 | If no match is found, fasd will try the same process ignoring case. If still no 185 | match is found, fasd will allow extra characters to be placed between query 186 | characters for fuzzy matching. 187 | 188 | Tips: 189 | 190 | * If you want your last query not to match the last segment of the path, append 191 | `/` as the last query. 192 | * If you want your last query to match the end of the filename, append `$` to 193 | the last query. 194 | 195 | # How It Works 196 | 197 | When you run fasd init code or source `fasd`, fasd adds a hook which will be 198 | executed whenever you execute a command. The hook will scan your commands' 199 | arguments and determine if any of them refer to existing files or directories. 200 | If yes, fasd will add them to the database. 201 | 202 | # Compatibility 203 | 204 | Fasd's basic functionalities are POSIX compliant, meaning that you should be 205 | able to use fasd in all POSIX compliant shells. Your shell need to support 206 | command substitution in `$PS1` in order for fasd to automatically track your 207 | commands and files. This feature is not specified by the POSIX standard, but 208 | it's nonetheless present in many POSIX compliant shells. In shells without 209 | prompt command or prompt command substitution (csh for instance), you can add 210 | entries manually with `fasd -A`. You are very welcomed to contribute shell 211 | initialization code for not yet supported shells. 212 | 213 | Fasd has been tested on the following shells: bash, zsh, mksh, pdksh, dash, 214 | busybox ash, FreeBSD 9 /bin/sh and OpenBSD /bin/sh. 215 | 216 | # Synopsis 217 | 218 | fasd [options] [query ...] 219 | [f|a|s|d|z] [options] [query ...] 220 | options: 221 | -s list paths with scores 222 | -l list paths without scores 223 | -i interactive mode 224 | -e set command to execute on the result file 225 | -b only use backend 226 | -B add additional backend 227 | -a match files and directories 228 | -d match directories only 229 | -f match files only 230 | -r match by rank only 231 | -t match by recent access only 232 | -R reverse listing order 233 | -h show a brief help message 234 | -[0-9] select the nth entry 235 | 236 | fasd [-A|-D] [paths ...] 237 | -A add paths 238 | -D delete paths 239 | 240 | # Tab Completion 241 | 242 | Fasd offers two completion modes, command mode completion and word mode 243 | completion. Command mode completion works in bash and zsh. Word mode 244 | completion only works in zsh. 245 | 246 | Command mode completion is just like completion for any other commands. It is 247 | triggered when you hit tab on a `fasd` command or its aliases. Under this mode 248 | your queries can be separated by a space. Tip: if you find that the completion 249 | result overwrites your queries, type an extra space before you hit tab. 250 | 251 | Word mode completion can be triggered on *any* command. Word completion is 252 | triggered by any command line argument that starts with `,` (all), `f,` 253 | (files), or `d,` (directories), or that ends with `,,` (all), `,,f` (files), or 254 | `,,d` (directories). Examples: 255 | 256 | $ vim ,rc,lo 257 | $ vim /etc/rc.local 258 | 259 | $ mv index.html d,www 260 | $ mv index.html /var/www/ 261 | 262 | There are also three zle widgets: `fasd-complete`, `fasd-complete-f`, 263 | `fasd-complete-d`. You can bind them to keybindings you like: 264 | 265 | ```sh 266 | bindkey '^X^A' fasd-complete # C-x C-a to do fasd-complete (files and directories) 267 | bindkey '^X^F' fasd-complete-f # C-x C-f to do fasd-complete-f (only files) 268 | bindkey '^X^D' fasd-complete-d # C-x C-d to do fasd-complete-d (only directories) 269 | ``` 270 | 271 | # Backends 272 | 273 | Fasd can take advantage of different sources of recent / frequent files. Most 274 | desktop environments (such as OS X and Gtk) and some editors (such as Vim) keep 275 | a list of accessed files. Fasd can use them as additional backends if the data 276 | can be converted into fasd's native format. Below is a list of available 277 | backends. 278 | 279 | ``` 280 | `spotlight` 281 | OSX spotlight, provides entries that are changed today or opened within the 282 | past month 283 | 284 | `recently-used` 285 | GTK's recently-used file (Usually available on Linux) 286 | 287 | `current` 288 | Provides everything in $PWD (whereever you are executing `fasd`) 289 | 290 | `viminfo` 291 | Vim's editing history, useful if you want to define an alias just for editing 292 | things in vim 293 | ``` 294 | 295 | You can define your own backend by declaring a function by that name in your 296 | `.fasdrc`. You can set default backend with `_FASD_BACKENDS` variable in our 297 | `.fasdrc`. 298 | 299 | Fasd can mimic [v](http://github.com/rupa/v)'s behavior by this alias: 300 | 301 | ```sh 302 | alias v='f -t -e vim -b viminfo' 303 | ``` 304 | 305 | # Tweaks 306 | 307 | Some shell variables that you can set before sourcing `fasd`. You can set them 308 | in `$HOME/.fasdrc` 309 | 310 | ``` 311 | $_FASD_DATA 312 | Path to the fasd data file, default "$HOME/.fasd". 313 | 314 | $_FASD_BLACKLIST 315 | List of blacklisted strings. Commands matching them will not be processed. 316 | Default is "--help". 317 | 318 | $_FASD_SHIFT 319 | List of all commands that needs to be shifted, defaults to "sudo busybox". 320 | 321 | $_FASD_IGNORE 322 | List of all commands that will be ignored, defaults to "fasd ls echo". 323 | 324 | $_FASD_TRACK_PWD 325 | Fasd defaults to track your "$PWD". Set this to 0 to disable this behavior. 326 | 327 | $_FASD_AWK 328 | Which awk to use. Fasd can detect and use a compatible awk. 329 | 330 | $_FASD_SINK 331 | File to log all STDERR to, defaults to "/dev/null". 332 | 333 | $_FASD_MAX 334 | Max total score / weight, defaults to 2000. 335 | 336 | $_FASD_SHELL 337 | Which shell to execute. Some shells will run faster than others. fasd 338 | runs faster with dash and ksh variants. 339 | 340 | $_FASD_BACKENDS 341 | Default backends. 342 | 343 | $_FASD_RO 344 | If set to any non-empty string, fasd will not add or delete entries from 345 | database. You can set and export this variable from command line. 346 | 347 | $_FASD_FUZZY 348 | Level of "fuzziness" when doing fuzzy matching. More precisely, the number of 349 | characters that can be skipped to generate a match. Set to empty or 0 to 350 | disable fuzzy matching. Default value is 2. 351 | 352 | $_FASD_VIMINFO 353 | Path to .viminfo file for viminfo backend, defaults to "$HOME/.viminfo" 354 | 355 | $_FASD_RECENTLY_USED_XBEL 356 | Path to XDG recently-used.xbel file for recently-used backend, defaults to 357 | "$HOME/.local/share/recently-used.xbel" 358 | 359 | ``` 360 | 361 | # Debugging 362 | 363 | If fasd does not work as expected, please file a bug report describing the 364 | unexpected behavior along with your OS version, shell version, awk version, sed 365 | version, and a log file. 366 | 367 | You can set `_FASD_SINK` in your `.fasdrc` to obtain a log. 368 | 369 | ```sh 370 | _FASD_SINK="$HOME/.fasd.log" 371 | ``` 372 | 373 | # COPYING 374 | 375 | Fasd is originally written based on code from [z](https://github.com/rupa/z) by 376 | rupa deadwyler under the WTFPL license. Most if not all of the code has been 377 | rewritten. Fasd is licensed under the "MIT/X11" license. 378 | 379 | -------------------------------------------------------------------------------- /fasd: -------------------------------------------------------------------------------- 1 | #!/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 | 30 | fasd() { 31 | 32 | # make zsh do word splitting inside this function 33 | [ "$ZSH_VERSION" ] && emulate sh && setopt localoptions 34 | 35 | case $1 in 36 | --init) shift 37 | while [ "$1" ]; do 38 | case $1 in 39 | env) 40 | { # source rc files if present 41 | [ -s "/etc/fasdrc" ] && . "/etc/fasdrc" 42 | [ -s "$HOME/.fasdrc" ] && . "$HOME/.fasdrc" 43 | 44 | # set default options 45 | [ -z "$_FASD_DATA" ] && _FASD_DATA="$HOME/.fasd" 46 | [ -z "$_FASD_BLACKLIST" ] && _FASD_BLACKLIST="--help" 47 | [ -z "$_FASD_SHIFT" ] && _FASD_SHIFT="sudo busybox" 48 | [ -z "$_FASD_IGNORE" ] && _FASD_IGNORE="fasd ls echo" 49 | [ -z "$_FASD_SINK" ] && _FASD_SINK=/dev/null 50 | [ -z "$_FASD_TRACK_PWD" ] && _FASD_TRACK_PWD=1 51 | [ -z "$_FASD_MAX" ] && _FASD_MAX=2000 52 | [ -z "$_FASD_BACKENDS" ] && _FASD_BACKENDS=native 53 | [ -z "$_FASD_FUZZY" ] && _FASD_FUZZY=2 54 | [ -z "$_FASD_VIMINFO" ] && _FASD_VIMINFO="$HOME/.viminfo" 55 | [ -z "$_FASD_RECENTLY_USED_XBEL" ] && \ 56 | _FASD_RECENTLY_USED_XBEL="$HOME/.local/share/recently-used.xbel" 57 | 58 | if [ -z "$_FASD_AWK" ]; then 59 | # awk preferences 60 | local awk; for awk in mawk gawk original-awk nawk awk; do 61 | $awk "" && _FASD_AWK=$awk && break 62 | done 63 | fi 64 | } >> "${_FASD_SINK:-/dev/null}" 2>&1 65 | ;; 66 | 67 | auto) cat <> "$_FASD_SINK" 2>&1 77 | 78 | EOS 79 | ;; 80 | 81 | posix-alias) cat <& /dev/null || fasd -d'; 112 | EOS 113 | ;; 114 | 115 | zsh-hook) cat <> "$_FASD_SINK" 2>&1 119 | } 120 | autoload -Uz add-zsh-hook 121 | add-zsh-hook preexec _fasd_preexec 122 | 123 | EOS 124 | ;; 125 | 126 | bash-hook) cat <> "$_FASD_SINK" 2>&1 130 | } 131 | 132 | # add bash hook 133 | case \$PROMPT_COMMAND in 134 | *_fasd_prompt_func*) ;; 135 | *) PROMPT_COMMAND="_fasd_prompt_func;\$PROMPT_COMMAND";; 136 | esac 137 | 138 | EOS 139 | ;; 140 | 141 | posix-hook) cat <> "$_FASD_SINK" 2>&1 145 | } 146 | case \$PS1 in 147 | *_fasd_ps1_func*) ;; 148 | *) export PS1="\\\$(_fasd_ps1_func)\$PS1";; 149 | esac 150 | 151 | EOS 152 | ;; 153 | 154 | tcsh-hook) cat <& /dev/null'; 158 | EOS 159 | 160 | ;; 161 | 162 | zsh-ccomp) cat <> "$_FASD_SINK" | \\ 183 | sort -nr | sed 's/^[^ ]*[ ]*//' | while read -r line; do 184 | compadd -U -V fasd "\$line" 185 | done 186 | compstate[insert]=menu # no expand 187 | } 188 | _fasd_zsh_word_complete_f() { _fasd_zsh_word_complete f ; } 189 | _fasd_zsh_word_complete_d() { _fasd_zsh_word_complete d ; } 190 | _fasd_zsh_word_complete_trigger() { 191 | local _fasd_cur="\${words[CURRENT]}" 192 | eval \$(fasd --word-complete-trigger _fasd_zsh_word_complete \$_fasd_cur) 193 | } 194 | # define zle widgets 195 | zle -C fasd-complete complete-word _generic 196 | zstyle ':completion:fasd-complete:*' completer _fasd_zsh_word_complete 197 | zstyle ':completion:fasd-complete:*' menu-select 198 | 199 | zle -C fasd-complete-f complete-word _generic 200 | zstyle ':completion:fasd-complete-f:*' completer _fasd_zsh_word_complete_f 201 | zstyle ':completion:fasd-complete-f:*' menu-select 202 | 203 | zle -C fasd-complete-d complete-word _generic 204 | zstyle ':completion:fasd-complete-d:*' completer _fasd_zsh_word_complete_d 205 | zstyle ':completion:fasd-complete-d:*' menu-select 206 | } 207 | 208 | EOS 209 | ;; 210 | 211 | zsh-ccomp-install) cat <> "$_FASD_SINK" | sed -n "\\\$s/^.*'\\\\(.*\\\\)'/\\\\1/p") 251 | \${COMP_LINE#* }" | while read -r line; do 252 | quote_readline "\$line" 2>/dev/null || \\ 253 | printf %q "\$line" 2>/dev/null && \\ 254 | printf \\\\n 255 | done) 256 | local IFS=\$'\\n'; COMPREPLY=( \$RESULT ) 257 | } 258 | _fasd_bash_hook_cmd_complete() { 259 | for cmd in \$*; do 260 | complete -F _fasd_bash_cmd_complete \$cmd 261 | done 262 | } 263 | 264 | EOS 265 | ;; 266 | 267 | bash-ccomp-install) cat <$`{}]\{1,\}/\1 /g' 293 | ;; 294 | 295 | --proc) shift # process commands 296 | # stop if we don't own $_FASD_DATA or $_FASD_RO is set 297 | [ -f "$_FASD_DATA" -a ! -O "$_FASD_DATA" ] || [ "$_FASD_RO" ] && return 298 | 299 | # blacklists 300 | local each; for each in $_FASD_BLACKLIST; do 301 | case " $* " in *\ $each\ *) return;; esac 302 | done 303 | 304 | # shifts 305 | while true; do 306 | case " $_FASD_SHIFT " in 307 | *\ $1\ *) shift;; 308 | *) break;; 309 | esac 310 | done 311 | 312 | # ignores 313 | case " $_FASD_IGNORE " in 314 | *\ $1\ *) return;; 315 | esac 316 | 317 | shift; fasd --add "$@" # add all arguments except command 318 | ;; 319 | 320 | --add|-A) shift # add entries 321 | # stop if we don't own $_FASD_DATA or $_FASD_RO is set 322 | [ -f "$_FASD_DATA" -a ! -O "$_FASD_DATA" ] || [ "$_FASD_RO" ] && return 323 | 324 | # find all valid path arguments, convert them to simplest absolute form 325 | local paths="$(while [ "$1" ]; do 326 | [ -e "$1" ] && printf %s\\n "$1"; shift 327 | done | sed '/^[^/]/s@^@'"$PWD"'/@ 328 | s@/\.\.$@/../@;s@/\(\./\)\{1,\}@/@g;:0 329 | s@[^/][^/]*//*\.\./@/@;t 0 330 | s@^/*\.\./@/@;s@//*@/@g;s@/\.\{0,1\}$@@;s@^$@/@' 2>> "$_FASD_SINK" \ 331 | | tr '\n' '|')" 332 | 333 | # add current pwd if the option is set 334 | [ "$_FASD_TRACK_PWD" = "1" -a "$PWD" != "$HOME" ] && paths="$paths|$PWD" 335 | 336 | [ -z "${paths##\|}" ] && return # stop if we have nothing to add 337 | 338 | # maintain the file 339 | local tempfile 340 | tempfile="$(mktemp "$_FASD_DATA".XXXXXX)" || return 341 | $_FASD_AWK -v list="$paths" -v now="$(date +%s)" -v max="$_FASD_MAX" -F"|" ' 342 | BEGIN { 343 | split(list, files, "|") 344 | for(i in files) { 345 | path = files[i] 346 | if(path == "") continue 347 | paths[path] = path # array for checking 348 | rank[path] = 1 349 | time[path] = now 350 | } 351 | } 352 | $2 >= 1 { 353 | if($1 in paths) { 354 | rank[$1] = $2 + 1 / $2 355 | time[$1] = now 356 | } else { 357 | rank[$1] = $2 358 | time[$1] = $3 359 | } 360 | count += $2 361 | } 362 | END { 363 | if(count > max) 364 | for(i in rank) print i "|" 0.9*rank[i] "|" time[i] # aging 365 | else 366 | for(i in rank) print i "|" rank[i] "|" time[i] 367 | }' "$_FASD_DATA" 2>> "$_FASD_SINK" >| "$tempfile" 368 | if [ $? -ne 0 -a -f "$_FASD_DATA" ]; then 369 | env rm -f "$tempfile" 370 | else 371 | env mv -f "$tempfile" "$_FASD_DATA" 372 | fi 373 | ;; 374 | 375 | --delete|-D) shift # delete entries 376 | # stop if we don't own $_FASD_DATA or $_FASD_RO is set 377 | [ -f "$_FASD_DATA" -a ! -O "$_FASD_DATA" ] || [ "$_FASD_RO" ] && return 378 | 379 | # turn valid arguments into entry-deleting sed commands 380 | local sed_cmd="$(while [ "$1" ]; do printf %s\\n "$1"; shift; done | \ 381 | sed '/^[^/]/s@^@'"$PWD"'/@;s@/\.\.$@/../@;s@/\(\./\)\{1,\}@/@g;:0 382 | s@[^/][^/]*//*\.\./@/@;t 0 383 | s@^/*\.\./@/@;s@//*@/@g;s@/\.\{0,1\}$@@ 384 | s@^$@/@;s@\([.[\/*^$]\)@\\\1@g;s@^\(.*\)$@/^\1|/d@' 2>> "$_FASD_SINK")" 385 | 386 | # maintain the file 387 | local tempfile 388 | tempfile="$(mktemp "$_FASD_DATA".XXXXXX)" || return 389 | 390 | sed "$sed_cmd" "$_FASD_DATA" 2>> "$_FASD_SINK" >| "$tempfile" 391 | 392 | if [ $? -ne 0 -a -f "$_FASD_DATA" ]; then 393 | env rm -f "$tempfile" 394 | else 395 | env mv -f "$tempfile" "$_FASD_DATA" 396 | fi 397 | ;; 398 | 399 | --query) shift # query the db, --query [$typ ["$fnd" [$mode]]] 400 | [ -f "$_FASD_DATA" ] || return # no db yet 401 | [ "$1" ] && local typ="$1" 402 | [ "$2" ] && local fnd="$2" 403 | [ "$3" ] && local mode="$3" 404 | 405 | # cat all backends 406 | local each _fasd_data; for each in $_FASD_BACKENDS; do 407 | _fasd_data="$_fasd_data 408 | $(fasd --backend $each)" 409 | done 410 | [ "$_fasd_data" ] || _fasd_data="$(cat "$_FASD_DATA")" 411 | 412 | # set mode specific code for calculating the prior 413 | case $mode in 414 | rank) local prior='times[i]';; 415 | recent) local prior='sqrt(100000/(1+t-la[i]))';; 416 | *) local prior='times[i] * frecent(la[i])';; 417 | esac 418 | 419 | if [ "$fnd" ]; then # dafault matching 420 | local bre="$(printf %s\\n "$fnd" | sed 's/\([*\.\\\[]\)/\\\1/g 421 | s@ @[^|]*@g;s/\$$/|/')" 422 | bre='^[^|]*'"$bre"'[^|/]*|' 423 | local _ret="$(printf %s\\n "$_fasd_data" | grep "$bre")" 424 | [ "$_ret" ] && _ret="$(printf %s\\n "$_ret" | while read -r line; do 425 | [ -${typ:-e} "${line%%\|*}" ] && printf %s\\n "$line" 426 | done)" 427 | if [ "$_ret" ]; then 428 | _fasd_data="$_ret" 429 | else # no case mathcing 430 | _ret="$(printf %s\\n "$_fasd_data" | grep -i "$bre")" 431 | [ "$_ret" ] && _ret="$(printf %s\\n "$_ret" | while read -r line; do 432 | [ -${typ:-e} "${line%%\|*}" ] && printf %s\\n "$line" 433 | done)" 434 | if [ "$_ret" ]; then 435 | _fasd_data="$_ret" 436 | elif [ "${_FASD_FUZZY:-0}" -gt 0 ]; then # fuzzy matching 437 | local fuzzy_bre="$(printf %s\\n "$fnd" | \ 438 | sed 's/\([*\.\\\[]\)/\\\1/g;s/\$$/|/ 439 | s@\(\\\{0,1\}[^ ]\)@\1[^|/]\\{0,'"$_FASD_FUZZY"'\\}@g 440 | s@ @[^|]*@g')" 441 | fuzzy_bre='^[^|]*'"$fuzzy_bre"'[^|/]*|' 442 | _ret="$(printf %s\\n "$_fasd_data" | grep -i "$fuzzy_bre")" 443 | [ "$_ret" ] && _ret="$(printf %s\\n "$_ret" | while read -r line; do 444 | [ -${typ:-e} "${line%%\|*}" ] && printf %s\\n "$line" 445 | done)" 446 | [ "$_ret" ] && _fasd_data="$_ret" || _fasd_data= 447 | fi 448 | fi 449 | else # no query arugments 450 | _fasd_data="$(printf %s\\n "$_fasd_data" | while read -r line; do 451 | [ -${typ:-e} "${line%%\|*}" ] && printf %s\\n "$line" 452 | done)" 453 | fi 454 | 455 | # query the database 456 | [ "$_fasd_data" ] && printf %s\\n "$_fasd_data" | \ 457 | $_FASD_AWK -v t="$(date +%s)" -F"|" ' 458 | function frecent(time) { 459 | dx = t-time 460 | if( dx < 3600 ) return 6 461 | if( dx < 86400 ) return 4 462 | if( dx < 604800 ) return 2 463 | return 1 464 | } 465 | { 466 | if(!paths[$1]) { 467 | times[$1] = $2 468 | la[$1] = $3 469 | paths[$1] = 1 470 | } else { 471 | times[$1] += $2 472 | if($3 > la[$1]) la[$1] = $3 473 | } 474 | } 475 | END { 476 | for(i in paths) printf "%-10s %s\n", '"$prior"', i 477 | }' - 2>> "$_FASD_SINK" 478 | ;; 479 | 480 | --backend) 481 | case $2 in 482 | native) cat "$_FASD_DATA";; 483 | viminfo) 484 | < "$_FASD_VIMINFO" sed -n '/^>/{s@~@'"$HOME"'@ 485 | s/^..// 486 | p 487 | }' | $_FASD_AWK -v t="$(date +%s)" '{ 488 | t -= 60 489 | print $0 "|1|" t 490 | }' 491 | ;; 492 | recently-used) 493 | local nl="$(printf '\\\nX')"; nl="${nl%X}" # slash newline for sed 494 | tr -d '\n' < "$_FASD_RECENTLY_USED_XBEL" | \ 495 | sed 's@file:/@'"$nl"'@g;s@count="@'"$nl"'@g' | sed '1d;s/".*$//' | \ 496 | tr '\n' '|' | sed 's@|/@'"$nl"'@g' | $_FASD_AWK -F'|' '{ 497 | sum = 0 498 | for( i=2; i<=NF; i++ ) sum += $i 499 | print $1 "|" sum 500 | }' 501 | ;; 502 | current) 503 | for path in *; do 504 | printf "$PWD/%s|1\\n" "$path" 505 | done 506 | ;; 507 | spotlight) 508 | mdfind '(kMDItemFSContentChangeDate >= $time.today) || 509 | kMDItemLastUsedDate >= $time.this_month' \ 510 | | sed '/Library\//d 511 | /\.app$/d 512 | s/$/|2/' 513 | ;; 514 | *) eval "$2";; 515 | esac 516 | ;; 517 | 518 | *) # parsing logic and processing 519 | local fnd= last= _FASD_BACKENDS="$_FASD_BACKENDS" _fasd_data= comp= exec= 520 | while [ "$1" ]; do case $1 in 521 | --complete) [ "$2" = "--" ] && shift; set -- $2; local lst=1 r=r comp=1;; 522 | --query|--add|--delete|-A|-D) fasd "$@"; return $?;; 523 | --version) [ -z "$comp" ] && echo "1.0.1" && return;; 524 | --) while [ "$2" ]; do shift; fnd="$fnd $1"; last="$1"; done;; 525 | -*) local o="${1#-}"; while [ "$o" ]; do case $o in 526 | s*) local show=1;; 527 | l*) local lst=1;; 528 | i*) [ -z "$comp" ] && local interactive=1 show=1;; 529 | r*) local mode=rank;; 530 | t*) local mode=recent;; 531 | e*) o="${o#?}"; if [ "$o" ]; then # there are characters after "-e" 532 | local exec="$o" # anything after "-e" 533 | else # use the next argument 534 | local exec="${2:?"-e: Argument needed "}" 535 | shift 536 | fi; break;; 537 | b*) o="${o#?}"; if [ "$o" ]; then 538 | _FASD_BACKENDS="$o" 539 | else 540 | _FASD_BACKENDS="${2:?"-b: Argument needed"}" 541 | shift 542 | fi; break;; 543 | B*) o="${o#?}"; if [ "$o" ]; then 544 | _FASD_BACKENDS="$_FASD_BACKENDS $o" 545 | else 546 | _FASD_BACKENDS="$_FASD_BACKENDS ${2:?"-B: Argument needed"}" 547 | shift 548 | fi; break;; 549 | a*) local typ=e;; 550 | d*) local typ=d;; 551 | f*) local typ=f;; 552 | R*) local r=r;; 553 | [0-9]*) local _fasd_i="$o"; break;; 554 | h*) [ -z "$comp" ] && echo "fasd [options] [query ...] 555 | [f|a|s|d|z] [options] [query ...] 556 | options: 557 | -s list paths with scores 558 | -l list paths without scores 559 | -i interactive mode 560 | -e set command to execute on the result file 561 | -b only use backend 562 | -B add additional backend 563 | -a match files and directories 564 | -d match directories only 565 | -f match files only 566 | -r match by rank only 567 | -t match by recent access only 568 | -R reverse listing order 569 | -h show a brief help message 570 | -[0-9] select the nth entry 571 | 572 | fasd [-A|-D] [paths ...] 573 | -A add paths 574 | -D delete paths" >&2 && return;; 575 | esac; o="${o#?}"; done;; 576 | *) fnd="$fnd $1"; last="$1";; 577 | esac; shift; done 578 | 579 | # guess whether the last query is selected from tab completion 580 | case $last in 581 | /?*) if [ -z "$show$lst" -a -${typ:-e} "$last" -a "$exec" ]; then 582 | $exec "$last" 583 | return 584 | fi;; 585 | esac 586 | 587 | local R; [ -z "$r" ] && R=r || R= # let $R be the opposite of $r 588 | fnd="${fnd# }" 589 | 590 | local res 591 | res="$(fasd --query 2>> "$_FASD_SINK")" # query the database 592 | [ $? -gt 0 ] && return 593 | if [ 0 -lt ${_fasd_i:-0} ] 2>> "$_FASD_SINK"; then 594 | res="$(printf %s\\n "$res" | sort -n${R} | \ 595 | sed -n "$_fasd_i"'s/^[^ ]*[ ]*//p')" 596 | elif [ "$interactive" ] || [ "$exec" -a -z "$fnd$lst$show" -a -t 1 ]; then 597 | if [ "$(printf %s "$res" | sed -n '$=')" -gt 1 ]; then 598 | res="$(printf %s\\n "$res" | sort -n${R})" 599 | printf %s\\n "$res" | sed = | sed 'N;s/\n/ /' | sort -nr >&2 600 | printf "> " >&2 601 | local i; read i; [ 0 -lt "${i:-0}" ] 2>> "$_FASD_SINK" || return 1 602 | fi 603 | res="$(printf %s\\n "$res" | sed -n "${i:-1}"'s/^[^ ]*[ ]*//p')" 604 | elif [ "$lst" ]; then 605 | [ "$res" ] && printf %s\\n "$res" | sort -n${r} | sed 's/^[^ ]*[ ]*//' 606 | return 607 | elif [ "$show" ]; then 608 | [ "$res" ] && printf %s\\n "$res" | sort -n${r} 609 | return 610 | elif [ "$fnd" ] && [ "$exec" -o ! -t 1 ]; then # exec or subshell 611 | res="$(printf %s\\n "$res" | sort -n | sed -n '$s/^[^ ]*[ ]*//p')" 612 | else # no args, show 613 | [ "$res" ] && printf %s\\n "$res" | sort -n${r} 614 | return 615 | fi 616 | if [ "$res" ]; then 617 | fasd --add "$res" 618 | [ -z "$exec" ] && exec='printf %s\n' 619 | $exec "$res" 620 | fi 621 | ;; 622 | esac 623 | } 624 | 625 | fasd --init env 626 | 627 | case $- in 628 | *i*) ;; # assume being sourced, do nothing 629 | *) # assume being executed as an executable 630 | if [ -x "$_FASD_SHELL" -a -z "$_FASD_SET" ]; then 631 | _FASD_SET=1 exec $_FASD_SHELL "$0" "$@" 632 | else 633 | fasd "$@" 634 | fi;; 635 | esac 636 | 637 | -------------------------------------------------------------------------------- /fasd.1: -------------------------------------------------------------------------------- 1 | .TH "FASD" "1" "Jul 16, 2012" "fasd user manual" "" 2 | .SH NAME 3 | .PP 4 | fasd \- quick access to files and directories 5 | .SH SYNOPSIS 6 | .PP 7 | fasd [options] [query ...] 8 | .PP 9 | [f|a|s|d|z] [options] [query ...] 10 | .PP 11 | fasd [\-A|\-D] [paths ...] 12 | .SH OPTIONS 13 | .IP 14 | .nf 15 | \f[C] 16 | \-s\ \ \ \ \ \ \ \ \ list\ paths\ with\ ranks 17 | \-l\ \ \ \ \ \ \ \ \ list\ paths\ without\ ranks 18 | \-i\ \ \ \ \ \ \ \ \ interactive\ mode 19 | \-e\ \ \ \ set\ command\ to\ execute\ on\ the\ result\ file 20 | \-b\ \ \ only\ use\ \ backend 21 | \-B\ \ \ add\ additional\ backend\ 22 | \-a\ \ \ \ \ \ \ \ \ match\ files\ and\ directories 23 | \-d\ \ \ \ \ \ \ \ \ match\ directories\ only 24 | \-f\ \ \ \ \ \ \ \ \ match\ files\ only 25 | \-r\ \ \ \ \ \ \ \ \ match\ by\ rank\ only 26 | \-t\ \ \ \ \ \ \ \ \ match\ by\ recent\ access\ only 27 | \-R\ \ \ \ \ \ \ \ \ reverse\ listing\ order 28 | \-h\ \ \ \ \ \ \ \ \ show\ a\ brief\ help\ message 29 | \-[0\-9]\ \ \ \ \ select\ the\ nth\ entry 30 | \f[] 31 | .fi 32 | .SH DESCRIPTION 33 | .PP 34 | Fasd keeps track of files and directories you access in your shell and 35 | gives you quick access to them. 36 | You can use fasd to reference files or directories by just a few key 37 | identifying characters. 38 | You can use fasd to boost your command line productivity by defining 39 | your own aliases to launch programs on files or directories. 40 | Fasd, by default, provides some basic aliases, including a shell 41 | function "z" that resembles the functionality of "z" and "autojump." 42 | .PP 43 | The name "fasd" comes from the default suggested aliases 44 | \f[C]f\f[](files), \f[C]a\f[](files/directories), 45 | \f[C]s\f[](show/search/select), \f[C]d\f[](directories). 46 | .PP 47 | Fasd ranks files and directories by "frecency," that is, by both 48 | "frequency" and "recency." The term "frecency" was first coined by 49 | Mozilla and used in Firefox. 50 | .SH EXAMPLES 51 | .IP 52 | .nf 53 | \f[C] 54 | z\ bundle 55 | f\ \-e\ vim\ nginx\ conf 56 | f\ \-i\ rc$ 57 | vi\ `f\ nginx\ conf` 58 | cp\ update.html\ `d\ www` 59 | open\ `sf\ pdf` 60 | \f[] 61 | .fi 62 | .SH SHELL INITIALIZATION 63 | .PP 64 | To get fasd working in a shell, some initialization code must be run. 65 | Put lines below in your POSIX compatible shell rc. 66 | .IP 67 | .nf 68 | \f[C] 69 | eval\ "$(fasd\ \-\-init\ auto)" 70 | \f[] 71 | .fi 72 | .PP 73 | This will setup a command hook that executes on every command and 74 | advanced tab completion for zsh and bash. 75 | .PP 76 | If you want more control over what gets into your shell environment, you 77 | can pass customized set of arguments to \f[C]fasd\ \-\-init\f[]. 78 | .IP 79 | .nf 80 | \f[C] 81 | zsh\-hook\ \ \ \ \ \ \ \ \ \ \ \ \ #\ define\ _fasd_preexec\ and\ add\ it\ to\ zsh\ preexec\ array 82 | zsh\-ccomp\ \ \ \ \ \ \ \ \ \ \ \ #\ zsh\ command\ mode\ completion\ definitions 83 | zsh\-ccomp\-install\ \ \ \ #\ setup\ command\ mode\ completion\ for\ zsh 84 | zsh\-wcomp\ \ \ \ \ \ \ \ \ \ \ \ #\ zsh\ word\ mode\ completion\ definitions 85 | zsh\-wcomp\-install\ \ \ \ #\ setup\ word\ mode\ completion\ for\ zsh 86 | bash\-hook\ \ \ \ \ \ \ \ \ \ \ \ #\ add\ hook\ code\ to\ bash\ $PROMPT_COMMAND 87 | bash\-ccomp\ \ \ \ \ \ \ \ \ \ \ #\ bash\ command\ mode\ completion\ definitions 88 | bash\-ccomp\-install\ \ \ #\ setup\ command\ mode\ completion\ for\ bash 89 | posix\-alias\ \ \ \ \ \ \ \ \ \ #\ define\ aliases\ that\ applies\ to\ all\ posix\ shells 90 | posix\-hook\ \ \ \ \ \ \ \ \ \ \ #\ setup\ $PS1\ hook\ for\ shells\ that\[aq]s\ posix\ compatible 91 | tcsh\-alias\ \ \ \ \ \ \ \ \ \ \ #\ define\ aliases\ for\ tcsh 92 | tcsh\-hook\ \ \ \ \ \ \ \ \ \ \ \ #\ setup\ tcsh\ precmd\ alias 93 | \f[] 94 | .fi 95 | .PP 96 | Example for a minimal zsh setup (no tab completion): 97 | .IP 98 | .nf 99 | \f[C] 100 | eval\ "$(fasd\ \-\-init\ posix\-alias\ zsh\-hook)" 101 | \f[] 102 | .fi 103 | .PP 104 | Note that this method will slightly increase your shell start\-up time, 105 | since calling binaries has overhead. 106 | You can cache fasd init code if you want minimal overhead. 107 | Example code for bash (to be put into .bashrc): 108 | .IP 109 | .nf 110 | \f[C] 111 | fasd_cache="$HOME/.fasd\-init\-bash" 112 | if\ [\ "$(command\ \-v\ fasd)"\ \-nt\ "$fasd_cache"\ \-o\ !\ \-s\ "$fasd_cache"\ ];\ then 113 | \ \ fasd\ \-\-init\ posix\-alias\ bash\-hook\ bash\-ccomp\ bash\-ccomp\-install\ >|\ "$fasd_cache" 114 | fi 115 | source\ "$fasd_cache" 116 | unset\ fasd_cache 117 | \f[] 118 | .fi 119 | .PP 120 | Optionally, if you can also source \f[C]fasd\f[] if you want 121 | \f[C]fasd\f[] to be a shell function instead of an executable. 122 | .PP 123 | You can tweak initialization code. 124 | For instance, if you want to use "c" instead of "z" to do directory 125 | jumping, you can use the alias below: 126 | .IP 127 | .nf 128 | \f[C] 129 | alias\ c=\[aq]fasd_cd\ \-d\[aq] 130 | #\ `\-d\[aq]\ option\ present\ for\ bash\ completion 131 | #\ function\ fasd_cd\ is\ defined\ in\ posix\-alias 132 | \f[] 133 | .fi 134 | .SH MATCHING 135 | .PP 136 | Fasd has three matching modes: default, case\-insensitive, and fuzzy. 137 | .PP 138 | For a given set of queries (the set of command\-line arguments passed to 139 | fasd), a path is a match if and only if: 140 | .IP "1." 3 141 | Queries match the path in order. 142 | .IP "2." 3 143 | The last query matches the last segment of the path. 144 | .PP 145 | If no match is found, fasd will try the same process ignoring case. 146 | If still no match is found, fasd will allow extra characters to be 147 | placed between query characters for fuzzy matching. 148 | .PP 149 | Tips: 150 | .IP \[bu] 2 151 | If you want your last query not to match the last segment of the path, 152 | append `/\[aq] as the last query. 153 | .IP \[bu] 2 154 | If you want your last query to match the end of the filename, append 155 | `$\[aq] to the last query. 156 | .SH COMPATIBILITY 157 | .PP 158 | Fasd\[aq]s basic functionalities are POSIX compliant, meaning that you 159 | should be able to use fasd in all POSIX compliant shells. 160 | Your shell need to support command substitution in $PS1 in order for 161 | fasd to automatically track your commands and files. 162 | This feature is not specified by the POSIX standard, but it\[aq]s 163 | nonetheless present in many POSIX compliant shells. 164 | In shells without prompt command or prompt command substitution (tcsh 165 | for instance), you can add entries manually with "fasd \-A". 166 | You are very welcomed to contribute shell initialization code for not 167 | yet supported shells. 168 | .SH TAB COMPLETION 169 | .PP 170 | Fasd offers two completion modes, command mode completion and word mode 171 | completion. 172 | Command mode completion works in bash and zsh. 173 | Word mode completion only works in zsh. 174 | .PP 175 | Command mode completion is just like completion for any other commands. 176 | It is triggered when you hit tab on a fasd command or its aliases. 177 | Under this mode your queries can be separated by a space. 178 | Tip: if you find that the completion result overwrites your queries, 179 | type an extra space before you hit tab. 180 | .PP 181 | Word mode completion can be triggered on \f[I]any\f[] command. 182 | Word completion is triggered by any command line argument that starts 183 | with "," (all), "f," (files), or "d," (directories), or that ends with 184 | ",," (all), ",,f" (files), or ",,d" (directories). 185 | Examples: 186 | .IP 187 | .nf 188 | \f[C] 189 | $\ vim\ ,rc,lo 190 | $\ vim\ /etc/rc.local 191 | 192 | $\ mv\ index.html\ d,www 193 | $\ mv\ index.html\ /var/www/ 194 | \f[] 195 | .fi 196 | .PP 197 | There are also three zle widgets: "fasd\-complete", "fasd\-complete\-f", 198 | "fasd\-complete\-d". 199 | You can bind them to keybindings you like: 200 | .IP 201 | .nf 202 | \f[C] 203 | bindkey\ \[aq]^X^A\[aq]\ fasd\-complete\ \ \ \ #\ C\-x\ C\-a\ to\ do\ fasd\-complete\ (files\ and\ directories) 204 | bindkey\ \[aq]^X^F\[aq]\ fasd\-complete\-f\ \ #\ C\-x\ C\-f\ to\ do\ fasd\-complete\-f\ (only\ files) 205 | bindkey\ \[aq]^X^D\[aq]\ fasd\-complete\-d\ \ #\ C\-x\ C\-d\ to\ do\ fasd\-complete\-d\ (only\ directories) 206 | \f[] 207 | .fi 208 | .SH BACKENDS 209 | .PP 210 | Fasd can take advantage of different sources of recent / frequent files. 211 | Most desktop environments (such as OS X and Gtk) and some editors (such 212 | as Vim) keep a list of accessed files. 213 | Fasd can use them as additional backends if the data can be converted 214 | into fasd\[aq]s native format. 215 | Below is a list of available backends. 216 | .IP \[bu] 2 217 | spotlight: OSX spotlight, provides entries that are changed today or 218 | opened within the past month 219 | .IP \[bu] 2 220 | recently\-used: GTK\[aq]s recently\-used file (Usually available on 221 | Linux) 222 | .IP \[bu] 2 223 | current: Provides everything in $PWD (whereever you are executing 224 | \f[C]fasd\f[]) 225 | .IP \[bu] 2 226 | viminfo: Vim\[aq]s editing history, useful if you want to define an 227 | alias just for editing things in vim 228 | .PP 229 | You can define your own backend by declaring a function by that name in 230 | your \f[C]\&.fasdrc\f[]. 231 | You can set default backend with \f[C]_FASD_BACKENDS\f[] variable in our 232 | \f[C]\&.fasdrc\f[]. 233 | .SH TWEAKS 234 | .PP 235 | Upon every execution, fasd will source "/etc/fasdrc" and "$HOME/.fasdrc" 236 | if they are present. 237 | Below are some variables you can set: 238 | .IP 239 | .nf 240 | \f[C] 241 | $_FASD_DATA 242 | Path\ to\ the\ fasd\ data\ file,\ default\ "$HOME/.fasd". 243 | 244 | $_FASD_BLACKLIST 245 | List\ of\ blacklisted\ strings.\ Commands\ matching\ them\ will\ not\ be\ processed. 246 | Default\ is\ "\-\-help". 247 | 248 | $_FASD_SHIFT 249 | List\ of\ all\ commands\ that\ needs\ to\ be\ shifted,\ defaults\ to\ "sudo\ busybox". 250 | 251 | $_FASD_IGNORE 252 | List\ of\ all\ commands\ that\ will\ be\ ignored,\ defaults\ to\ "fasd\ ls\ echo". 253 | 254 | $_FASD_TRACK_PWD 255 | Fasd\ defaults\ to\ track\ your\ "$PWD".\ Set\ this\ to\ 0\ to\ disable\ this\ behavior. 256 | 257 | $_FASD_AWK 258 | Which\ awk\ to\ use.\ fasd\ can\ detect\ and\ use\ a\ compatible\ awk. 259 | 260 | $_FASD_SINK 261 | File\ to\ log\ all\ STDERR\ to,\ defaults\ to\ "/dev/null". 262 | 263 | $_FASD_MAX 264 | Max\ total\ score\ /\ weight,\ defaults\ to\ 2000. 265 | 266 | $_FASD_SHELL 267 | Which\ shell\ to\ execute.\ Some\ shells\ will\ run\ faster\ than\ others.\ fasd 268 | runs\ faster\ with\ dash\ and\ ksh\ variants. 269 | 270 | $_FASD_BACKENDS 271 | Default\ backends. 272 | 273 | $_FASD_RO 274 | If\ set\ to\ any\ non\-empty\ string,\ fasd\ will\ not\ add\ or\ delete\ entries\ from 275 | database.\ You\ can\ set\ and\ export\ this\ variable\ from\ command\ line. 276 | 277 | $_FASD_FUZZY 278 | Level\ of\ "fuzziness"\ when\ doing\ fuzzy\ matching.\ More\ precisely,\ the\ number\ of 279 | characters\ that\ can\ be\ skipped\ to\ generate\ a\ match.\ Set\ to\ empty\ or\ 0\ to 280 | disable\ fuzzy\ matching.\ Default\ value\ is\ 2. 281 | 282 | $_FASD_VIMINFO 283 | Path\ to\ .viminfo\ file\ for\ viminfo\ backend,\ defaults\ to\ "$HOME/.viminfo" 284 | 285 | $_FASD_RECENTLY_USED_XBEL 286 | Path\ to\ XDG\ recently\-used.xbel\ file\ for\ recently\-used\ backend,\ defaults\ to 287 | "$HOME/.local/share/recently\-used.xbel" 288 | \f[] 289 | .fi 290 | .SH DEBUGGING 291 | .PP 292 | Fasd is hosted on GitHub: https://github.com/clvv/fasd 293 | .PP 294 | If fasd does not work as expected, please file a bug report on GitHub 295 | describing the unexpected behavior along with your OS version, shell 296 | version, awk version, sed version, and a log file. 297 | .PP 298 | You can set \f[C]_FASD_SINK\f[] in your \f[C]\&.fasdrc\f[] to obtain a 299 | log. 300 | .IP 301 | .nf 302 | \f[C] 303 | _FASD_SINK="$HOME/.fasd.log" 304 | \f[] 305 | .fi 306 | .SH COPYING 307 | .PP 308 | Fasd is originally written based on code from z 309 | (https://github.com/rupa/z) by rupa deadwyler under the WTFPL license. 310 | Most if not all of the code has been rewritten. 311 | Fasd is licensed under the "MIT/X11" license. 312 | .SH AUTHORS 313 | Wei Dai . 314 | -------------------------------------------------------------------------------- /fasd.1.md: -------------------------------------------------------------------------------- 1 | % FASD(1) fasd user manual 2 | % Wei Dai 3 | % Jul 16, 2012 4 | 5 | # NAME 6 | 7 | fasd - quick access to files and directories 8 | 9 | # SYNOPSIS 10 | 11 | fasd [options] [query ...] 12 | 13 | [f|a|s|d|z] [options] [query ...] 14 | 15 | fasd [-A|-D] [paths ...] 16 | 17 | # OPTIONS 18 | 19 | -s list paths with ranks 20 | -l list paths without ranks 21 | -i interactive mode 22 | -e set command to execute on the result file 23 | -b only use backend 24 | -B add additional backend 25 | -a match files and directories 26 | -d match directories only 27 | -f match files only 28 | -r match by rank only 29 | -t match by recent access only 30 | -R reverse listing order 31 | -h show a brief help message 32 | -[0-9] select the nth entry 33 | 34 | # DESCRIPTION 35 | 36 | Fasd keeps track of files and directories you access in your shell and gives you 37 | quick access to them. You can use fasd to reference files or directories by just 38 | a few key identifying characters. You can use fasd to boost your command line 39 | productivity by defining your own aliases to launch programs on files or 40 | directories. Fasd, by default, provides some basic aliases, including a shell 41 | function "z" that resembles the functionality of "z" and "autojump." 42 | 43 | The name "fasd" comes from the default suggested aliases `f`(files), 44 | `a`(files/directories), `s`(show/search/select), `d`(directories). 45 | 46 | Fasd ranks files and directories by "frecency," that is, by both "frequency" 47 | and "recency." The term "frecency" was first coined by Mozilla and used in 48 | Firefox. 49 | 50 | # EXAMPLES 51 | 52 | z bundle 53 | f -e vim nginx conf 54 | f -i rc$ 55 | vi `f nginx conf` 56 | cp update.html `d www` 57 | open `sf pdf` 58 | 59 | # SHELL INITIALIZATION 60 | 61 | To get fasd working in a shell, some initialization code must be run. Put 62 | lines below in your POSIX compatible shell rc. 63 | 64 | eval "$(fasd --init auto)" 65 | 66 | This will setup a command hook that executes on every command and advanced tab 67 | completion for zsh and bash. 68 | 69 | If you want more control over what gets into your shell environment, you can 70 | pass customized set of arguments to `fasd --init`. 71 | 72 | zsh-hook # define _fasd_preexec and add it to zsh preexec array 73 | zsh-ccomp # zsh command mode completion definitions 74 | zsh-ccomp-install # setup command mode completion for zsh 75 | zsh-wcomp # zsh word mode completion definitions 76 | zsh-wcomp-install # setup word mode completion for zsh 77 | bash-hook # add hook code to bash $PROMPT_COMMAND 78 | bash-ccomp # bash command mode completion definitions 79 | bash-ccomp-install # setup command mode completion for bash 80 | posix-alias # define aliases that applies to all posix shells 81 | posix-hook # setup $PS1 hook for shells that's posix compatible 82 | tcsh-alias # define aliases for tcsh 83 | tcsh-hook # setup tcsh precmd alias 84 | 85 | Example for a minimal zsh setup (no tab completion): 86 | 87 | eval "$(fasd --init posix-alias zsh-hook)" 88 | 89 | Note that this method will slightly increase your shell start-up time, since 90 | calling binaries has overhead. You can cache fasd init code if you want 91 | minimal overhead. Example code for bash (to be put into .bashrc): 92 | 93 | fasd_cache="$HOME/.fasd-init-bash" 94 | if [ "$(command -v fasd)" -nt "$fasd_cache" -o ! -s "$fasd_cache" ]; then 95 | fasd --init posix-alias bash-hook bash-ccomp bash-ccomp-install >| "$fasd_cache" 96 | fi 97 | source "$fasd_cache" 98 | unset fasd_cache 99 | 100 | Optionally, if you can also source `fasd` if you want `fasd` to be a shell 101 | function instead of an executable. 102 | 103 | You can tweak initialization code. For instance, if you want to use "c" 104 | instead of "z" to do directory jumping, you can use the alias below: 105 | 106 | alias c='fasd_cd -d' 107 | # `-d' option present for bash completion 108 | # function fasd_cd is defined in posix-alias 109 | 110 | # MATCHING 111 | 112 | Fasd has three matching modes: default, case-insensitive, and fuzzy. 113 | 114 | For a given set of queries (the set of command-line arguments passed to fasd), 115 | a path is a match if and only if: 116 | 117 | 1. Queries match the path in order. 118 | 2. The last query matches the last segment of the path. 119 | 120 | If no match is found, fasd will try the same process ignoring case. If still no 121 | match is found, fasd will allow extra characters to be placed between query 122 | characters for fuzzy matching. 123 | 124 | Tips: 125 | 126 | * If you want your last query not to match the last segment of the path, append 127 | `/' as the last query. 128 | * If you want your last query to match the end of the filename, append `$' to 129 | the last query. 130 | 131 | # COMPATIBILITY 132 | 133 | Fasd's basic functionalities are POSIX compliant, meaning that you should be 134 | able to use fasd in all POSIX compliant shells. Your shell need to support 135 | command substitution in $PS1 in order for fasd to automatically track your 136 | commands and files. This feature is not specified by the POSIX standard, but 137 | it's nonetheless present in many POSIX compliant shells. In shells without 138 | prompt command or prompt command substitution (tcsh for instance), you can add 139 | entries manually with "fasd -A". You are very welcomed to contribute shell 140 | initialization code for not yet supported shells. 141 | 142 | # TAB COMPLETION 143 | 144 | Fasd offers two completion modes, command mode completion and word mode 145 | completion. Command mode completion works in bash and zsh. Word mode 146 | completion only works in zsh. 147 | 148 | Command mode completion is just like completion for any other commands. It is 149 | triggered when you hit tab on a fasd command or its aliases. Under this mode 150 | your queries can be separated by a space. Tip: if you find that the completion 151 | result overwrites your queries, type an extra space before you hit tab. 152 | 153 | Word mode completion can be triggered on *any* command. Word completion is 154 | triggered by any command line argument that starts with "," (all), "f," 155 | (files), or "d," (directories), or that ends with ",," (all), ",,f" (files), 156 | or ",,d" (directories). Examples: 157 | 158 | $ vim ,rc,lo 159 | $ vim /etc/rc.local 160 | 161 | $ mv index.html d,www 162 | $ mv index.html /var/www/ 163 | 164 | There are also three zle widgets: "fasd-complete", "fasd-complete-f", 165 | "fasd-complete-d". You can bind them to keybindings you like: 166 | 167 | bindkey '^X^A' fasd-complete # C-x C-a to do fasd-complete (files and directories) 168 | bindkey '^X^F' fasd-complete-f # C-x C-f to do fasd-complete-f (only files) 169 | bindkey '^X^D' fasd-complete-d # C-x C-d to do fasd-complete-d (only directories) 170 | 171 | # BACKENDS 172 | 173 | Fasd can take advantage of different sources of recent / frequent files. Most 174 | desktop environments (such as OS X and Gtk) and some editors (such as Vim) keep 175 | a list of accessed files. Fasd can use them as additional backends if the data 176 | can be converted into fasd's native format. Below is a list of available 177 | backends. 178 | 179 | * spotlight: OSX spotlight, provides entries that are changed today or opened 180 | within the past month 181 | 182 | * recently-used: GTK's recently-used file (Usually available on Linux) 183 | 184 | * current: Provides everything in $PWD (whereever you are executing `fasd`) 185 | 186 | * viminfo: Vim's editing history, useful if you want to define an alias just 187 | for editing things in vim 188 | 189 | You can define your own backend by declaring a function by that name in your 190 | `.fasdrc`. You can set default backend with `_FASD_BACKENDS` variable in our 191 | `.fasdrc`. 192 | 193 | # TWEAKS 194 | 195 | Upon every execution, fasd will source "/etc/fasdrc" and "$HOME/.fasdrc" if 196 | they are present. Below are some variables you can set: 197 | 198 | $_FASD_DATA 199 | Path to the fasd data file, default "$HOME/.fasd". 200 | 201 | $_FASD_BLACKLIST 202 | List of blacklisted strings. Commands matching them will not be processed. 203 | Default is "--help". 204 | 205 | $_FASD_SHIFT 206 | List of all commands that needs to be shifted, defaults to "sudo busybox". 207 | 208 | $_FASD_IGNORE 209 | List of all commands that will be ignored, defaults to "fasd ls echo". 210 | 211 | $_FASD_TRACK_PWD 212 | Fasd defaults to track your "$PWD". Set this to 0 to disable this behavior. 213 | 214 | $_FASD_AWK 215 | Which awk to use. fasd can detect and use a compatible awk. 216 | 217 | $_FASD_SINK 218 | File to log all STDERR to, defaults to "/dev/null". 219 | 220 | $_FASD_MAX 221 | Max total score / weight, defaults to 2000. 222 | 223 | $_FASD_SHELL 224 | Which shell to execute. Some shells will run faster than others. fasd 225 | runs faster with dash and ksh variants. 226 | 227 | $_FASD_BACKENDS 228 | Default backends. 229 | 230 | $_FASD_RO 231 | If set to any non-empty string, fasd will not add or delete entries from 232 | database. You can set and export this variable from command line. 233 | 234 | $_FASD_FUZZY 235 | Level of "fuzziness" when doing fuzzy matching. More precisely, the number of 236 | characters that can be skipped to generate a match. Set to empty or 0 to 237 | disable fuzzy matching. Default value is 2. 238 | 239 | $_FASD_VIMINFO 240 | Path to .viminfo file for viminfo backend, defaults to "$HOME/.viminfo" 241 | 242 | $_FASD_RECENTLY_USED_XBEL 243 | Path to XDG recently-used.xbel file for recently-used backend, defaults to 244 | "$HOME/.local/share/recently-used.xbel" 245 | 246 | # DEBUGGING 247 | 248 | Fasd is hosted on GitHub: https://github.com/clvv/fasd 249 | 250 | If fasd does not work as expected, please file a bug report on GitHub describing 251 | the unexpected behavior along with your OS version, shell version, awk version, 252 | sed version, and a log file. 253 | 254 | You can set `_FASD_SINK` in your `.fasdrc` to obtain a log. 255 | 256 | _FASD_SINK="$HOME/.fasd.log" 257 | 258 | # COPYING 259 | 260 | Fasd is originally written based on code from z (https://github.com/rupa/z) by 261 | rupa deadwyler under the WTFPL license. Most if not all of the code has been 262 | rewritten. Fasd is licensed under the "MIT/X11" license. 263 | 264 | --------------------------------------------------------------------------------