{"id":13539646,"url":"https://github.com/lincheney/fzf-tab-completion","last_synced_at":"2025-04-02T06:31:11.467Z","repository":{"id":44618102,"uuid":"96753421","full_name":"lincheney/fzf-tab-completion","owner":"lincheney","description":"Tab completion using fzf","archived":false,"fork":false,"pushed_at":"2024-11-30T03:19:52.000Z","size":353,"stargazers_count":661,"open_issues_count":18,"forks_count":42,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-11-30T04:20:11.897Z","etag":null,"topics":["bash","completion","fzf","readline","rust","zsh"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lincheney.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-10T08:19:52.000Z","updated_at":"2024-11-30T03:19:55.000Z","dependencies_parsed_at":"2024-01-07T11:23:19.130Z","dependency_job_id":"bf76b9ff-dcfc-49f8-b087-749c7bb3af20","html_url":"https://github.com/lincheney/fzf-tab-completion","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lincheney%2Ffzf-tab-completion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lincheney%2Ffzf-tab-completion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lincheney%2Ffzf-tab-completion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lincheney%2Ffzf-tab-completion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lincheney","download_url":"https://codeload.github.com/lincheney/fzf-tab-completion/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246767836,"owners_count":20830564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","completion","fzf","readline","rust","zsh"],"created_at":"2024-08-01T09:01:29.929Z","updated_at":"2025-04-02T06:31:11.459Z","avatar_url":"https://github.com/lincheney.png","language":"Shell","funding_links":[],"categories":["Completions","Shell","bash","\u003ca name=\"utility\"\u003e\u003c/a\u003eUtilities"],"sub_categories":["ZSH on Windows"],"readme":"# fzf-tab-completion\n\nTab completion using fzf in zsh, bash, GNU readline apps (e.g. `python`, `php -a` etc.)\n\nThis is distinct from\n[fzf's own implementation for completion](https://github.com/junegunn/fzf#fuzzy-completion-for-bash-and-zsh),\nin that it works _with_ the existing completion mechanisms\nrather than [creating a new mechanism](https://github.com/junegunn/fzf/wiki/Examples-(completion)).\n\n## Example\n\u003cdetails\u003e\u003csummary\u003eClick here to show screencast\u003c/summary\u003e\n\n![Example](./example.svg)\n\u003c/details\u003e\n\n## Installation\n\n1. You need to [install fzf](https://github.com/junegunn/fzf#installation) first.\n1. If you are using OSX you may need to install some additional things:\n    * e.g. `brew install gawk grep gnu-sed coreutils`\n1. Clone this repository: `git clone https://github.com/lincheney/fzf-tab-completion ...`\n    * you can also choose to download only the scripts you need, up to you.\n1. Follow instructions on how to set up for:\n    * [zsh](#zsh)\n    * [bash](#bash)\n    * [readline](#readline)\n    * [nodejs](#nodejs-repl)\n    * [python3](#python3)\n1. The following environment variables are supported, just as in fzf's \"vanilla\" completion.\n    * `$FZF_TMUX_HEIGHT`\n    * `$FZF_COMPLETION_OPTS`\n    * `$FZF_DEFAULT_OPTS`\n\n    See also \u003chttps://github.com/junegunn/fzf#settings\u003e\n\n    Avoid changing these `fzf` flags: `-n`, `--nth`, `--with-nth`, `-d`\n\n## zsh\n\nAdd to your `~/.zshrc`:\n```bash\nsource /path/to/fzf-tab-completion/zsh/fzf-zsh-completion.sh\nbindkey '^I' fzf_completion\n```\nIf you have also enabled fzf's zsh completion, then the `bindkey` line is optional.\n\nNote that this does not provide `**`-style triggers,\nyou will need to enable fzf's zsh completion _as well_.\n\n#### --tiebreak=chunk\n\nThe default `fzf` tiebreak setting is line: `Prefers line with shorter length`.\nThe length of the zsh display strings may skew the ordering of the results even though they are not part of the match.\nYou may find that adding the `fzf` flag `--tiebreak=chunk` to the environment variable `$FZF_COMPLETION_OPTS` provides better behaviour.\n\n#### tmux\n\n`$FZF_TMUX_OPTS` is respected same as in [fzf](https://github.com/junegunn/fzf#key-bindings-for-command-line)\nhowever you must have fzf's keybindings enabled as well.\n\n#### Searching display strings\n\nBy default, display strings are shown but cannot be searched in fzf.\nThis is configurable via `zstyle`:\n```bash\n# only for git\nzstyle ':completion:*:*:git:*' fzf-search-display true\n# or for everything\nzstyle ':completion:*' fzf-search-display true\n```\n\n#### Specifying keybindings\n\nYou can specify `fzf` keybindings to execute shell commands *after* `fzf` has closed.\nThis is configurable via the `fzf-completion-keybindings` zstyle.\n\nKeybinds look like: `KEY:SCRIPT`\nWhen `KEY` is pressed, `fzf` will *exit* and the zsh `SCRIPT` will run.\nIf the keybind is given in the form `KEY:accept:SCRIPT` then the selected matches will also be completed before `SCRIPT` is run.\n`KEY` is any valid `fzf` key.\n\nThere is an additional function `repeat-fzf-completion` that can be called in the `SCRIPT` to retrigger `fzf` completion.\n\nNo keybinds are configured by default.\n\n```bash\n# press ctrl-r to repeat completion *without* accepting i.e. reload the completion\n# press right to accept the completion and retrigger it\n# press alt-enter to accept the completion and run it\nkeys=(\n    ctrl-r:'repeat-fzf-completion'\n    right:accept:'repeat-fzf-completion'\n    alt-enter:accept:'zle accept-line'\n)\n\nzstyle ':completion:*' fzf-completion-keybindings \"${keys[@]}\"\n# also accept and retrigger completion when pressing / when completing cd\nzstyle ':completion::*:cd:*' fzf-completion-keybindings \"${keys[@]}\" /:accept:'repeat-fzf-completion'\n```\n\nNote that you can still specify the normal `--bind ...` options in e.g. `$FZF_COMPLETION_OPTS`\nif you need to perform `fzf` specific actions or don't need to run zsh commands.\n\n#### Specifying custom fzf options\n\nYou can specify custom `fzf` options with the `fzf-completion-opts` style.\nThis allows you to have different options based on the command being completed\n(as opposed to the `$FZF_DEFAULT_OPTS` etc environment variables which are global).\n\nThis is most useful for changing the `--preview` option.\nUse `{1}` for the selected text (or `{+1}` if using multi-select).\nNote `{1}` or `{+1}` will come through \"shell-escaped\", so you will need to unescape it, e.g. using `eval` or `printf %b`\n\n```bash\n# basic file preview for ls (you can replace with something more sophisticated than head)\nzstyle ':completion::*:ls::*' fzf-completion-opts --preview='eval head {1}'\n\n# preview when completing env vars (note: only works for exported variables)\n# eval twice, first to unescape the string, second to expand the $variable\nzstyle ':completion::*:(-command-|-parameter-|-brace-parameter-|export|unset|expand):*' fzf-completion-opts --preview='eval eval echo {1}'\n\n# preview a `git status` when completing git add\nzstyle ':completion::*:git::git,add,*' fzf-completion-opts --preview='git -c color.status=always status --short'\n\n# if other subcommand to git is given, show a git diff or git log\nzstyle ':completion::*:git::*,[a-z]*' fzf-completion-opts --preview='\neval set -- {+1}\nfor arg in \"$@\"; do\n    { git diff --color=always -- \"$arg\" | git log --color=always \"$arg\" } 2\u003e/dev/null\ndone'\n```\n\n#### changing display string color\n\nBy default, the display string and the input prefix (i.e. the parts of the strings that are *not* searchable)\nare highlighted with `\\x1b[37m` which *should* come out as a light grey.\n\nYou can change this with the `fzf-completion-secondary-color` zstyle, e.g.:\n```bash\n# make it red instead\nzstyle ':completion:*' fzf-completion-secondary-color red\n```\n\nIt supports anything that can be used in the zsh prompt escape `%F{...}`, e.g. certain names like `red` or hex sequences like `#ff0000`.\nConsult `man --pager='less -p ^\\\\s*fg=colour' zshzle` for other possible values.\nIf set to an empty string, no color will be applied at all.\n\n## bash\n\nAdd to your `~/.bashrc`:\n```bash\nsource /path/to/fzf-tab-completion/bash/fzf-bash-completion.sh\nbind -x '\"\\t\": fzf_bash_completion'\n```\n\nNote that this does not provide `**`-style triggers,\nyou will need to enable fzf's bash completion _as well_.\n\nIf you are using a `bash` that is dynamically linked against readline (`LD_PRELOAD= ldd $(which bash)`)\nyou may prefer (or not!) to use the [readline](#readline) method instead.\n\n#### Changing fzf prompt\n\nThe `FZF_TAB_COMPLETION_PROMPT` environment variable sets the prompt prefix\nThe default is `'\u003e '`.\nYou could, for example, change it to `FZF_TAB_COMPLETION_PROMPT='❯ '`. \n\n#### Autocomplete common prefix\n\nBy default, fzf is always shown whenever there are at least 2 matches.\nYou can change this to a more \"vanilla\" tab completion experience where\nit attempts to complete the longest common prefix *before* showing matches in fzf.\n\nThis is controlled by the variables\n* `FZF_COMPLETION_AUTO_COMMON_PREFIX=true` - completes the common prefix if it is also a match\n* `FZF_COMPLETION_AUTO_COMMON_PREFIX_PART=true` - with the above variable, completes the common prefix even if it is not a match\n\nFor example, if we have following files in a directory:\n```\nabcdef-1234\nabcdef-5678\nabc\nother\n```\n\nWith `FZF_COMPLETION_AUTO_COMMON_PREFIX=true`:\n* when completing `ls \u003ctab\u003e`, it will display fzf with all 4 files (as normal)\n* when completing `ls a\u003ctab\u003e`, it will automatically complete to `ls abc`.\n    Pressing tab again will show fzf with the first 3 files.\n* when completing `ls abcd\u003ctab\u003e` it will show fzf with the first 2 files (as normal)\n* With `FZF_COMPLETION_AUTO_COMMON_PREFIX_PART=true` set as well:\n    * when completing `ls abcd\u003ctab\u003e`, it will automatically complete to `ls abcdef-`.\n        Pressing tab again will show fzf with the first 2 files.\n\n#### tmux\n\n`$FZF_TMUX_OPTS` is respected same as in [fzf](https://github.com/junegunn/fzf#key-bindings-for-command-line)\nhowever you must have fzf's keybindings enabled as well.\n\n#### Custom loading message\n\n`bash` clears the prompt and input line before running the completion,\nso a loading message is printed instead.\n\nYou can customise the message by overriding the `_fzf_bash_completion_loading_msg()` function.\n\nFor example the following \"re-prints\" the prompt and input line\nto make this less jarring\n(note this may or may not work, there's no detection of `$PS2` and there is always some unavoidable flicker):\n```bash\n_fzf_bash_completion_loading_msg() { echo \"${PS1@P}${READLINE_LINE}\" | tail -n1; }\n```\n\n## readline\n\nNOTE: This uses a `LD_PRELOAD` hack, is only supported on Linux and only for GNU readline\n(*not* e.g. libedit or other readline alternatives).\n\n1. Run: `cd /path/to/fzf-tab-completion/readline/ \u0026\u0026 cargo build --release`\n1. Copy/symlink `/path/to/fzf-tab-completion/readline/bin/rl_custom_complete` into your `$PATH`\n1. Add to your `~/.inputrc`:\n   ```\n   $include function rl_custom_complete /path/to/fzf-tab-completion/readline/target/release/librl_custom_complete.so\n   \"\\t\": rl_custom_complete\n   ```\n1. Build https://github.com/lincheney/rl_custom_function/\n   * this should produce a file `librl_custom_function.so` which you will use with `LD_PRELOAD` in the next step.\n1. Run something interactive that uses readline, e.g. python:\n   ```bash\n   LD_PRELOAD=/path/to/librl_custom_function.so python\n   ```\n1. To apply this all applications more permanently,\n   you will need to set `LD_PRELOAD` somewhere like `/etc/environment` or `~/.pam_environment`.\n   * NOTE: if you set `LD_PRELOAD` in your `.bashrc`, or similar, it will affect applications run _from_ `bash`\n      but not the parent `bash` process itself.\n   * See also: [link](https://wiki.archlinux.org/index.php/Environment_variables#Per_user)\n\nThese are the applications that I have seen working:\n* `python2`, `python3`\n    * only `PYTHON_BASIC_REPL=1 python3` if python 3.13+, otherwise see [python3](#python3)\n* `php -a`\n* `R`\n* `lftp`\n* `irb --legacy` (the new `irb` in ruby 2.7 uses `ruby-reline` instead of readline)\n* `gdb`\n* `sqlite3`\n* `bash` (only when not statically but dynamically linked to libreadline)\n\n## nodejs repl\n\n1. Copy/symlink `/path/to/fzf-tab-completion/node/rl_custom_complete` into your `$PATH`\n1. Then run `node -r /path/to/fzf-tab-completion.git/node/fzf-node-completion.js`\n    * You may wish to add a shell alias to your `~/.zshrc`/`~/.bashrc` to avoid typing out the full command each time, e.g.:\n        `alias node='node -r /path/to/fzf-tab-completion.git/node/fzf-node-completion.js`\n\n## python3\n\n1. Copy/symlink `/path/to/fzf-tab-completion/python/rl_custom_complete` into your `$PATH`\n1. Add the code below to either:\n    * your `~/.pythonstartup`\n    * your `$PYTHONPATH/usercustomize.py`\n        * see \u003chttps://docs.python.org/3/tutorial/appendix.html#the-customization-modules\u003e\n        * for example, I have `export PYTHONPATH=$HOME/dotfiles/pythonpath` and a file `$HOME/dotfiles/pythonpath/usercustomize.py`\n```python\nwith open('/path/to/fzf-tab-completion.git/python/fzf_python_completion.py') as file:\n    exec(file.read())\n```\n\nThis should work with:\n* a normal python shell `python3`, including the new interactive shell from 3.13+\n* the old interactive shell i.e. `PYTHON_BASIC_REPL=1 python3`\n* (only when added to `usercustomize.py`) anything that uses `readline.set_completer(...)`, including:\n    * `python3 -m asyncio`\n    * `pdb` / `breakpoint()`\n\n## Related projects\n\n* \u003chttps://github.com/rockandska/fzf-obc\u003e (fzf tab completion in bash)\n* \u003chttps://github.com/Aloxaf/fzf-tab\u003e (fzf tab completion in zsh)\n* \u003chttps://github.com/lincheney/rl_custom_isearch\u003e (fzf for history search in all readline applications)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flincheney%2Ffzf-tab-completion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flincheney%2Ffzf-tab-completion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flincheney%2Ffzf-tab-completion/lists"}