- Notifications
You must be signed in to change notification settings - Fork1
A descendant of fasd offering faster performance on Windows/Cygwin and (eventually) more...
License
clarity20/fasder
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A descendant of Wei Dai'sfasd project offeringimproved performance on Cygwin/Windows and (eventually) more...
Fasder (approximate pronunciation "faster") is a command-line productivitybooster that offers quick jumping and naming access to files and directoriesat the POSIX shell prompt.Fasder tracks your command history to give priorityaccess to the files you've accessed most often or most recently.Fasder is a direct descendant offasd which wasinspired by tools likeautojump,z andv.
fasder (and its ancestorfasd) takes its name from the convenient defaultaliases that provide most offasder's functionality:
f
(files),a
(all, i.e. files/directories)s
(show/search/select interactively)d
(directories).
Fasder ranks files and directories by "frecency," that is, by a combination of"frequency" and "recency." The term "frecency" was coined by Mozilla and isused in Firefox(link).
If you use your shell to navigate and launch applications,fasder can help youdo so more efficiently. Withfasder, you can open files from any directory.Fasder can find a "frecent" file or directory and open it with the command youspecify. Here are some scenarios where thefasder command on the leftwill expand to the shell command on the right. Pretty magical, huh?
v def conf => vim /some/awkward/path/to/type/default.conf j abc => cd /hell/of/a/awkward/path/to/get/to/abcdef m movie => mplayer /whatever/whatever/whatever/awesome_movie.mp4 o eng paper => xdg-open /you/dont/remember/where/english_paper.pdf vim `f rc lo` => vim /etc/rc.local vim `f rc conf` => vim /etc/rc.conf
Fasder comes with some useful aliases by default:
alias a='fasder -a'# anyalias s='fasder -si'# show / search / selectalias d='fasder -d'# directoryalias f='fasder -f'# filealias sd='fasder -sid'# interactive directory selectionalias sf='fasder -sif'# interactive file selectionalias z='fasder_cd -d'# cd, same functionality as j in autojumpalias zz='fasder_cd -d -i'# cd with interactive selection
Fasder will smartly detect when to display a list of files or just the bestmatch. For instance, when you call fasder in a subshell with some searchparameters, fasder will only return the best match. This enables you to do:
mv update.html`d www`cp`f mov`.
Fasder is a self-contained POSIX shell script that can be either sourced orexecuted. A Makefile is provided to installfasder
andfasder.1
to thedesired places.
System-wide install:
make install
Install to $HOME:
PREFIX=$HOME make install
Or alternatively you can just copyfasder
anywhere you like (preferablyunder some directory in your$PATH
).
To get fasder working in a shell, some initialization code must be run. Put thefollowing line in your shell rc:
eval"$(fasder --init auto)"
This will setup a command hook that executes on every command as well asadvanced tab completion for zsh and bash.
If you want more control over what gets into your shell environment, you canpass a customized set of arguments tofasder --init
.
zsh-hook # define _fasder_preexec and add it to zsh preexec arrayzsh-ccomp # zsh command mode completion definitionszsh-ccomp-install # setup command mode completion for zshzsh-wcomp # zsh word mode completion definitionszsh-wcomp-install # setup word mode completion for zshbash-hook # add hook code to bash $PROMPT_COMMANDbash-ccomp # bash command mode completion definitionsbash-ccomp-install # setup command mode completion for bashposix-alias # define aliases that applies to all posix shellsposix-hook # setup $PS1 hook for shells that's posix compatibletcsh-alias # define aliases for tcshtcsh-hook # setup tcsh precmd alias
Example for a minimal zsh setup (no tab completion):
eval"$(fasder --init posix-alias zsh-hook)"
Note that this method will slightly increase your shell start-up time, sincecalling binaries has overhead. You can cache fasder init code if you want minimaloverhead. Example code for bash (to be put into .bashrc):
fasd_cache="$HOME/.fasder-init-bash"if ["$(command -v fasder)"-nt"$fasd_cache"-o!-s"$fasd_cache" ];then fasder --init posix-alias bash-hook bash-ccomp bash-ccomp-install>|"$fasd_cache"fisource"$fasd_cache"unset fasd_cache
Optionally, you can also sourcefasder
if you wantfasder
to be a shellfunction instead of an executable.
You can tweak the initialization code. For instance, if you want to use "c"instead of "z" to do directory jumping, you can use the alias below:
alias c='fasder_cd -d'# `-d` option present for bash completion# function fasder_cd is defined in posix-alias
After you install fasder, warm up the fasder database by opening some files(with any program) as youcd
around your filesystem. Then try some of theexamples below.
f foo# list frecent files matching fooa foo bar# list frecent files and directories matching foo and barf js$# list frecent files that ends in jsf -e vim foo# run vim on the most frecent file matching foomplayer`f bar`# run mplayer on the most frecent file matching barz foo# cd into the most frecent directory matching fooopen`sf pdf`# interactively select a file matching pdf and launch `open`
You can add your own aliases to fully utilize the power of fasder. Here aresome examples to get you started:
alias v='f -e vim'# quick opening files with vimalias m='f -e mplayer'# quick opening files with mplayeralias o='a -e xdg-open'# quick opening files with xdg-open
If you're using bash, you have to call_fasder_bash_hook_cmd_complete
to makecompletion work. For instance:
_fasder_bash_hook_cmd_complete v m j o
You can select an entry in the list of matching files.
Fasder has three matching modes: default, case-insensitive, and fuzzy.
For a given set of queries (groups of command-line arguments passed to fasder),a pathname is a match if and only if:
- Queries match the pathin order.
- The last query matches thelast segment of the path.
If no match is found, fasder will try the same process ignoring case. Failingthis, fasder will allow extra characters to be placed between querycharacters for fuzzy matching.
Tips:
- If you want your last query not to match the last segment of the path, append
/
to the last query. - If you want your last query to match the end of the filename, append
$
tothe last query.
When you initialize the fasder system (typically through your shell configscripts), fasder creates a hook function which will be executed afterevery shell command. The hook will scan your commands for fileand directory names and add them to its database.
Fasder's basic functionalities are POSIX compliant, meaning that you should beable touse fasder in all POSIX compliant shells. Your shell needs to supportcommand substitution in$PS1
in order to automatically track yourcommands and files. This feature is not specified by the POSIX standard, butis present in many POSIX-compliant shells. In shells withoutprompt command or prompt command substitution (csh for instance), you can addentries manually withfasder -A
. You are most welcome to contribute shellinitialization code for shells not yet supported.
Fasder has been tested on the following shells: bash, zsh, mksh, pdksh, dash,busybox ash, FreeBSD 9 /bin/sh and OpenBSD /bin/sh.
Fasder is written in bash-4.1; you need a bash interpreter at least as new.Basically, we've traded in the POSIX compatibility offasd for Bash's greaterrange of built-in features to "squeeze" the script for faster performance.
fasder [options] [query ...][f|a|s|d|z] [options] [query ...] options: -s list paths with scores -l list paths without scores -i interactive mode -e <cmd> set command to execute on the result file -b <name> only use <name> backend -B <name> add additional backend <name> -a match files and directories -d match directories only -f match files only -r match by rank only -t match by recent access only -R reverse listing order -h show a brief help message -[0-9] select the nth entryfasder [-A|-D] [paths ...] -A add paths -D delete paths
Fasder offers two completion modes: command completion and wordcompletion. Command completion works in bash and zsh. Wordcompletion only works in zsh.
Command completion is just like completion for any other command. It istriggered when you hit tab on afasd
command or its aliases. Under this modeyour queries can be separated by a space. Tip: if you find that the completionresult overwrites your queries, type an extra space before you hit tab.
Word completion can be triggered onany command. Word completion istriggered by any command line argument that starts with,
(all),f,
(files), ord,
(directories), or that ends with,,
(all),,,f
(files), or,,d
(directories). Examples:
$ vim ,rc,lo<Tab>$ vim /etc/rc.local$ mv index.html d,www<Tab>$ mv index.html /var/www/
There are also three zle widgets:fasder-complete
,fasder-complete-f
,fasder-complete-d
. You can bind them to any keybindings you like:
bindkey'^X^A' fasder-complete# C-x C-a to do fasder-complete (files and directories)bindkey'^X^F' fasder-complete-f# C-x C-f to do fasder-complete-f (only files)bindkey'^X^D' fasder-complete-d# C-x C-d to do fasder-complete-d (only directories)
Fasder can take advantage of different sources of recent / frequent files. Mostdesktop environments (such as OS X and Gtk) and some editors (such as Vim) keepa list of accessed files. Fasder can use them as additional backends if the datacan be converted into fasder's native format. Below is a list of availablebackends.
`spotlight`OSX spotlight, provides entries that were changed today or opened within thepast month`recently-used`GTK's recently-used file (Usually available on Linux)`current`Provides everything in $PWD (wherever you are executing `fasder`)`viminfo`Vim's editing history, useful if you want to define an alias just for editingthings in vim
You can define your own backend by declaring a function by that name in your.fasdrc
. You can set default backend with_FASD_BACKENDS
variable in your.fasdrc
.
Fasder can mimicv's behavior by this alias:
alias v='f -t -e vim -b viminfo'
The following shell variables can be set before sourcingfasder
. You can set themin$HOME/.fasdrc
$_FASD_DATAPath to the fasder data file, default "$HOME/.fasd".$_FASD_BLACKLISTList of "blacklisted" strings. Commands matching them will not be processed.Default is "--help".$_FASD_SHIFTList of all command names that need to be shifted; defaults to "sudo busybox".$_FASD_IGNOREList of all commands that will be ignored; defaults to "fasder ls echo".$_FASD_TRACK_PWDFasder tracks your "$PWD" by default. Set this to 0 to disable this behavior.$_FASD_AWKThe awk program to use. Fasder can detect and use a compatible awk.$_FASD_SINKLog file to capture the standard error; defaults to "/dev/null".$_FASD_MAXMaximum total score / weight; defaults to 2000.$_FASD_SHELLThe shell to execute. Some shells will run faster than others. fasderruns faster with dash and ksh variants.$_FASD_BACKENDSDefault backends. (See the "backends" section above.)$_FASD_ROIf set to any non-empty string, fasder will not add or delete entries fromthe database. You can set and export this variable from the command line.$_FASD_FUZZYLevel of "fuzziness" when doing fuzzy matching. More precisely, the number ofcharacters that can be skipped to generate a match. Set to empty or 0 todisable fuzzy matching. Default value is 2.$_FASD_VIMINFOPath to .viminfo file for viminfo backend; defaults to "$HOME/.viminfo"$_FASD_RECENTLY_USED_XBELPath to XDG recently-used.xbel file for recently-used backend, defaults to"$HOME/.local/share/recently-used.xbel"
If fasder does not work as expected, please file a bug report describing theunexpected behavior along with your OS version, shell version, awk version, sedversion, and a log file.
You can set_FASD_SINK
in your.fasdrc
to obtain a log.
_FASD_SINK="$HOME/.fasd.log"
Fasder is adapted from Wei Dai'sfasd project.Fasd is based on code fromz byrupa deadwyler under the WTFPL license. Most if not all of the code has beenrewritten. Fasder is licensed under the "MIT/X11" license.
Thoughts about a faster "fasder"
- Discuss the optimization strategies employed.
- Discuss the remaining bottlenecks in the prompt hook: the call to mapfile,the "heaviness" of forking a process under Cygwin, and the extra burden whencontext-switching into a Cygwin shell (especially the DLLs) from the outside.
- Optimization work thus far has focused on the prompt hook and the
--add
and--query
options. For the other options, there is still plenty of low-hangingfruit. - There are many style issues: Comments and variable names can be made better,for example. Sub-functions can be extracted. Low-hanging fruit here too.
- Implement a --clean option to delete duplicate entries and entries no longerpresent in the filesystem
- Inventory the open issues and PRs of the original fasd projectfor anything we might wish to address here.
- Develop a more thorough, systematic testing process. There are two classes of use cases:(1) the hidden action of the _fasder_prompt_func (the prompt hook) and(2) the explicit invocation of fasder or its short aliases. Regarding the former,the script's dependency on a
PROMPT_COMMAND
whose exact behaviorchanges whenever we edit the script makes testing challenging; the situation is akin tothe observer effect familiar to physicists. As a workaround, we couldstructure our test rig to invoke "fasder --proc " directly for each testcase while we monitor the effects this has on a suitably mocked-up data file.OTOH, the "type 2" use cases wherein fasder is explicitly called should be easier to test. - The original fasd contains notes about downloading it through package managersor the project website. Consider pursuing either or both of these for fasder.