Fuzzy path searching for shells
Fuzzy file or path searcher in the shell which provides path completion similar to the ctrlp plugin for vim. Start a command and then hit Ctrl+p to see a list of possible paths. Enter search terms to narrow down the list and then select the appropriate completion using your arrow keys or Ctrl+j/k.
fzsl uses a single matching algorithm but provides the user with a wide variety of ways to influence how file scanning is performed as it is by far the most intensive part of this process. Scanners are selected by first checking if they are valid for the current working directory and then ranked by a user-selected priority.
All configuration of fzsl is done in an ini style which is interpreted by the python ConfigParser module. Each section defines a new scanner with the section title used as the scanner name. Configuration is read from ~/.config/fzslrc if it exists, if not fzsl will fall back to /usr/share/fzsl/fzsl.conf. The default configuration that ships with fzsl contains full documentation for all scanner types and should be referenced. It currently handles standard directories, git checkouts and scanning for only directories. It also has a number of examples for how to define additional scanners. Scanners with a priority less than 0 can only be used by passing the scanner name to fzsl with the –rule argument.
Simple scanners use shell commands and or functions to check if they are suitable and to scan for files. They are very easy to configure and should support the vast majority of use cases. Simple scanners are defined by setting two shell commands that should be executed. The first detects if the scanner is suitable for the current working directory and the second performs the scanning. Simple scanners should also set a priority for ranking if more than one scanner is valid. If the priority is not specified, it defaults to 0. Finally, a cache and root path for the scanning command can be set. For example:
# Standard git rule [git] type = simple detect_cmd = git rev-parse cmd = git ls-files priority = 10 # If the directory has a large number of files such that scanning # takes too long, a cache can be used. The cache can be regenerated # by an external script or by pressing F5 or ctrl+r in the UI. [linux] type = simple root_path = /usr/src/linux cmd = find . cache = ~/.fzsl-cache/linux
The only requirement for the cmd and detect_cmd is that they are available in your standard login shell. For instance, if using bash, they should be defined in ~/.bash_profile:
[shell-function-scanner] type = simple detect_cmd = my_detect_function cmd = my_scanning_function priority = 100
The root path has two possible uses. First, if the current working directory is a subdirectory of the root path, the scanner will be considered suitable for use when scanning. Second, if the root_path is specified along with detect_cmd, then the root_path will be used as the current working directory when executing the detect_cmd.
To use the stdout of a command rather than a fixed string as the root_path, preface the root_command with a !. For example,:
root_path = !echo "my/root/path"
Python scanners offer a deeper level of customization for scanners. They must derive from the fzsl.Scanner class. See pydoc fzsl.Scanner. The priority attribute should be set and the methods is_suitable(self, path) and scan(self, path=None, rescan=False) need to be defined. Any caching is left up to the implementor. Any extra options set in the scanner configuration are passed to the scanners __init__ method as keyword arguments. Perhaps the best example is to show how one could create a Simple Scanner using fzsl itself:
# Example plugin file that loads the default simple scanner. [default-via-plugin] type = python path = /usr/lib/python2.7/site-packages/fzsl/scanner.py object = SimpleScanner # The following are passed as keyword arguments to the # RuleScanner constructor cmd = find . priority = 0
fzsl can be installed via pip or by simply running the included setup.py script:
pip install fzsl # OR python setup.py install --root <destination> --record installed_files.txt
fzsl will not modify your shell by default. It is up to you to source the included /usr/share/fzsl/fzsl.bash. It defines two functions that will add fzsl functionality directly to your shell. See the script for further documentation.
fzsl will launch a ncurses interface when prompted to start matching in the current directory. Once the file list has been populated by the scanner, the user can begin to input characters to be fuzzily matched against the scanned paths. As the query is updated, the list of available paths will be trimmed. A portion of each path will be highlighted to represent which part of it was best matched against the query. The user can also move the cursor around to support editing of the query. The following keybindings are defined.