pax_global_header00006660000000000000000000000064147612620110014512gustar00rootroot0000000000000052 comment=0012183ede3619e2bf52932c196377f8a7befbf6 fzf-0.60.3/000077500000000000000000000000001476126201100123655ustar00rootroot00000000000000fzf-0.60.3/.github/000077500000000000000000000000001476126201100137255ustar00rootroot00000000000000fzf-0.60.3/.github/FUNDING.yml000066400000000000000000000000211476126201100155330ustar00rootroot00000000000000github: junegunn fzf-0.60.3/.github/ISSUE_TEMPLATE/000077500000000000000000000000001476126201100161105ustar00rootroot00000000000000fzf-0.60.3/.github/ISSUE_TEMPLATE/issue_template.yml000066400000000000000000000022121476126201100216530ustar00rootroot00000000000000--- name: Issue Template description: Report a problem or bug related to fzf to help us improve body: - type: markdown attributes: value: ISSUES NOT FOLLOWING THIS TEMPLATE WILL BE CLOSED AND DELETED - type: checkboxes attributes: label: Checklist options: - label: I have read through the manual page (`man fzf`) required: true - label: I have searched through the existing issues required: true - label: For bug reports, I have checked if the bug is reproducible in the latest version of fzf required: false - type: input attributes: label: Output of `fzf --version` placeholder: e.g. 0.48.1 (d579e33) validations: required: true - type: checkboxes attributes: label: OS options: - label: Linux - label: macOS - label: Windows - label: Etc. - type: checkboxes attributes: label: Shell options: - label: bash - label: zsh - label: fish - type: textarea attributes: label: Problem / Steps to reproduce validations: required: true fzf-0.60.3/.github/dependabot.yml000066400000000000000000000003211476126201100165510ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" fzf-0.60.3/.github/workflows/000077500000000000000000000000001476126201100157625ustar00rootroot00000000000000fzf-0.60.3/.github/workflows/codeql-analysis.yml000066400000000000000000000021271476126201100215770ustar00rootroot00000000000000# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning name: CodeQL on: push: branches: [ master, devel ] pull_request: branches: [ master ] workflow_dispatch: permissions: contents: read jobs: analyze: permissions: actions: read # for github/codeql-action/init to get workflow details contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/autobuild to send a status report name: Analyze runs-on: ubuntu-latest strategy: fail-fast: false matrix: language: ['go'] steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - name: Autobuild uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 fzf-0.60.3/.github/workflows/depsreview.yaml000066400000000000000000000004501476126201100210220ustar00rootroot00000000000000name: 'Dependency Review' on: [pull_request] permissions: contents: read jobs: dependency-review: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' uses: actions/checkout@v4 - name: 'Dependency Review' uses: actions/dependency-review-action@v4 fzf-0.60.3/.github/workflows/linux.yml000066400000000000000000000015231476126201100176450ustar00rootroot00000000000000--- name: Test fzf on Linux on: push: branches: [ master, devel ] pull_request: branches: [ master ] workflow_dispatch: permissions: contents: read env: LANG: C.UTF-8 jobs: build: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version: "1.20" - name: Setup Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 3.4.1 - name: Install packages run: sudo apt-get install --yes zsh fish tmux - name: Install Ruby gems run: bundle install - name: Rubocop run: make lint - name: Unit test run: make test - name: Integration test run: make install && ./install --all && tmux new-session -d && ruby test/runner.rb --verbose fzf-0.60.3/.github/workflows/macos.yml000066400000000000000000000017511476126201100176130ustar00rootroot00000000000000--- name: Test fzf on macOS on: push: branches: [ master, devel ] pull_request: branches: [ master ] workflow_dispatch: permissions: contents: read jobs: build: runs-on: macos-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version: "1.20" - name: Setup Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 3.0.0 - name: Install packages run: HOMEBREW_NO_INSTALL_CLEANUP=1 brew install fish zsh tmux - name: Install Ruby gems run: gem install --no-document minitest:5.14.2 rubocop:1.0.0 rubocop-minitest:0.10.1 rubocop-performance:1.8.1 - name: Rubocop run: rubocop --require rubocop-minitest --require rubocop-performance - name: Unit test run: make test - name: Integration test run: make install && ./install --all && LC_ALL=C tmux new-session -d && ruby test/test_go.rb --verbose fzf-0.60.3/.github/workflows/sponsors.yml000066400000000000000000000010531476126201100203720ustar00rootroot00000000000000--- name: Generate Sponsors README on: workflow_dispatch: schedule: - cron: 0 0 * * 0 jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout ๐Ÿ›Ž๏ธ uses: actions/checkout@v4 - name: Generate Sponsors ๐Ÿ’– uses: JamesIves/github-sponsors-readme-action@v1 with: token: ${{ secrets.SPONSORS_TOKEN }} file: 'README.md' - name: Deploy to GitHub Pages ๐Ÿš€ uses: JamesIves/github-pages-deploy-action@v4 with: branch: master folder: '.' fzf-0.60.3/.github/workflows/typos.yml000066400000000000000000000003011476126201100176550ustar00rootroot00000000000000name: "Spell Check" on: [pull_request] jobs: typos: name: Spell Check with Typos runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: crate-ci/typos@v1.29.4 fzf-0.60.3/.github/workflows/winget.yml000066400000000000000000000005061476126201100200030ustar00rootroot00000000000000name: Publish to Winget on: release: types: [released] jobs: publish: runs-on: ubuntu-latest steps: - uses: vedantmgoyal2009/winget-releaser@v2 with: identifier: junegunn.fzf installers-regex: '-windows_(armv7|arm64|amd64)\.zip$' token: ${{ secrets.WINGET_TOKEN }} fzf-0.60.3/.gitignore000066400000000000000000000001331476126201100143520ustar00rootroot00000000000000bin/fzf bin/fzf.exe dist target pkg .DS_Store doc/tags vendor gopath *.zwc fzf tmp *.patch fzf-0.60.3/.goreleaser.yml000066400000000000000000000043701476126201100153220ustar00rootroot00000000000000--- version: 2 project_name: fzf before: hooks: - go mod download builds: - id: fzf goos: - darwin - linux - windows - freebsd - openbsd goarch: - amd64 - arm - arm64 - loong64 - ppc64le - s390x goarm: - 5 - 6 - 7 flags: - -trimpath ldflags: - "-s -w -X main.version={{ .Version }} -X main.revision={{ .ShortCommit }}" ignore: - goos: freebsd goarch: arm - goos: openbsd goarch: arm - goos: freebsd goarch: arm64 - goos: openbsd goarch: arm64 # .goreleaser.yaml notarize: macos: - # Whether this configuration is enabled or not. # # Default: false. # Templates: allowed. enabled: "{{ not .IsSnapshot }}" # Before notarizing, we need to sign the binary. # This blocks defines the configuration for doing so. sign: # The .p12 certificate file path or its base64'd contents. certificate: "{{.Env.MACOS_SIGN_P12}}" # The password to be used to open the certificate. password: "{{.Env.MACOS_SIGN_PASSWORD}}" # Then, we notarize the binaries. notarize: # The issuer ID. # Its the UUID you see when creating the App Store Connect key. issuer_id: "{{.Env.MACOS_NOTARY_ISSUER_ID}}" # Key ID. # You can see it in the list of App Store Connect Keys. # It will also be in the ApiKey filename. key_id: "{{.Env.MACOS_NOTARY_KEY_ID}}" # The .p8 key file path or its base64'd contents. key: "{{.Env.MACOS_NOTARY_KEY}}" # Whether to wait for the notarization to finish. # Not recommended, as it could take a really long time. wait: true archives: - name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" builds: - fzf format: tar.gz format_overrides: - goos: windows format: zip files: - non-existent* release: github: owner: junegunn name: fzf prerelease: auto name_template: '{{ .Version }}' snapshot: name_template: "{{ .Version }}-devel" changelog: sort: asc filters: exclude: - README - test fzf-0.60.3/.rubocop.yml000066400000000000000000000014321476126201100146370ustar00rootroot00000000000000AllCops: NewCops: enable Layout/LineLength: Enabled: false Metrics: Enabled: false Lint/ShadowingOuterLocalVariable: Enabled: false Lint/NestedMethodDefinition: Enabled: false Style/MethodCallWithArgsParentheses: Enabled: true AllowedMethods: - assert - exit - paste - puts - raise - refute - require - send_keys AllowedPatterns: - ^assert_ - ^refute_ Style/NumericPredicate: Enabled: false Style/StringConcatenation: Enabled: false Style/OptionalBooleanParameter: Enabled: false Style/WordArray: MinSize: 1 Minitest/AssertEqual: Enabled: false Minitest/EmptyLineBeforeAssertionMethods: Enabled: false Naming/VariableNumber: Enabled: false Lint/EmptyBlock: Enabled: false Style/SafeNavigationChainLength: Enabled: false fzf-0.60.3/.tool-versions000066400000000000000000000000321476126201100152040ustar00rootroot00000000000000golang 1.20.13 ruby 3.4.1 fzf-0.60.3/ADVANCED.md000066400000000000000000000706741476126201100140720ustar00rootroot00000000000000Advanced fzf examples ====================== * *Last update: 2025/02/02* * *Requires fzf 0.59.0 or later* --- * [Introduction](#introduction) * [Display modes](#display-modes) * [`--height`](#--height) * [`--tmux`](#--tmux) * [Dynamic reloading of the list](#dynamic-reloading-of-the-list) * [Updating the list of processes by pressing CTRL-R](#updating-the-list-of-processes-by-pressing-ctrl-r) * [Toggling between data sources](#toggling-between-data-sources) * [Toggling with a single key binding](#toggling-with-a-single-key-binding) * [Ripgrep integration](#ripgrep-integration) * [Using fzf as the secondary filter](#using-fzf-as-the-secondary-filter) * [Using fzf as interactive Ripgrep launcher](#using-fzf-as-interactive-ripgrep-launcher) * [Switching to fzf-only search mode](#switching-to-fzf-only-search-mode) * [Switching between Ripgrep mode and fzf mode](#switching-between-ripgrep-mode-and-fzf-mode) * [Switching between Ripgrep mode and fzf mode using a single key binding](#switching-between-ripgrep-mode-and-fzf-mode-using-a-single-key-binding) * [Controlling Ripgrep search and fzf search simultaneously](#controlling-ripgrep-search-and-fzf-search-simultaneously) * [Log tailing](#log-tailing) * [Key bindings for git objects](#key-bindings-for-git-objects) * [Files listed in `git status`](#files-listed-in-git-status) * [Branches](#branches) * [Commit hashes](#commit-hashes) * [Color themes](#color-themes) * [fzf Theme Playground](#fzf-theme-playground) * [Generating fzf color theme from Vim color schemes](#generating-fzf-color-theme-from-vim-color-schemes) Introduction ------------ fzf is an interactive [Unix filter][filter] program that is designed to be used with other Unix tools. It reads a list of items from the standard input, allows you to select a subset of the items, and prints the selected ones to the standard output. You can think of it as an interactive version of *grep*, and it's already useful even if you don't know any of its options. ```sh # 1. ps: Feed the list of processes to fzf # 2. fzf: Interactively select a process using fuzzy matching algorithm # 3. awk: Take the PID from the selected line # 3. kill: Kill the process with the PID ps -ef | fzf | awk '{print $2}' | xargs kill -9 ``` [filter]: https://en.wikipedia.org/wiki/Filter_(software) While the above example succinctly summarizes the fundamental concept of fzf, you can build much more sophisticated interactive workflows using fzf once you learn its wide variety of features. - To see the full list of options and features, see `man fzf` - To see the latest additions, see [CHANGELOG.md](CHANGELOG.md) This document will guide you through some examples that will familiarize you with the advanced features of fzf. Display modes ------------- ### `--height` fzf by default opens in fullscreen mode, but it's not always desirable. Oftentimes, you want to see the current context of the terminal while using fzf. `--height` is an option for opening fzf below the cursor in non-fullscreen mode so you can still see the previous commands and their results above it. ```sh fzf --height=40% ``` ![image](https://user-images.githubusercontent.com/700826/113379893-c184c680-93b5-11eb-9676-c7c0a2f01748.png) You might also want to experiment with other layout options such as `--layout=reverse`, `--info=inline`, `--border`, `--margin`, etc. ```sh fzf --height=40% --layout=reverse fzf --height=40% --layout=reverse --info=inline fzf --height=40% --layout=reverse --info=inline --border fzf --height=40% --layout=reverse --info=inline --border --margin=1 fzf --height=40% --layout=reverse --info=inline --border --margin=1 --padding=1 ``` ![image](https://user-images.githubusercontent.com/700826/113379932-dfeac200-93b5-11eb-9e28-df1a2ee71f90.png) *(See man page to see the full list of options)* But you definitely don't want to repeat `--height=40% --layout=reverse --info=inline --border --margin=1 --padding=1` every time you use fzf. You could write a wrapper script or shell alias, but there is an easier option. Define `$FZF_DEFAULT_OPTS` like so: ```sh export FZF_DEFAULT_OPTS="--height=40% --layout=reverse --info=inline --border --margin=1 --padding=1" ``` ### `--tmux` (Requires tmux 3.3 or later) If you're using tmux, you can open fzf in a tmux popup using `--tmux` option. ```sh # Open fzf in a tmux popup at the center of the screen with 70% width and height fzf --tmux 70% ``` ![image](https://github.com/junegunn/fzf/assets/700826/9c365405-c700-49b2-8985-60d822ed4cff) `--tmux` option is silently ignored if you're not on tmux. So if you're trying to avoid opening fzf in fullscreen, try specifying both `--height` and `--tmux`. ```sh # --tmux is specified later so it takes precedence over --height when on tmux. # If you're not on tmux, --tmux is ignored and --height is used instead. fzf --height 70% --tmux 70% ``` You can also specify the position, width, and height of the popup window in the following format: * `[center|top|bottom|left|right][,SIZE[%]][,SIZE[%][,border-native]]` ```sh # 100% width and 60% height fzf --tmux 100%,60% --border horizontal ``` ![image](https://github.com/junegunn/fzf/assets/700826/f80d3514-d69f-42f2-a8de-a392a562bfcf) ```sh # On the right (50% width) fzf --tmux right ``` ![image](https://github.com/junegunn/fzf/assets/700826/4033ade4-7efa-421b-a3fb-a430d197098a) ```sh # On the left (40% width and 70% height) fzf --tmux left,40%,70% ``` ![image](https://github.com/junegunn/fzf/assets/700826/efe43881-2bf0-49ea-ab2e-1377f778cd52) > [!TIP] > You might also want to check out my tmux plugins which support this popup > window layout. > > - https://github.com/junegunn/tmux-fzf-url > - https://github.com/junegunn/tmux-fzf-maccy Dynamic reloading of the list ----------------------------- fzf can dynamically update the candidate list using an arbitrary program with `reload` bindings (The design document for `reload` can be found [here][reload]). [reload]: https://github.com/junegunn/fzf/issues/1750 ### Updating the list of processes by pressing CTRL-R This example shows how you can set up a binding for dynamically updating the list without restarting fzf. ```sh (date; ps -ef) | fzf --bind='ctrl-r:reload(date; ps -ef)' \ --header=$'Press CTRL-R to reload\n\n' --header-lines=2 \ --preview='echo {}' --preview-window=down,3,wrap \ --layout=reverse --height=80% | awk '{print $2}' | xargs kill -9 ``` ![image](https://user-images.githubusercontent.com/700826/113465047-200c7c00-946c-11eb-918c-268f37a900c8.png) - The initial command is `(date; ps -ef)`. It prints the current date and time, and the list of the processes. - With `--header` option, you can show any message as the fixed header. - To disallow selecting the first two lines (`date` and `ps` header), we use `--header-lines=2` option. - `--bind='ctrl-r:reload(date; ps -ef)'` binds CTRL-R to `reload` action that runs `date; ps -ef`, so we can update the list of the processes by pressing CTRL-R. - We use simple `echo {}` preview option, so we can see the entire line on the preview window below even if it's too long ### Toggling between data sources You're not limited to just one reload binding. Set up multiple bindings so you can switch between data sources. ```sh find * | fzf --prompt 'All> ' \ --header 'CTRL-D: Directories / CTRL-F: Files' \ --bind 'ctrl-d:change-prompt(Directories> )+reload(find * -type d)' \ --bind 'ctrl-f:change-prompt(Files> )+reload(find * -type f)' ``` ![image](https://user-images.githubusercontent.com/700826/113465073-4af6d000-946c-11eb-858f-2372c0955f67.png) ![image](https://user-images.githubusercontent.com/700826/113465072-46321c00-946c-11eb-9b6f-cda3951df579.png) ### Toggling with a single key binding The above example uses two different key bindings to toggle between two modes, but can we just use a single key binding? To make a key binding behave differently each time it is pressed, we need: 1. a way to store the current state. i.e. "which mode are we in?" 2. and a way to dynamically perform different actions depending on the state. The following example shows how to 1. store the current mode in the prompt string, 2. and use this information (`$FZF_PROMPT`) to determine which actions to perform using the `transform` action. ```sh fd --type file | fzf --prompt 'Files> ' \ --header 'CTRL-T: Switch between Files/Directories' \ --bind 'ctrl-t:transform:[[ ! $FZF_PROMPT =~ Files ]] && echo "change-prompt(Files> )+reload(fd --type file)" || echo "change-prompt(Directories> )+reload(fd --type directory)"' \ --preview '[[ $FZF_PROMPT =~ Files ]] && bat --color=always {} || tree -C {}' ``` Ripgrep integration ------------------- ### Using fzf as the secondary filter * Requires [bat][bat] * Requires [Ripgrep][rg] [bat]: https://github.com/sharkdp/bat [rg]: https://github.com/BurntSushi/ripgrep fzf is pretty fast for filtering a list that you will rarely have to think about its performance. But it is not the right tool for searching for text inside many large files, and in that case you should definitely use something like [Ripgrep][rg]. In the next example, Ripgrep is the primary filter that searches for the given text in files, and fzf is used as the secondary fuzzy filter that adds interactivity to the workflow. And we use [bat][bat] to show the matching line in the preview window. This is a bash script and it will not run as expected on other non-compliant shells. To avoid the compatibility issue, let's save this snippet as a script file called `rfv`. ```bash #!/usr/bin/env bash # 1. Search for text in files using Ripgrep # 2. Interactively narrow down the list using fzf # 3. Open the file in Vim rg --color=always --line-number --no-heading --smart-case "${*:-}" | fzf --ansi \ --color "hl:-1:underline,hl+:-1:underline:reverse" \ --delimiter : \ --preview 'bat --color=always {1} --highlight-line {2}' \ --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \ --bind 'enter:become(vim {1} +{2})' ``` And run it with an initial query string. ```sh # Make the script executable chmod +x rfv # Run it with the initial query "algo" ./rfv algo ``` > Ripgrep will perform the initial search and list all the lines that contain `algo`. Then we further narrow down the list on fzf. ![image](https://user-images.githubusercontent.com/700826/113683873-a42a6200-96ff-11eb-9666-26ce4091b0e4.png) I know it's a lot to digest, let's try to break down the code. - Ripgrep prints the matching lines in the following format ``` man/man1/fzf.1:54:.BI "--algo=" TYPE man/man1/fzf.1:55:Fuzzy matching algorithm (default: v2) man/man1/fzf.1:58:.BR v2 " Optimal scoring algorithm (quality)" src/pattern_test.go:7: "github.com/junegunn/fzf/src/algo" ``` The first token delimited by `:` is the file path, and the second token is the line number of the matching line. They respectively correspond to `{1}` and `{2}` in the preview command. - `--preview 'bat --color=always {1} --highlight-line {2}'` - As we run `rg` with `--color=always` option, we should tell fzf to parse ANSI color codes in the input by setting `--ansi`. - We customize how fzf colors various text elements using `--color` option. `-1` tells fzf to keep the original color from the input. See `man fzf` for available color options. - The value of `--preview-window` option consists of 5 components delimited by `,` 1. `up` โ€” Position of the preview window 1. `60%` โ€” Size of the preview window 1. `border-bottom` โ€” Preview window border only on the bottom side 1. `+{2}+3/3` โ€” Scroll offset of the preview contents 1. `~3` โ€” Fixed header - Let's break down the latter two. We want to display the bat output in the preview window with a certain scroll offset so that the matching line is positioned near the center of the preview window. - `+{2}` โ€” The base offset is extracted from the second token - `+3` โ€” We add 3 lines to the base offset to compensate for the header part of `bat` output - ``` โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ File: CHANGELOG.md โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 1 โ”‚ CHANGELOG 2 โ”‚ ========= 3 โ”‚ 4 โ”‚ 0.26.0 5 โ”‚ ------ ``` - `/3` adjusts the offset so that the matching line is shown at a third position in the window - `~3` makes the top three lines fixed header so that they are always visible regardless of the scroll offset - Instead of using shell script to process the final output of fzf, we use `become(...)` action which was added in [fzf 0.38.0][0.38.0] to turn fzf into a new process that opens the file with `vim` (`vim {1}`) and move the cursor to the line (`+{2}`). [0.38.0]: https://github.com/junegunn/fzf/blob/master/CHANGELOG.md#0380 ### Using fzf as interactive Ripgrep launcher We have learned that we can bind `reload` action to a key (e.g. `--bind=ctrl-r:execute(ps -ef)`). In the next example, we are going to **bind `reload` action to `change` event** so that whenever the user *changes* the query string on fzf, `reload` action is triggered. Here is a variation of the above `rfv` script. fzf will restart Ripgrep every time the user updates the query string on fzf. Searching and filtering is completely done by Ripgrep, and fzf merely provides the interactive interface. So we lose the "fuzziness", but the performance will be better on larger projects, and it will free up memory as you narrow down the results. ```bash #!/usr/bin/env bash # 1. Search for text in files using Ripgrep # 2. Interactively restart Ripgrep with reload action # 3. Open the file in Vim RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " INITIAL_QUERY="${*:-}" fzf --ansi --disabled --query "$INITIAL_QUERY" \ --bind "start:reload:$RG_PREFIX {q}" \ --bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \ --delimiter : \ --preview 'bat --color=always {1} --highlight-line {2}' \ --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \ --bind 'enter:become(vim {1} +{2})' ``` ![image](https://user-images.githubusercontent.com/700826/113684212-f9ff0a00-96ff-11eb-8737-7bb571d320cc.png) - Instead of starting fzf in the usual `rg ... | fzf` form, we make it start the initial Ripgrep process immediately via `start:reload` binding for the consistency of the code. - Filtering is no longer a responsibility of fzf; hence `--disabled` - `{q}` in the reload command evaluates to the query string on fzf prompt. - `sleep 0.1` in the reload command is for "debouncing". This small delay will reduce the number of intermediate Ripgrep processes while we're typing in a query. ### Switching to fzf-only search mode In the previous example, we lost fuzzy matching capability as we completely delegated search functionality to Ripgrep. But we can dynamically switch to fzf-only search mode by *"unbinding"* `reload` action from `change` event. ```sh #!/usr/bin/env bash # Two-phase filtering with Ripgrep and fzf # # 1. Search for text in files using Ripgrep # 2. Interactively restart Ripgrep with reload action # * Press alt-enter to switch to fzf-only filtering # 3. Open the file in Vim RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " INITIAL_QUERY="${*:-}" fzf --ansi --disabled --query "$INITIAL_QUERY" \ --bind "start:reload:$RG_PREFIX {q}" \ --bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \ --bind "alt-enter:unbind(change,alt-enter)+change-prompt(2. fzf> )+enable-search+clear-query" \ --color "hl:-1:underline,hl+:-1:underline:reverse" \ --prompt '1. ripgrep> ' \ --delimiter : \ --preview 'bat --color=always {1} --highlight-line {2}' \ --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \ --bind 'enter:become(vim {1} +{2})' ``` * Phase 1. Filtering with Ripgrep ![image](https://user-images.githubusercontent.com/700826/119213880-735e8a80-bafd-11eb-8493-123e4be24fbc.png) * Phase 2. Filtering with fzf ![image](https://user-images.githubusercontent.com/700826/119213887-7e191f80-bafd-11eb-98c9-71a1af9d7aab.png) - We added `--prompt` option to show that fzf is initially running in "Ripgrep launcher mode". - We added `alt-enter` binding that 1. unbinds `change` event, so Ripgrep is no longer restarted on key press 2. changes the prompt to `2. fzf>` 3. enables search functionality of fzf 4. clears the current query string that was used to start Ripgrep process 5. and unbinds `alt-enter` itself as this is a one-off event - We reverted `--color` option for customizing how the matching chunks are displayed in the second phase ### Switching between Ripgrep mode and fzf mode [fzf 0.30.0][0.30.0] added `rebind` action so we can "rebind" the bindings that were previously "unbound" via `unbind`. This is an improved version of the previous example that allows us to switch between Ripgrep launcher mode and fzf-only filtering mode via CTRL-R and CTRL-F. ```sh #!/usr/bin/env bash # Switch between Ripgrep launcher mode (CTRL-R) and fzf filtering mode (CTRL-F) rm -f /tmp/rg-fzf-{r,f} RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " INITIAL_QUERY="${*:-}" fzf --ansi --disabled --query "$INITIAL_QUERY" \ --bind "start:reload($RG_PREFIX {q})+unbind(ctrl-r)" \ --bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \ --bind "ctrl-f:unbind(change,ctrl-f)+change-prompt(2. fzf> )+enable-search+rebind(ctrl-r)+transform-query(echo {q} > /tmp/rg-fzf-r; cat /tmp/rg-fzf-f)" \ --bind "ctrl-r:unbind(ctrl-r)+change-prompt(1. ripgrep> )+disable-search+reload($RG_PREFIX {q} || true)+rebind(change,ctrl-f)+transform-query(echo {q} > /tmp/rg-fzf-f; cat /tmp/rg-fzf-r)" \ --color "hl:-1:underline,hl+:-1:underline:reverse" \ --prompt '1. ripgrep> ' \ --delimiter : \ --header 'โ•ฑ CTRL-R (ripgrep mode) โ•ฑ CTRL-F (fzf mode) โ•ฑ' \ --preview 'bat --color=always {1} --highlight-line {2}' \ --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \ --bind 'enter:become(vim {1} +{2})' ``` - To restore the query string when switching between modes, we store the current query in `/tmp/rg-fzf-{r,f}` files and restore the query using `transform-query` action which was added in [fzf 0.36.0][0.36.0]. - Also note that we unbind `ctrl-r` binding on `start` event which is triggered once when fzf starts. [0.30.0]: https://github.com/junegunn/fzf/blob/master/CHANGELOG.md#0300 [0.36.0]: https://github.com/junegunn/fzf/blob/master/CHANGELOG.md#0360 ### Switching between Ripgrep mode and fzf mode using a single key binding In contrast to the previous version, we use just one hotkey to toggle between ripgrep and fzf mode. This is achieved by using the `$FZF_PROMPT` as a state within the `transform` action, a feature introduced in [fzf 0.45.0][0.45.0]. A more detailed explanation of this feature can be found in a previous section - [Toggling with a single keybinding](#toggling-with-a-single-key-binding). [0.45.0]: https://github.com/junegunn/fzf/blob/master/CHANGELOG.md#0450 When using the `transform` action, the placeholder (`\{q}`) should be escaped to prevent immediate evaluation. ```sh #!/usr/bin/env bash # Switch between Ripgrep mode and fzf filtering mode (CTRL-T) rm -f /tmp/rg-fzf-{r,f} RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " INITIAL_QUERY="${*:-}" fzf --ansi --disabled --query "$INITIAL_QUERY" \ --bind "start:reload:$RG_PREFIX {q}" \ --bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \ --bind 'ctrl-t:transform:[[ ! $FZF_PROMPT =~ ripgrep ]] && echo "rebind(change)+change-prompt(1. ripgrep> )+disable-search+transform-query:echo \{q} > /tmp/rg-fzf-f; cat /tmp/rg-fzf-r" || echo "unbind(change)+change-prompt(2. fzf> )+enable-search+transform-query:echo \{q} > /tmp/rg-fzf-r; cat /tmp/rg-fzf-f"' \ --color "hl:-1:underline,hl+:-1:underline:reverse" \ --prompt '1. ripgrep> ' \ --delimiter : \ --header 'CTRL-T: Switch between ripgrep/fzf' \ --preview 'bat --color=always {1} --highlight-line {2}' \ --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \ --bind 'enter:become(vim {1} +{2})' ``` ### Controlling Ripgrep search and fzf search simultaneously `search` and `transform-search` action allow you to trigger an fzf search with an arbitrary query string. This frees fzf from strictly following the prompt input, enabling custom search syntax. In the example below, `transform` action is used to conditionally trigger `reload` for ripgrep, followed by `search` for fzf. The first word of the query initiates the Ripgrep process to generate the initial results, while the remainder of the query is passed to fzf for secondary filtering. ```sh #!/usr/bin/env bash export TEMP=$(mktemp -u) trap 'rm -f "$TEMP"' EXIT INITIAL_QUERY="${*:-}" TRANSFORMER=' rg_pat={q:1} # The first word is passed to ripgrep fzf_pat={q:2..} # The rest are passed to fzf if ! [[ -r "$TEMP" ]] || [[ $rg_pat != $(cat "$TEMP") ]]; then echo "$rg_pat" > "$TEMP" printf "reload:sleep 0.1; rg --column --line-number --no-heading --color=always --smart-case %q || true" "$rg_pat" fi echo "+search:$fzf_pat" ' fzf --ansi --disabled --query "$INITIAL_QUERY" \ --with-shell 'bash -c' \ --bind "start,change:transform:$TRANSFORMER" \ --color "hl:-1:underline,hl+:-1:underline:reverse" \ --delimiter : \ --preview 'bat --color=always {1} --highlight-line {2}' \ --preview-window 'up,60%,border-line,+{2}+3/3,~3' \ --bind 'enter:become(vim {1} +{2})' ``` Log tailing ----------- fzf can run long-running preview commands and render partial results before completion. And when you specify `follow` flag in `--preview-window` option, fzf will "`tail -f`" the result, automatically scrolling to the bottom. ```bash # With "follow", preview window will automatically scroll to the bottom. # "\033[2J" is an ANSI escape sequence for clearing the screen. # When fzf reads this code it clears the previous preview contents. fzf --preview-window follow --preview 'for i in $(seq 100000); do echo "$i" sleep 0.01 (( i % 300 == 0 )) && printf "\033[2J" done' ``` ![image](https://user-images.githubusercontent.com/700826/113473303-dd669600-94a3-11eb-88a9-1f61b996bb0e.png) Admittedly, that was a silly example. Here's a practical one for browsing Kubernetes pods. ```bash pods() { command='kubectl get pods --all-namespaces' fzf \ --info=inline --layout=reverse --header-lines=1 \ --prompt "$(kubectl config current-context | sed 's/-context$//')> " \ --header $'โ•ฑ Enter (kubectl exec) โ•ฑ CTRL-O (open log in editor) โ•ฑ CTRL-R (reload) โ•ฑ\n\n' \ --bind 'start,ctrl-r:reload:$command' \ --bind 'ctrl-/:change-preview-window(80%,border-bottom|hidden|)' \ --bind 'enter:execute:kubectl exec -it --namespace {1} {2} -- bash' \ --bind 'ctrl-o:execute:${EDITOR:-vim} <(kubectl logs --all-containers --namespace {1} {2})' \ --preview-window up:follow \ --preview 'kubectl logs --follow --all-containers --tail=10000 --namespace {1} {2}' "$@" } ``` ![image](https://user-images.githubusercontent.com/700826/113473547-1d7a4880-94a5-11eb-98ef-9aa6f0ed215a.png) - The preview window will *"log tail"* the pod - Holding on to a large amount of log will consume a lot of memory. So we limited the initial log amount with `--tail=10000`. - `execute` bindings allow you to run any command without leaving fzf - Press enter key on a pod to `kubectl exec` into it - Press CTRL-O to open the log in your editor - Press CTRL-R to reload the pod list - Press CTRL-/ repeatedly to rotate through a different sets of preview window options 1. `80%,border-bottom` 1. `hidden` 1. Empty string after `|` translates to the default options from `--preview-window` Key bindings for git objects ---------------------------- Oftentimes, you want to put the identifiers of various Git object to the command-line. For example, it is common to write commands like these: ```sh git checkout [SOME_COMMIT_HASH or BRANCH or TAG] git diff [SOME_COMMIT_HASH or BRANCH or TAG] [SOME_COMMIT_HASH or BRANCH or TAG] ``` [fzf-git.sh](https://github.com/junegunn/fzf-git.sh) project defines a set of fzf-based key bindings for Git objects. I strongly recommend that you check them out because they are seriously useful. ### Files listed in `git status` CTRL-GCTRL-F ![image](https://user-images.githubusercontent.com/700826/113473779-a9d93b00-94a6-11eb-87b5-f62a8d0a0efc.png) ### Branches CTRL-GCTRL-B ![image](https://user-images.githubusercontent.com/700826/113473758-87dfb880-94a6-11eb-82f4-9218103f10bd.png) ### Commit hashes CTRL-GCTRL-H ![image](https://user-images.githubusercontent.com/700826/113473765-91692080-94a6-11eb-8d38-ed4d41f27ac1.png) Color themes ------------ You can customize how fzf colors the text elements with `--color` option. Here are a few color themes. Note that you need a terminal emulator that can display 24-bit colors. ```sh # junegunn/seoul256.vim (dark) export FZF_DEFAULT_OPTS='--color=bg+:#3F3F3F,bg:#4B4B4B,border:#6B6B6B,spinner:#98BC99,hl:#719872,fg:#D9D9D9,header:#719872,info:#BDBB72,pointer:#E12672,marker:#E17899,fg+:#D9D9D9,preview-bg:#3F3F3F,prompt:#98BEDE,hl+:#98BC99' ``` ![seoul256](https://user-images.githubusercontent.com/700826/113475011-2c192d80-94ae-11eb-9d17-1e5867bae01f.png) ```sh # junegunn/seoul256.vim (light) export FZF_DEFAULT_OPTS='--color=bg+:#D9D9D9,bg:#E1E1E1,border:#C8C8C8,spinner:#719899,hl:#719872,fg:#616161,header:#719872,info:#727100,pointer:#E12672,marker:#E17899,fg+:#616161,preview-bg:#D9D9D9,prompt:#0099BD,hl+:#719899' ``` ![seoul256-light](https://user-images.githubusercontent.com/700826/113475022-389d8600-94ae-11eb-905f-0939dd535837.png) ```sh # morhetz/gruvbox export FZF_DEFAULT_OPTS='--color=bg+:#3c3836,bg:#32302f,spinner:#fb4934,hl:#928374,fg:#ebdbb2,header:#928374,info:#8ec07c,pointer:#fb4934,marker:#fb4934,fg+:#ebdbb2,prompt:#fb4934,hl+:#fb4934' ``` ![gruvbox](https://user-images.githubusercontent.com/700826/113475042-494dfc00-94ae-11eb-9322-cd03a027305a.png) ```sh # arcticicestudio/nord-vim export FZF_DEFAULT_OPTS='--color=bg+:#3B4252,bg:#2E3440,spinner:#81A1C1,hl:#616E88,fg:#D8DEE9,header:#616E88,info:#81A1C1,pointer:#81A1C1,marker:#81A1C1,fg+:#D8DEE9,prompt:#81A1C1,hl+:#81A1C1' ``` ![nord](https://user-images.githubusercontent.com/700826/113475063-67b3f780-94ae-11eb-9b24-5f0d22b63399.png) ```sh # tomasr/molokai export FZF_DEFAULT_OPTS='--color=bg+:#293739,bg:#1B1D1E,border:#808080,spinner:#E6DB74,hl:#7E8E91,fg:#F8F8F2,header:#7E8E91,info:#A6E22E,pointer:#A6E22E,marker:#F92672,fg+:#F8F8F2,prompt:#F92672,hl+:#F92672' ``` ![molokai](https://user-images.githubusercontent.com/700826/113475085-8619f300-94ae-11eb-85e4-2766fc3246bf.png) ### fzf Theme Playground [fzf Theme Playground](https://vitormv.github.io/fzf-themes/) created by [Vitor Mello](https://github.com/vitormv) is a webpage where you can interactively create fzf themes. ### Generating fzf color theme from Vim color schemes The Vim plugin of fzf can generate `--color` option from the current color scheme according to `g:fzf_colors` variable. You can find the detailed explanation [here](https://github.com/junegunn/fzf/blob/master/README-VIM.md#explanation-of-gfzf_colors). Here is an example. Add this to your Vim configuration file. ```vim let g:fzf_colors = \ { 'fg': ['fg', 'Normal'], \ 'bg': ['bg', 'Normal'], \ 'preview-bg': ['bg', 'NormalFloat'], \ 'hl': ['fg', 'Comment'], \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'hl+': ['fg', 'Statement'], \ 'info': ['fg', 'PreProc'], \ 'border': ['fg', 'Ignore'], \ 'prompt': ['fg', 'Conditional'], \ 'pointer': ['fg', 'Exception'], \ 'marker': ['fg', 'Keyword'], \ 'spinner': ['fg', 'Label'], \ 'header': ['fg', 'Comment'] } ``` Then you can see how the `--color` option is generated by printing the result of `fzf#wrap()`. ```vim :echo fzf#wrap() ``` Use this command to append `export FZF_DEFAULT_OPTS="..."` line to the end of the current file. ```vim :call append('$', printf('export FZF_DEFAULT_OPTS="%s"', matchstr(fzf#wrap().options, "--color[^']*"))) ``` fzf-0.60.3/BUILD.md000066400000000000000000000032661476126201100135550ustar00rootroot00000000000000Building fzf ============ Build instructions ------------------ ### Prerequisites - Go 1.20 or above ### Using Makefile ```sh # Build fzf binary for your platform in target make # Build fzf binary and copy it to bin directory make install # Build fzf binaries and archives for all platforms using goreleaser make build # Publish GitHub release make release ``` > [!WARNING] > Makefile uses git commands to determine the version and the revision > information for `fzf --version`. So if you're building fzf from an > environment where its git information is not available, you have to manually > set `$FZF_VERSION` and `$FZF_REVISION`. > > e.g. `FZF_VERSION=0.24.0 FZF_REVISION=tarball make` > [!TIP] > To build fzf with profiling options enabled, set `TAGS=pprof` > > ```sh > TAGS=pprof make clean install > fzf --profile-cpu /tmp/cpu.pprof --profile-mem /tmp/mem.pprof \ > --profile-block /tmp/block.pprof --profile-mutex /tmp/mutex.pprof > ``` Third-party libraries used -------------------------- - [rivo/uniseg](https://github.com/rivo/uniseg) - Licensed under [MIT](https://raw.githubusercontent.com/rivo/uniseg/master/LICENSE.txt) - [mattn/go-shellwords](https://github.com/mattn/go-shellwords) - Licensed under [MIT](http://mattn.mit-license.org) - [mattn/go-isatty](https://github.com/mattn/go-isatty) - Licensed under [MIT](http://mattn.mit-license.org) - [tcell](https://github.com/gdamore/tcell) - Licensed under [Apache License 2.0](https://github.com/gdamore/tcell/blob/master/LICENSE) - [fastwalk](https://github.com/charlievieth/fastwalk) - Licensed under [MIT](https://raw.githubusercontent.com/charlievieth/fastwalk/master/LICENSE) License ------- [MIT](LICENSE) fzf-0.60.3/CHANGELOG.md000066400000000000000000003065441476126201100142120ustar00rootroot00000000000000CHANGELOG ========= 0.60.3 ------ - Bug fixes and improvements - [fish] Enable multiple history commands insertion (#4280) (@bitraid) - [walker] Append '/' to directory entries on MSYS2 (#4281) - Trim trailing whitespaces after processing ANSI sequences (#4282) - Remove temp files before `become` when using `--tmux` option (#4283) - Fix condition for using item numlines cache (#4285) (@alex-huff) - Make `--accept-nth` compatible with `--select-1` (#4287) - Increase the query length limit from 300 to 1000 (#4292) - [windows] Prevent fzf from consuming user input while paused (#4260) 0.60.2 ------ - Template for `--with-nth` and `--accept-nth` now supports `{n}` which evaluates to the zero-based ordinal index of the item - Fixed a regression that caused the last field in the "nth" expression to be trimmed when a regular expression delimiter is used - Thanks to @phanen for the fix - Fixed 'jump' action when the pointer is an empty string 0.60.1 ------ - Bug fixes and minor improvements - Built-in walker now prints directory entries with a trailing slash - Fixed a bug causing unexpected behavior with [fzf-tab](https://github.com/Aloxaf/fzf-tab). Please upgrade if you use it. - Thanks to @alexeisersun, @bitraid, @Lompik, and @fsc0 for the contributions 0.60.0 ------ _Release highlights: https://junegunn.github.io/fzf/releases/0.60.0/_ - Added `--accept-nth` for choosing output fields ```sh ps -ef | fzf --multi --header-lines 1 | awk '{print $2}' # Becomes ps -ef | fzf --multi --header-lines 1 --accept-nth 2 git branch | fzf | cut -c3- # Can be rewritten as git branch | fzf --accept-nth -1 ``` - `--accept-nth` and `--with-nth` now support a template that includes multiple field index expressions in curly braces ```sh echo foo,bar,baz | fzf --delimiter , --accept-nth '{1}, {3}, {2}' # foo, baz, bar echo foo,bar,baz | fzf --delimiter , --with-nth '{1},{3},{2},{1..2}' # foo,baz,bar,foo,bar ``` - Added `exclude` and `exclude-multi` actions for dynamically excluding items ```sh seq 100 | fzf --bind 'ctrl-x:exclude' # 'exclude-multi' will exclude the selected items or the current item seq 100 | fzf --multi --bind 'ctrl-x:exclude-multi' ``` - Preview window now prints wrap indicator when wrapping is enabled ```sh seq 100 | xargs | fzf --wrap --preview 'echo {}' --preview-window wrap ``` - Bug fixes and improvements 0.59.0 ------ _Release highlights: https://junegunn.github.io/fzf/releases/0.59.0/_ - Prioritizing file name matches (#4192) - Added a new tiebreak option `pathname` for prioritizing file name matches - `--scheme=path` now sets `--tiebreak=pathname,length` - fzf will automatically choose `path` scheme * when the input is a TTY device, where fzf would start its built-in walker or run `$FZF_DEFAULT_COMMAND` which is usually a command for listing files, * but not when `reload` or `transform` action is bound to `start` event, because in that case, fzf can't be sure of the input type. - Added `--header-lines-border` to display header from `--header-lines` with a separate border ```sh # Use --header-lines-border to separate two headers ps -ef | fzf --style full --layout reverse --header-lines 1 \ --bind 'ctrl-r:reload(ps -ef)' --header 'Press CTRL-R to reload' \ --header-lines-border bottom --no-list-border ``` - `click-header` event now sets `$FZF_CLICK_HEADER_WORD` and `$FZF_CLICK_HEADER_NTH`. You can use them to implement a clickable header for changing the search scope using the new `transform-nth` action. ```sh # Click on the header line to limit search scope ps -ef | fzf --style full --layout reverse --header-lines 1 \ --header-lines-border bottom --no-list-border \ --color fg:dim,nth:regular \ --bind 'click-header:transform-nth( echo $FZF_CLICK_HEADER_NTH )+transform-prompt( echo "$FZF_CLICK_HEADER_WORD> " )' ``` - `$FZF_KEY` was updated to expose the type of the click. e.g. `click`, `ctrl-click`, etc. You can use it to implement a more sophisticated behavior. - `kill` completion for bash and zsh were updated to use this feature - Added `--no-input` option to completely disable and hide the input section ```sh # Click header to trigger search fzf --header '[src] [test]' --no-input --layout reverse \ --header-border bottom --input-border \ --bind 'click-header:transform-search:echo ${FZF_CLICK_HEADER_WORD:1:-1}' # Vim-like mode switch fzf --layout reverse-list --no-input \ --bind 'j:down,k:up,/:show-input+unbind(j,k,/)' \ --bind 'enter,esc,ctrl-c:transform: if [[ $FZF_INPUT_STATE = enabled ]]; then echo "rebind(j,k,/)+hide-input" elif [[ $FZF_KEY = enter ]]; then echo accept else echo abort fi ' ``` - You can later show the input section using `show-input` or `toggle-input` action, and hide it again using `hide-input`, or `toggle-input`. - Extended `{q}` placeholder to support ranges. e.g. `{q:1}`, `{q:2..}`, etc. - Added `search(...)` and `transform-search(...)` action to trigger an fzf search with an arbitrary query string. This can be used to extend the search syntax of fzf. In the following example, fzf will use the first word of the query to trigger ripgrep search, and use the rest of the query to perform fzf search within the result. ```sh export TEMP=$(mktemp -u) trap 'rm -f "$TEMP"' EXIT TRANSFORMER=' rg_pat={q:1} # The first word is passed to ripgrep fzf_pat={q:2..} # The rest are passed to fzf if ! [[ -r "$TEMP" ]] || [[ $rg_pat != $(cat "$TEMP") ]]; then echo "$rg_pat" > "$TEMP" printf "reload:sleep 0.1; rg --column --line-number --no-heading --color=always --smart-case %q || true" "$rg_pat" fi echo "+search:$fzf_pat" ' fzf --ansi --disabled \ --with-shell 'bash -c' \ --bind "start,change:transform:$TRANSFORMER" ``` - You can now bind actions to multiple keys and events at once by writing a comma-separated list of keys and events before the colon ```sh # Load 'ps -ef' output on start and reload it on CTRL-R fzf --bind 'start,ctrl-r:reload:ps -ef' ``` - `--min-height` option now takes a number followed by `+`, which tells fzf to show at least that many items in the list section. The default value is now changed to `10+`. ```sh # You will only see the input section which takes 3 lines fzf --style=full --height 1% --min-height 3 # You will see 3 items in the list section fzf --style full --height 1% --min-height 3+ ``` - Shell integration scripts were updated to use `--min-height 20+` by default - `--header-lines` will be displayed at the top in `reverse-list` layout - Added `bell` action to ring the terminal bell ```sh # Press CTRL-Y to copy the current line to the clipboard and ring the bell fzf --bind 'ctrl-y:execute-silent(echo -n {} | pbcopy)+bell' ``` - Added `toggle-bind` action - Bug fixes and improvements - Fixed fish script to support fish 3.1.2 or later (@bitraid) 0.58.0 ------ _Release highlights: https://junegunn.github.io/fzf/releases/0.58.0/_ This version introduces three new border types, `--list-border`, `--input-border`, and `--header-border`, offering much greater flexibility for customizing the user interface. Also, fzf now offers "style presets" for quick customization, which can be activated using the `--style` option. | Preset | Screenshot | | :--- | :--- | | `default` | | | `full` | | | `minimal` | | - Style presets (#4160) - `--style=full[:BORDER_STYLE]` - `--style=default` - `--style=minimal` - Border and label for the list section (#4148) - Options - `--list-border[=STYLE]` - `--list-label=LABEL` - `--list-label-pos=COL[:bottom]` - Colors - `list-fg` - `list-bg` - `list-border` - `list-label` - Actions - `change-list-label` - `transform-list-label` - Border and label for the input section (prompt line and info line) (#4154) - Options - `--input-border[=STYLE]` - `--input-label=LABEL` - `--input-label-pos=COL[:bottom]` - Colors - `input-fg` (`query`) - `input-bg` - `input-border` - `input-label` - Actions - `change-input-label` - `transform-input-label` - Border and label for the header section (#4159) - Options - `--header-border[=STYLE]` - `--header-label=LABEL` - `--header-label-pos=COL[:bottom]` - Colors - `header-fg` (`header`) - `header-bg` - `header-border` - `header-label` - Actions - `change-header-label` - `transform-header-label` - Added `--preview-border[=STYLE]` as short for `--preview-window=border[-STYLE]` - Added new preview border style `line` which draws a single separator line between the preview window and the rest of the interface - fzf will now render a dashed line (`โ”ˆโ”ˆ`) in each `--gap` for better visual separation. ```sh # All bash/zsh functions, highlighted declare -f | perl -0 -pe 's/^}\n/}\0/gm' | bat --plain --language bash --color always | fzf --read0 --ansi --layout reverse --multi --highlight-line --gap ``` * You can customize the line using `--gap-line[=STR]`. - You can specify `border-native` to `--tmux` so that native tmux border is used instead of `--border`. This can be useful if you start a different program from inside the popup. ```sh fzf --tmux border-native --bind 'enter:execute:less {}' ``` - Added `toggle-multi-line` action - Added `toggle-hscroll` action - Added `change-nth` action for dynamically changing the value of the `--nth` option ```sh # Start with --nth 1, then 2, then 3, then back to the default, 1 echo 'foo foobar foobarbaz' | fzf --bind 'space:change-nth(2|3|)' --nth 1 -q foo ``` - `--nth` parts of each line can now be rendered in a different text style ```sh # nth in a different style ls -al | fzf --nth -1 --color nth:italic ls -al | fzf --nth -1 --color nth:reverse ls -al | fzf --nth -1 --color nth:reverse:bold # Dim the other parts ls -al | fzf --nth -1 --color nth:regular,fg:dim # With 'change-nth'. The current nth option is exported as $FZF_NTH. ps -ef | fzf --reverse --header-lines 1 --header-border bottom --input-border \ --color nth:regular,fg:dim \ --bind 'ctrl-n:change-nth(8..|1|2|3|4|5|6|7|)' \ --bind 'result:transform-prompt:echo "${FZF_NTH}> "' ``` - A single-character delimiter is now treated as a plain string delimiter rather than a regular expression delimiter, even if it's a regular expression meta-character. - This means you can just write `--delimiter '|'` instead of escaping it as `--delimiter '\|'` - Bug fixes - Bug fixes and improvements in fish scripts (thanks to @bitraid) 0.57.0 ------ - You can now resize the preview window by dragging the border - Built-in walker improvements - `--walker-root` can take multiple directory arguments. e.g. `--walker-root include src lib` - `--walker-skip` can handle multi-component patterns. e.g. `--walker-skip target/build` - Removed long processing delay when displaying images in the preview window - `FZF_PREVIEW_*` environment variables are exported to all child processes (#4098) - Bug fixes in fish scripts 0.56.3 ------ - Bug fixes in zsh scripts - fix(zsh): handle backtick trigger edge case (#4090) - revert(zsh): remove 'fc -RI' call in the history widget (#4093) - Thanks to @LangLangBart for the contributions 0.56.2 ------ - Bug fixes - Fixed abnormal scrolling behavior when `--wrap` is set (#4083) - [zsh] Fixed warning message when `ksh_arrays` is set (#4084) 0.56.1 ------ - Bug fixes and improvements - Fixed a race condition which would cause fzf to present stale results after `reload` (#4070) - `page-up` and `page-down` actions now work correctly with multi-line items (#4069) - `{n}` is allowed in `SCROLL` expression in `--preview-window` (#4079) - [zsh] Fixed regression in history loading with shared option (#4071) - [zsh] Better command extraction in zsh completion (#4082) - Thanks to @LangLangBart, @jaydee-coder, @alex-huff, and @vejkse for the contributions 0.56.0 ------ - Added `--gap[=N]` option to display empty lines between items. - This can be useful to visually separate adjacent multi-line items. ```sh # All bash functions, highlighted declare -f | perl -0777 -pe 's/^}\n/}\0/gm' | bat --plain --language bash --color always | fzf --read0 --ansi --reverse --multi --highlight-line --gap ``` - Or just to make the list easier to read. For single-line items, you probably want to set `--color gutter:-1` as well to hide the gutter. ```sh fzf --info inline-right --gap --color gutter:-1 ``` - Added `noinfo` option to `--preview-window` to hide the scroll indicator in the preview window - Bug fixes - Thanks to @LangLangBart, @akinomyoga, and @charlievieth for fixing the bugs 0.55.0 ------ _Release highlights: https://junegunn.github.io/fzf/releases/0.55.0/_ - Added `exact-boundary-match` type to the search syntax. When a search term is single-quoted, fzf will search for the exact occurrences of the string with both ends at word boundaries. ```sh fzf --query "'here'" << EOF come here not there EOF ``` - [bash] Fuzzy path completion is enabled for all commands - 1. If the default completion is not already set - 2. And if the current bash supports `complete -D` option - However, fuzzy completion for some commands can be "dynamically" disabled by the dynamic completion loader - See the comment in `__fzf_default_completion` function for more information - Comments are now allowed in `$FZF_DEFAULT_OPTS` and `$FZF_DEFAULT_OPTS_FILE` ```sh export FZF_DEFAULT_OPTS=' # Layout options --layout=reverse --info=inline-right # Show info on the right side of the prompt line # ... ' ``` - Hyperlinks (OSC 8) are now supported in the preview window and in the main window ```sh printf '<< \e]8;;http://github.com/junegunn/fzf\e\\Link to \e[32mfz\e[0mf\e]8;;\e\\ >>' | fzf --ansi fzf --preview "printf '<< \e]8;;http://github.com/junegunn/fzf\e\\Link to \e[32mfz\e[0mf\e]8;;\e\\ >>'" ``` - The default `--ellipsis` is now `ยทยท` instead of `..`. - [vim] A spec can have `exit` callback that is called with the exit status of fzf - This can be used to clean up temporary resources or restore the original state when fzf is closed without a selection - Fixed `--tmux bottom` when the status line is not at the bottom - Fixed extra scroll offset in multi-line mode (`--read0` or `--wrap`) - Added fallback `ps` command for `kill` completion on Cygwin 0.54.3 ------ - Fixed incompatibility of adaptive height specification and 'start:reload' ```sh # A regression in 0.54.0 would cause this to fail fzf --height '~100%' --bind 'start:reload:seq 10' ``` - Environment variables are now available to `$FZF_DEFAULT_COMMAND` ```sh FZF_DEFAULT_COMMAND='echo $FZF_QUERY' fzf --query foo ``` 0.54.2 ------ - Fixed incorrect syntax highlighting of truncated multi-line entries - Updated GoReleaser to 2.1.0 to simplify notarization of macOS binaries - macOS archives will be in `tar.gz` format instead of `zip` format since we no longer notarize the zip files but binaries - (Windows) Reverted a mintty fix in 0.54.0 - As a result, mouse may not work on mintty in fullscreen mode. However, fzf will correctly read non-ASCII input in fullscreen mode (`--no-height`). - fzf unfortunately cannot read non-ASCII input when not in fullscreen mode on Windows. So if you need to input non-ASCII characters, add `--no-height` to your `$FZF_DEFAULT_OPTS`. - Any help in fixing this issue will be appreciated (#3799, #3847). 0.54.1 ------ - Updated [fastwalk](https://github.com/charlievieth/fastwalk) dependency for built-in directory walker - [fastwalk: add optional sorting and improve documentation](https://github.com/charlievieth/fastwalk/pull/27) - [fastwalk: only check if MSYSTEM is set during MSYS/MSYS2](https://github.com/charlievieth/fastwalk/pull/28) - Thanks to @charlievieth - Reverted ALT-C binding of fish to use `cd` instead of `builtin cd` - `builtin cd` was introduced to work around a bug of `cd` coming from `zoxide init --cmd cd fish` where it cannot handle `--` argument. - However, the default `cd` of fish is actually a wrapper function for supporting `cd -`, so we want to use it instead. - See [#3928](https://github.com/junegunn/fzf/pull/3928) for more information and consider helping zoxide fix the bug. 0.54.0 ------ _Release highlights: https://junegunn.github.io/fzf/releases/0.54.0/_ - Implemented line wrap of long items - `--wrap` option enables line wrap - `--wrap-sign` customizes the sign for wrapped lines (default: `โ†ณ `) - `toggle-wrap` action toggles line wrap ```sh history | fzf --tac --wrap --bind 'ctrl-/:toggle-wrap' --wrap-sign $'\tโ†ณ ' ``` - fzf by default binds `CTRL-/` and `ALT-/` to `toggle-wrap` - Updated shell integration scripts to leverage line wrap - CTRL-R binding includes `--wrap-sign $'\tโ†ณ '` to indent wrapped lines - `kill **` completion uses `--wrap` to show the whole line by default instead of showing it in the preview window - Added `--info-command` option for customizing the info line ```sh # Prepend the current cursor position in yellow fzf --info-command='echo -e "\x1b[33;1m$FZF_POS\x1b[m/$FZF_INFO ๐Ÿ’›"' ``` - `$FZF_INFO` is set to the original info text - ANSI color codes are supported - Pointer and marker signs can be set to empty strings ```sh # Minimal style fzf --pointer '' --marker '' --prompt '' --info hidden ``` - Better cache management and improved rendering for `--tail` - Improved `--sync` behavior - When `--sync` is provided, fzf will not render the interface until the initial filtering and the associated actions (bound to any of `start`, `load`, `result`, or `focus`) are complete. ```sh # fzf will not render intermediate states (sleep 1; seq 1000000; sleep 1) | fzf --sync --query 5 --listen --bind start:up,load:up,result:up,focus:change-header:Ready ``` - GET endpoint is now available from `execute` and `transform` actions (it used to timeout due to lock conflict) ```sh fzf --listen --sync --bind 'focus:transform-header:curl -s localhost:$FZF_PORT?limit=0 | jq .' ``` - Added `offset-middle` action to place the current item is in the middle of the screen - fzf will not start the initial reader when `reload` or `reload-sync` is bound to `start` event. `fzf < /dev/null` or `: | fzf` are no longer required and extraneous `load` event will not fire due to the empty list. ```sh # Now this will work as expected. Previously, this would print an invalid header line. # `fzf < /dev/null` or `: | fzf` would fix the problem, but then an extraneous # `load` event would fire and the header would be prematurely updated. fzf --header 'Loading ...' --header-lines 1 \ --bind 'start:reload:sleep 1; ps -ef' \ --bind 'load:change-header:Loaded!' ``` - Fixed mouse support on Windows - Fixed crash when using `--tiebreak=end` with very long items - zsh 5.0 compatibility (thanks to @LangLangBart) - Fixed `--walker-skip` to also skip symlinks to directories - Fixed `result` event not fired when input stream is not complete - New tags will have `v` prefix so that they are available on https://proxy.golang.org/ 0.53.0 ------ _Release highlights: https://junegunn.github.io/fzf/releases/0.53.0/_ - Multi-line display - See [Processing multi-line items](https://junegunn.github.io/fzf/tips/processing-multi-line-items/) - fzf can now display multi-line items ```sh # All bash functions, highlighted declare -f | perl -0777 -pe 's/^}\n/}\0/gm' | bat --plain --language bash --color always | fzf --read0 --ansi --reverse --multi --highlight-line # Ripgrep multi-line output rg --pretty bash | perl -0777 -pe 's/\n\n/\n\0/gm' | fzf --read0 --ansi --multi --highlight-line --reverse --tmux 70% ``` - To disable multi-line display, use `--no-multi-line` - CTRL-R bindings of bash, zsh, and fish have been updated to leverage multi-line display - The default `--pointer` and `--marker` have been changed from `>` to Unicode bar characters as they look better with multi-line items - Added `--marker-multi-line` to customize the select marker for multi-line entries with the default set to `โ•ปโ”ƒโ•น` ``` โ•ปFirst line โ”ƒ... โ•นLast line ``` - Native tmux integration - Added `--tmux` option to replace fzf-tmux script and simplify distribution ```sh # --tmux [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]] # Center, 100% width and 70% height fzf --tmux 100%,70% --border horizontal --padding 1,2 # Left, 30% width fzf --tmux left,30% # Bottom, 50% height fzf --tmux bottom,50% ``` - To keep the implementation simple, it only uses popups. You need tmux 3.3 or later. - To use `--tmux` in Vim plugin: ```vim let g:fzf_layout = { 'tmux': '100%,70%' } ``` - Added support for endless input streams - See [Browsing log stream with fzf](https://junegunn.github.io/fzf/tips/browsing-log-streams/) - Added `--tail=NUM` option to limit the number of items to keep in memory. This is useful when you want to browse an endless stream of data (e.g. log stream) with fzf while limiting memory usage. ```sh # Interactive filtering of a log stream tail -f *.log | fzf --tail 100000 --tac --no-sort --exact ``` - Better Windows Support - fzf now works on Git bash (mintty) out of the box via winpty integration - Many fixes and improvements for Windows - man page is now embedded in the binary; `fzf --man` to see it - Changed the default `--scroll-off` to 3, as we think it's a better default - Process started by `execute` action now directly writes to and reads from `/dev/tty`. Manual `/dev/tty` redirection for interactive programs is no longer required. ```sh # Vim will work fine without /dev/tty redirection ls | fzf --bind 'space:execute:vim {}' > selected ``` - Added `print(...)` action to queue an arbitrary string to be printed on exit. This was mainly added to work around the limitation of `--expect` where it's not compatible with `--bind` on the same key and it would ignore other actions bound to it. ```sh # This doesn't work as expected because --expect is not compatible with --bind fzf --multi --expect ctrl-y --bind 'ctrl-y:select-all' # This is something you can do instead fzf --multi --bind 'enter:print()+accept,ctrl-y:select-all+print(ctrl-y)+accept' ``` - We also considered making them compatible, but realized that some users may have been relying on the current behavior. - [`NO_COLOR`](https://no-color.org/) environment variable is now respected. If the variable is set, fzf defaults to `--no-color` unless otherwise specified. 0.52.1 ------ - Fixed a critical bug in the Windows version - Windows users are strongly encouraged to upgrade to this version 0.52.0 ------ - Added `--highlight-line` to highlight the whole current line (ร  la `set cursorline` of Vim) - Added color names for selected lines: `selected-fg`, `selected-bg`, and `selected-hl` ```sh fzf --border --multi --info inline-right --layout reverse --marker โ– --pointer โ–Œ --prompt 'โ–Œ ' \ --highlight-line --color gutter:-1,selected-bg:238,selected-fg:146,current-fg:189 ``` - Added `click-header` event that is triggered when the header section is clicked. When the event is triggered, `$FZF_CLICK_HEADER_COLUMN` and `$FZF_CLICK_HEADER_LINE` are set. ```sh fd --type f | fzf --header $'[Files] [Directories]' --header-first \ --bind 'click-header:transform: (( FZF_CLICK_HEADER_COLUMN <= 7 )) && echo "reload(fd --type f)" (( FZF_CLICK_HEADER_COLUMN >= 9 )) && echo "reload(fd --type d)" ' ``` - Add `$FZF_COMPLETION_{DIR,PATH}_OPTS` for separately customizing the behavior of fuzzy completion ```sh # Set --walker options without 'follow' not to follow symbolic links FZF_COMPLETION_PATH_OPTS="--walker=file,dir,hidden" FZF_COMPLETION_DIR_OPTS="--walker=dir,hidden" ``` - Fixed Windows argument escaping - Bug fixes and improvements - The code was heavily refactored to allow using fzf as a library in Go programs. The API is still experimental and subject to change. - https://gist.github.com/junegunn/193990b65be48a38aac6ac49d5669170 0.51.0 ------ - Added a new environment variable `$FZF_POS` exported to the child processes. It's the vertical position of the cursor in the list starting from 1. ```sh # Toggle selection to the top or to the bottom seq 30 | fzf --multi --bind 'load:pos(10)' \ --bind 'shift-up:transform:for _ in $(seq $FZF_POS $FZF_MATCH_COUNT); do echo -n +toggle+up; done' \ --bind 'shift-down:transform:for _ in $(seq 1 $FZF_POS); do echo -n +toggle+down; done' ``` - Added `--with-shell` option to start child processes with a custom shell command and flags ```sh gem list | fzf --with-shell 'ruby -e' \ --preview 'pp Gem::Specification.find_by_name({1})' \ --bind 'ctrl-o:execute-silent: spec = Gem::Specification.find_by_name({1}) [spec.homepage, *spec.metadata.filter { _1.end_with?("uri") }.values].uniq.each do system "open", _1 end ' ``` - Added `change-multi` action for dynamically changing `--multi` option - `change-multi` - enable multi-select mode with no limit - `change-multi(NUM)` - enable multi-select mode with a limit - `change-multi(0)` - disable multi-select mode - Windows improvements - `become` action is now supported on Windows - Unlike in *nix, this does not use `execve(2)`. Instead it spawns a new process and waits for it to finish, so the exact behavior may differ. - Fixed argument escaping for Windows cmd.exe. No redundant escaping of backslashes. - Bug fixes and improvements 0.50.0 ------ - Search performance optimization. You can observe 50%+ improvement in some scenarios. ``` $ rg --line-number --no-heading --smart-case . > $DATA $ wc < $DATA 5520118 26862362 897487793 $ hyperfine -w 1 -L bin fzf-0.49.0,fzf-7ce6452,fzf-a5447b8,fzf '{bin} --filter "///" < $DATA | head -30' Summary fzf --filter "///" < $DATA | head -30 ran 1.16 ยฑ 0.03 times faster than fzf-a5447b8 --filter "///" < $DATA | head -30 1.23 ยฑ 0.03 times faster than fzf-7ce6452 --filter "///" < $DATA | head -30 1.52 ยฑ 0.03 times faster than fzf-0.49.0 --filter "///" < $DATA | head -30 ``` - Added `jump` and `jump-cancel` events that are triggered when leaving `jump` mode ```sh # Default behavior fzf --bind space:jump # Same as jump-accept action fzf --bind space:jump,jump:accept # Accept on jump, abort on cancel fzf --bind space:jump,jump:accept,jump-cancel:abort # Change header on jump-cancel fzf --bind 'space:change-header(Type jump label)+jump,jump-cancel:change-header:Jump cancelled' ``` - Added a new environment variable `$FZF_KEY` exported to the child processes. It's the name of the last key pressed. ```sh fzf --bind 'space:jump,jump:accept,jump-cancel:transform:[[ $FZF_KEY =~ ctrl-c ]] && echo abort' ``` - fzf can be built with profiling options. See [BUILD.md](BUILD.md) for more information. - Bug fixes 0.49.0 ------ - Ingestion performance improved by around 40% (more or less depending on options) - `--info=hidden` and `--info=inline-right` will no longer hide the horizontal separator by default. This gives you more flexibility in customizing the layout. ```sh fzf --border --info=inline-right fzf --border --info=inline-right --separator โ• fzf --border --info=inline-right --no-separator fzf --border --info=hidden fzf --border --info=hidden --separator โ” fzf --border --info=hidden --no-separator ``` - Added two environment variables exported to the child processes - `FZF_PREVIEW_LABEL` - `FZF_BORDER_LABEL` ```sh # Use the current value of $FZF_PREVIEW_LABEL to determine which actions to perform git ls-files | fzf --header 'Press CTRL-P to change preview mode' \ --bind='ctrl-p:transform:[[ $FZF_PREVIEW_LABEL =~ cat ]] \ && echo "change-preview(git log --color=always \{})+change-preview-label([[ log ]])" \ || echo "change-preview(bat --color=always \{})+change-preview-label([[ cat ]])"' ``` - Renamed `track` action to `track-current` to highlight the difference between the global tracking state set by `--track` and a one-off tracking action - `track` is still available as an alias - Added `untrack-current` and `toggle-track-current` actions - `*-current` actions are no-op when the global tracking state is set - Bug fixes and minor improvements 0.48.1 ------ - CTRL-T and ALT-C bindings can be disabled by setting `FZF_CTRL_T_COMMAND` and `FZF_ALT_C_COMMAND` to empty strings respectively when sourcing the script ```sh # bash FZF_CTRL_T_COMMAND= FZF_ALT_C_COMMAND= eval "$(fzf --bash)" # zsh FZF_CTRL_T_COMMAND= FZF_ALT_C_COMMAND= eval "$(fzf --zsh)" # fish fzf --fish | FZF_CTRL_T_COMMAND= FZF_ALT_C_COMMAND= source ``` - Setting the variables after sourcing the script will have no effect - Bug fixes 0.48.0 ------ - Shell integration scripts are now embedded in the fzf binary. This simplifies the distribution, and the users are less likely to have problems caused by using incompatible scripts and binaries. - bash ```sh # Set up fzf key bindings and fuzzy completion eval "$(fzf --bash)" ``` - zsh ```sh # Set up fzf key bindings and fuzzy completion eval "$(fzf --zsh)" ``` - fish ```fish # Set up fzf key bindings fzf --fish | source ``` - Added options for customizing the behavior of the built-in walker | Option | Description | Default | | --- | --- | --- | | `--walker=OPTS` | Walker options (`[file][,dir][,follow][,hidden]`) | `file,follow,hidden` | | `--walker-root=DIR` | Root directory from which to start walker | `.` | | `--walker-skip=DIRS` | Comma-separated list of directory names to skip | `.git,node_modules` | - Examples ```sh # Built-in walker is only used by standalone fzf when $FZF_DEFAULT_COMMAND is not set unset FZF_DEFAULT_COMMAND fzf # default: --walker=file,follow,hidden --walker-root=. --walker-skip=.git,node_modules fzf --walker=file,dir,hidden,follow --walker-skip=.git,node_modules,target # Walker options in $FZF_DEFAULT_OPTS export FZF_DEFAULT_OPTS="--walker=file,dir,hidden,follow --walker-skip=.git,node_modules,target" fzf # Reading from STDIN; --walker is ignored seq 100 | fzf --walker=dir # Reading from $FZF_DEFAULT_COMMAND; --walker is ignored export FZF_DEFAULT_COMMAND='seq 100' fzf --walker=dir ``` - Shell integration scripts have been updated to use the built-in walker with these new options and they are now much faster out of the box. 0.47.0 ------ - Replaced ["the default find command"][find] with a built-in directory walker to simplify the code and to achieve better performance and consistent behavior across platforms. This doesn't affect you if you have `$FZF_DEFAULT_COMMAND` set. - Breaking changes: - Unlike [the previous "find" command][find], the new traversal code will list hidden files, but hidden directories will still be ignored - No filtering of `devtmpfs` or `proc` types - Traversal is parallelized, so the order of the entries will be different each time - You may wonder why fzf implements directory walker anyway when it's a filter program following the [Unix philosophy][unix]. But fzf has had [the walker code for years][walker] to tackle the performance problem on Windows. And I decided to use the same approach on different platforms as well for the benefits listed above. - Built-in walker is using the excellent [charlievieth/fastwalk][fastwalk] library, which easily outperforms its competitors and supports safely following symlinks. - Added `$FZF_DEFAULT_OPTS_FILE` to allow managing default options in a file - See [#3618](https://github.com/junegunn/fzf/pull/3618) - Option precedence from lower to higher 1. Options read from `$FZF_DEFAULT_OPTS_FILE` 1. Options from `$FZF_DEFAULT_OPTS` 1. Options from command-line arguments - Bug fixes and improvements [find]: https://github.com/junegunn/fzf/blob/0.46.1/src/constants.go#L60-L64 [walker]: https://github.com/junegunn/fzf/pull/1847 [fastwalk]: https://github.com/charlievieth/fastwalk [unix]: https://en.wikipedia.org/wiki/Unix_philosophy 0.46.1 ------ - Bug fixes and improvements - Fixed Windows binaries - Downgraded Go version to 1.20 to support older versions of Windows - https://tip.golang.org/doc/go1.21#windows - Updated [rivo/uniseg](https://github.com/rivo/uniseg) dependency to v0.4.6 0.46.0 ------ - Added two new events - `result` - triggered when the filtering for the current query is complete and the result list is ready - `resize` - triggered when the terminal size is changed - fzf now exports the following environment variables to the child processes | Variable | Description | | --- | --- | | `FZF_LINES` | Number of lines fzf takes up excluding padding and margin | | `FZF_COLUMNS` | Number of columns fzf takes up excluding padding and margin | | `FZF_TOTAL_COUNT` | Total number of items | | `FZF_MATCH_COUNT` | Number of matched items | | `FZF_SELECT_COUNT` | Number of selected items | | `FZF_QUERY` | Current query string | | `FZF_PROMPT` | Prompt string | | `FZF_ACTION` | The name of the last action performed | - This allows you to write sophisticated transformations like so ```sh # Script to dynamically resize the preview window transformer=' # 1 line for info, another for prompt, and 2 more lines for preview window border lines=$(( FZF_LINES - FZF_MATCH_COUNT - 4 )) if [[ $FZF_MATCH_COUNT -eq 0 ]]; then echo "change-preview-window:hidden" elif [[ $lines -gt 3 ]]; then echo "change-preview-window:$lines" elif [[ $FZF_PREVIEW_LINES -ne 3 ]]; then echo "change-preview-window:3" fi ' seq 10000 | fzf --preview 'seq {} 10000' --preview-window up \ --bind "result:transform:$transformer" \ --bind "resize:transform:$transformer" ``` - And we're phasing out `{fzf:prompt}` and `{fzf:action}` - Changed [mattn/go-runewidth](https://github.com/mattn/go-runewidth) dependency to [rivo/uniseg](https://github.com/rivo/uniseg) for accurate results - Set `--ambidouble` if your terminal displays ambiguous width characters (e.g. box-drawing characters for borders) as 2 columns - `RUNEWIDTH_EASTASIAN=1` is still respected for backward compatibility, but it's recommended that you use this new option instead - Bug fixes 0.45.0 ------ - Added `transform` action to conditionally perform a series of actions ```sh # Disallow selecting an empty line echo -e "1. Hello\n2. Goodbye\n\n3. Exit" | fzf --height '~100%' --reverse --header 'Select one' \ --bind 'enter:transform:[[ -n {} ]] && echo accept || echo "change-header:Invalid selection"' # Move cursor past the empty line echo -e "1. Hello\n2. Goodbye\n\n3. Exit" | fzf --height '~100%' --reverse --header 'Select one' \ --bind 'enter:transform:[[ -n {} ]] && echo accept || echo "change-header:Invalid selection"' \ --bind 'focus:transform:[[ -n {} ]] && exit; [[ {fzf:action} =~ up$ ]] && echo up || echo down' # A single key binding to toggle between modes fd --type file | fzf --prompt 'Files> ' \ --header 'CTRL-T: Switch between Files/Directories' \ --bind 'ctrl-t:transform:[[ ! {fzf:prompt} =~ Files ]] && echo "change-prompt(Files> )+reload(fd --type file)" || echo "change-prompt(Directories> )+reload(fd --type directory)"' ``` - Added placeholder expressions - `{fzf:action}` - The name of the last action performed - `{fzf:prompt}` - Prompt string (including ANSI color codes) - `{fzf:query}` - Synonym for `{q}` - Added support for negative height ```sh # Terminal height minus 1, so you can still see the command line fzf --height=-1 ``` - This handles a terminal resize better than `--height=$(($(tput lines) - 1))` - Added `accept-or-print-query` action that acts like `accept` but prints the current query when there's no match for the query ```sh # You can make CTRL-R paste the current query when there's no match export FZF_CTRL_R_OPTS='--bind enter:accept-or-print-query' ``` - Note that there are alternative ways to implement the same strategy ```sh # 'become' is apparently more versatile but it's not available on Windows. export FZF_CTRL_R_OPTS='--bind "enter:become:if [ -z {} ]; then echo {q}; else echo {}; fi"' # Using the new 'transform' action export FZF_CTRL_R_OPTS='--bind "enter:transform:[ -z {} ] && echo print-query || echo accept"' ``` - Added `show-header` and `hide-header` actions - Bug fixes 0.44.1 ------ - Fixed crash when preview window is hidden on `focus` event 0.44.0 ------ - (Experimental) Sixel image support in preview window (not available on Windows) - [bin/fzf-preview.sh](bin/fzf-preview.sh) is added to demonstrate how to display an image using Kitty image protocol or Sixel. You can use it like so: ```sh fzf --preview='fzf-preview.sh {}' ``` - (Experimental) iTerm2 inline image protocol support in preview window (not available on Windows) ```sh # Using https://iterm2.com/utilities/imgcat fzf --preview 'imgcat -W $FZF_PREVIEW_COLUMNS -H $FZF_PREVIEW_LINES {}' ``` - HTTP server can be configured to accept remote connections ```sh # FZF_API_KEY is required for a non-localhost listen address export FZF_API_KEY="$(head -c 32 /dev/urandom | base64)" fzf --listen 0.0.0.0:6266 ``` - To allow remote process execution, use `--listen-unsafe` instead (`execute*`, `reload*`, `become`, `preview`, `change-preview`, `transform-*`) ```sh fzf --listen-unsafe 0.0.0.0:6266 ``` - Bug fixes 0.43.0 ------ - (Experimental) Added support for Kitty image protocol in the preview window (not available on Windows) ```sh fzf --preview=' if file --mime-type {} | grep -qF image/; then # --transfer-mode=memory is the fastest option but if you want fzf to be able # to redraw the image on terminal resize or on 'change-preview-window', # you need to use --transfer-mode=stream. kitty icat --clear --transfer-mode=memory --unicode-placeholder --stdin=no --place=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}@0x0 {} | sed \$d else bat --color=always {} fi ' ``` - (Experimental) `--listen` server can report program state in JSON format (`GET /`) ```sh # fzf server started in "headless" mode fzf --listen 6266 2> /dev/null # Get program state curl localhost:6266 | jq . # Increase the number of items returned (default: 100) curl localhost:6266?limit=1000 | jq . ``` - `--listen` server can be secured by setting `$FZF_API_KEY` environment variable. ```sh export FZF_API_KEY="$(head -c 32 /dev/urandom | base64)" # Server fzf --listen 6266 # Client curl localhost:6266 -H "x-api-key: $FZF_API_KEY" -d 'change-query(yo)' ``` - Added `toggle-header` action - Added mouse events for `--bind` - `scroll-up` (bound to `up`) - `scroll-down` (bound to `down`) - `shift-scroll-up` (bound to `toggle+up`) - `shift-scroll-down` (bound to `toggle+down`) - `shift-left-click` (bound to `toggle`) - `shift-right-click` (bound to `toggle`) - `preview-scroll-up` (bound to `preview-up`) - `preview-scroll-down` (bound to `preview-down`) ```sh # Twice faster scrolling both in the main window and the preview window fzf --bind 'scroll-up:up+up,scroll-down:down+down' \ --bind 'preview-scroll-up:preview-up+preview-up' \ --bind 'preview-scroll-down:preview-down+preview-down' \ --preview 'cat {}' ``` - Added `offset-up` and `offset-down` actions ```sh # Scrolling will behave similarly to CTRL-E and CTRL-Y of vim fzf --bind scroll-up:offset-up,scroll-down:offset-down \ --bind ctrl-y:offset-up,ctrl-e:offset-down \ --scroll-off=5 ``` - Shell extensions - Updated bash completion for fzf options - bash key bindings no longer requires perl; it will use awk or mawk instead if perl is not found - Basic context-aware completion for ssh command - Applied `--scheme=path` for better ordering of the result - Bug fixes and improvements 0.42.0 ------ - Added new info style: `--info=right` - Added new info style: `--info=inline-right` - Added new border style `thinblock` which uses symbols for legacy computing [one eighth block elements](https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing) - Similarly to `block`, this style is suitable when using a different background color because the window is completely contained within the border. ```sh BAT_THEME=GitHub fzf --info=right --border=thinblock --preview-window=border-thinblock \ --margin=3 --scrollbar=โ–โ–• --preview='bat --color=always --style=numbers {}' \ --color=light,query:238,fg:238,bg:251,bg+:249,gutter:251,border:248,preview-bg:253 ``` - This style may not render correctly depending on the font and the terminal emulator. 0.41.1 ------ - Fixed a bug where preview window is not updated when `--disabled` is set and a reload is triggered by `change:reload` binding 0.41.0 ------ - Added color name `preview-border` and `preview-scrollbar` - Added new border style `block` which uses [block elements](https://en.wikipedia.org/wiki/Block_Elements) - `--scrollbar` can take two characters, one for the main window, the other for the preview window - Putting it altogether: ```sh fzf-tmux -p 80% --padding 1,2 --preview 'bat --style=plain --color=always {}' \ --color 'bg:237,bg+:235,gutter:237,border:238,scrollbar:236' \ --color 'preview-bg:235,preview-border:236,preview-scrollbar:234' \ --preview-window 'border-block' --border block --scrollbar 'โ–Œโ–' ``` - Bug fixes and improvements 0.40.0 ------ - Added `zero` event that is triggered when there's no match ```sh # Reload the candidate list when there's no match echo $RANDOM | fzf --bind 'zero:reload(echo $RANDOM)+clear-query' --height 3 ``` - New actions - Added `track` action which makes fzf track the current item when the search result is updated. If the user manually moves the cursor, or the item is not in the updated search result, tracking is automatically disabled. Tracking is useful when you want to see the surrounding items by deleting the query string. ```sh # Narrow down the list with a query, point to a command, # and hit CTRL-T to see its surrounding commands. export FZF_CTRL_R_OPTS=" --preview 'echo {}' --preview-window up:3:hidden:wrap --bind 'ctrl-/:toggle-preview' --bind 'ctrl-t:track+clear-query' --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort' --color header:italic --header 'Press CTRL-Y to copy command into clipboard'" ``` - Added `change-header(...)` - Added `transform-header(...)` - Added `toggle-track` action - Fixed `--track` behavior when used with `--tac` - However, using `--track` with `--tac` is not recommended. The resulting behavior can be very confusing. - Bug fixes and improvements 0.39.0 ------ - Added `one` event that is triggered when there's only one match ```sh # Automatically select the only match seq 10 | fzf --bind one:accept ``` - Added `--track` option that makes fzf track the current selection when the result list is updated. This can be useful when browsing logs using fzf with sorting disabled. ```sh git log --oneline --graph --color=always | nl | fzf --ansi --track --no-sort --layout=reverse-list ``` - If you use `--listen` option without a port number fzf will automatically allocate an available port and export it as `$FZF_PORT` environment variable. ```sh # Automatic port assignment fzf --listen --bind 'start:execute-silent:echo $FZF_PORT > /tmp/fzf-port' # Say hello curl "localhost:$(cat /tmp/fzf-port)" -d 'preview:echo Hello, fzf is listening on $FZF_PORT.' ``` - A carriage return and a line feed character will be rendered as dim โ and โŠ respectively. ```sh printf "foo\rbar\nbaz" | fzf --read0 --preview 'echo {}' ``` - fzf will stop rendering a non-displayable characters as a space. This will likely cause less glitches in the preview window. ```sh fzf --preview 'head -1000 /dev/random' ``` - Bug fixes and improvements 0.38.0 ------ - New actions - `become(...)` - Replace the current fzf process with the specified command using `execve(2)` system call. See https://github.com/junegunn/fzf#turning-into-a-different-process for more information. ```sh # Open selected files in Vim fzf --multi --bind 'enter:become(vim {+})' # Open the file in Vim and go to the line git grep --line-number . | fzf --delimiter : --nth 3.. --bind 'enter:become(vim {1} +{2})' ``` - This action is not supported on Windows - `show-preview` - `hide-preview` - Bug fixes - `--preview-window 0,hidden` should not execute the preview command until `toggle-preview` action is triggered 0.37.0 ------ - Added a way to customize the separator of inline info ```sh fzf --info 'inline: โ•ฑ ' --prompt 'โ•ฑ ' --color prompt:bright-yellow ``` - New event - `focus` - Triggered when the focus changes due to a vertical cursor movement or a search result update ```sh fzf --bind 'focus:transform-preview-label:echo [ {} ]' --preview 'cat {}' # Any action bound to the event runs synchronously and thus can make the interface sluggish # e.g. lolcat isn't one of the fastest programs, and every cursor movement in # fzf will be noticeably affected by its execution time fzf --bind 'focus:transform-preview-label:echo [ {} ] | lolcat -f' --preview 'cat {}' # Beware not to introduce an infinite loop seq 10 | fzf --bind 'focus:up' --cycle ``` - New actions - `change-border-label` - `change-preview-label` - `transform-border-label` - `transform-preview-label` - Bug fixes and improvements 0.36.0 ------ - Added `--listen=HTTP_PORT` option to start HTTP server. It allows external processes to send actions to perform via POST method. ```sh # Start HTTP server on port 6266 fzf --listen 6266 # Send actions to the server curl -XPOST localhost:6266 -d 'reload(seq 100)+change-prompt(hundred> )' ``` - Added draggable scrollbar to the main search window and the preview window ```sh # Hide scrollbar fzf --no-scrollbar # Customize scrollbar fzf --scrollbar โ”† --color scrollbar:blue ``` - New event - Added `load` event that is triggered when the input stream is complete and the initial processing of the list is complete. ```sh # Change the prompt to "loaded" when the input stream is complete (seq 10; sleep 1; seq 11 20) | fzf --prompt 'Loading> ' --bind 'load:change-prompt:Loaded> ' # You can use it instead of 'start' event without `--sync` if asynchronous # trigger is not an issue. (seq 10; sleep 1; seq 11 20) | fzf --bind 'load:last' ``` - New actions - Added `pos(...)` action to move the cursor to the numeric position - `first` and `last` are equivalent to `pos(1)` and `pos(-1)` respectively ```sh # Put the cursor on the 10th item seq 100 | fzf --sync --bind 'start:pos(10)' # Put the cursor on the 10th to last item seq 100 | fzf --sync --bind 'start:pos(-10)' ``` - Added `reload-sync(...)` action which replaces the current list only after the reload process is complete. This is useful when the command takes a while to produce the initial output and you don't want fzf to run against an empty list while the command is running. ```sh # You can still filter and select entries from the initial list for 3 seconds seq 100 | fzf --bind 'load:reload-sync(sleep 3; seq 1000)+unbind(load)' ``` - Added `next-selected` and `prev-selected` actions to move between selected items ```sh # `next-selected` will move the pointer to the next selected item below the current line # `prev-selected` will move the pointer to the previous selected item above the current line seq 10 | fzf --multi --bind ctrl-n:next-selected,ctrl-p:prev-selected # Both actions respect --layout option seq 10 | fzf --multi --bind ctrl-n:next-selected,ctrl-p:prev-selected --layout reverse ``` - Added `change-query(...)` action that simply changes the query string to the given static string. This can be useful when used with `--listen`. ```sh curl localhost:6266 -d "change-query:$(date)" ``` - Added `transform-prompt(...)` action for transforming the prompt string using an external command ```sh # Press space to change the prompt string using an external command # (only the first line of the output is taken) fzf --bind 'space:reload(ls),load:transform-prompt(printf "%s> " "$(date)")' ``` - Added `transform-query(...)` action for transforming the query string using an external command ```sh # Press space to convert the query to uppercase letters fzf --bind 'space:transform-query(tr "[:lower:]" "[:upper:]" <<< {q})' # Bind it to 'change' event for automatic conversion fzf --bind 'change:transform-query(tr "[:lower:]" "[:upper:]" <<< {q})' # Can only type numbers fzf --bind 'change:transform-query(sed "s/[^0-9]//g" <<< {q})' ``` - `put` action can optionally take an argument string ```sh # a will put 'alpha' on the prompt, ctrl-b will put 'bravo' fzf --bind 'a:put+put(lpha),ctrl-b:put(bravo)' ``` - Added color name `preview-label` for `--preview-label` (defaults to `label` for `--border-label`) - Better support for (Windows) terminals where each box-drawing character takes 2 columns. Set `RUNEWIDTH_EASTASIAN` environment variable to `0` or `1`. - On Vim, the variable will be automatically set if `&ambiwidth` is `double` - Behavior changes - fzf will always execute the preview command if the command template contains `{q}` even when it's empty. If you prefer the old behavior, you'll have to check if `{q}` is empty in your command. ```sh # This will show // even when the query is empty : | fzf --preview 'echo /{q}/' # But if you don't want it, : | fzf --preview '[ -n {q} ] || exit; echo /{q}/' ``` - `double-click` will behave the same as `enter` unless otherwise specified, so you don't have to repeat the same action twice in `--bind` in most cases. ```sh # No need to bind 'double-click' to the same action fzf --bind 'enter:execute:less {}' # --bind 'double-click:execute:less {}' ``` - If the color for `separator` is not specified, it will default to the color for `border`. Same holds true for `scrollbar`. This is to reduce the number of configuration items required to achieve a consistent color scheme. - If `follow` flag is specified in `--preview-window` option, fzf will automatically scroll to the bottom of the streaming preview output. But when the user manually scrolls the window, the following stops. With this version, fzf will resume following if the user scrolls the window to the bottom. - Default border style on Windows is changed to `sharp` because some Windows terminals are not capable of displaying `rounded` border characters correctly. - Minor bug fixes and improvements 0.35.1 ------ - Fixed a bug where fzf with `--tiebreak=chunk` crashes on inverse match query - Fixed a bug where clicking above fzf would paste escape sequences 0.35.0 ------ - Added `start` event that is triggered only once when fzf finder starts. Since fzf consumes the input stream asynchronously, the input list is not available unless you use `--sync`. ```sh seq 100 | fzf --multi --sync --bind 'start:last+select-all+preview(echo welcome)' ``` - Added `--border-label` and `--border-label-pos` for putting label on the border ```sh # ANSI color codes are supported # (with https://github.com/busyloop/lolcat) label=$(curl -s http://metaphorpsum.com/sentences/1 | lolcat -f) # Border label at the center fzf --height=10 --border --border-label="โ•ข $label โ•Ÿ" --color=label:italic:black # Left-aligned (positive integer) fzf --height=10 --border --border-label="โ•ข $label โ•Ÿ" --border-label-pos=3 --color=label:italic:black # Right-aligned (negative integer) on the bottom line (:bottom) fzf --height=10 --border --border-label="โ•ข $label โ•Ÿ" --border-label-pos=-3:bottom --color=label:italic:black ``` - Also added `--preview-label` and `--preview-label-pos` for the border of the preview window ```sh fzf --preview 'cat {}' --border --preview-label=' Preview ' --preview-label-pos=2 ``` - Info panel (match counter) will be followed by a horizontal separator by default - Use `--no-separator` or `--separator=''` to hide the separator - You can specify an arbitrary string that is repeated to form the horizontal separator. e.g. `--separator=โ•ธ` - The color of the separator can be customized via `--color=separator:...` - ANSI color codes are also supported ```sh fzf --separator=โ•ธ --color=separator:green fzf --separator=$(lolcat -f -F 1.4 <<< โ–โ–โ–‚โ–ƒโ–„โ–…โ–†โ–†โ–…โ–„โ–ƒโ–‚โ–โ–) --info=inline ``` - Added `--border=bold` and `--border=double` along with `--preview-window=border-bold` and `--preview-window=border-double` 0.34.0 ------ - Added support for adaptive `--height`. If the `--height` value is prefixed with `~`, fzf will automatically determine the height in the range according to the input size. ```sh seq 1 | fzf --height ~70% --border --padding 1 --margin 1 seq 10 | fzf --height ~70% --border --padding 1 --margin 1 seq 100 | fzf --height ~70% --border --padding 1 --margin 1 ``` - There are a few limitations - Not compatible with percent top/bottom margin/padding ```sh # This is not allowed (top/bottom margin in percent value) fzf --height ~50% --border --margin 5%,10% # This is allowed (top/bottom margin in fixed value) fzf --height ~50% --border --margin 2,10% ``` - fzf will not start until it can determine the right height for the input ```sh # fzf will open immediately (sleep 2; seq 10) | fzf --height 50% # fzf will open after 2 seconds (sleep 2; seq 10) | fzf --height ~50% (sleep 2; seq 1000) | fzf --height ~50% ``` - Fixed tcell renderer used to render full-screen fzf on Windows - ~~`--no-clear` is deprecated. Use `reload` action instead.~~ 0.33.0 ------ - Added `--scheme=[default|path|history]` option to choose scoring scheme - (Experimental) - We updated the scoring algorithm in 0.32.0, however we have learned that this new scheme (`default`) is not always giving the optimal result - `path`: Additional bonus point is only given to the characters after path separator. You might want to choose this scheme if you have many files with spaces in their paths. - `history`: No additional bonus points are given so that we give more weight to the chronological ordering. This is equivalent to the scoring scheme before 0.32.0. This also sets `--tiebreak=index`. - ANSI color sequences with colon delimiters are now supported. ```sh printf "\e[38;5;208mOption 1\e[m\nOption 2" | fzf --ansi printf "\e[38:5:208mOption 1\e[m\nOption 2" | fzf --ansi ``` - Support `border-{up,down}` as the synonyms for `border-{top,bottom}` in `--preview-window` - Added support for ANSI `strikethrough` ```sh printf "\e[9mdeleted" | fzf --ansi fzf --color fg+:strikethrough ``` 0.32.1 ------ - Fixed incorrect ordering of `--tiebreak=chunk` - fzf-tmux will show fzf border instead of tmux popup border (requires tmux 3.3) ```sh fzf-tmux -p70% fzf-tmux -p70% --color=border:bright-red fzf-tmux -p100%,60% --color=border:bright-yellow --border=horizontal --padding 1,5 --margin 1,0 fzf-tmux -p70%,100% --color=border:bright-green --border=vertical # Key bindings (CTRL-T, CTRL-R, ALT-C) will use these options export FZF_TMUX_OPTS='-p100%,60% --color=border:green --border=horizontal --padding 1,5 --margin 1,0' ``` 0.32.0 ------ - Updated the scoring algorithm - Different bonus points to different categories of word boundaries (listed higher to lower bonus point) - Word after whitespace characters or beginning of the string - Word after common delimiter characters (`/,:;|`) - Word after other non-word characters ```sh # foo/bar.sh` is preferred over `foo-bar.sh` on `bar` fzf --query=bar --height=4 << EOF foo-bar.sh foo/bar.sh EOF ``` - Added a new tiebreak `chunk` - Favors the line with shorter matched chunk. A chunk is a set of consecutive non-whitespace characters. - Unlike the default `length`, this scheme works well with tabular input ```sh # length prefers item #1, because the whole line is shorter, # chunk prefers item #2, because the matched chunk ("foo") is shorter fzf --height=6 --header-lines=2 --tiebreak=chunk --reverse --query=fo << "EOF" N | Field1 | Field2 | Field3 - | ------ | ------ | ------ 1 | hello | foobar | baz 2 | world | foo | bazbaz EOF ``` - If the input does not contain any spaces, `chunk` is equivalent to `length`. But we're not going to set it as the default because it is computationally more expensive. - Bug fixes and improvements 0.31.0 ------ - Added support for an alternative preview window layout that is activated when the size of the preview window is smaller than a certain threshold. ```sh # If the width of the preview window is smaller than 50 columns, # it will be displayed above the search window. fzf --preview 'cat {}' --preview-window 'right,50%,border-left,<50(up,30%,border-bottom)' # Or you can just hide it like so fzf --preview 'cat {}' --preview-window '<50(hidden)' ``` - fzf now uses SGR mouse mode to properly support mouse on larger terminals - You can now use characters that do not satisfy `unicode.IsGraphic` constraint for `--marker`, `--pointer`, and `--ellipsis`. Allows Nerd Fonts and stuff. Use at your own risk. - Bug fixes and improvements - Shell extension - `kill` completion now requires trigger sequence (`**`) for consistency 0.30.0 ------ - Fixed cursor flickering over the screen by hiding it during rendering - Added `--ellipsis` option. You can take advantage of it to make fzf effectively search non-visible parts of the item. ```sh # Search against hidden line numbers on the far right nl /usr/share/dict/words | awk '{printf "%s%1000s\n", $2, $1}' | fzf --nth=-1 --no-hscroll --ellipsis='' | awk '{print $2}' ``` - Added `rebind` action for restoring bindings after `unbind` - Bug fixes and improvements 0.29.0 ------ - Added `change-preview(...)` action to change the `--preview` command - cf. `preview(...)` is a one-off action that doesn't change the default preview command - Added `change-preview-window(...)` action - You can rotate through the different options separated by `|` ```sh fzf --preview 'cat {}' --preview-window right:40% \ --bind 'ctrl-/:change-preview-window(right,70%|down,40%,border-top|hidden|)' ``` - Fixed rendering of the prompt line when overflow occurs with `--info=inline` 0.28.0 ------ - Added `--header-first` option to print header before the prompt line ```sh fzf --header $'Welcome to fzf\nโ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”โ–”' --reverse --height 30% --border --header-first ``` - Added `--scroll-off=LINES` option (similar to `scrolloff` option of Vim) - You can set it to a very large number so that the cursor stays in the middle of the screen while scrolling ```sh fzf --scroll-off=5 fzf --scroll-off=999 ``` - Fixed bug where preview window is not updated on `reload` (#2644) - fzf on Windows will also use `$SHELL` to execute external programs - See #2638 and #2647 - Thanks to @rashil2000, @vovcacik, and @janlazo 0.27.3 ------ - Preview window is `hidden` by default when there are `preview` bindings but `--preview` command is not given - Fixed bug where `{n}` is not properly reset on `reload` - Fixed bug where spinner is not displayed on `reload` - Enhancements in tcell renderer for Windows (#2616) - Vim plugin - `sinklist` is added as a synonym to `sink*` so that it's easier to add a function to a spec dictionary ```vim let spec = { 'source': 'ls', 'options': ['--multi', '--preview', 'cat {}'] } function spec.sinklist(matches) echom string(a:matches) endfunction call fzf#run(fzf#wrap(spec)) ``` - Vim 7 compatibility 0.27.2 ------ - 16 base ANSI colors can be specified by their names ```sh fzf --color fg:3,fg+:11 fzf --color fg:yellow,fg+:bright-yellow ``` - Fix bug where `--read0` not properly displaying long lines 0.27.1 ------ - Added `unbind` action. In the following Ripgrep launcher example, you can use `unbind(reload)` to switch to fzf-only filtering mode. - See https://github.com/junegunn/fzf/blob/master/ADVANCED.md#switching-to-fzf-only-search-mode - Vim plugin - Vim plugin will stop immediately even when the source command hasn't finished ```vim " fzf will read the stream file while allowing other processes to append to it call fzf#run({'source': 'cat /dev/null > /tmp/stream; tail -f /tmp/stream'}) ``` - It is now possible to open popup window relative to the current window ```vim let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } } ``` 0.27.0 ------ - More border options for `--preview-window` ```sh fzf --preview 'cat {}' --preview-window border-left fzf --preview 'cat {}' --preview-window border-left --border horizontal fzf --preview 'cat {}' --preview-window top:border-bottom fzf --preview 'cat {}' --preview-window top:border-horizontal ``` - Automatically set `/dev/tty` as STDIN on execute action ```sh # Redirect /dev/tty to suppress "Vim: Warning: Input is not from a terminal" # ls | fzf --bind "enter:execute(vim {} < /dev/tty)" # "< /dev/tty" part is no longer needed ls | fzf --bind "enter:execute(vim {})" ``` - Bug fixes and improvements - Signed and notarized macOS binaries (Huge thanks to [BACKERS.md](https://github.com/junegunn/junegunn/blob/main/BACKERS.md)!) 0.26.0 ------ - Added support for fixed header in preview window ```sh # Display top 3 lines as the fixed header fzf --preview 'bat --style=header,grid --color=always {}' --preview-window '~3' ``` - More advanced preview offset expression to better support the fixed header ```sh # Preview with bat, matching line in the middle of the window below # the fixed header of the top 3 lines # # ~3 Top 3 lines as the fixed header # +{2} Base scroll offset extracted from the second field # +3 Extra offset to compensate for the 3-line header # /2 Put in the middle of the preview area # git grep --line-number '' | fzf --delimiter : \ --preview 'bat --style=full --color=always --highlight-line {2} {1}' \ --preview-window '~3:+{2}+3/2' ``` - Added `select` and `deselect` action for unconditionally selecting or deselecting a single item in `--multi` mode. Complements `toggle` action. - Significant performance improvement in ANSI code processing - Bug fixes and improvements - Built with Go 1.16 0.25.1 ------ - Added `close` action - Close preview window if open, abort fzf otherwise - Bug fixes and improvements 0.25.0 ------ - Text attributes set in `--color` are not reset when fzf sees another `--color` option for the same element. This allows you to put custom text attributes in your `$FZF_DEFAULT_OPTS` and still have those attributes even when you override the colors. ```sh # Default colors and attributes fzf # Apply custom text attributes export FZF_DEFAULT_OPTS='--color fg+:italic,hl:-1:underline,hl+:-1:reverse:underline' fzf # Different colors but you still have the attributes fzf --color hl:176,hl+:177 # Write "regular" if you want to clear the attributes fzf --color hl:176:regular,hl+:177:regular ``` - Renamed `--phony` to `--disabled` - You can dynamically enable and disable the search functionality using the new `enable-search`, `disable-search`, and `toggle-search` actions - You can assign a different color to the query string for when search is disabled ```sh fzf --color query:#ffffff,disabled:#999999 --bind space:toggle-search ``` - Added `last` action to move the cursor to the last match - The opposite action `top` is renamed to `first`, but `top` is still recognized as a synonym for backward compatibility - Added `preview-top` and `preview-bottom` actions - Extended support for alt key chords: alt with any case-sensitive single character ```sh fzf --bind alt-,:first,alt-.:last ``` 0.24.4 ------ - Added `--preview-window` option `follow` ```sh # Preview window will automatically scroll to the bottom fzf --preview-window follow --preview 'for i in $(seq 100000); do echo "$i" sleep 0.01 (( i % 300 == 0 )) && printf "\033[2J" done' ``` - Added `change-prompt` action ```sh fzf --prompt 'foo> ' --bind $'a:change-prompt:\x1b[31mbar> ' ``` - Bug fixes and improvements 0.24.3 ------ - Added `--padding` option ```sh fzf --margin 5% --padding 5% --border --preview 'cat {}' \ --color bg:#222222,preview-bg:#333333 ``` 0.24.2 ------ - Bug fixes and improvements 0.24.1 ------ - Fixed broken `--color=[bw|no]` option 0.24.0 ------ - Real-time rendering of preview window ```sh # fzf can render preview window before the command completes fzf --preview 'sleep 1; for i in $(seq 100); do echo $i; sleep 0.01; done' # Preview window can process ANSI escape sequence (CSI 2 J) for clearing the display fzf --preview 'for i in $(seq 100000); do (( i % 200 == 0 )) && printf "\033[2J" echo "$i" sleep 0.01 done' ``` - Updated `--color` option to support text styles - `regular` / `bold` / `dim` / `underline` / `italic` / `reverse` / `blink` ```sh # * Set -1 to keep the original color # * Multiple style attributes can be combined # * Italic style may not be supported by some terminals rg --line-number --no-heading --color=always "" | fzf --ansi --prompt "Rg: " \ --color fg+:italic,hl:underline:-1,hl+:italic:underline:reverse:-1 \ --color pointer:reverse,prompt:reverse,input:159 \ --pointer ' ' ``` - More `--border` options - `vertical`, `top`, `bottom`, `left`, `right` - Updated Vim plugin to use these new `--border` options ```vim " Floating popup window in the center of the screen let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } " Popup with 100% width let g:fzf_layout = { 'window': { 'width': 1.0, 'height': 0.5, 'border': 'horizontal' } } " Popup with 100% height let g:fzf_layout = { 'window': { 'width': 0.5, 'height': 1.0, 'border': 'vertical' } } " Similar to 'down' layout, but it uses a popup window and doesn't affect the window layout let g:fzf_layout = { 'window': { 'width': 1.0, 'height': 0.5, 'yoffset': 1.0, 'border': 'top' } } " Opens on the right; " 'highlight' option is still supported but it will only take the foreground color of the group let g:fzf_layout = { 'window': { 'width': 0.5, 'height': 1.0, 'xoffset': 1.0, 'border': 'left', 'highlight': 'Comment' } } ``` - To indicate if `--multi` mode is enabled, fzf will print the number of selected items even when no item is selected ```sh seq 100 | fzf # 100/100 seq 100 | fzf --multi # 100/100 (0) seq 100 | fzf --multi 5 # 100/100 (0/5) ``` - Since 0.24.0, release binaries will be uploaded to https://github.com/junegunn/fzf/releases 0.23.1 ------ - Added `--preview-window` options for disabling flags - `nocycle` - `nohidden` - `nowrap` - `default` - Built with Go 1.14.9 due to performance regression - https://github.com/golang/go/issues/40727 0.23.0 ------ - Support preview scroll offset relative to window height ```sh git grep --line-number '' | fzf --delimiter : \ --preview 'bat --style=numbers --color=always --highlight-line {2} {1}' \ --preview-window +{2}-/2 ``` - Added `--preview-window` option for sharp edges (`--preview-window sharp`) - Added `--preview-window` option for cyclic scrolling (`--preview-window cycle`) - Reduced vertical padding around the preview window when `--preview-window noborder` is used - Added actions for preview window - `preview-half-page-up` - `preview-half-page-down` - Vim - Popup width and height can be given in absolute integer values - Added `fzf#exec()` function for getting the path of fzf executable - It also downloads the latest binary if it's not available by running `./install --bin` - Built with Go 1.15.2 - We no longer provide 32-bit binaries 0.22.0 ------ - Added more options for `--bind` - `backward-eof` event ```sh # Aborts when you delete backward when the query prompt is already empty fzf --bind backward-eof:abort ``` - `refresh-preview` action ```sh # Rerun preview command when you hit '?' fzf --preview 'echo $RANDOM' --bind '?:refresh-preview' ``` - `preview` action ```sh # Default preview command with an extra preview binding fzf --preview 'file {}' --bind '?:preview:cat {}' # A preview binding with no default preview command # (Preview window is initially empty) fzf --bind '?:preview:cat {}' # Preview window hidden by default, it appears when you first hit '?' fzf --bind '?:preview:cat {}' --preview-window hidden ``` - Added preview window option for setting the initial scroll offset ```sh # Initial scroll offset is set to the line number of each line of # git grep output *minus* 5 lines git grep --line-number '' | fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5 ``` - Added support for ANSI colors in `--prompt` string - Smart match of accented characters - An unaccented character in the query string will match both accented and unaccented characters, while an accented character will only match accented characters. This is similar to how "smart-case" match works. - Vim plugin - `tmux` layout option for using fzf-tmux ```vim let g:fzf_layout = { 'tmux': '-p90%,60%' } ``` 0.21.1 ------ - Shell extension - CTRL-R will remove duplicate commands - fzf-tmux - Supports tmux popup window (require tmux 3.2 or above) - ```sh # 50% width and height fzf-tmux -p # 80% width and height fzf-tmux -p 80% # 80% width and 40% height fzf-tmux -p 80%,40% fzf-tmux -w 80% -h 40% # Window position fzf-tmux -w 80% -h 40% -x 0 -y 0 fzf-tmux -w 80% -h 40% -y 1000 # Write ordinary fzf options after -- fzf-tmux -p -- --reverse --info=inline --margin 2,4 --border ``` - On macOS, you can build the latest tmux from the source with `brew install tmux --HEAD` - Bug fixes - Fixed Windows file traversal not to include directories - Fixed ANSI colors with `--keep-right` - Fixed _fzf_complete for zsh - Built with Go 1.14.1 0.21.0 ------ - `--height` option is now available on Windows as well (@kelleyma49) - Added `--pointer` and `--marker` options - Added `--keep-right` option that keeps the right end of the line visible when it's too long - Style changes - `--border` will now print border with rounded corners around the finder instead of printing horizontal lines above and below it. The previous style is available via `--border=horizontal` - Unicode spinner - More keys and actions for `--bind` - Added PowerShell script for downloading Windows binary - Vim plugin: Built-in floating windows support ```vim let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } ``` - bash: Various improvements in key bindings (CTRL-T, CTRL-R, ALT-C) - CTRL-R will start with the current command-line as the initial query - CTRL-R properly supports multi-line commands - Fuzzy completion API changed ```sh # Previous: fzf arguments given as a single string argument # - This style is still supported, but it's deprecated _fzf_complete "--multi --reverse --prompt=\"doge> \"" "$@" < <( echo foo ) # New API: multiple fzf arguments before "--" # - Easier to write multiple options _fzf_complete --multi --reverse --prompt="doge> " -- "$@" < <( echo foo ) ``` - Bug fixes and improvements 0.20.0 ------ - Customizable preview window color (`preview-fg` and `preview-bg` for `--color`) ```sh fzf --preview 'cat {}' \ --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899' \ --border --height 20 --layout reverse --info inline ``` - Removed the immediate flicking of the screen on `reload` action. ```sh : | fzf --bind 'change:reload:seq {q}' --phony ``` - Added `clear-query` and `clear-selection` actions for `--bind` - It is now possible to split a composite bind action over multiple `--bind` expressions by prefixing the later ones with `+`. ```sh fzf --bind 'ctrl-a:up+up' # Can be now written as fzf --bind 'ctrl-a:up' --bind 'ctrl-a:+up' # This is useful when you need to write special execute/reload form (i.e. `execute:...`) # to avoid parse errors and add more actions to the same key fzf --multi --bind 'ctrl-l:select-all+execute:less {+f}' --bind 'ctrl-l:+deselect-all' ``` - Fixed parse error of `--bind` expression where concatenated execute/reload action contains `+` character. ```sh fzf --multi --bind 'ctrl-l:select-all+execute(less {+f})+deselect-all' ``` - Fixed bugs of reload action - Not triggered when there's no match even when the command doesn't have any placeholder expressions - Screen not properly cleared when `--header-lines` not filled on reload 0.19.0 ------ - Added `--phony` option which completely disables search functionality. Useful when you want to use fzf only as a selector interface. See below. - Added "reload" action for dynamically updating the input list without restarting fzf. See https://github.com/junegunn/fzf/issues/1750 to learn more about it. ```sh # Using fzf as the selector interface for ripgrep RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " INITIAL_QUERY="foo" FZF_DEFAULT_COMMAND="$RG_PREFIX '$INITIAL_QUERY' || true" \ fzf --bind "change:reload:$RG_PREFIX {q} || true" \ --ansi --phony --query "$INITIAL_QUERY" ``` - `--multi` now takes an optional integer argument which indicates the maximum number of items that can be selected ```sh seq 100 | fzf --multi 3 --reverse --height 50% ``` - If a placeholder expression for `--preview` and `execute` action (and the new `reload` action) contains `f` flag, it is replaced to the path of a temporary file that holds the evaluated list. This is useful when you multi-select a large number of items and the length of the evaluated string may exceed [`ARG_MAX`][argmax]. ```sh # Press CTRL-A to select 100K items and see the sum of all the numbers seq 100000 | fzf --multi --bind ctrl-a:select-all \ --preview "awk '{sum+=\$1} END {print sum}' {+f}" ``` - `deselect-all` no longer deselects unmatched items. It is now consistent with `select-all` and `toggle-all` in that it only affects matched items. - Due to the limitation of bash, fuzzy completion is enabled by default for a fixed set of commands. A helper function for easily setting up fuzzy completion for any command is now provided. ```sh # usage: _fzf_setup_completion path|dir COMMANDS... _fzf_setup_completion path git kubectl ``` - Info line style can be changed by `--info=STYLE` - `--info=default` - `--info=inline` (same as old `--inline-info`) - `--info=hidden` - Preview window border can be disabled by adding `noborder` to `--preview-window`. - When you transform the input with `--with-nth`, the trailing white spaces are removed. - `ctrl-\`, `ctrl-]`, `ctrl-^`, and `ctrl-/` can now be used with `--bind` - See https://github.com/junegunn/fzf/milestone/15?closed=1 for more details [argmax]: https://unix.stackexchange.com/questions/120642/what-defines-the-maximum-size-for-a-command-single-argument 0.18.0 ------ - Added placeholder expression for zero-based item index: `{n}` and `{+n}` - `fzf --preview 'echo {n}: {}'` - Added color option for the gutter: `--color gutter:-1` - Added `--no-unicode` option for drawing borders in non-Unicode, ASCII characters - `FZF_PREVIEW_LINES` and `FZF_PREVIEW_COLUMNS` are exported to preview process - fzf still overrides `LINES` and `COLUMNS` as before, but they may be reset by the default shell. - Bug fixes and improvements - See https://github.com/junegunn/fzf/milestone/14?closed=1 - Built with Go 1.12.1 0.17.5 ------ - Bug fixes and improvements - See https://github.com/junegunn/fzf/milestone/13?closed=1 - Search query longer than the screen width is allowed (up to 300 chars) - Built with Go 1.11.1 0.17.4 ------ - Added `--layout` option with a new layout called `reverse-list`. - `--layout=reverse` is a synonym for `--reverse` - `--layout=default` is a synonym for `--no-reverse` - Preview window will be updated even when there is no match for the query if any of the placeholder expressions (e.g. `{q}`, `{+}`) evaluates to a non-empty string. - More keys for binding: `shift-{up,down}`, `alt-{up,down,left,right}` - fzf can now start even when `/dev/tty` is not available by making an educated guess. - Updated the default command for Windows. - Fixes and improvements on bash/zsh completion - install and uninstall scripts now supports generating files under `XDG_CONFIG_HOME` on `--xdg` flag. See https://github.com/junegunn/fzf/milestone/12?closed=1 for the full list of changes. 0.17.3 ------ - `$LINES` and `$COLUMNS` are exported to preview command so that the command knows the exact size of the preview window. - Better error messages when the default command or `$FZF_DEFAULT_COMMAND` fails. - Reverted #1061 to avoid having duplicate entries in the list when find command detected a file system loop (#1120). The default command now requires that find supports `-fstype` option. - fzf now distinguishes mouse left click and right click (#1130) - Right click is now bound to `toggle` action by default - `--bind` understands `left-click` and `right-click` - Added `replace-query` action (#1137) - Replaces query string with the current selection - Added `accept-non-empty` action (#1162) - Same as accept, except that it prevents fzf from exiting without any selection 0.17.1 ------ - Fixed custom background color of preview window (#1046) - Fixed background color issues of Windows binary - Fixed Windows binary to execute command using cmd.exe with no parsing and escaping (#1072) - Added support for `window` layout on Vim 8 using Vim 8 terminal (#1055) 0.17.0-2 -------- A maintenance release for auxiliary scripts. fzf binaries are not updated. - Experimental support for the builtin terminal of Vim 8 - fzf can now run inside GVim - Updated Vim plugin to better handle `&shell` issue on fish - Fixed a bug of fzf-tmux where invalid output is generated - Fixed fzf-tmux to work even when `tput` does not work 0.17.0 ------ - Performance optimization - One can match literal spaces in extended-search mode with a space prepended by a backslash. - `--expect` is now additive and can be specified multiple times. 0.16.11 ------- - Performance optimization - Fixed missing preview update 0.16.10 ------- - Fixed invalid handling of ANSI colors in preview window - Further improved `--ansi` performance 0.16.9 ------ - Memory and performance optimization - Around 20% performance improvement for general use cases - Up to 5x faster processing of `--ansi` - Up to 50% reduction of memory usage - Bug fixes and usability improvements - Fixed handling of bracketed paste mode - [ERROR] on info line when the default command failed - More efficient rendering of preview window - `--no-clear` updated for repetitive relaunching scenarios 0.16.8 ------ - New `change` event and `top` action for `--bind` - `fzf --bind change:top` - Move cursor to the top result whenever the query string is changed - `fzf --bind 'ctrl-w:unix-word-rubout+top,ctrl-u:unix-line-discard+top'` - `top` combined with `unix-word-rubout` and `unix-line-discard` - Fixed inconsistent tiebreak scores when `--nth` is used - Proper display of tab characters in `--prompt` - Fixed not to `--cycle` on page-up/page-down to prevent overshoot - Git revision in `--version` output - Basic support for Cygwin environment - Many fixes in Vim plugin on Windows/Cygwin (thanks to @janlazo) 0.16.7 ------ - Added support for `ctrl-alt-[a-z]` key chords - CTRL-Z (SIGSTOP) now works with fzf - fzf will export `$FZF_PREVIEW_WINDOW` so that the scripts can use it - Bug fixes and improvements in Vim plugin and shell extensions 0.16.6 ------ - Minor bug fixes and improvements - Added `--no-clear` option for scripting purposes 0.16.5 ------ - Minor bug fixes - Added `toggle-preview-wrap` action - Built with Go 1.8 0.16.4 ------ - Added `--border` option to draw border above and below the finder - Bug fixes and improvements 0.16.3 ------ - Fixed a bug where fzf incorrectly display the lines when straddling tab characters are trimmed - Placeholder expression used in `--preview` and `execute` action can optionally take `+` flag to be used with multiple selections - e.g. `git log --oneline | fzf --multi --preview 'git show {+1}'` - Added `execute-silent` action for executing a command silently without switching to the alternate screen. This is useful when the process is short-lived and you're not interested in its output. - e.g. `fzf --bind 'ctrl-y:execute!(echo -n {} | pbcopy)'` - `ctrl-space` is allowed in `--bind` 0.16.2 ------ - Dropped ncurses dependency - Binaries for freebsd, openbsd, arm5, arm6, arm7, and arm8 - Official 24-bit color support - Added support for composite actions in `--bind`. Multiple actions can be chained using `+` separator. - e.g. `fzf --bind 'ctrl-y:execute(echo -n {} | pbcopy)+abort'` - `--preview-window` with size 0 is allowed. This is used to make fzf execute preview command in the background without displaying the result. - Minor bug fixes and improvements 0.16.1 ------ - Fixed `--height` option to properly fill the window with the background color - Added `half-page-up` and `half-page-down` actions - Added `-L` flag to the default find command 0.16.0 ------ - *Added `--height HEIGHT[%]` option* - fzf can now display finder without occupying the full screen - Preview window will truncate long lines by default. Line wrap can be enabled by `:wrap` flag in `--preview-window`. - Latin script letters will be normalized before matching so that it's easier to match against accented letters. e.g. `sodanco` can match `Sรณ Danรงo Samba`. - Normalization can be disabled via `--literal` - Added `--filepath-word` to make word-wise movements/actions (`alt-b`, `alt-f`, `alt-bs`, `alt-d`) respect path separators 0.15.9 ------ - Fixed rendering glitches introduced in 0.15.8 - The default escape delay is reduced to 50ms and is configurable via `$ESCDELAY` - Scroll indicator at the top-right corner of the preview window is always displayed when there's overflow - Can now be built with ncurses 6 or tcell to support extra features - *ncurses 6* - Supports more than 256 color pairs - Supports italics - *tcell* - 24-bit color support - See https://github.com/junegunn/fzf/blob/master/BUILD.md 0.15.8 ------ - Updated ANSI processor to handle more VT-100 escape sequences - Added `--no-bold` (and `--bold`) option - Improved escape sequence processing for WSL - Added support for `alt-[0-9]`, `f11`, and `f12` for `--bind` and `--expect` 0.15.7 ------ - Fixed panic when color is disabled and header lines contain ANSI colors 0.15.6 ------ - Windows binaries! (@kelleyma49) - Fixed the bug where header lines are cleared when preview window is toggled - Fixed not to display ^N and ^O on screen - Fixed cursor keys (or any key sequence that starts with ESC) on WSL by making fzf wait for additional keystrokes after ESC for up to 100ms 0.15.5 ------ - Setting foreground color will no longer set background color to black - e.g. `fzf --color fg:153` - `--tiebreak=end` will consider relative position instead of absolute distance - Updated `fzf#wrap` function to respect `g:fzf_colors` 0.15.4 ------ - Added support for range expression in preview and execute action - e.g. `ls -l | fzf --preview="echo user={3} when={-4..-2}; cat {-1}" --header-lines=1` - `{q}` will be replaced to the single-quoted string of the current query - Fixed to properly handle unicode whitespace characters - Display scroll indicator in preview window - Inverse search term will use exact matcher by default - This is a breaking change, but I believe it makes much more sense. It is almost impossible to predict which entries will be filtered out due to a fuzzy inverse term. You can still perform inverse-fuzzy-match by prepending `!'` to the term. 0.15.3 ------ - Added support for more ANSI attributes: dim, underline, blink, and reverse - Fixed race condition in `toggle-preview` 0.15.2 ------ - Preview window is now scrollable - With mouse scroll or with bindable actions - `preview-up` - `preview-down` - `preview-page-up` - `preview-page-down` - Updated ANSI processor to support high intensity colors and ignore some VT100-related escape sequences 0.15.1 ------ - Fixed panic when the pattern occurs after 2^15-th column - Fixed rendering delay when displaying extremely long lines 0.15.0 ------ - Improved fuzzy search algorithm - Added `--algo=[v1|v2]` option so one can still choose the old algorithm which values the search performance over the quality of the result - Advanced scoring criteria - `--read0` to read input delimited by ASCII NUL character - `--print0` to print output delimited by ASCII NUL character 0.13.5 ------ - Memory and performance optimization - Up to 2x performance with half the amount of memory 0.13.4 ------ - Performance optimization - Memory footprint for ascii string is reduced by 60% - 15 to 20% improvement of query performance - Up to 45% better performance of `--nth` with non-regex delimiters - Fixed invalid handling of `hidden` property of `--preview-window` 0.13.3 ------ - Fixed duplicate rendering of the last line in preview window 0.13.2 ------ - Fixed race condition where preview window is not properly cleared 0.13.1 ------ - Fixed UI issue with large `--preview` output with many ANSI codes 0.13.0 ------ - Added preview feature - `--preview CMD` - `--preview-window POS[:SIZE][:hidden]` - `{}` in execute action is now replaced to the single-quoted (instead of double-quoted) string of the current line - Fixed to ignore control characters for bracketed paste mode 0.12.2 ------ - 256-color capability detection does not require `256` in `$TERM` - Added `print-query` action - More named keys for binding; F1 ~ F10, ALT-/, ALT-space, and ALT-enter - Added `jump` and `jump-accept` actions that implement [EasyMotion][em]-like movement ![][jump] [em]: https://github.com/easymotion/vim-easymotion [jump]: https://cloud.githubusercontent.com/assets/700826/15367574/b3999dc4-1d64-11e6-85da-28ceeb1a9bc2.png 0.12.1 ------ - Ranking algorithm introduced in 0.12.0 is now universally applied - Fixed invalid cache reference in exact mode - Fixes and improvements in Vim plugin and shell extensions 0.12.0 ------ - Enhanced ranking algorithm - Minor bug fixes 0.11.4 ------ - Added `--hscroll-off=COL` option (default: 10) (#513) - Some fixes in Vim plugin and shell extensions 0.11.3 ------ - Graceful exit on SIGTERM (#482) - `$SHELL` instead of `sh` for `execute` action and `$FZF_DEFAULT_COMMAND` (#481) - Changes in fuzzy completion API - [`_fzf_compgen_{path,dir}`](https://github.com/junegunn/fzf/commit/9617647) - [`_fzf_complete_COMMAND_post`](https://github.com/junegunn/fzf/commit/8206746) for post-processing 0.11.2 ------ - `--tiebreak` now accepts comma-separated list of sort criteria - Each criterion should appear only once in the list - `index` is only allowed at the end of the list - `index` is implicitly appended to the list when not specified - Default is `length` (or equivalently `length,index`) - `begin` criterion will ignore leading whitespaces when calculating the index - Added `toggle-in` and `toggle-out` actions - Switch direction depending on `--reverse`-ness - `export FZF_DEFAULT_OPTS="--bind tab:toggle-out,shift-tab:toggle-in"` - Reduced the initial delay when `--tac` is not given - fzf defers the initial rendering of the screen up to 100ms if the input stream is ongoing to prevent unnecessary redraw during the initial phase. However, 100ms delay is quite noticeable and might give the impression that fzf is not snappy enough. This commit reduces the maximum delay down to 20ms when `--tac` is not specified, in which case the input list quickly fills the entire screen. 0.11.1 ------ - Added `--tabstop=SPACES` option 0.11.0 ------ - Added OR operator for extended-search mode - Added `--execute-multi` action - Fixed incorrect cursor position when unicode wide characters are used in `--prompt` - Fixes and improvements in shell extensions 0.10.9 ------ - Extended-search mode is now enabled by default - `--extended-exact` is deprecated and instead we have `--exact` for orthogonally controlling "exactness" of search - Fixed not to display non-printable characters - Added `double-click` for `--bind` option - More robust handling of SIGWINCH 0.10.8 ------ - Fixed panic when trying to set colors after colors are disabled (#370) 0.10.7 ------ - Fixed unserialized interrupt handling during execute action which often caused invalid memory access and crash - Changed `--tiebreak=length` (default) to use trimmed length when `--nth` is used 0.10.6 ------ - Replaced `--header-file` with `--header` option - `--header` and `--header-lines` can be used together - Changed exit status - 0: Okay - 1: No match - 2: Error - 130: Interrupted - 64-bit linux binary is statically-linked with ncurses to avoid compatibility issues. 0.10.5 ------ - `'`-prefix to unquote the term in `--extended-exact` mode - Backward scan when `--tiebreak=end` is set 0.10.4 ------ - Fixed to remove ANSI code from output when `--with-nth` is set 0.10.3 ------ - Fixed slow performance of `--with-nth` when used with `--delimiter` - Regular expression engine of Golang as of now is very slow, so the fixed version will treat the given delimiter pattern as a plain string instead of a regular expression unless it contains special characters and is a valid regular expression. - Simpler regular expression for delimiter for better performance 0.10.2 ------ ### Fixes and improvements - Improvement in perceived response time of queries - Eager, efficient rune array conversion - Graceful exit when failed to initialize ncurses (invalid $TERM) - Improved ranking algorithm when `--nth` option is set - Changed the default command not to fail when there are files whose names start with dash 0.10.1 ------ ### New features - Added `--margin` option - Added options for sticky header - `--header-file` - `--header-lines` - Added `cancel` action which clears the input or closes the finder when the input is already empty - e.g. `export FZF_DEFAULT_OPTS="--bind esc:cancel"` - Added `delete-char/eof` action to differentiate `CTRL-D` and `DEL` ### Minor improvements/fixes - Fixed to allow binding colon and comma keys - Fixed ANSI processor to handle color regions spanning multiple lines 0.10.0 ------ ### New features - More actions for `--bind` - `select-all` - `deselect-all` - `toggle-all` - `ignore` - `execute(...)` action for running arbitrary command without leaving fzf - `fzf --bind "ctrl-m:execute(less {})"` - `fzf --bind "ctrl-t:execute(tmux new-window -d 'vim {}')"` - If the command contains parentheses, use any of the follows alternative notations to avoid parse errors - `execute[...]` - `execute~...~` - `execute!...!` - `execute@...@` - `execute#...#` - `execute$...$` - `execute%...%` - `execute^...^` - `execute&...&` - `execute*...*` - `execute;...;` - `execute/.../` - `execute|...|` - `execute:...` - This is the special form that frees you from parse errors as it does not expect the closing character - The catch is that it should be the last one in the comma-separated list - Added support for optional search history - `--history HISTORY_FILE` - When used, `CTRL-N` and `CTRL-P` are automatically remapped to `next-history` and `previous-history` - `--history-size MAX_ENTRIES` (default: 1000) - Cyclic scrolling can be enabled with `--cycle` - Fixed the bug where the spinner was not spinning on idle input stream - e.g. `sleep 100 | fzf` ### Minor improvements/fixes - Added synonyms for key names that can be specified for `--bind`, `--toggle-sort`, and `--expect` - Fixed the color of multi-select marker on the current line - Fixed to allow `^pattern$` in extended-search mode 0.9.13 ------ ### New features - Color customization with the extended `--color` option ### Bug fixes - Fixed premature termination of Reader in the presence of a long line which is longer than 64KB 0.9.12 ------ ### New features - Added `--bind` option for custom key bindings ### Bug fixes - Fixed to update "inline-info" immediately after terminal resize - Fixed ANSI code offset calculation 0.9.11 ------ ### New features - Added `--inline-info` option for saving screen estate (#202) - Useful inside Neovim - e.g. `let $FZF_DEFAULT_OPTS = $FZF_DEFAULT_OPTS.' --inline-info'` ### Bug fixes - Invalid mutation of input on case conversion (#209) - Smart-case for each term in extended-search mode (#208) - Fixed double-click result when scroll offset is positive 0.9.10 ------ ### Improvements - Performance optimization - Less aggressive memoization to limit memory usage ### New features - Added color scheme for light background: `--color=light` 0.9.9 ----- ### New features - Added `--tiebreak` option (#191) - Added `--no-hscroll` option (#193) - Visual indication of `--toggle-sort` (#194) 0.9.8 ----- ### Bug fixes - Fixed Unicode case handling (#186) - Fixed to terminate on RuneError (#185) 0.9.7 ----- ### New features - Added `--toggle-sort` option (#173) - `--toggle-sort=ctrl-r` is applied to `CTRL-R` shell extension ### Bug fixes - Fixed to print empty line if `--expect` is set and fzf is completed by `--select-1` or `--exit-0` (#172) - Fixed to allow comma character as an argument to `--expect` option 0.9.6 ----- ### New features #### Added `--expect` option (#163) If you provide a comma-separated list of keys with `--expect` option, fzf will allow you to select the match and complete the finder when any of the keys is pressed. Additionally, fzf will print the name of the key pressed as the first line of the output so that your script can decide what to do next based on the information. ```sh fzf --expect=ctrl-v,ctrl-t,alt-s,f1,f2,~,@ ``` The updated vim plugin uses this option to implement [ctrlp](https://github.com/kien/ctrlp.vim)-compatible key bindings. ### Bug fixes - Fixed to ignore ANSI escape code `\e[K` (#162) 0.9.5 ----- ### New features #### Added `--ansi` option (#150) If you give `--ansi` option to fzf, fzf will interpret ANSI color codes from the input, display the item with the ANSI colors (true colors are not supported), and strips the codes from the output. This option is off by default as it entails some overhead. ### Improvements #### Reduced initial memory footprint (#151) By removing unnecessary copy of pointers, fzf will use significantly smaller amount of memory when it's started. The difference is hugely noticeable when the input is extremely large. (e.g. `locate / | fzf`) ### Bug fixes - Fixed panic on `--no-sort --filter ''` (#149) 0.9.4 ----- ### New features #### Added `--tac` option to reverse the order of the input. One might argue that this option is unnecessary since we can already put `tac` or `tail -r` in the command pipeline to achieve the same result. However, the advantage of `--tac` is that it does not block until the input is complete. ### *Backward incompatible changes* #### Changed behavior on `--no-sort` `--no-sort` option will no longer reverse the display order within finder. You may want to use the new `--tac` option with `--no-sort`. ``` history | fzf +s --tac ``` ### Improvements #### `--filter` will not block when sort is disabled When fzf works in filtering mode (`--filter`) and sort is disabled (`--no-sort`), there's no need to block until input is complete. The new version of fzf will print the matches on-the-fly when the following condition is met: --filter TERM --no-sort [--no-tac --no-sync] or simply: -f TERM +s This change removes unnecessary delay in the use cases like the following: fzf -f xxx +s | head -5 However, in this case, fzf processes the lines sequentially, so it cannot utilize multiple cores, and fzf will run slightly slower than the previous mode of execution where filtering is done in parallel after the entire input is loaded. If the user is concerned about this performance problem, one can add `--sync` option to re-enable buffering. 0.9.3 ----- ### New features - Added `--sync` option for multi-staged filtering ### Improvements - `--select-1` and `--exit-0` will start finder immediately when the condition cannot be met fzf-0.60.3/Dockerfile000066400000000000000000000010001476126201100143460ustar00rootroot00000000000000FROM rubylang/ruby:3.4.1-noble RUN apt-get update -y && apt install -y git make golang zsh fish tmux RUN gem install --no-document -v 5.22.3 minitest RUN echo '. /usr/share/bash-completion/completions/git' >> ~/.bashrc RUN echo '. ~/.bashrc' >> ~/.bash_profile # Do not set default PS1 RUN rm -f /etc/bash.bashrc COPY . /fzf RUN cd /fzf && make install && ./install --all ENV LANG=C.UTF-8 CMD ["bash", "-ic", "tmux new 'set -o pipefail; ruby /fzf/test/runner.rb | tee out && touch ok' && cat out && [ -e ok ]"] fzf-0.60.3/Gemfile000066400000000000000000000002641476126201100136620ustar00rootroot00000000000000# frozen_string_literal: true source 'https://rubygems.org' gem 'minitest', '5.25.4' gem 'rubocop', '1.71.0' gem 'rubocop-minitest', '0.36.0' gem 'rubocop-performance', '1.23.1' fzf-0.60.3/Gemfile.lock000066400000000000000000000021061476126201100146060ustar00rootroot00000000000000GEM remote: https://rubygems.org/ specs: ast (2.4.2) json (2.9.1) language_server-protocol (3.17.0.3) minitest (5.25.4) parallel (1.26.3) parser (3.3.7.0) ast (~> 2.4.1) racc racc (1.8.1) rainbow (3.1.1) regexp_parser (2.10.0) rubocop (1.71.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) rubocop-ast (>= 1.36.2, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) rubocop-ast (1.37.0) parser (>= 3.3.1.0) rubocop-minitest (0.36.0) rubocop (>= 1.61, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) rubocop-performance (1.23.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) unicode-display_width (2.6.0) PLATFORMS arm64-darwin-23 ruby DEPENDENCIES minitest (= 5.25.4) rubocop (= 1.71.0) rubocop-minitest (= 0.36.0) rubocop-performance (= 1.23.1) BUNDLED WITH 2.6.2 fzf-0.60.3/LICENSE000066400000000000000000000020751476126201100133760ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2013-2024 Junegunn Choi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. fzf-0.60.3/Makefile000066400000000000000000000124371476126201100140340ustar00rootroot00000000000000GO ?= go GOOS ?= $(shell $(GO) env GOOS) MAKEFILE := $(realpath $(lastword $(MAKEFILE_LIST))) ROOT_DIR := $(shell dirname $(MAKEFILE)) SOURCES := $(wildcard *.go src/*.go src/*/*.go shell/*sh man/man1/*.1) $(MAKEFILE) ifdef FZF_VERSION VERSION := $(FZF_VERSION) else VERSION := $(shell git describe --abbrev=0 2> /dev/null | sed "s/^v//") endif ifeq ($(VERSION),) $(error Not on git repository; cannot determine $$FZF_VERSION) endif VERSION_TRIM := $(shell echo $(VERSION) | sed "s/^v//; s/-.*//") VERSION_REGEX := $(subst .,\.,$(VERSION_TRIM)) ifdef FZF_REVISION REVISION := $(FZF_REVISION) else REVISION := $(shell git log -n 1 --pretty=format:%h --abbrev=8 -- $(SOURCES) 2> /dev/null) endif ifeq ($(REVISION),) $(error Not on git repository; cannot determine $$FZF_REVISION) endif BUILD_FLAGS := -a -ldflags "-s -w -X main.version=$(VERSION) -X main.revision=$(REVISION)" -tags "$(TAGS)" -trimpath BINARY32 := fzf-$(GOOS)_386 BINARY64 := fzf-$(GOOS)_amd64 BINARYS390 := fzf-$(GOOS)_s390x BINARYARM5 := fzf-$(GOOS)_arm5 BINARYARM6 := fzf-$(GOOS)_arm6 BINARYARM7 := fzf-$(GOOS)_arm7 BINARYARM8 := fzf-$(GOOS)_arm8 BINARYPPC64LE := fzf-$(GOOS)_ppc64le BINARYRISCV64 := fzf-$(GOOS)_riscv64 BINARYLOONG64 := fzf-$(GOOS)_loong64 # https://en.wikipedia.org/wiki/Uname UNAME_M := $(shell uname -m) ifeq ($(UNAME_M),x86_64) BINARY := $(BINARY64) else ifeq ($(UNAME_M),amd64) BINARY := $(BINARY64) else ifeq ($(UNAME_M),s390x) BINARY := $(BINARYS390) else ifeq ($(UNAME_M),i686) BINARY := $(BINARY32) else ifeq ($(UNAME_M),i386) BINARY := $(BINARY32) else ifeq ($(UNAME_M),armv5l) BINARY := $(BINARYARM5) else ifeq ($(UNAME_M),armv6l) BINARY := $(BINARYARM6) else ifeq ($(UNAME_M),armv7l) BINARY := $(BINARYARM7) else ifeq ($(UNAME_M),armv8l) # armv8l is always 32-bit and should implement the armv7 ISA, so # just use the same filename as for armv7. BINARY := $(BINARYARM7) else ifeq ($(UNAME_M),arm64) BINARY := $(BINARYARM8) else ifeq ($(UNAME_M),aarch64) BINARY := $(BINARYARM8) else ifeq ($(UNAME_M),ppc64le) BINARY := $(BINARYPPC64LE) else ifeq ($(UNAME_M),riscv64) BINARY := $(BINARYRISCV64) else ifeq ($(UNAME_M),loongarch64) BINARY := $(BINARYLOONG64) else $(error Build on $(UNAME_M) is not supported, yet.) endif all: target/$(BINARY) test: $(SOURCES) SHELL=/bin/sh GOOS= $(GO) test -v -tags "$(TAGS)" \ github.com/junegunn/fzf/src \ github.com/junegunn/fzf/src/algo \ github.com/junegunn/fzf/src/tui \ github.com/junegunn/fzf/src/util itest: ruby test/runner.rb bench: cd src && SHELL=/bin/sh GOOS= $(GO) test -v -tags "$(TAGS)" -run=Bench -bench=. -benchmem lint: $(SOURCES) test/*.rb test/lib/*.rb [ -z "$$(gofmt -s -d src)" ] || (gofmt -s -d src; exit 1) bundle exec rubocop -a --require rubocop-minitest --require rubocop-performance install: bin/fzf generate: PATH=$(PATH):$(GOPATH)/bin $(GO) generate ./... build: goreleaser build --clean --snapshot --skip=post-hooks release: # Make sure that the tests pass and the build works TAGS=tcell make test make test build clean ifndef GITHUB_TOKEN $(error GITHUB_TOKEN is not defined) endif # Check if we are on master branch ifneq ($(shell git symbolic-ref --short HEAD),master) $(error Not on master branch) endif # Check if version numbers are properly updated grep -q ^$(VERSION_REGEX)$$ CHANGELOG.md grep -qF '"fzf $(VERSION_TRIM)"' man/man1/fzf.1 grep -qF '"fzf $(VERSION_TRIM)"' man/man1/fzf-tmux.1 grep -qF $(VERSION) install grep -qF $(VERSION) install.ps1 # Make release note out of CHANGELOG.md mkdir -p tmp sed -n '/^$(VERSION_REGEX)$$/,/^[0-9]/p' CHANGELOG.md | tail -r | \ sed '1,/^ *$$/d' | tail -r | sed 1,2d | tee tmp/release-note # Push to temp branch first so that install scripts always works on master branch git checkout -B temp master git push origin temp --follow-tags --force # Make a GitHub release goreleaser --clean --release-notes tmp/release-note # Push to master git checkout master git push origin master # Delete temp branch git push origin --delete temp clean: $(RM) -r dist target target/$(BINARY32): $(SOURCES) GOARCH=386 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARY64): $(SOURCES) GOARCH=amd64 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYS390): $(SOURCES) GOARCH=s390x $(GO) build $(BUILD_FLAGS) -o $@ # https://github.com/golang/go/wiki/GoArm target/$(BINARYARM5): $(SOURCES) GOARCH=arm GOARM=5 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYARM6): $(SOURCES) GOARCH=arm GOARM=6 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYARM7): $(SOURCES) GOARCH=arm GOARM=7 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYARM8): $(SOURCES) GOARCH=arm64 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYPPC64LE): $(SOURCES) GOARCH=ppc64le $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYRISCV64): $(SOURCES) GOARCH=riscv64 $(GO) build $(BUILD_FLAGS) -o $@ target/$(BINARYLOONG64): $(SOURCES) GOARCH=loong64 $(GO) build $(BUILD_FLAGS) -o $@ bin/fzf: target/$(BINARY) | bin -rm -f bin/fzf cp -f target/$(BINARY) bin/fzf docker: docker build -t fzf-ubuntu . docker run -it fzf-ubuntu tmux docker-test: docker build -t fzf-ubuntu . docker run -it fzf-ubuntu update: $(GO) get -u $(GO) mod tidy .PHONY: all generate build release test itest bench lint install clean docker docker-test update fzf-0.60.3/README-VIM.md000066400000000000000000000427541476126201100143110ustar00rootroot00000000000000FZF Vim integration =================== Installation ------------ Once you have fzf installed, you can enable it inside Vim simply by adding the directory to `&runtimepath` in your Vim configuration file. The path may differ depending on the package manager. ```vim " If installed using Homebrew set rtp+=/usr/local/opt/fzf " If installed using Homebrew on Apple Silicon set rtp+=/opt/homebrew/opt/fzf " If you have cloned fzf on ~/.fzf directory set rtp+=~/.fzf ``` If you use [vim-plug](https://github.com/junegunn/vim-plug), the same can be written as: ```vim " If installed using Homebrew Plug '/usr/local/opt/fzf' " If installed using Homebrew on Apple Silicon Plug '/opt/homebrew/opt/fzf' " If you have cloned fzf on ~/.fzf directory Plug '~/.fzf' ``` But if you want the latest Vim plugin file from GitHub rather than the one included in the package, write: ```vim Plug 'junegunn/fzf' ``` The Vim plugin will pick up fzf binary available on the system. If fzf is not found on `$PATH`, it will ask you if it should download the latest binary for you. To make sure that you have the latest version of the binary, set up post-update hook like so: ```vim Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } ``` Summary ------- The Vim plugin of fzf provides two core functions, and `:FZF` command which is the basic file selector command built on top of them. 1. **`fzf#run([spec dict])`** - Starts fzf inside Vim with the given spec - `:call fzf#run({'source': 'ls'})` 2. **`fzf#wrap([spec dict]) -> (dict)`** - Takes a spec for `fzf#run` and returns an extended version of it with additional options for addressing global preferences (`g:fzf_xxx`) - `:echo fzf#wrap({'source': 'ls'})` - We usually *wrap* a spec with `fzf#wrap` before passing it to `fzf#run` - `:call fzf#run(fzf#wrap({'source': 'ls'}))` 3. **`:FZF [fzf_options string] [path string]`** - Basic fuzzy file selector - A reference implementation for those who don't want to write VimScript to implement custom commands - If you're looking for more such commands, check out [fzf.vim](https://github.com/junegunn/fzf.vim) project. The most important of all is `fzf#run`, but it would be easier to understand the whole if we start off with `:FZF` command. `:FZF[!]` --------- ```vim " Look for files under current directory :FZF " Look for files under your home directory :FZF ~ " With fzf command-line options :FZF --reverse --info=inline /tmp " Bang version starts fzf in fullscreen mode :FZF! ``` Similarly to [ctrlp.vim](https://github.com/kien/ctrlp.vim), use enter key, `CTRL-T`, `CTRL-X` or `CTRL-V` to open selected files in the current window, in new tabs, in horizontal splits, or in vertical splits respectively. Note that the environment variables `FZF_DEFAULT_COMMAND` and `FZF_DEFAULT_OPTS` also apply here. ### Configuration - `g:fzf_action` - Customizable extra key bindings for opening selected files in different ways - `g:fzf_layout` - Determines the size and position of fzf window - `g:fzf_colors` - Customizes fzf colors to match the current color scheme - `g:fzf_history_dir` - Enables history feature #### Examples ```vim " This is the default extra key bindings let g:fzf_action = { \ 'ctrl-t': 'tab split', \ 'ctrl-x': 'split', \ 'ctrl-v': 'vsplit' } " An action can be a reference to a function that processes selected lines function! s:build_quickfix_list(lines) call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }')) copen cc endfunction let g:fzf_action = { \ 'ctrl-q': function('s:build_quickfix_list'), \ 'ctrl-t': 'tab split', \ 'ctrl-x': 'split', \ 'ctrl-v': 'vsplit' } " Default fzf layout " - Popup window (center of the screen) let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } " - Popup window (center of the current window) let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true } } " - Popup window (anchored to the bottom of the current window) let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } } " - down / up / left / right let g:fzf_layout = { 'down': '40%' } " - Window using a Vim command let g:fzf_layout = { 'window': 'enew' } let g:fzf_layout = { 'window': '-tabnew' } let g:fzf_layout = { 'window': '10new' } " Customize fzf colors to match your color scheme " - fzf#wrap translates this to a set of `--color` options let g:fzf_colors = \ { 'fg': ['fg', 'Normal'], \ 'bg': ['bg', 'Normal'], \ 'hl': ['fg', 'Comment'], \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'hl+': ['fg', 'Statement'], \ 'info': ['fg', 'PreProc'], \ 'border': ['fg', 'Ignore'], \ 'prompt': ['fg', 'Conditional'], \ 'pointer': ['fg', 'Exception'], \ 'marker': ['fg', 'Keyword'], \ 'spinner': ['fg', 'Label'], \ 'header': ['fg', 'Comment'] } " Enable per-command history " - History files will be stored in the specified directory " - When set, CTRL-N and CTRL-P will be bound to 'next-history' and " 'previous-history' instead of 'down' and 'up'. let g:fzf_history_dir = '~/.local/share/fzf-history' ``` ##### Explanation of `g:fzf_colors` `g:fzf_colors` is a dictionary mapping fzf elements to a color specification list: element: [ component, group1 [, group2, ...] ] - `element` is an fzf element to apply a color to: | Element | Description | | --- | --- | | `fg` / `bg` / `hl` | Item (foreground / background / highlight) | | `fg+` / `bg+` / `hl+` | Current item (foreground / background / highlight) | | `preview-fg` / `preview-bg` | Preview window text and background | | `hl` / `hl+` | Highlighted substrings (normal / current) | | `gutter` | Background of the gutter on the left | | `pointer` | Pointer to the current line (`>`) | | `marker` | Multi-select marker (`>`) | | `border` | Border around the window (`--border` and `--preview`) | | `header` | Header (`--header` or `--header-lines`) | | `info` | Info line (match counters) | | `spinner` | Streaming input indicator | | `query` | Query string | | `disabled` | Query string when search is disabled | | `prompt` | Prompt before query (`> `) | | `pointer` | Pointer to the current line (`>`) | - `component` specifies the component (`fg` / `bg`) from which to extract the color when considering each of the following highlight groups - `group1 [, group2, ...]` is a list of highlight groups that are searched (in order) for a matching color definition For example, consider the following specification: ```vim 'prompt': ['fg', 'Conditional', 'Comment'], ``` This means we color the **prompt** - using the `fg` attribute of the `Conditional` if it exists, - otherwise use the `fg` attribute of the `Comment` highlight group if it exists, - otherwise fall back to the default color settings for the **prompt**. You can examine the color option generated according the setting by printing the result of `fzf#wrap()` function like so: ```vim :echo fzf#wrap() ``` `fzf#run` --------- `fzf#run()` function is the core of Vim integration. It takes a single dictionary argument, *a spec*, and starts fzf process accordingly. At the very least, specify `sink` option to tell what it should do with the selected entry. ```vim call fzf#run({'sink': 'e'}) ``` We haven't specified the `source`, so this is equivalent to starting fzf on command line without standard input pipe; fzf will traverse the file system under the current directory to get the list of files. (If `$FZF_DEFAULT_COMMAND` is set, fzf will use the output of the command instead.) When you select one, it will open it with the sink, `:e` command. If you want to open it in a new tab, you can pass `:tabedit` command instead as the sink. ```vim call fzf#run({'sink': 'tabedit'}) ``` You can use any shell command as the source to generate the list. The following example will list the files managed by git. It's equivalent to running `git ls-files | fzf` on shell. ```vim call fzf#run({'source': 'git ls-files', 'sink': 'e'}) ``` fzf options can be specified as `options` entry in spec dictionary. ```vim call fzf#run({'sink': 'tabedit', 'options': '--multi --reverse'}) ``` You can also pass a layout option if you don't want fzf window to take up the entire screen. ```vim " up / down / left / right / window are allowed call fzf#run({'source': 'git ls-files', 'sink': 'e', 'left': '40%'}) call fzf#run({'source': 'git ls-files', 'sink': 'e', 'window': '30vnew'}) ``` `source` doesn't have to be an external shell command, you can pass a Vim array as the source. In the next example, we pass the names of color schemes as the source to implement a color scheme selector. ```vim call fzf#run({'source': map(split(globpath(&rtp, 'colors/*.vim')), \ 'fnamemodify(v:val, ":t:r")'), \ 'sink': 'colo', 'left': '25%'}) ``` The following table summarizes the available options. | Option name | Type | Description | | -------------------------- | ------------- | ---------------------------------------------------------------- | | `source` | string | External command to generate input to fzf (e.g. `find .`) | | `source` | list | Vim list as input to fzf | | `sink` | string | Vim command to handle the selected item (e.g. `e`, `tabe`) | | `sink` | funcref | Function to be called with each selected item | | `sinklist` (or `sink*`) | funcref | Similar to `sink`, but takes the list of output lines at once | | `exit` | funcref | Function to be called with the exit status of fzf (e.g. 0, 1, 2, 130) | | `options` | string/list | Options to fzf | | `dir` | string | Working directory | | `up`/`down`/`left`/`right` | number/string | (Layout) Window position and size (e.g. `20`, `50%`) | | `tmux` | string | (Layout) `--tmux` options (e.g. `90%,70%`) | | `window` (Vim 8 / Neovim) | string | (Layout) Command to open fzf window (e.g. `vertical aboveleft 30new`) | | `window` (Vim 8 / Neovim) | dict | (Layout) Popup window settings (e.g. `{'width': 0.9, 'height': 0.6}`) | `options` entry can be either a string or a list. For simple cases, string should suffice, but prefer to use list type to avoid escaping issues. ```vim call fzf#run({'options': '--reverse --prompt "C:\\Program Files\\"'}) call fzf#run({'options': ['--reverse', '--prompt', 'C:\Program Files\']}) ``` When `window` entry is a dictionary, fzf will start in a popup window. The following options are allowed: - Required: - `width` [float range [0 ~ 1]] or [integer range [8 ~ ]] - `height` [float range [0 ~ 1]] or [integer range [4 ~ ]] - Optional: - `yoffset` [float default 0.5 range [0 ~ 1]] - `xoffset` [float default 0.5 range [0 ~ 1]] - `relative` [boolean default v:false] - `border` [string default `rounded` (`sharp` on Windows)]: Border style - `rounded` / `sharp` / `horizontal` / `vertical` / `top` / `bottom` / `left` / `right` / `no[ne]` `fzf#wrap` ---------- We have seen that several aspects of `:FZF` command can be configured with a set of global option variables; different ways to open files (`g:fzf_action`), window position and size (`g:fzf_layout`), color palette (`g:fzf_colors`), etc. So how can we make our custom `fzf#run` calls also respect those variables? Simply by *"wrapping"* the spec dictionary with `fzf#wrap` before passing it to `fzf#run`. - **`fzf#wrap([name string], [spec dict], [fullscreen bool]) -> (dict)`** - All arguments are optional. Usually we only need to pass a spec dictionary. - `name` is for managing history files. It is ignored if `g:fzf_history_dir` is not defined. - `fullscreen` can be either `0` or `1` (default: 0). `fzf#wrap` takes a spec and returns an extended version of it (also a dictionary) with additional options for addressing global preferences. You can examine the return value of it like so: ```vim echo fzf#wrap({'source': 'ls'}) ``` After we *"wrap"* our spec, we pass it to `fzf#run`. ```vim call fzf#run(fzf#wrap({'source': 'ls'})) ``` Now it supports `CTRL-T`, `CTRL-V`, and `CTRL-X` key bindings (configurable via `g:fzf_action`) and it opens fzf window according to `g:fzf_layout` setting. To make it easier to use, let's define `LS` command. ```vim command! LS call fzf#run(fzf#wrap({'source': 'ls'})) ``` Type `:LS` and see how it works. We would like to make `:LS!` (bang version) open fzf in fullscreen, just like `:FZF!`. Add `-bang` to command definition, and use `` value to set the last `fullscreen` argument of `fzf#wrap` (see `:help `). ```vim " On :LS!, evaluates to '!', and '!0' becomes 1 command! -bang LS call fzf#run(fzf#wrap({'source': 'ls'}, 0)) ``` Our `:LS` command will be much more useful if we can pass a directory argument to it, so that something like `:LS /tmp` is possible. ```vim command! -bang -complete=dir -nargs=? LS \ call fzf#run(fzf#wrap({'source': 'ls', 'dir': }, 0)) ``` Lastly, if you have enabled `g:fzf_history_dir`, you might want to assign a unique name to our command and pass it as the first argument to `fzf#wrap`. ```vim " The query history for this command will be stored as 'ls' inside g:fzf_history_dir. " The name is ignored if g:fzf_history_dir is not defined. command! -bang -complete=dir -nargs=? LS \ call fzf#run(fzf#wrap('ls', {'source': 'ls', 'dir': }, 0)) ``` ### Global options supported by `fzf#wrap` - `g:fzf_layout` - `g:fzf_action` - **Works only when no custom `sink` (or `sinklist`) is provided** - Having custom sink usually means that each entry is not an ordinary file path (e.g. name of color scheme), so we can't blindly apply the same strategy (i.e. `tabedit some-color-scheme` doesn't make sense) - `g:fzf_colors` - `g:fzf_history_dir` Tips ---- ### fzf inside terminal buffer On the latest versions of Vim and Neovim, fzf will start in a terminal buffer. If you find the default ANSI colors to be different, consider configuring the colors using `g:terminal_ansi_colors` in regular Vim or `g:terminal_color_x` in Neovim. ```vim " Terminal colors for seoul256 color scheme if has('nvim') let g:terminal_color_0 = '#4e4e4e' let g:terminal_color_1 = '#d68787' let g:terminal_color_2 = '#5f865f' let g:terminal_color_3 = '#d8af5f' let g:terminal_color_4 = '#85add4' let g:terminal_color_5 = '#d7afaf' let g:terminal_color_6 = '#87afaf' let g:terminal_color_7 = '#d0d0d0' let g:terminal_color_8 = '#626262' let g:terminal_color_9 = '#d75f87' let g:terminal_color_10 = '#87af87' let g:terminal_color_11 = '#ffd787' let g:terminal_color_12 = '#add4fb' let g:terminal_color_13 = '#ffafaf' let g:terminal_color_14 = '#87d7d7' let g:terminal_color_15 = '#e4e4e4' else let g:terminal_ansi_colors = [ \ '#4e4e4e', '#d68787', '#5f865f', '#d8af5f', \ '#85add4', '#d7afaf', '#87afaf', '#d0d0d0', \ '#626262', '#d75f87', '#87af87', '#ffd787', \ '#add4fb', '#ffafaf', '#87d7d7', '#e4e4e4' \ ] endif ``` ### Starting fzf in a popup window ```vim " Required: " - width [float range [0 ~ 1]] or [integer range [8 ~ ]] " - height [float range [0 ~ 1]] or [integer range [4 ~ ]] " " Optional: " - xoffset [float default 0.5 range [0 ~ 1]] " - yoffset [float default 0.5 range [0 ~ 1]] " - relative [boolean default v:false] " - border [string default 'rounded']: Border style " - 'rounded' / 'sharp' / 'horizontal' / 'vertical' / 'top' / 'bottom' / 'left' / 'right' let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } ``` Alternatively, you can make fzf open in a tmux popup window (requires tmux 3.2 or above) by putting `--tmux` option value in `tmux` key. ```vim " See `--tmux` option in `man fzf` for available options " [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]] if exists('$TMUX') let g:fzf_layout = { 'tmux': '90%,70%' } else let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } endif ``` ### Hide statusline When fzf starts in a terminal buffer, the file type of the buffer is set to `fzf`. So you can set up `FileType fzf` autocmd to customize the settings of the window. For example, if you open fzf on the bottom on the screen (e.g. `{'down': '40%'}`), you might want to temporarily disable the statusline for a cleaner look. ```vim let g:fzf_layout = { 'down': '30%' } autocmd! FileType fzf autocmd FileType fzf set laststatus=0 noshowmode noruler \| autocmd BufLeave set laststatus=2 showmode ruler ``` [License](LICENSE) ------------------ The MIT License (MIT) Copyright (c) 2013-2024 Junegunn Choi fzf-0.60.3/README.md000066400000000000000000001245521476126201100136550ustar00rootroot00000000000000
Special thanks to:

Warp sponsorship ### [Warp, the intelligent terminal for developers](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=fzf) [Available for MacOS, Linux, & Windows](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=fzf)

fzf - a command-line fuzzy finder [![github-actions](https://github.com/junegunn/fzf/workflows/Test%20fzf%20on%20Linux/badge.svg)](https://github.com/junegunn/fzf/actions) === fzf is a general-purpose command-line fuzzy finder. It's an interactive filter program for any kind of list; files, command history, processes, hostnames, bookmarks, git commits, etc. It implements a "fuzzy" matching algorithm, so you can quickly type in patterns with omitted characters and still get the results you want. Highlights ---------- - ๐Ÿ“ฆ **Portable** โ€” Distributed as a single binary for easy installation - โšก **Blazingly fast** โ€” Highly optimized code instantly processes millions of items - ๐Ÿ› ๏ธ **Extremely versatile** โ€” Fully customizable via an event-action binding mechanism - ๐Ÿ”‹ **Batteries included** โ€” Includes integration with bash, zsh, fish, Vim, and Neovim Sponsors โค๏ธ ----------- I would like to thank all the sponsors of this project who make it possible for me to continue to improve fzf. If you'd like to sponsor this project, please visit https://github.com/sponsors/junegunn. User avatar: miyanokomiyaUser avatar: Jon GjengsetUser avatar: Kyle L. DavisUser avatar: Frederick ZhangUser avatar: Moritz DietzUser avatar: Mikkel MalmbergUser avatar: Pierre DubouilhUser avatar: Fulvio ScapinUser avatar: Ryan Roden-CorrentUser avatar: Jordan ArentsenUser avatar: Alex ViscreanuUser avatar: David BalateroUser avatar: User avatar: Ben ElanUser avatar: Paweล‚ DudaUser avatar: Damien RajonUser avatar: ArtBITUser avatar: User avatar: HovisUser avatar: Darius JondaUser avatar: Cristian DominguezUser avatar: Chang-Hung LiangUser avatar: Ben LechlitnerUser avatar: george looshchUser avatar: Takumi KAGIYAMAUser avatar: Paul OLeary McCannUser avatar: Robert BeegerUser avatar: Yoway BuornUser avatar: Josh ScalisiUser avatar: Alec ScottUser avatar: thanks.devUser avatar: Artur SapekUser avatar: Guillaume GelinUser avatar: User avatar: Rob LevyUser avatar: Gloria ZhaoUser avatar: Markus KollerUser avatar: User avatar: jamesobUser avatar: Johan Le BrayUser avatar: Panos LampropoulosUser avatar: bespinianUser avatar: Markus Schneider-PargmannUser avatar: Ben SmithUser avatar: Charlie EganUser avatar: Tyler HobbsUser avatar: Neil ParikhUser avatar: Jamie SchembriUser avatar: dockienUser avatar: Russell GilmoreUser avatar: Lukas WaymannUser avatar: Farzad SadeghiUser avatar: User avatar: Bruno PazUser avatar: Timothy BennettUser avatar: Daniel HornerUser avatar: AdamUser avatar: Red OchsenbeinUser avatar: YuryUser avatar: Christian AngermannUser avatar: Table of Contents ----------------- * [Installation](#installation) * [Using Homebrew](#using-homebrew) * [Linux packages](#linux-packages) * [Windows packages](#windows-packages) * [Using git](#using-git) * [Binary releases](#binary-releases) * [Setting up shell integration](#setting-up-shell-integration) * [Vim/Neovim plugin](#vimneovim-plugin) * [Upgrading fzf](#upgrading-fzf) * [Building fzf](#building-fzf) * [Usage](#usage) * [Using the finder](#using-the-finder) * [Display modes](#display-modes) * [`--height` mode](#--height-mode) * [`--tmux` mode](#--tmux-mode) * [Search syntax](#search-syntax) * [Environment variables](#environment-variables) * [Customizing the look](#customizing-the-look) * [Options](#options) * [Demo](#demo) * [Examples](#examples) * [Key bindings for command-line](#key-bindings-for-command-line) * [Fuzzy completion for bash and zsh](#fuzzy-completion-for-bash-and-zsh) * [Files and directories](#files-and-directories) * [Process IDs](#process-ids) * [Host names](#host-names) * [Environment variables / Aliases](#environment-variables--aliases) * [Customizing fzf options for completion](#customizing-fzf-options-for-completion) * [Customizing completion source for paths and directories](#customizing-completion-source-for-paths-and-directories) * [Supported commands](#supported-commands) * [Custom fuzzy completion](#custom-fuzzy-completion) * [Vim plugin](#vim-plugin) * [Advanced topics](#advanced-topics) * [Customizing for different types of input](#customizing-for-different-types-of-input) * [Performance](#performance) * [Executing external programs](#executing-external-programs) * [Turning into a different process](#turning-into-a-different-process) * [Reloading the candidate list](#reloading-the-candidate-list) * [1. Update the list of processes by pressing CTRL-R](#1-update-the-list-of-processes-by-pressing-ctrl-r) * [2. Switch between sources by pressing CTRL-D or CTRL-F](#2-switch-between-sources-by-pressing-ctrl-d-or-ctrl-f) * [3. Interactive ripgrep integration](#3-interactive-ripgrep-integration) * [Preview window](#preview-window) * [Previewing an image](#previewing-an-image) * [Tips](#tips) * [Respecting `.gitignore`](#respecting-gitignore) * [Fish shell](#fish-shell) * [fzf Theme Playground](#fzf-theme-playground) * [Related projects](#related-projects) * [License](#license) Installation ------------ ### Using Homebrew You can use [Homebrew](https://brew.sh/) (on macOS or Linux) to install fzf. ```sh brew install fzf ``` > [!IMPORTANT] > To set up shell integration (key bindings and fuzzy completion), > see [the instructions below](#setting-up-shell-integration). fzf is also available [via MacPorts][portfile]: `sudo port install fzf` [portfile]: https://github.com/macports/macports-ports/blob/master/sysutils/fzf/Portfile ### Linux packages | Package Manager | Linux Distribution | Command | | --------------- | ----------------------- | ---------------------------------- | | APK | Alpine Linux | `sudo apk add fzf` | | APT | Debian 9+/Ubuntu 19.10+ | `sudo apt install fzf` | | Conda | | `conda install -c conda-forge fzf` | | DNF | Fedora | `sudo dnf install fzf` | | Nix | NixOS, etc. | `nix-env -iA nixpkgs.fzf` | | Pacman | Arch Linux | `sudo pacman -S fzf` | | pkg | FreeBSD | `pkg install fzf` | | pkgin | NetBSD | `pkgin install fzf` | | pkg_add | OpenBSD | `pkg_add fzf` | | Portage | Gentoo | `emerge --ask app-shells/fzf` | | Spack | | `spack install fzf` | | XBPS | Void Linux | `sudo xbps-install -S fzf` | | Zypper | openSUSE | `sudo zypper install fzf` | > [!IMPORTANT] > To set up shell integration (key bindings and fuzzy completion), > see [the instructions below](#setting-up-shell-integration). [![Packaging status](https://repology.org/badge/vertical-allrepos/fzf.svg?columns=3)](https://repology.org/project/fzf/versions) ### Windows packages On Windows, fzf is available via [Chocolatey][choco], [Scoop][scoop], [Winget][winget], and [MSYS2][msys2]: | Package manager | Command | | --------------- | ------------------------------------- | | Chocolatey | `choco install fzf` | | Scoop | `scoop install fzf` | | Winget | `winget install fzf` | | MSYS2 (pacman) | `pacman -S $MINGW_PACKAGE_PREFIX-fzf` | [choco]: https://chocolatey.org/packages/fzf [scoop]: https://github.com/ScoopInstaller/Main/blob/master/bucket/fzf.json [winget]: https://github.com/microsoft/winget-pkgs/tree/master/manifests/j/junegunn/fzf [msys2]: https://packages.msys2.org/base/mingw-w64-fzf ### Using git Alternatively, you can "git clone" this repository to any directory and run [install](https://github.com/junegunn/fzf/blob/master/install) script. ```sh git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install ``` The install script will add lines to your shell configuration file to modify `$PATH` and set up shell integration. ### Binary releases You can download the official fzf binaries from the releases page. * https://github.com/junegunn/fzf/releases ### Setting up shell integration Add the following line to your shell configuration file. * bash ```sh # Set up fzf key bindings and fuzzy completion eval "$(fzf --bash)" ``` * zsh ```sh # Set up fzf key bindings and fuzzy completion source <(fzf --zsh) ``` * fish ```fish # Set up fzf key bindings fzf --fish | source ``` > [!NOTE] > `--bash`, `--zsh`, and `--fish` options are only available in fzf 0.48.0 or > later. If you have an older version of fzf, or want finer control, you can > source individual script files in the [/shell](/shell) directory. The > location of the files may vary depending on the package manager you use. > Please refer to the package documentation for more information. > (e.g. `apt show fzf`) > [!TIP] > You can disable CTRL-T or ALT-C binding by setting `FZF_CTRL_T_COMMAND` or > `FZF_ALT_C_COMMAND` to an empty string when sourcing the script. > For example, to disable ALT-C binding: > > * bash: `FZF_ALT_C_COMMAND= eval "$(fzf --bash)"` > * zsh: `FZF_ALT_C_COMMAND= source <(fzf --zsh)` > * fish: `fzf --fish | FZF_ALT_C_COMMAND= source` > > Setting the variables after sourcing the script will have no effect. ### Vim/Neovim plugin If you use [vim-plug](https://github.com/junegunn/vim-plug), add this to your Vim configuration file: ```vim Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } Plug 'junegunn/fzf.vim' ``` * `junegunn/fzf` provides the basic library functions * `fzf#install()` makes sure that you have the latest binary * `junegunn/fzf.vim` is [a separate project](https://github.com/junegunn/fzf.vim) that provides a variety of useful commands To learn more about the Vim integration, see [README-VIM.md](README-VIM.md). > [!TIP] > If you use Neovim and prefer Lua-based plugins, check out > [fzf-lua](https://github.com/ibhagwan/fzf-lua). Upgrading fzf ------------- fzf is being actively developed, and you might want to upgrade it once in a while. Please follow the instruction below depending on the installation method used. - git: `cd ~/.fzf && git pull && ./install` - brew: `brew update; brew upgrade fzf` - macports: `sudo port upgrade fzf` - chocolatey: `choco upgrade fzf` - vim-plug: `:PlugUpdate fzf` Building fzf ------------ See [BUILD.md](BUILD.md). Usage ----- fzf will launch interactive finder, read the list from STDIN, and write the selected item to STDOUT. ```sh find * -type f | fzf > selected ``` Without STDIN pipe, fzf will traverse the file system under the current directory to get the list of files. ```sh vim $(fzf) ``` > [!NOTE] > You can override the default behavior > * Either by setting `$FZF_DEFAULT_COMMAND` to a command that generates the desired list > * Or by setting `--walker`, `--walker-root`, and `--walker-skip` options in `$FZF_DEFAULT_OPTS` > [!WARNING] > A more robust solution would be to use `xargs` but we've presented > the above as it's easier to grasp > ```sh > fzf --print0 | xargs -0 -o vim > ``` > [!TIP] > fzf also has the ability to turn itself into a different process. > > ```sh > fzf --bind 'enter:become(vim {})' > ``` > > *See [Turning into a different process](#turning-into-a-different-process) > for more information.* ### Using the finder - `CTRL-K` / `CTRL-J` (or `CTRL-P` / `CTRL-N`) to move cursor up and down - `Enter` key to select the item, `CTRL-C` / `CTRL-G` / `ESC` to exit - On multi-select mode (`-m`), `TAB` and `Shift-TAB` to mark multiple items - Emacs style key bindings - Mouse: scroll, click, double-click; shift-click and shift-scroll on multi-select mode ### Display modes fzf by default runs in fullscreen mode, but there are other display modes. #### `--height` mode With `--height HEIGHT[%]`, fzf will start below the cursor with the given height. ```sh fzf --height 40% ``` `reverse` layout and `--border` goes well with this option. ```sh fzf --height 40% --layout reverse --border ``` By prepending `~` to the height, you're setting the maximum height. ```sh # Will take as few lines as possible to display the list seq 3 | fzf --height ~100% seq 3000 | fzf --height ~100% ``` Height value can be a negative number. ```sh # Screen height - 3 fzf --height -3 ``` #### `--tmux` mode With `--tmux` option, fzf will start in a tmux popup. ```sh # --tmux [center|top|bottom|left|right][,SIZE[%]][,SIZE[%][,border-native]] fzf --tmux center # Center, 50% width and height fzf --tmux 80% # Center, 80% width and height fzf --tmux 100%,50% # Center, 100% width and 50% height fzf --tmux left,40% # Left, 40% width fzf --tmux left,40%,90% # Left, 40% width, 90% height fzf --tmux top,40% # Top, 40% height fzf --tmux bottom,80%,40% # Bottom, 80% height, 40% height ``` `--tmux` is silently ignored when you're not on tmux. > [!NOTE] > If you're stuck with an old version of tmux that doesn't support popup, > or if you want to open fzf in a regular tmux pane, check out > [fzf-tmux](bin/fzf-tmux) script. > [!TIP] > You can add these options to `$FZF_DEFAULT_OPTS` so that they're applied by > default. For example, > > ```sh > # Open in tmux popup if on tmux, otherwise use --height mode > export FZF_DEFAULT_OPTS='--height 40% --tmux bottom,40% --layout reverse --border top' > ``` ### Search syntax Unless otherwise specified, fzf starts in "extended-search mode" where you can type in multiple search terms delimited by spaces. e.g. `^music .mp3$ sbtrkt !fire` | Token | Match type | Description | | --------- | -------------------------------------- | ------------------------------------------ | | `sbtrkt` | fuzzy-match | Items that match `sbtrkt` | | `'wild` | exact-match (quoted) | Items that include `wild` | | `'wild'` | exact-boundary-match (quoted both ends) | Items that include `wild` at word boundaries | | `^music` | prefix-exact-match | Items that start with `music` | | `.mp3$` | suffix-exact-match | Items that end with `.mp3` | | `!fire` | inverse-exact-match | Items that do not include `fire` | | `!^music` | inverse-prefix-exact-match | Items that do not start with `music` | | `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.mp3` | If you don't prefer fuzzy matching and do not wish to "quote" every word, start fzf with `-e` or `--exact` option. Note that when `--exact` is set, `'`-prefix "unquotes" the term. A single bar character term acts as an OR operator. For example, the following query matches entries that start with `core` and end with either `go`, `rb`, or `py`. ``` ^core go$ | rb$ | py$ ``` ### Environment variables - `FZF_DEFAULT_COMMAND` - Default command to use when input is tty - e.g. `export FZF_DEFAULT_COMMAND='fd --type f'` - `FZF_DEFAULT_OPTS` - Default options - e.g. `export FZF_DEFAULT_OPTS="--layout=reverse --inline-info"` - `FZF_DEFAULT_OPTS_FILE` - If you prefer to manage default options in a file, set this variable to point to the location of the file - e.g. `export FZF_DEFAULT_OPTS_FILE=~/.fzfrc` > [!WARNING] > `FZF_DEFAULT_COMMAND` is not used by shell integration due to the > slight difference in requirements. > > * `CTRL-T` runs `$FZF_CTRL_T_COMMAND` to get a list of files and directories > * `ALT-C` runs `$FZF_ALT_C_COMMAND` to get a list of directories > * `vim ~/**` runs `fzf_compgen_path()` with the prefix (`~/`) as the first argument > * `cd foo**` runs `fzf_compgen_dir()` with the prefix (`foo`) as the first argument > > The available options are described later in this document. ### Customizing the look The user interface of fzf is fully customizable with a large number of configuration options. For a quick setup, you can start with one of the style presets โ€” `default`, `full`, or `minimal` โ€” using the `--style` option. ```sh fzf --style full \ --preview 'fzf-preview.sh {}' --bind 'focus:transform-header:file --brief {}' ``` | Preset | Screenshot | | :--- | :--- | | `default` | | | `full` | | | `minimal` | | Here's an example based on the `full` preset:
```sh git ls-files | fzf --style full \ --border --padding 1,2 \ --border-label ' Demo ' --input-label ' Input ' --header-label ' File Type ' \ --preview 'fzf-preview.sh {}' \ --bind 'result:transform-list-label: if [[ -z $FZF_QUERY ]]; then echo " $FZF_MATCH_COUNT items " else echo " $FZF_MATCH_COUNT matches for [$FZF_QUERY] " fi ' \ --bind 'focus:transform-preview-label:[[ -n {} ]] && printf " Previewing [%s] " {}' \ --bind 'focus:+transform-header:file --brief {} || echo "No file selected"' \ --bind 'ctrl-r:change-list-label( Reloading the list )+reload(sleep 2; git ls-files)' \ --color 'border:#aaaaaa,label:#cccccc' \ --color 'preview-border:#9999cc,preview-label:#ccccff' \ --color 'list-border:#669966,list-label:#99cc99' \ --color 'input-border:#996666,input-label:#ffcccc' \ --color 'header-border:#6699cc,header-label:#99ccff' ```
### Options See the man page (`fzf --man` or `man fzf`) for the full list of options. ### Demo If you learn by watching videos, check out this screencast by [@samoshkin](https://github.com/samoshkin) to explore `fzf` features. Examples -------- * [Wiki page of examples](https://github.com/junegunn/fzf/wiki/examples) * *Disclaimer: The examples on this page are maintained by the community and are not thoroughly tested* * [Advanced fzf examples](https://github.com/junegunn/fzf/blob/master/ADVANCED.md) Key bindings for command-line ----------------------------- By [setting up shell integration](#setting-up-shell-integration), you can use the following key bindings in bash, zsh, and fish. - `CTRL-T` - Paste the selected files and directories onto the command-line - The list is generated using `--walker file,dir,follow,hidden` option - You can override the behavior by setting `FZF_CTRL_T_COMMAND` to a custom command that generates the desired list - Or you can set `--walker*` options in `FZF_CTRL_T_OPTS` - Set `FZF_CTRL_T_OPTS` to pass additional options to fzf ```sh # Preview file content using bat (https://github.com/sharkdp/bat) export FZF_CTRL_T_OPTS=" --walker-skip .git,node_modules,target --preview 'bat -n --color=always {}' --bind 'ctrl-/:change-preview-window(down|hidden|)'" ``` - Can be disabled by setting `FZF_CTRL_T_COMMAND` to an empty string when sourcing the script - `CTRL-R` - Paste the selected command from history onto the command-line - If you want to see the commands in chronological order, press `CTRL-R` again which toggles sorting by relevance - Press `CTRL-/` or `ALT-/` to toggle line wrapping - Set `FZF_CTRL_R_OPTS` to pass additional options to fzf ```sh # CTRL-Y to copy the command into clipboard using pbcopy export FZF_CTRL_R_OPTS=" --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort' --color header:italic --header 'Press CTRL-Y to copy command into clipboard'" ``` - `ALT-C` - cd into the selected directory - The list is generated using `--walker dir,follow,hidden` option - Set `FZF_ALT_C_COMMAND` to override the default command - Or you can set `--walker-*` options in `FZF_ALT_C_OPTS` - Set `FZF_ALT_C_OPTS` to pass additional options to fzf ```sh # Print tree structure in the preview window export FZF_ALT_C_OPTS=" --walker-skip .git,node_modules,target --preview 'tree -C {}'" ``` - Can be disabled by setting `FZF_ALT_C_COMMAND` to an empty string when sourcing the script Display modes for these bindings can be separately configured via `FZF_{CTRL_T,CTRL_R,ALT_C}_OPTS` or globally via `FZF_DEFAULT_OPTS`. (e.g. `FZF_CTRL_R_OPTS='--tmux bottom,60% --height 60% --border top'`) More tips can be found on [the wiki page](https://github.com/junegunn/fzf/wiki/Configuring-shell-key-bindings). Fuzzy completion for bash and zsh --------------------------------- ### Files and directories Fuzzy completion for files and directories can be triggered if the word before the cursor ends with the trigger sequence, which is by default `**`. - `COMMAND [DIRECTORY/][FUZZY_PATTERN]**` ```sh # Files under the current directory # - You can select multiple items with TAB key vim ** # Files under parent directory vim ../** # Files under parent directory that match `fzf` vim ../fzf** # Files under your home directory vim ~/** # Directories under current directory (single-selection) cd ** # Directories under ~/github that match `fzf` cd ~/github/fzf** ``` ### Process IDs Fuzzy completion for PIDs is provided for kill command. ```sh # Can select multiple processes with or keys kill -9 ** ``` ### Host names For ssh and telnet commands, fuzzy completion for hostnames is provided. The names are extracted from /etc/hosts and ~/.ssh/config. ```sh ssh ** telnet ** ``` ### Environment variables / Aliases ```sh unset ** export ** unalias ** ``` ### Customizing fzf options for completion ```sh # Use ~~ as the trigger sequence instead of the default ** export FZF_COMPLETION_TRIGGER='~~' # Options to fzf command export FZF_COMPLETION_OPTS='--border --info=inline' # Options for path completion (e.g. vim **) export FZF_COMPLETION_PATH_OPTS='--walker file,dir,follow,hidden' # Options for directory completion (e.g. cd **) export FZF_COMPLETION_DIR_OPTS='--walker dir,follow' # Advanced customization of fzf options via _fzf_comprun function # - The first argument to the function is the name of the command. # - You should make sure to pass the rest of the arguments ($@) to fzf. _fzf_comprun() { local command=$1 shift case "$command" in cd) fzf --preview 'tree -C {} | head -200' "$@" ;; export|unset) fzf --preview "eval 'echo \$'{}" "$@" ;; ssh) fzf --preview 'dig {}' "$@" ;; *) fzf --preview 'bat -n --color=always {}' "$@" ;; esac } ``` ### Customizing completion source for paths and directories ```sh # Use fd (https://github.com/sharkdp/fd) for listing path candidates. # - The first argument to the function ($1) is the base path to start traversal # - See the source code (completion.{bash,zsh}) for the details. _fzf_compgen_path() { fd --hidden --follow --exclude ".git" . "$1" } # Use fd to generate the list for directory completion _fzf_compgen_dir() { fd --type d --hidden --follow --exclude ".git" . "$1" } ``` ### Supported commands On bash, fuzzy completion is enabled only for a predefined set of commands (`complete | grep _fzf` to see the list). But you can enable it for other commands as well by using `_fzf_setup_completion` helper function. ```sh # usage: _fzf_setup_completion path|dir|var|alias|host COMMANDS... _fzf_setup_completion path ag git kubectl _fzf_setup_completion dir tree ``` ### Custom fuzzy completion _**(Custom completion API is experimental and subject to change)**_ For a command named _"COMMAND"_, define `_fzf_complete_COMMAND` function using `_fzf_complete` helper. ```sh # Custom fuzzy completion for "doge" command # e.g. doge ** _fzf_complete_doge() { _fzf_complete --multi --reverse --prompt="doge> " -- "$@" < <( echo very echo wow echo such echo doge ) } ``` - The arguments before `--` are the options to fzf. - After `--`, simply pass the original completion arguments unchanged (`"$@"`). - Then, write a set of commands that generates the completion candidates and feed its output to the function using process substitution (`< <(...)`). zsh will automatically pick up the function using the naming convention but in bash you have to manually associate the function with the command using the `complete` command. ```sh [ -n "$BASH" ] && complete -F _fzf_complete_doge -o default -o bashdefault doge ``` If you need to post-process the output from fzf, define `_fzf_complete_COMMAND_post` as follows. ```sh _fzf_complete_foo() { _fzf_complete --multi --reverse --header-lines=3 -- "$@" < <( ls -al ) } _fzf_complete_foo_post() { awk '{print $NF}' } [ -n "$BASH" ] && complete -F _fzf_complete_foo -o default -o bashdefault foo ``` Vim plugin ---------- See [README-VIM.md](README-VIM.md). Advanced topics --------------- ### Customizing for different types of input Since fzf is a general-purpose text filter, its algorithm was designed to "generally" work well with any kind of input. However, admittedly, there is no true one-size-fits-all solution, and you may want to tweak the algorithm and some of the settings depending on the type of the input. To make this process easier, fzf provides a set of "scheme"s for some common input types. | Scheme | Description | | :--- | :--- | | `--scheme=default` | Generic scheme designed to work well with any kind of input | | `--scheme=path` | Suitable for file paths | | `--scheme=history` | Suitable for command history or any input where chronological ordering is important | (See `fzf --man` for the details) ### Performance fzf is fast. Performance should not be a problem in most use cases. However, you might want to be aware of the options that can affect performance. - `--ansi` tells fzf to extract and parse ANSI color codes in the input, and it makes the initial scanning slower. So it's not recommended that you add it to your `$FZF_DEFAULT_OPTS`. - `--nth` makes fzf slower because it has to tokenize each line. - A plain string `--delimiter` should be preferred over a regular expression delimiter. - `--with-nth` makes fzf slower as fzf has to tokenize and reassemble each line. ### Executing external programs You can set up key bindings for starting external processes without leaving fzf (`execute`, `execute-silent`). ```bash # Press F1 to open the file with less without leaving fzf # Press CTRL-Y to copy the line to clipboard and aborts fzf (requires pbcopy) fzf --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort' ``` See *KEY BINDINGS* section of the man page for details. ### Turning into a different process `become(...)` is similar to `execute(...)`/`execute-silent(...)` described above, but instead of executing the command and coming back to fzf on complete, it turns fzf into a new process for the command. ```sh fzf --bind 'enter:become(vim {})' ``` Compared to the seemingly equivalent command substitution `vim "$(fzf)"`, this approach has several advantages: * Vim will not open an empty file when you terminate fzf with CTRL-C * Vim will not open an empty file when you press ENTER on an empty result * Can handle multiple selections even when they have whitespaces ```sh fzf --multi --bind 'enter:become(vim {+})' ``` To be fair, running `fzf --print0 | xargs -0 -o vim` instead of `vim "$(fzf)"` resolves all of the issues mentioned. Nonetheless, `become(...)` still offers additional benefits in different scenarios. * You can set up multiple bindings to handle the result in different ways without any wrapping script ```sh fzf --bind 'enter:become(vim {}),ctrl-e:become(emacs {})' ``` * Previously, you would have to use `--expect=ctrl-e` and check the first line of the output of fzf * You can easily build the subsequent command using the field index expressions of fzf ```sh # Open the file in Vim and go to the line git grep --line-number . | fzf --delimiter : --nth 3.. --bind 'enter:become(vim {1} +{2})' ``` ### Reloading the candidate list By binding `reload` action to a key or an event, you can make fzf dynamically reload the candidate list. See https://github.com/junegunn/fzf/issues/1750 for more details. #### 1. Update the list of processes by pressing CTRL-R ```sh ps -ef | fzf --bind 'ctrl-r:reload(ps -ef)' \ --header 'Press CTRL-R to reload' --header-lines=1 \ --height=50% --layout=reverse ``` #### 2. Switch between sources by pressing CTRL-D or CTRL-F ```sh FZF_DEFAULT_COMMAND='find . -type f' \ fzf --bind 'ctrl-d:reload(find . -type d),ctrl-f:reload(eval "$FZF_DEFAULT_COMMAND")' \ --height=50% --layout=reverse ``` #### 3. Interactive ripgrep integration The following example uses fzf as the selector interface for ripgrep. We bound `reload` action to `change` event, so every time you type on fzf, the ripgrep process will restart with the updated query string denoted by the placeholder expression `{q}`. Also, note that we used `--disabled` option so that fzf doesn't perform any secondary filtering. ```sh : | rg_prefix='rg --column --line-number --no-heading --color=always --smart-case' \ fzf --bind 'start:reload:$rg_prefix ""' \ --bind 'change:reload:$rg_prefix {q} || true' \ --bind 'enter:become(vim {1} +{2})' \ --ansi --disabled \ --height=50% --layout=reverse ``` If ripgrep doesn't find any matches, it will exit with a non-zero exit status, and fzf will warn you about it. To suppress the warning message, we added `|| true` to the command, so that it always exits with 0. See ["Using fzf as interactive Ripgrep launcher"](https://github.com/junegunn/fzf/blob/master/ADVANCED.md#using-fzf-as-interactive-ripgrep-launcher) for more sophisticated examples. ### Preview window When the `--preview` option is set, fzf automatically starts an external process with the current line as the argument and shows the result in the split window. Your `$SHELL` is used to execute the command with `$SHELL -c COMMAND`. The window can be scrolled using the mouse or custom key bindings. ```bash # {} is replaced with the single-quoted string of the focused line fzf --preview 'cat {}' ``` Preview window supports ANSI colors, so you can use any program that syntax-highlights the content of a file, such as [Bat](https://github.com/sharkdp/bat) or [Highlight](https://gitlab.com/saalen/highlight): ```bash fzf --preview 'bat --color=always {}' --preview-window '~3' ``` You can customize the size, position, and border of the preview window using `--preview-window` option, and the foreground and background color of it with `--color` option. For example, ```bash fzf --height 40% --layout reverse --info inline --border \ --preview 'file {}' --preview-window up,1,border-horizontal \ --bind 'ctrl-/:change-preview-window(50%|hidden|)' \ --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899' ``` See the man page (`man fzf`) for the full list of options. More advanced examples can be found [here](https://github.com/junegunn/fzf/blob/master/ADVANCED.md). > [!WARNING] > Since fzf is a general-purpose text filter rather than a file finder, **it is > not a good idea to add `--preview` option to your `$FZF_DEFAULT_OPTS`**. > > ```sh > # ********************* > # ** DO NOT DO THIS! ** > # ********************* > export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always --line-range :500 {}"' > > # bat doesn't work with any input other than the list of files > ps -ef | fzf > seq 100 | fzf > history | fzf > ``` ### Previewing an image fzf can display images in the preview window using one of the following protocols: * [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) * [iTerm2 inline images protocol](https://iterm2.com/documentation-images.html) * [Sixel](https://en.wikipedia.org/wiki/Sixel) See [bin/fzf-preview.sh](bin/fzf-preview.sh) script for more information. ```sh fzf --preview 'fzf-preview.sh {}' ``` Tips ---- ### Respecting `.gitignore` You can use [fd](https://github.com/sharkdp/fd), [ripgrep](https://github.com/BurntSushi/ripgrep), or [the silver searcher](https://github.com/ggreer/the_silver_searcher) to traverse the file system while respecting `.gitignore`. ```sh # Feed the output of fd into fzf fd --type f --strip-cwd-prefix | fzf # Setting fd as the default source for fzf export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix' # Now fzf (w/o pipe) will use the fd command to generate the list fzf # To apply the command to CTRL-T as well export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" ``` If you want the command to follow symbolic links and don't want it to exclude hidden files, use the following command: ```sh export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow --exclude .git' ``` ### Fish shell `CTRL-T` key binding of fish, unlike those of bash and zsh, will use the last token on the command-line as the root directory for the recursive search. For instance, hitting `CTRL-T` at the end of the following command-line ```sh ls /var/ ``` will list all files and directories under `/var/`. When using a custom `FZF_CTRL_T_COMMAND`, use the unexpanded `$dir` variable to make use of this feature. `$dir` defaults to `.` when the last token is not a valid directory. Example: ```sh set -g FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'" ``` ### fzf Theme Playground [fzf Theme Playground](https://vitormv.github.io/fzf-themes/) created by [Vitor Mello](https://github.com/vitormv) is a webpage where you can interactively create fzf themes. Related projects ---------------- https://github.com/junegunn/fzf/wiki/Related-projects [License](LICENSE) ------------------ The MIT License (MIT) Copyright (c) 2013-2024 Junegunn Choi fzf-0.60.3/bin/000077500000000000000000000000001476126201100131355ustar00rootroot00000000000000fzf-0.60.3/bin/fzf-preview.sh000077500000000000000000000054651476126201100157520ustar00rootroot00000000000000#!/usr/bin/env bash # # The purpose of this script is to demonstrate how to preview a file or an # image in the preview window of fzf. # # Dependencies: # - https://github.com/sharkdp/bat # - https://github.com/hpjansson/chafa # - https://iterm2.com/utilities/imgcat if [[ $# -ne 1 ]]; then >&2 echo "usage: $0 FILENAME[:LINENO][:IGNORED]" exit 1 fi file=${1/#\~\//$HOME/} center=0 if [[ ! -r $file ]]; then if [[ $file =~ ^(.+):([0-9]+)\ *$ ]] && [[ -r ${BASH_REMATCH[1]} ]]; then file=${BASH_REMATCH[1]} center=${BASH_REMATCH[2]} elif [[ $file =~ ^(.+):([0-9]+):[0-9]+\ *$ ]] && [[ -r ${BASH_REMATCH[1]} ]]; then file=${BASH_REMATCH[1]} center=${BASH_REMATCH[2]} fi fi type=$(file --brief --dereference --mime -- "$file") if [[ ! $type =~ image/ ]]; then if [[ $type =~ =binary ]]; then file "$1" exit fi # Sometimes bat is installed as batcat. if command -v batcat > /dev/null; then batname="batcat" elif command -v bat > /dev/null; then batname="bat" else cat "$1" exit fi ${batname} --style="${BAT_STYLE:-numbers}" --color=always --pager=never --highlight-line="${center:-0}" -- "$file" exit fi dim=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES} if [[ $dim = x ]]; then dim=$(stty size < /dev/tty | awk '{print $2 "x" $1}') elif ! [[ $KITTY_WINDOW_ID ]] && (( FZF_PREVIEW_TOP + FZF_PREVIEW_LINES == $(stty size < /dev/tty | awk '{print $1}') )); then # Avoid scrolling issue when the Sixel image touches the bottom of the screen # * https://github.com/junegunn/fzf/issues/2544 dim=${FZF_PREVIEW_COLUMNS}x$((FZF_PREVIEW_LINES - 1)) fi # 1. Use icat (from Kitty) if kitten is installed if [[ $KITTY_WINDOW_ID ]] || [[ $GHOSTTY_RESOURCES_DIR ]] && command -v kitten > /dev/null; then # 1. 'memory' is the fastest option but if you want the image to be scrollable, # you have to use 'stream'. # # 2. The last line of the output is the ANSI reset code without newline. # This confuses fzf and makes it render scroll offset indicator. # So we remove the last line and append the reset code to its previous line. kitten icat --clear --transfer-mode=memory --unicode-placeholder --stdin=no --place="$dim@0x0" "$file" | sed '$d' | sed $'$s/$/\e[m/' # 2. Use chafa with Sixel output elif command -v chafa > /dev/null; then chafa -s "$dim" "$file" # Add a new line character so that fzf can display multiple images in the preview window echo # 3. If chafa is not found but imgcat is available, use it on iTerm2 elif command -v imgcat > /dev/null; then # NOTE: We should use https://iterm2.com/utilities/it2check to check if the # user is running iTerm2. But for the sake of simplicity, we just assume # that's the case here. imgcat -W "${dim%%x*}" -H "${dim##*x}" "$file" # 4. Cannot find any suitable method to preview the image else file "$file" fi fzf-0.60.3/bin/fzf-tmux000077500000000000000000000163411476126201100146500ustar00rootroot00000000000000#!/usr/bin/env bash # fzf-tmux: starts fzf in a tmux pane # usage: fzf-tmux [LAYOUT OPTIONS] [--] [FZF OPTIONS] fail() { >&2 echo "$1" exit 2 } fzf="$(command which fzf)" || fzf="$(dirname "$0")/fzf" [[ -x "$fzf" ]] || fail 'fzf executable not found' args=() opt="" skip="" swap="" close="" term="" [[ -n "$LINES" ]] && lines=$LINES || lines=$(tput lines) || lines=$(tmux display-message -p "#{pane_height}") [[ -n "$COLUMNS" ]] && columns=$COLUMNS || columns=$(tput cols) || columns=$(tmux display-message -p "#{pane_width}") tmux_version=$(tmux -V | sed 's/[^0-9.]//g') tmux_32=$(awk '{print ($1 >= 3.2)}' <<< "$tmux_version" 2> /dev/null || bc -l <<< "$tmux_version >= 3.2") help() { >&2 echo 'usage: fzf-tmux [LAYOUT OPTIONS] [--] [FZF OPTIONS] LAYOUT OPTIONS: (default layout: -d 50%) Popup window (requires tmux 3.2 or above): -p [WIDTH[%][,HEIGHT[%]]] (default: 50%) -w WIDTH[%] -h HEIGHT[%] -x COL -y ROW Split pane: -u [HEIGHT[%]] Split above (up) -d [HEIGHT[%]] Split below (down) -l [WIDTH[%]] Split left -r [WIDTH[%]] Split right ' exit } while [[ $# -gt 0 ]]; do arg="$1" shift [[ -z "$skip" ]] && case "$arg" in -) term=1 ;; --help) help ;; --version) echo "fzf-tmux (with fzf $("$fzf" --version))" exit ;; -p*|-w*|-h*|-x*|-y*|-d*|-u*|-r*|-l*) if [[ "$arg" =~ ^-[pwhxy] ]]; then [[ "$opt" =~ "-E" ]] || opt="-E" elif [[ "$arg" =~ ^.[lr] ]]; then opt="-h" if [[ "$arg" =~ ^.l ]]; then opt="$opt -d" swap="; swap-pane -D ; select-pane -L" close="; tmux swap-pane -D" fi else opt="" if [[ "$arg" =~ ^.u ]]; then opt="$opt -d" swap="; swap-pane -D ; select-pane -U" close="; tmux swap-pane -D" fi fi if [[ ${#arg} -gt 2 ]]; then size="${arg:2}" else if [[ "$1" =~ ^[0-9%,]+$ ]] || [[ "$1" =~ ^[A-Z]$ ]]; then size="$1" shift else continue fi fi if [[ "$arg" =~ ^-p ]]; then if [[ -n "$size" ]]; then w=${size%%,*} h=${size##*,} opt="$opt -w$w -h$h" fi elif [[ "$arg" =~ ^-[whxy] ]]; then opt="$opt ${arg:0:2}$size" elif [[ "$size" =~ %$ ]]; then size=${size:0:((${#size}-1))} if [[ $tmux_32 = 1 ]]; then if [[ -n "$swap" ]]; then opt="$opt -l $(( 100 - size ))%" else opt="$opt -l $size%" fi else if [[ -n "$swap" ]]; then opt="$opt -p $(( 100 - size ))" else opt="$opt -p $size" fi fi else if [[ -n "$swap" ]]; then if [[ "$arg" =~ ^.l ]]; then max=$columns else max=$lines fi size=$(( max - size )) [[ $size -lt 0 ]] && size=0 opt="$opt -l $size" else opt="$opt -l $size" fi fi ;; --) # "--" can be used to separate fzf-tmux options from fzf options to # avoid conflicts skip=1 continue ;; *) args+=("$arg") ;; esac [[ -n "$skip" ]] && args+=("$arg") done if [[ -z "$TMUX" ]]; then "$fzf" "${args[@]}" exit $? fi # * --height option is not allowed # * CTRL-Z is also disabled # * fzf-tmux script is not compatible with --tmux option in fzf 0.53.0 or later args=("${args[@]}" "--no-height" "--bind=ctrl-z:ignore" "--no-tmux") # Handle zoomed tmux pane without popup options by moving it to a temp window if [[ ! "$opt" =~ "-E" ]] && tmux list-panes -F '#F' | grep -q Z; then zoomed_without_popup=1 original_window=$(tmux display-message -p "#{window_id}") tmp_window=$(tmux new-window -d -P -F "#{window_id}" "bash -c 'while :; do for c in \\| / - '\\;' do sleep 0.2; printf \"\\r\$c fzf-tmux is running\\r\"; done; done'") tmux swap-pane -t $tmp_window \; select-window -t $tmp_window fi set -e # Clean up named pipes on exit id=$RANDOM argsf="${TMPDIR:-/tmp}/fzf-args-$id" fifo1="${TMPDIR:-/tmp}/fzf-fifo1-$id" fifo2="${TMPDIR:-/tmp}/fzf-fifo2-$id" fifo3="${TMPDIR:-/tmp}/fzf-fifo3-$id" if tmux_win_opts=$(tmux show-options -p remain-on-exit \; show-options -p synchronize-panes 2> /dev/null); then tmux_win_opts=( $(sed '/ off/d; s/synchronize-panes/set-option -p synchronize-panes/; s/remain-on-exit/set-option -p remain-on-exit/; s/$/ \\;/' <<< "$tmux_win_opts") ) tmux_off_opts='; set-option -p synchronize-panes off ; set-option -p remain-on-exit off' else tmux_win_opts=( $(tmux show-window-options remain-on-exit \; show-window-options synchronize-panes | sed '/ off/d; s/^/set-window-option /; s/$/ \\;/') ) tmux_off_opts='; set-window-option synchronize-panes off ; set-window-option remain-on-exit off' fi cleanup() { \rm -f $argsf $fifo1 $fifo2 $fifo3 # Restore tmux window options if [[ "${#tmux_win_opts[@]}" -gt 1 ]]; then eval "tmux ${tmux_win_opts[*]}" fi # Remove temp window if we were zoomed without popup options if [[ -n "$zoomed_without_popup" ]]; then tmux display-message -p "#{window_id}" > /dev/null tmux swap-pane -t $original_window \; \ select-window -t $original_window \; \ kill-window -t $tmp_window \; \ resize-pane -Z fi if [[ $# -gt 0 ]]; then trap - EXIT exit 130 fi } trap 'cleanup 1' SIGUSR1 trap 'cleanup' EXIT envs="export TERM=$TERM " if [[ "$opt" =~ "-E" ]]; then if [[ $tmux_version = 3.2 ]]; then FZF_DEFAULT_OPTS="--margin 0,1 $FZF_DEFAULT_OPTS" elif [[ $tmux_32 = 1 ]]; then FZF_DEFAULT_OPTS="--border $FZF_DEFAULT_OPTS" opt="-B $opt" else echo "fzf-tmux: tmux 3.2 or above is required for popup mode" >&2 exit 2 fi fi envs="$envs FZF_DEFAULT_COMMAND=$(printf %q "$FZF_DEFAULT_COMMAND")" envs="$envs FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS")" envs="$envs FZF_DEFAULT_OPTS_FILE=$(printf %q "$FZF_DEFAULT_OPTS_FILE")" [[ -n "$RUNEWIDTH_EASTASIAN" ]] && envs="$envs RUNEWIDTH_EASTASIAN=$(printf %q "$RUNEWIDTH_EASTASIAN")" [[ -n "$BAT_THEME" ]] && envs="$envs BAT_THEME=$(printf %q "$BAT_THEME")" echo "$envs;" > "$argsf" # Build arguments to fzf opts=$(printf "%q " "${args[@]}") pppid=$$ echo -n "trap 'kill -SIGUSR1 -$pppid' EXIT SIGINT SIGTERM;" >> $argsf close="; trap - EXIT SIGINT SIGTERM $close" export TMUX=$(cut -d , -f 1,2 <<< "$TMUX") mkfifo -m o+w $fifo2 if [[ "$opt" =~ "-E" ]]; then cat $fifo2 & if [[ -n "$term" ]] || [[ -t 0 ]]; then cat <<< "\"$fzf\" $opts > $fifo2; out=\$? $close; exit \$out" >> $argsf else mkfifo $fifo1 cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; out=\$? $close; exit \$out" >> $argsf cat <&0 > $fifo1 & fi tmux popup -d "$PWD" $opt "bash $argsf" > /dev/null 2>&1 exit $? fi mkfifo -m o+w $fifo3 if [[ -n "$term" ]] || [[ -t 0 ]]; then cat <<< "\"$fzf\" $opts > $fifo2; echo \$? > $fifo3 $close" >> $argsf else mkfifo $fifo1 cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; echo \$? > $fifo3 $close" >> $argsf cat <&0 > $fifo1 & fi tmux \ split-window -c "$PWD" $opt "bash -c 'exec -a fzf bash $argsf'" $swap \ $tmux_off_opts \ > /dev/null 2>&1 || { "$fzf" "${args[@]}"; exit $?; } cat $fifo2 exit "$(cat $fifo3)" fzf-0.60.3/doc/000077500000000000000000000000001476126201100131325ustar00rootroot00000000000000fzf-0.60.3/doc/fzf.txt000066400000000000000000000521111476126201100144600ustar00rootroot00000000000000fzf.txt fzf Last change: February 15 2024 FZF - TABLE OF CONTENTS *fzf* *fzf-toc* ============================================================================== FZF Vim integration |fzf-vim-integration| Installation |fzf-installation| Summary |fzf-summary| :FZF[!] |:FZF| Configuration |fzf-configuration| Examples |fzf-examples| Explanation of g:fzf_colors |fzf-explanation-of-gfzfcolors| fzf#run |fzf#run| fzf#wrap |fzf#wrap| Global options supported by fzf#wrap |fzf-global-options-supported-by-fzf#wrap| Tips |fzf-tips| fzf inside terminal buffer |fzf-inside-terminal-buffer| Starting fzf in a popup window |fzf-starting-fzf-in-a-popup-window| Hide statusline |fzf-hide-statusline| License |fzf-license| FZF VIM INTEGRATION *fzf-vim-integration* ============================================================================== INSTALLATION *fzf-installation* ============================================================================== Once you have fzf installed, you can enable it inside Vim simply by adding the directory to 'runtimepath' in your Vim configuration file. The path may differ depending on the package manager. > " If installed using Homebrew set rtp+=/usr/local/opt/fzf " If installed using Homebrew on Apple Silicon set rtp+=/opt/homebrew/opt/fzf " If you have cloned fzf on ~/.fzf directory set rtp+=~/.fzf < If you use {vim-plug}{1}, the same can be written as: > " If installed using Homebrew Plug '/usr/local/opt/fzf' " If installed using Homebrew on Apple Silicon Plug '/opt/homebrew/opt/fzf' " If you have cloned fzf on ~/.fzf directory Plug '~/.fzf' < But if you want the latest Vim plugin file from GitHub rather than the one included in the package, write: > Plug 'junegunn/fzf' < The Vim plugin will pick up fzf binary available on the system. If fzf is not found on `$PATH`, it will ask you if it should download the latest binary for you. To make sure that you have the latest version of the binary, set up post-update hook like so: *fzf#install* > Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } < {1} https://github.com/junegunn/vim-plug SUMMARY *fzf-summary* ============================================================================== The Vim plugin of fzf provides two core functions, and `:FZF` command which is the basic file selector command built on top of them. 1. `fzf#run([spec dict])` - Starts fzf inside Vim with the given spec - `:call fzf#run({'source': 'ls'})` 2. `fzf#wrap([spec dict]) -> (dict)` - Takes a spec for `fzf#run` and returns an extended version of it with additional options for addressing global preferences (`g:fzf_xxx`) - `:echo fzf#wrap({'source': 'ls'})` - We usually wrap a spec with `fzf#wrap` before passing it to `fzf#run` - `:call fzf#run(fzf#wrap({'source': 'ls'}))` 3. `:FZF [fzf_options string] [path string]` - Basic fuzzy file selector - A reference implementation for those who don't want to write VimScript to implement custom commands - If you're looking for more such commands, check out {fzf.vim}{2} project. The most important of all is `fzf#run`, but it would be easier to understand the whole if we start off with `:FZF` command. {2} https://github.com/junegunn/fzf.vim :FZF[!] ============================================================================== *:FZF* > " Look for files under current directory :FZF " Look for files under your home directory :FZF ~ " With fzf command-line options :FZF --reverse --info=inline /tmp " Bang version starts fzf in fullscreen mode :FZF! < Similarly to {ctrlp.vim}{3}, use enter key, CTRL-T, CTRL-X or CTRL-V to open selected files in the current window, in new tabs, in horizontal splits, or in vertical splits respectively. Note that the environment variables `FZF_DEFAULT_COMMAND` and `FZF_DEFAULT_OPTS` also apply here. {3} https://github.com/kien/ctrlp.vim < Configuration >_____________________________________________________________~ *fzf-configuration* *g:fzf_action* *g:fzf_layout* *g:fzf_colors* *g:fzf_history_dir* - `g:fzf_action` - Customizable extra key bindings for opening selected files in different ways - `g:fzf_layout` - Determines the size and position of fzf window - `g:fzf_colors` - Customizes fzf colors to match the current color scheme - `g:fzf_history_dir` - Enables history feature Examples~ *fzf-examples* > " This is the default extra key bindings let g:fzf_action = { \ 'ctrl-t': 'tab split', \ 'ctrl-x': 'split', \ 'ctrl-v': 'vsplit' } " An action can be a reference to a function that processes selected lines function! s:build_quickfix_list(lines) call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }')) copen cc endfunction let g:fzf_action = { \ 'ctrl-q': function('s:build_quickfix_list'), \ 'ctrl-t': 'tab split', \ 'ctrl-x': 'split', \ 'ctrl-v': 'vsplit' } " Default fzf layout " - Popup window (center of the screen) let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } " - Popup window (center of the current window) let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true } } " - Popup window (anchored to the bottom of the current window) let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } } " - down / up / left / right let g:fzf_layout = { 'down': '40%' } " - Window using a Vim command let g:fzf_layout = { 'window': 'enew' } let g:fzf_layout = { 'window': '-tabnew' } let g:fzf_layout = { 'window': '10new' } " Customize fzf colors to match your color scheme " - fzf#wrap translates this to a set of `--color` options let g:fzf_colors = \ { 'fg': ['fg', 'Normal'], \ 'bg': ['bg', 'Normal'], \ 'hl': ['fg', 'Comment'], \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'hl+': ['fg', 'Statement'], \ 'info': ['fg', 'PreProc'], \ 'border': ['fg', 'Ignore'], \ 'prompt': ['fg', 'Conditional'], \ 'pointer': ['fg', 'Exception'], \ 'marker': ['fg', 'Keyword'], \ 'spinner': ['fg', 'Label'], \ 'header': ['fg', 'Comment'] } " Enable per-command history " - History files will be stored in the specified directory " - When set, CTRL-N and CTRL-P will be bound to 'next-history' and " 'previous-history' instead of 'down' and 'up'. let g:fzf_history_dir = '~/.local/share/fzf-history' < Explanation of g:fzf_colors~ *fzf-explanation-of-gfzfcolors* `g:fzf_colors` is a dictionary mapping fzf elements to a color specification list: > element: [ component, group1 [, group2, ...] ] < - `element` is an fzf element to apply a color to: ----------------------------+------------------------------------------------------ Element | Description ~ ----------------------------+------------------------------------------------------ `fg` / `bg` / `hl` | Item (foreground / background / highlight) `fg+` / `bg+` / `hl+` | Current item (foreground / background / highlight) `preview-fg` / `preview-bg` | Preview window text and background `hl` / `hl+` | Highlighted substrings (normal / current) `gutter` | Background of the gutter on the left `pointer` | Pointer to the current line ( `>` ) `marker` | Multi-select marker ( `>` ) `border` | Border around the window ( `--border` and `--preview` ) `header` | Header ( `--header` or `--header-lines` ) `info` | Info line (match counters) `spinner` | Streaming input indicator `query` | Query string `disabled` | Query string when search is disabled `prompt` | Prompt before query ( `> ` ) `pointer` | Pointer to the current line ( `>` ) ----------------------------+------------------------------------------------------ - `component` specifies the component (`fg` / `bg`) from which to extract the color when considering each of the following highlight groups - `group1 [, group2, ...]` is a list of highlight groups that are searched (in order) for a matching color definition For example, consider the following specification: > 'prompt': ['fg', 'Conditional', 'Comment'], < This means we color the prompt - using the `fg` attribute of the `Conditional` if it exists, - otherwise use the `fg` attribute of the `Comment` highlight group if it exists, - otherwise fall back to the default color settings for the prompt. You can examine the color option generated according the setting by printing the result of `fzf#wrap()` function like so: > :echo fzf#wrap() < FZF#RUN ============================================================================== *fzf#run* `fzf#run()` function is the core of Vim integration. It takes a single dictionary argument, a spec, and starts fzf process accordingly. At the very least, specify `sink` option to tell what it should do with the selected entry. > call fzf#run({'sink': 'e'}) < We haven't specified the `source`, so this is equivalent to starting fzf on command line without standard input pipe; fzf will traverse the file system under the current directory to get the list of files. (If `$FZF_DEFAULT_COMMAND` is set, fzf will use the output of the command instead.) When you select one, it will open it with the sink, `:e` command. If you want to open it in a new tab, you can pass `:tabedit` command instead as the sink. > call fzf#run({'sink': 'tabedit'}) < You can use any shell command as the source to generate the list. The following example will list the files managed by git. It's equivalent to running `git ls-files | fzf` on shell. > call fzf#run({'source': 'git ls-files', 'sink': 'e'}) < fzf options can be specified as `options` entry in spec dictionary. > call fzf#run({'sink': 'tabedit', 'options': '--multi --reverse'}) < You can also pass a layout option if you don't want fzf window to take up the entire screen. > " up / down / left / right / window are allowed call fzf#run({'source': 'git ls-files', 'sink': 'e', 'left': '40%'}) call fzf#run({'source': 'git ls-files', 'sink': 'e', 'window': '30vnew'}) < `source` doesn't have to be an external shell command, you can pass a Vim array as the source. In the next example, we pass the names of color schemes as the source to implement a color scheme selector. > call fzf#run({'source': map(split(globpath(&rtp, 'colors/*.vim')), \ 'fnamemodify(v:val, ":t:r")'), \ 'sink': 'colo', 'left': '25%'}) < The following table summarizes the available options. ---------------------------+---------------+---------------------------------------------------------------------- Option name | Type | Description ~ ---------------------------+---------------+---------------------------------------------------------------------- `source` | string | External command to generate input to fzf (e.g. `find .` ) `source` | list | Vim list as input to fzf `sink` | string | Vim command to handle the selected item (e.g. `e` , `tabe` ) `sink` | funcref | Function to be called with each selected item `sinklist` (or `sink*` ) | funcref | Similar to `sink` , but takes the list of output lines at once `exit` | funcref | Function to be called with the exit status of fzf (e.g. 0, 1, 2, 130) `options` | string/list | Options to fzf `dir` | string | Working directory `up` / `down` / `left` / `right` | number/string | (Layout) Window position and size (e.g. `20` , `50%` ) `tmux` | string | (Layout) `--tmux` options (e.g. `90%,70%` ) `window` (Vim 8 / Neovim) | string | (Layout) Command to open fzf window (e.g. `vertical aboveleft 30new` ) `window` (Vim 8 / Neovim) | dict | (Layout) Popup window settings (e.g. `{'width': 0.9, 'height': 0.6}` ) ---------------------------+---------------+---------------------------------------------------------------------- `options` entry can be either a string or a list. For simple cases, string should suffice, but prefer to use list type to avoid escaping issues. > call fzf#run({'options': '--reverse --prompt "C:\\Program Files\\"'}) call fzf#run({'options': ['--reverse', '--prompt', 'C:\Program Files\']}) < When `window` entry is a dictionary, fzf will start in a popup window. The following options are allowed: - Required: - `width` [float range [0 ~ 1]] or [integer range [8 ~ ]] - `height` [float range [0 ~ 1]] or [integer range [4 ~ ]] - Optional: - `yoffset` [float default 0.5 range [0 ~ 1]] - `xoffset` [float default 0.5 range [0 ~ 1]] - `relative` [boolean default v:false] - `border` [string default `rounded` (`sharp` on Windows)]: Border style - `rounded` / `sharp` / `horizontal` / `vertical` / `top` / `bottom` / `left` / `right` / `no[ne]` FZF#WRAP ============================================================================== *fzf#wrap* We have seen that several aspects of `:FZF` command can be configured with a set of global option variables; different ways to open files (`g:fzf_action`), window position and size (`g:fzf_layout`), color palette (`g:fzf_colors`), etc. So how can we make our custom `fzf#run` calls also respect those variables? Simply by "wrapping" the spec dictionary with `fzf#wrap` before passing it to `fzf#run`. - `fzf#wrap([name string], [spec dict], [fullscreen bool]) -> (dict)` - All arguments are optional. Usually we only need to pass a spec dictionary. - `name` is for managing history files. It is ignored if `g:fzf_history_dir` is not defined. - `fullscreen` can be either `0` or `1` (default: 0). `fzf#wrap` takes a spec and returns an extended version of it (also a dictionary) with additional options for addressing global preferences. You can examine the return value of it like so: > echo fzf#wrap({'source': 'ls'}) < After we "wrap" our spec, we pass it to `fzf#run`. > call fzf#run(fzf#wrap({'source': 'ls'})) < Now it supports CTRL-T, CTRL-V, and CTRL-X key bindings (configurable via `g:fzf_action`) and it opens fzf window according to `g:fzf_layout` setting. To make it easier to use, let's define `LS` command. > command! LS call fzf#run(fzf#wrap({'source': 'ls'})) < Type `:LS` and see how it works. We would like to make `:LS!` (bang version) open fzf in fullscreen, just like `:FZF!`. Add `-bang` to command definition, and use value to set the last `fullscreen` argument of `fzf#wrap` (see :help ). > " On :LS!, evaluates to '!', and '!0' becomes 1 command! -bang LS call fzf#run(fzf#wrap({'source': 'ls'}, 0)) < Our `:LS` command will be much more useful if we can pass a directory argument to it, so that something like `:LS /tmp` is possible. > command! -bang -complete=dir -nargs=? LS \ call fzf#run(fzf#wrap({'source': 'ls', 'dir': }, 0)) < Lastly, if you have enabled `g:fzf_history_dir`, you might want to assign a unique name to our command and pass it as the first argument to `fzf#wrap`. > " The query history for this command will be stored as 'ls' inside g:fzf_history_dir. " The name is ignored if g:fzf_history_dir is not defined. command! -bang -complete=dir -nargs=? LS \ call fzf#run(fzf#wrap('ls', {'source': 'ls', 'dir': }, 0)) < < Global options supported by fzf#wrap >______________________________________~ *fzf-global-options-supported-by-fzf#wrap* - `g:fzf_layout` - `g:fzf_action` - Works only when no custom `sink` (or `sinklist`) is provided - Having custom sink usually means that each entry is not an ordinary file path (e.g. name of color scheme), so we can't blindly apply the same strategy (i.e. `tabedit some-color-scheme` doesn't make sense) - `g:fzf_colors` - `g:fzf_history_dir` TIPS *fzf-tips* ============================================================================== < fzf inside terminal buffer >________________________________________________~ *fzf-inside-terminal-buffer* On the latest versions of Vim and Neovim, fzf will start in a terminal buffer. If you find the default ANSI colors to be different, consider configuring the colors using `g:terminal_ansi_colors` in regular Vim or `g:terminal_color_x` in Neovim. > " Terminal colors for seoul256 color scheme if has('nvim') let g:terminal_color_0 = '#4e4e4e' let g:terminal_color_1 = '#d68787' let g:terminal_color_2 = '#5f865f' let g:terminal_color_3 = '#d8af5f' let g:terminal_color_4 = '#85add4' let g:terminal_color_5 = '#d7afaf' let g:terminal_color_6 = '#87afaf' let g:terminal_color_7 = '#d0d0d0' let g:terminal_color_8 = '#626262' let g:terminal_color_9 = '#d75f87' let g:terminal_color_10 = '#87af87' let g:terminal_color_11 = '#ffd787' let g:terminal_color_12 = '#add4fb' let g:terminal_color_13 = '#ffafaf' let g:terminal_color_14 = '#87d7d7' let g:terminal_color_15 = '#e4e4e4' else let g:terminal_ansi_colors = [ \ '#4e4e4e', '#d68787', '#5f865f', '#d8af5f', \ '#85add4', '#d7afaf', '#87afaf', '#d0d0d0', \ '#626262', '#d75f87', '#87af87', '#ffd787', \ '#add4fb', '#ffafaf', '#87d7d7', '#e4e4e4' \ ] endif < < Starting fzf in a popup window >____________________________________________~ *fzf-starting-fzf-in-a-popup-window* > " Required: " - width [float range [0 ~ 1]] or [integer range [8 ~ ]] " - height [float range [0 ~ 1]] or [integer range [4 ~ ]] " " Optional: " - xoffset [float default 0.5 range [0 ~ 1]] " - yoffset [float default 0.5 range [0 ~ 1]] " - relative [boolean default v:false] " - border [string default 'rounded']: Border style " - 'rounded' / 'sharp' / 'horizontal' / 'vertical' / 'top' / 'bottom' / 'left' / 'right' let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } < Alternatively, you can make fzf open in a tmux popup window (requires tmux 3.2 or above) by putting `--tmux` options in `tmux` key. > " See `--tmux` option in `man fzf` for available options " [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]] if exists('$TMUX') let g:fzf_layout = { 'tmux': '90%,70%' } else let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } } endif < < Hide statusline >___________________________________________________________~ *fzf-hide-statusline* When fzf starts in a terminal buffer, the file type of the buffer is set to `fzf`. So you can set up `FileType fzf` autocmd to customize the settings of the window. For example, if you open fzf on the bottom on the screen (e.g. `{'down': '40%'}`), you might want to temporarily disable the statusline for a cleaner look. > let g:fzf_layout = { 'down': '30%' } autocmd! FileType fzf autocmd FileType fzf set laststatus=0 noshowmode noruler \| autocmd BufLeave set laststatus=2 showmode ruler < LICENSE *fzf-license* ============================================================================== The MIT License (MIT) Copyright (c) 2013-2024 Junegunn Choi ============================================================================== vim:tw=78:sw=2:ts=2:ft=help:norl:nowrap: fzf-0.60.3/go.mod000066400000000000000000000010161476126201100134710ustar00rootroot00000000000000module github.com/junegunn/fzf require ( github.com/charlievieth/fastwalk v1.0.9 github.com/gdamore/tcell/v2 v2.8.1 github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741 github.com/mattn/go-isatty v0.0.20 github.com/rivo/uniseg v0.4.7 golang.org/x/sys v0.30.0 golang.org/x/term v0.29.0 ) require ( github.com/gdamore/encoding v1.0.1 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect golang.org/x/text v0.21.0 // indirect ) go 1.20 fzf-0.60.3/go.sum000066400000000000000000000171101476126201100135200ustar00rootroot00000000000000github.com/charlievieth/fastwalk v1.0.9 h1:Odb92AfoReO3oFBfDGT5J+nwgzQPF/gWAw6E6/lkor0= github.com/charlievieth/fastwalk v1.0.9/go.mod h1:yGy1zbxog41ZVMcKA/i8ojXLFsuayX5VvwhQVoj9PBI= github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU= github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741 h1:7dYDtfMDfKzjT+DVfIS4iqknSEKtZpEcXtu6vuaasHs= github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741/go.mod h1:6EILKtGpo5t+KLb85LNZLAF6P9LKp78hJI80PXMcn3c= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= fzf-0.60.3/install000077500000000000000000000243771476126201100137760ustar00rootroot00000000000000#!/usr/bin/env bash set -u version=0.60.3 auto_completion= key_bindings= update_config=2 shells="bash zsh fish" prefix='~/.fzf' prefix_expand=~/.fzf fish_dir=${XDG_CONFIG_HOME:-$HOME/.config}/fish help() { cat << EOF usage: $0 [OPTIONS] --help Show this message --bin Download fzf binary only; Do not generate ~/.fzf.{bash,zsh} --all Download fzf binary and update configuration files to enable key bindings and fuzzy completion --xdg Generate files under \$XDG_CONFIG_HOME/fzf --[no-]key-bindings Enable/disable key bindings (CTRL-T, CTRL-R, ALT-C) --[no-]completion Enable/disable fuzzy completion (bash & zsh) --[no-]update-rc Whether or not to update shell configuration files --no-bash Do not set up bash configuration --no-zsh Do not set up zsh configuration --no-fish Do not set up fish configuration EOF } for opt in "$@"; do case $opt in --help) help exit 0 ;; --all) auto_completion=1 key_bindings=1 update_config=1 ;; --xdg) prefix='"${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf' prefix_expand=${XDG_CONFIG_HOME:-$HOME/.config}/fzf/fzf mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/fzf" ;; --key-bindings) key_bindings=1 ;; --no-key-bindings) key_bindings=0 ;; --completion) auto_completion=1 ;; --no-completion) auto_completion=0 ;; --update-rc) update_config=1 ;; --no-update-rc) update_config=0 ;; --bin) ;; --no-bash) shells=${shells/bash/} ;; --no-zsh) shells=${shells/zsh/} ;; --no-fish) shells=${shells/fish/} ;; *) echo "unknown option: $opt" help exit 1 ;; esac done cd "$(dirname "${BASH_SOURCE[0]}")" fzf_base=$(pwd) fzf_base_esc=$(printf %q "$fzf_base") ask() { while true; do read -p "$1 ([y]/n) " -r REPLY=${REPLY:-"y"} if [[ $REPLY =~ ^[Yy]$ ]]; then return 1 elif [[ $REPLY =~ ^[Nn]$ ]]; then return 0 fi done } check_binary() { echo -n " - Checking fzf executable ... " local output output=$(FZF_DEFAULT_OPTS= "$fzf_base"/bin/fzf --version 2>&1) if [ $? -ne 0 ]; then echo "Error: $output" binary_error="Invalid binary" else output=${output/ */} if [ "$version" != "$output" ]; then echo "$output != $version" binary_error="Invalid version" else echo "$output" binary_error="" return 0 fi fi rm -f "$fzf_base"/bin/fzf return 1 } link_fzf_in_path() { if which_fzf="$(command -v fzf)"; then echo " - Found in \$PATH" echo " - Creating symlink: bin/fzf -> $which_fzf" (cd "$fzf_base"/bin && rm -f fzf && ln -sf "$which_fzf" fzf) check_binary && return fi return 1 } try_curl() { command -v curl > /dev/null && if [[ $1 =~ tar.gz$ ]]; then curl -fL $1 | tar --no-same-owner -xzf - else local temp=${TMPDIR:-/tmp}/fzf.zip curl -fLo "$temp" $1 && unzip -o "$temp" && rm -f "$temp" fi } try_wget() { command -v wget > /dev/null && if [[ $1 =~ tar.gz$ ]]; then wget -O - $1 | tar --no-same-owner -xzf - else local temp=${TMPDIR:-/tmp}/fzf.zip wget -O "$temp" $1 && unzip -o "$temp" && rm -f "$temp" fi } download() { echo "Downloading bin/fzf ..." if [ -x "$fzf_base"/bin/fzf ]; then echo " - Already exists" check_binary && return fi link_fzf_in_path && return mkdir -p "$fzf_base"/bin && cd "$fzf_base"/bin if [ $? -ne 0 ]; then binary_error="Failed to create bin directory" return fi local url url=https://github.com/junegunn/fzf/releases/download/v$version/${1} set -o pipefail if ! (try_curl $url || try_wget $url); then set +o pipefail binary_error="Failed to download with curl and wget" return fi set +o pipefail if [ ! -f fzf ]; then binary_error="Failed to download ${1}" return fi chmod +x fzf && check_binary } # Try to download binary executable archi=$(uname -sm) binary_available=1 binary_error="" case "$archi" in Darwin\ arm64) download fzf-$version-darwin_arm64.tar.gz ;; Darwin\ x86_64) download fzf-$version-darwin_amd64.tar.gz ;; Linux\ armv5*) download fzf-$version-linux_armv5.tar.gz ;; Linux\ armv6*) download fzf-$version-linux_armv6.tar.gz ;; Linux\ armv7*) download fzf-$version-linux_armv7.tar.gz ;; Linux\ armv8*) download fzf-$version-linux_arm64.tar.gz ;; Linux\ aarch64*) download fzf-$version-linux_arm64.tar.gz ;; Linux\ loongarch64) download fzf-$version-linux_loong64.tar.gz ;; Linux\ ppc64le) download fzf-$version-linux_ppc64le.tar.gz ;; Linux\ *64) download fzf-$version-linux_amd64.tar.gz ;; Linux\ s390x) download fzf-$version-linux_s390x.tar.gz ;; FreeBSD\ *64) download fzf-$version-freebsd_amd64.tar.gz ;; OpenBSD\ *64) download fzf-$version-openbsd_amd64.tar.gz ;; CYGWIN*\ *64) download fzf-$version-windows_amd64.zip ;; MINGW*\ *64) download fzf-$version-windows_amd64.zip ;; MSYS*\ *64) download fzf-$version-windows_amd64.zip ;; Windows*\ *64) download fzf-$version-windows_amd64.zip ;; *) binary_available=0 binary_error=1 ;; esac cd "$fzf_base" if [ -n "$binary_error" ]; then if [ $binary_available -eq 0 ]; then echo "No prebuilt binary for $archi ..." else echo " - $binary_error !!!" fi if command -v go > /dev/null; then echo -n "Building binary (go install github.com/junegunn/fzf) ... " if [ -z "${GOPATH-}" ]; then export GOPATH="${TMPDIR:-/tmp}/fzf-gopath" mkdir -p "$GOPATH" fi if go install -ldflags "-s -w -X main.version=$version -X main.revision=go-install" github.com/junegunn/fzf; then echo "OK" cp "$GOPATH/bin/fzf" "$fzf_base/bin/" else echo "Failed to build binary. Installation failed." exit 1 fi else echo "go executable not found. Installation failed." exit 1 fi fi [[ "$*" =~ "--bin" ]] && exit 0 for s in $shells; do if ! command -v "$s" > /dev/null; then shells=${shells/$s/} fi done if [[ ${#shells} -lt 3 ]]; then echo "No shell configuration to be updated." exit 0 fi # Auto-completion if [ -z "$auto_completion" ]; then ask "Do you want to enable fuzzy auto-completion?" auto_completion=$? fi # Key-bindings if [ -z "$key_bindings" ]; then ask "Do you want to enable key bindings?" key_bindings=$? fi echo for shell in $shells; do [[ "$shell" = fish ]] && continue src=${prefix_expand}.${shell} echo -n "Generate $src ... " fzf_completion="source \"$fzf_base/shell/completion.${shell}\"" if [ $auto_completion -eq 0 ]; then fzf_completion="# $fzf_completion" fi fzf_key_bindings="source \"$fzf_base/shell/key-bindings.${shell}\"" if [ $key_bindings -eq 0 ]; then fzf_key_bindings="# $fzf_key_bindings" fi cat > "$src" << EOF # Setup fzf # --------- if [[ ! "\$PATH" == *$fzf_base_esc/bin* ]]; then PATH="\${PATH:+\${PATH}:}$fzf_base/bin" fi EOF if [[ $auto_completion -eq 1 ]] && [[ $key_bindings -eq 1 ]]; then if [[ "$shell" = zsh ]]; then echo "source <(fzf --$shell)" >> "$src" else echo "eval \"\$(fzf --$shell)\"" >> "$src" fi else cat >> "$src" << EOF # Auto-completion # --------------- $fzf_completion # Key bindings # ------------ $fzf_key_bindings EOF fi echo "OK" done # fish if [[ "$shells" =~ fish ]]; then echo -n "Update fish_user_paths ... " fish << EOF echo \$fish_user_paths | \grep "$fzf_base"/bin > /dev/null or set --universal fish_user_paths \$fish_user_paths "$fzf_base"/bin EOF [ $? -eq 0 ] && echo "OK" || echo "Failed" fi append_line() { local update line file pat lines update="$1" line="$2" file="$3" pat="${4:-}" lines="" echo "Update $file:" echo " - $line" if [ -f "$file" ]; then if [ $# -lt 4 ]; then lines=$(\grep -nF "$line" "$file") else lines=$(\grep -nF "$pat" "$file") fi fi if [ -n "$lines" ]; then echo " - Already exists:" sed 's/^/ Line /' <<< "$lines" update=0 if ! \grep -qv "^[0-9]*:[[:space:]]*#" <<< "$lines" ; then echo " - But they all seem to be commented" ask " - Continue modifying $file?" update=$? fi fi set -e if [ "$update" -eq 1 ]; then [ -f "$file" ] && echo >> "$file" echo "$line" >> "$file" echo " + Added" else echo " ~ Skipped" fi echo set +e } create_file() { local file="$1" shift echo "Create $file:" for line in "$@"; do echo " $line" echo "$line" >> "$file" done echo } if [ $update_config -eq 2 ]; then echo ask "Do you want to update your shell configuration files?" update_config=$? fi echo for shell in $shells; do [[ "$shell" = fish ]] && continue [ $shell = zsh ] && dest=${ZDOTDIR:-~}/.zshrc || dest=~/.bashrc append_line $update_config "[ -f ${prefix}.${shell} ] && source ${prefix}.${shell}" "$dest" "${prefix}.${shell}" done if [ $key_bindings -eq 1 ] && [[ "$shells" =~ fish ]]; then bind_file="${fish_dir}/functions/fish_user_key_bindings.fish" if [ ! -e "$bind_file" ]; then mkdir -p "${fish_dir}/functions" create_file "$bind_file" \ 'function fish_user_key_bindings' \ ' fzf --fish | source' \ 'end' else echo "Check $bind_file:" lno=$(\grep -nF "fzf_key_bindings" "$bind_file" | sed 's/:.*//' | tr '\n' ' ') if [[ -n $lno ]]; then echo " ** Found 'fzf_key_bindings' in line #$lno" echo " ** You have to replace the line to 'fzf --fish | source'" echo else echo " - Clear" echo append_line $update_config "fzf --fish | source" "$bind_file" fi fi fi if [ $update_config -eq 1 ]; then echo 'Finished. Restart your shell or reload config file.' if [[ "$shells" =~ bash ]]; then echo -n ' source ~/.bashrc # bash' [[ "$archi" =~ Darwin ]] && echo -n ' (.bashrc should be loaded from .bash_profile)' echo fi [[ "$shells" =~ zsh ]] && echo " source ${ZDOTDIR:-~}/.zshrc # zsh" [[ "$shells" =~ fish ]] && [ $key_bindings -eq 1 ] && echo ' fzf_key_bindings # fish' echo echo 'Use uninstall script to remove fzf.' echo fi echo 'For more information, see: https://github.com/junegunn/fzf' fzf-0.60.3/install.ps1000066400000000000000000000035321476126201100144630ustar00rootroot00000000000000$version="0.60.3" $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition function check_binary () { Write-Host " - Checking fzf executable ... " -NoNewline $output=cmd /c $fzf_base\bin\fzf.exe --version 2>&1 if (-not $?) { Write-Host "Error: $output" $binary_error="Invalid binary" } else { $output=(-Split $output)[0] if ($version -ne $output) { Write-Host "$output != $version" $binary_error="Invalid version" } else { Write-Host "$output" $binary_error="" return 1 } } Remove-Item "$fzf_base\bin\fzf.exe" return 0 } function download { param($file) Write-Host "Downloading bin/fzf ..." if (Test-Path "$fzf_base\bin\fzf.exe") { Write-Host " - Already exists" if (check_binary) { return } } if (-not (Test-Path "$fzf_base\bin")) { md "$fzf_base\bin" } if (-not $?) { $binary_error="Failed to create bin directory" return } cd "$fzf_base\bin" $url="https://github.com/junegunn/fzf/releases/download/v$version/$file" $temp=$env:TMP + "\fzf.zip" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 if ($PSVersionTable.PSVersion.Major -ge 3) { Invoke-WebRequest -Uri $url -OutFile $temp } else { (New-Object Net.WebClient).DownloadFile($url, $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$temp")) } if ($?) { (Microsoft.PowerShell.Archive\Expand-Archive -Path $temp -DestinationPath .); (Remove-Item $temp) } else { $binary_error="Failed to download with powershell" } if (-not (Test-Path fzf.exe)) { $binary_error="Failed to download $file" return } echo y | icacls $fzf_base\bin\fzf.exe /grant Administrator:F ; check_binary >$null } download "fzf-$version-windows_amd64.zip" Write-Host 'For more information, see: https://github.com/junegunn/fzf' fzf-0.60.3/main.go000066400000000000000000000036631476126201100136500ustar00rootroot00000000000000package main import ( _ "embed" "fmt" "os" "os/exec" "strings" fzf "github.com/junegunn/fzf/src" "github.com/junegunn/fzf/src/protector" ) var version = "0.60" var revision = "devel" //go:embed shell/key-bindings.bash var bashKeyBindings []byte //go:embed shell/completion.bash var bashCompletion []byte //go:embed shell/key-bindings.zsh var zshKeyBindings []byte //go:embed shell/completion.zsh var zshCompletion []byte //go:embed shell/key-bindings.fish var fishKeyBindings []byte //go:embed man/man1/fzf.1 var manPage []byte func printScript(label string, content []byte) { fmt.Println("### " + label + " ###") fmt.Println(strings.TrimSpace(string(content))) fmt.Println("### end: " + label + " ###") } func exit(code int, err error) { if code == fzf.ExitError && err != nil { fmt.Fprintln(os.Stderr, err.Error()) } os.Exit(code) } func main() { protector.Protect() options, err := fzf.ParseOptions(true, os.Args[1:]) if err != nil { exit(fzf.ExitError, err) return } if options.Bash { printScript("key-bindings.bash", bashKeyBindings) printScript("completion.bash", bashCompletion) return } if options.Zsh { printScript("key-bindings.zsh", zshKeyBindings) printScript("completion.zsh", zshCompletion) return } if options.Fish { printScript("key-bindings.fish", fishKeyBindings) fmt.Println("fzf_key_bindings") return } if options.Help { fmt.Print(fzf.Usage) return } if options.Version { if len(revision) > 0 { fmt.Printf("%s (%s)\n", version, revision) } else { fmt.Println(version) } return } if options.Man { file := fzf.WriteTemporaryFile([]string{string(manPage)}, "\n") if len(file) == 0 { fmt.Print(string(manPage)) return } defer os.Remove(file) cmd := exec.Command("man", file) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout if err := cmd.Run(); err != nil { fmt.Print(string(manPage)) } return } code, err := fzf.Run(options) exit(code, err) } fzf-0.60.3/man/000077500000000000000000000000001476126201100131405ustar00rootroot00000000000000fzf-0.60.3/man/man1/000077500000000000000000000000001476126201100137745ustar00rootroot00000000000000fzf-0.60.3/man/man1/fzf-tmux.1000066400000000000000000000037461476126201100156500ustar00rootroot00000000000000.ig The MIT License (MIT) Copyright (c) 2013-2024 Junegunn Choi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. .TH fzf\-tmux 1 "Mar 2025" "fzf 0.60.3" "fzf\-tmux - open fzf in tmux split pane" .SH NAME fzf\-tmux - open fzf in tmux split pane .SH SYNOPSIS .B fzf\-tmux [\fILAYOUT OPTIONS\fR] [\-\-] [\fIFZF OPTIONS\fR] .SH DESCRIPTION fzf\-tmux is a wrapper script for fzf that opens fzf in a tmux split pane or in a tmux popup window. It is designed to work just like fzf except that it does not take up the whole screen. You can safely use fzf\-tmux instead of fzf in your scripts as the extra options will be silently ignored if you're not on tmux. .SH LAYOUT OPTIONS (default layout: \fB\-d 50%\fR) .SS Popup window (requires tmux 3.2 or above) .TP .B "\-p [WIDTH[%][,HEIGHT[%]]]" .TP .B "\-w WIDTH[%]" .TP .B "\-h WIDTH[%]" .TP .B "\-x COL" .TP .B "\-y ROW" .SS Split pane .TP .B "\-u [height[%]]" Split above (up) .TP .B "\-d [height[%]]" Split below (down) .TP .B "\-l [width[%]]" Split left .TP .B "\-r [width[%]]" Split right fzf-0.60.3/man/man1/fzf.1000066400000000000000000001771221476126201100146550ustar00rootroot00000000000000.ig The MIT License (MIT) Copyright (c) 2013-2024 Junegunn Choi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. .TH fzf 1 "Mar 2025" "fzf 0.60.3" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder .SH SYNOPSIS fzf [\fIoptions\fR] .SH DESCRIPTION fzf is an interactive filter program for any kind of list. It implements a "fuzzy" matching algorithm, so you can quickly type in patterns with omitted characters and still get the results you want. .SH OPTIONS .SS NOTE .TP Most long options have the opposite version with \fB\-\-no\-\fR prefix. .SS SEARCH .TP .B "\-x, \-\-extended" Extended-search mode. Enabled by default. You can disable it with \fB+x\fR or \fB\-\-no\-extended\fR. .TP .B "\-e, \-\-exact" Enable exact-match .TP .B "\-i, \-\-ignore\-case" Case-insensitive match (default: smart-case match) .TP .B "+i, \-\-no\-ignore\-case" Case-sensitive match .TP .B "\-\-smart\-case" Smart-case match (default). In this mode, the search is case-insensitive by default, but it becomes case-sensitive if the query contains any uppercase letters. .TP .B "\-\-literal" Do not normalize latin script letters for matching. .TP .BI "\-\-scheme=" SCHEME Choose scoring scheme tailored for different types of input. .RS .B default .RS Generic scoring scheme designed to work well with any type of input. .RE .RE .RS .B path .RS Additional bonus point is only given to the characters after path separator. You might want to choose this scheme over \fBdefault\fR if you have many files with spaces in their paths. This also sets \fB\-\-tiebreak=pathname,length\fR, to prioritize matches occurring in the tail element of a file path. .RE .RE .RS .B history .RS Scoring scheme well suited for command history or any input where chronological ordering is important. No additional bonus points are given so that we give more weight to the chronological ordering. This also sets \fB\-\-tiebreak=index\fR. .RE .RE .RS fzf chooses \fBpath\fR scheme when the input is a TTY device, where fzf would start its built-in walker or run \fB$FZF_DEFAULT_COMMAND\fR, and there is no \fBreload\fR or \fBtransform\fR action bound to \fBstart\fR event. Otherwise, it chooses \fBdefault\fR scheme. .RE .TP .BI "\-\-algo=" TYPE Fuzzy matching algorithm (default: v2) .br .BR v2 " Optimal scoring algorithm (quality)" .br .BR v1 " Faster but not guaranteed to find the optimal result (performance)" .br .TP .BI "\-n, \-\-nth=" "N[,..]" Comma-separated list of field index expressions for limiting search scope. See \fBFIELD INDEX EXPRESSION\fR for the details. When you use this option with \fB\-\-with\-nth\fR, the field index expressions are calculated against the transformed lines (unlike in \fB\-\-preview\fR where fields are extracted from the original lines) because fzf doesn't allow searching against the hidden fields. .TP .BI "\-\-with\-nth=" "N[,..] or TEMPLATE" Transform the presentation of each line using the field index expressions. For advanced transformation, you can provide a template containing field index expressions in curly braces. When you use a template, the trailing delimiter is stripped from each expression, giving you more control over the output. \fB{n}\fR in template evaluates to the zero-based ordinal index of the line. .RS e.g. # Single expression: drop the first field echo foo bar baz | fzf --with-nth 2.. # Use template to rearrange fields echo foo,bar,baz | fzf --delimiter , --with-nth '{n},{1},{3},{2},{1..2}' .RE .TP .BI "\-\-accept\-nth=" "N[,..] or TEMPLATE" Define which fields to print on accept. The last delimiter is stripped from the output. For advanced transformation, you can provide a template containing field index expressions in curly braces. When you use a template, the trailing delimiter is stripped from each expression, giving you more control over the output. \fB{n}\fR in template evaluates to the zero-based ordinal index of the line. .RS e.g. # Single expression echo foo bar baz | fzf --accept-nth 2 # Template echo foo bar baz | fzf --accept-nth 'Index: {n}, 1st: {1}, 2nd: {2}, 3rd: {3}' .RE .TP .B "+s, \-\-no\-sort" Do not sort the result .TP .BI "\-d, \-\-delimiter=" "STR" Field delimiter regex for \fB\-\-nth\fR, \fB\-\-with\-nth\fR, and field index expressions (default: AWK-style) .TP .B "\-\-tail=NUM" Maximum number of items to keep in memory. This is useful when you want to browse an endless stream of data (e.g. log stream) with fzf while limiting memory usage. .RS e.g. \fB# Interactive filtering of a log stream tail \-f *.log | fzf \-\-tail 100000 \-\-tac \-\-no\-sort \-\-exact\fR .RE .TP .BI "\-\-disabled" Do not perform search. With this option, fzf becomes a simple selector interface rather than a "fuzzy finder". You can later enable the search using \fBenable\-search\fR or \fBtoggle\-search\fR action. .TP .BI "\-\-tiebreak=" "CRI[,..]" Comma-separated list of sort criteria to apply when the scores are tied. .br .br .BR length " Prefers line with shorter length" .br .BR chunk " Prefers line with shorter matched chunk (delimited by whitespaces)" .br .BR pathname " Prefers line with matched substring in the file name of the path" .br .BR begin " Prefers line with matched substring closer to the beginning" .br .BR end " Prefers line with matched substring closer to the end" .br .BR index " Prefers line that appeared earlier in the input stream" .br .br - Each criterion should appear only once in the list .br - \fBindex\fR is only allowed at the end of the list .br - \fBindex\fR is implicitly appended to the list when not specified .br - Default is \fBlength\fR (or equivalently \fBlength\fR,index) .br - If \fBend\fR is found in the list, fzf will scan each line backwards .SS INPUT/OUTPUT .TP .B "\-\-read0" Read input delimited by ASCII NUL characters instead of newline characters .TP .B "\-\-print0" Print output delimited by ASCII NUL characters instead of newline characters .TP .B "\-\-ansi" Enable processing of ANSI color codes .TP .B "\-\-sync" Synchronous search for multi-staged filtering. If specified, fzf will launch the finder only after the input stream is complete and the initial filtering and the associated actions (bound to any of \fBstart\fR, \fBload\fR, \fBresult\fR, or \fBfocus\fR) are complete. .RS e.g. \fB# Avoid rendering both fzf instances at the same time fzf \-\-multi | fzf \-\-sync # fzf will not render intermediate states (sleep 1; seq 1000000; sleep 1) | fzf \-\-sync \-\-query 5 \-\-listen \-\-bind start:up,load:up,result:up,focus:change\-header:Ready\fR .RE .SS GLOBAL STYLE .TP .BI "\-\-style=" "PRESET" Apply a style preset [default|minimal|full[:BORDER_STYLE]] .TP .BI "\-\-color=" "[BASE_SCHEME][,COLOR_NAME[:ANSI_COLOR][:ANSI_ATTRIBUTES]]..." Color configuration. The name of the base color scheme is followed by custom color mappings. .RS .B BASE SCHEME: (default: \fBdark\fR on 256-color terminal, otherwise \fB16\fR; If \fBNO_COLOR\fR is set, \fBbw\fR) \fBdark \fRColor scheme for dark 256-color terminal \fBlight \fRColor scheme for light 256-color terminal \fB16 \fRColor scheme for 16-color terminal \fBbw \fRNo colors (equivalent to \fB\-\-no\-color\fR) .B COLOR NAMES: \fBfg \fRText \fBlist\-fg \fRText in the list section \fBselected\-fg \fRSelected line text \fBpreview\-fg \fRPreview window text \fBbg \fRBackground \fBlist\-bg \fRList section background \fBselected\-bg \fRSelected line background \fBpreview\-bg \fRPreview window background \fBinput\-bg \fRInput window background (\fB\-\-input\-border\fR) \fBheader\-bg \fRHeader window background (\fB\-\-header\-border\fR) \fBhl \fRHighlighted substrings \fBselected\-hl \fRHighlighted substrings in the selected line \fBcurrent\-fg (fg+) \fRText (current line) \fBcurrent\-bg (bg+) \fRBackground (current line) \fBgutter \fRGutter on the left \fBcurrent\-hl (hl+) \fRHighlighted substrings (current line) \fBquery (input\-fg) \fRQuery string \fBdisabled \fRQuery string when search is disabled (\fB\-\-disabled\fR) \fBinfo \fRInfo line (match counters) \fBborder \fRBorder around the window (\fB\-\-border\fR and \fB\-\-preview\fR) \fBlist\-border \fRBorder around the list section (\fB\-\-list\-border\fR) \fBscrollbar \fRScrollbar \fBseparator \fRHorizontal separator on info line \fBgap\-line \fRHorizontal line on each gap \fBpreview\-border \fRBorder around the preview window (\fB\-\-preview\fR) \fBpreview\-scrollbar \fRScrollbar \fBinput\-border \fRBorder around the input window (\fB\-\-input\-border\fR) \fBheader\-border \fRBorder around the header window (\fB\-\-header\-border\fR) \fBlabel \fRBorder label (\fB\-\-border\-label\fR, \fB\-\-list\-label\fR, \fB\-\-input\-label\fR, and \fB\-\-preview\-label\fR) \fBlist\-label \fRBorder label of the list section (\fB\-\-list\-label\fR) \fBpreview\-label \fRBorder label of the preview window (\fB\-\-preview\-label\fR) \fBinput\-label \fRBorder label of the input window (\fB\-\-input\-label\fR) \fBheader\-label \fRBorder label of the header window (\fB\-\-header\-label\fR) \fBprompt \fRPrompt \fBpointer \fRPointer to the current line \fBmarker \fRMulti\-select marker \fBspinner \fRStreaming input indicator \fBheader (header\-fg) \fRHeader \fBnth \fRParts of the line specified by \fB\-\-nth\fR (only supports attributes) .B ANSI COLORS: \fB\-1 \fRDefault terminal foreground/background color \fB \fR(or the original color of the text) \fB0 ~ 15 \fR16 base colors \fBblack\fR \fBred\fR \fBgreen\fR \fByellow\fR \fBblue\fR \fBmagenta\fR \fBcyan\fR \fBwhite\fR \fBbright\-black\fR (gray | grey) \fBbright\-red\fR \fBbright\-green\fR \fBbright\-yellow\fR \fBbright\-blue\fR \fBbright\-magenta\fR \fBbright\-cyan\fR \fBbright\-white\fR \fB16 ~ 255 \fRANSI 256 colors \fB#rrggbb \fR24-bit colors .B ANSI ATTRIBUTES: (Only applies to foreground colors) \fBregular \fRClears previously set attributes; should precede the other ones \fBbold\fR \fBunderline\fR \fBreverse\fR \fBdim\fR \fBitalic\fR \fBstrikethrough\fR .B EXAMPLES: \fB# Seoul256 theme with 8-bit colors # (https://github.com/junegunn/seoul256.vim) fzf \-\-color='bg:237,bg+:236,info:143,border:240,spinner:108' \\ \-\-color='hl:65,fg:252,header:65,fg+:252' \\ \-\-color='pointer:161,marker:168,prompt:110,hl+:108' # Seoul256 theme with 24-bit colors fzf \-\-color='bg:#4B4B4B,bg+:#3F3F3F,info:#BDBB72,border:#6B6B6B,spinner:#98BC99' \\ \-\-color='hl:#719872,fg:#D9D9D9,header:#719872,fg+:#D9D9D9' \\ \-\-color='pointer:#E12672,marker:#E17899,prompt:#98BEDE,hl+:#98BC99'\fR .RE .TP .B "\-\-no\-color" Disable colors .TP .B "\-\-no\-bold" Do not use bold text .TP .B "\-\-black" Use black background .SS DISPLAY MODE .TP .BI "\-\-height=" "[~]HEIGHT[%]" Display fzf window below the cursor with the given height instead of using the full screen. If a negative value is specified, the height is calculated as the terminal height minus the given value. fzf \-\-height=\-1 When prefixed with \fB~\fR, fzf will automatically determine the height in the range according to the input size. # Will not take up 100% of the screen seq 5 | fzf \-\-height=~100% Adaptive height has the following limitations: .br * Cannot be used with top/bottom margin and padding given in percent size .br * Negative value is not allowed .br * It will not find the right size when there are multi-line items .TP .BI "\-\-min\-height=" "HEIGHT[+]" Minimum height when \fB\-\-height\fR is given as a percentage. Add \fB+\fR to automatically increase the value according to the other layout options so that the specified number of items are visible in the list section (default: \fB10+\fR). Ignored when \fB\-\-height\fR is not specified or set as an absolute value. .TP .BI "\-\-tmux" "[=[center|top|bottom|left|right][,SIZE[%]][,SIZE[%]][,border-native]]" Start fzf in a tmux popup (default \fBcenter,50%\fR). Requires tmux 3.3 or later. This option is ignored if you are not running fzf inside tmux. e.g. \fB# Popup in the center with 70% width and height fzf \-\-tmux 70% # Popup on the left with 40% width and 100% height fzf \-\-tmux right,40% # Popup on the bottom with 100% width and 30% height fzf \-\-tmux bottom,30% # Popup on the top with 80% width and 40% height fzf \-\-tmux top,80%,40% # Popup with a native tmux border in the center with 80% width and height fzf \-\-tmux center,80%,border\-native\fR .SS LAYOUT .TP .BI "\-\-layout=" "LAYOUT" Choose the layout (default: default) .br .BR default " Display from the bottom of the screen" .br .BR reverse " Display from the top of the screen" .br .BR reverse\-list " Display from the top of the screen, prompt at the bottom" .br .TP .B "\-\-reverse" A synonym for \fB\-\-layout=reverse\fB .TP .BI "\-\-margin=" MARGIN Comma-separated expression for margins around the finder. .br .br .RS .BR TRBL " Same margin for top, right, bottom, and left" .br .BR TB,RL " Vertical, horizontal margin" .br .BR T,RL,B " Top, horizontal, bottom margin" .br .BR T,R,B,L " Top, right, bottom, left margin" .br .br Each part can be given in absolute number or in percentage relative to the terminal size with \fB%\fR suffix. .br .br e.g. \fBfzf \-\-margin 10% fzf \-\-margin 1,5%\fR .RE .TP .BI "\-\-padding=" PADDING Comma-separated expression for padding inside the border. Padding is distinguishable from margin only when \fB\-\-border\fR option is used. .br .br e.g. \fBfzf \-\-margin 5% \-\-padding 5% \-\-border \-\-preview 'cat {}' \\ \-\-color bg:#222222,preview\-bg:#333333\fR .br .RS .BR TRBL " Same padding for top, right, bottom, and left" .br .BR TB,RL " Vertical, horizontal padding" .br .BR T,RL,B " Top, horizontal, bottom padding" .br .BR T,R,B,L " Top, right, bottom, left padding" .br .RE .TP .BI "\-\-border" [=STYLE] Draw border around the finder .br .BR rounded " Border with rounded corners (default)" .br .BR sharp " Border with sharp corners" .br .BR bold " Border with bold lines" .br .BR double " Border with double lines" .br .BR block " Border using block elements; suitable when using different background colors" .br .BR thinblock " Border using legacy computing symbols; may not be displayed on some terminals" .br .BR horizontal " Horizontal lines above and below the finder" .br .BR vertical " Vertical lines on each side of the finder" .br .BR top " (up)" .br .BR bottom " (down)" .br .BR left .br .BR right .br .BR none .br If you use a terminal emulator where each box-drawing character takes 2 columns, try setting \fB\-\-ambidouble\fR. If the border is still not properly rendered, set \fB\-\-no\-unicode\fR. .TP .BI "\-\-border\-label" [=LABEL] Label to print on the horizontal border line. Should be used with one of the following \fB\-\-border\fR options. .br .B * rounded .br .B * sharp .br .B * bold .br .B * double .br .B * horizontal .br .BR "* top" " (up)" .br .BR "* bottom" " (down)" .br .br e.g. \fB# ANSI color codes are supported # (with https://github.com/busyloop/lolcat) label=$(curl \-s http://metaphorpsum.com/sentences/1 | lolcat \-f) # Border label at the center fzf \-\-height=10 \-\-border \-\-border\-label="โ•ข $label โ•Ÿ" \-\-color=label:italic:black # Left-aligned (positive integer) fzf \-\-height=10 \-\-border \-\-border\-label="โ•ข $label โ•Ÿ" \-\-border\-label\-pos=3 \-\-color=label:italic:black # Right-aligned (negative integer) on the bottom line (:bottom) fzf \-\-height=10 \-\-border \-\-border\-label="โ•ข $label โ•Ÿ" \-\-border\-label\-pos=\-3:bottom \-\-color=label:italic:black\fR .TP .BI "\-\-border\-label\-pos" [=N[:top|bottom]] Position of the border label on the border line. Specify a positive integer as the column position from the left. Specify a negative integer to right-align the label. Label is printed on the top border line by default, add \fB:bottom\fR to put it on the border line on the bottom. The default value \fB0 (or \fBcenter\fR) will put the label at the center of the border line. .SS LIST SECTION .TP .BI "\-m, \-\-multi" "[=MAX]" Enable multi-select with tab/shift\-tab. It optionally takes an integer argument which denotes the maximum number of items that can be selected. .TP .B "+m, \-\-no\-multi" Disable multi-select .TP .B "\-\-highlight\-line" Highlight the whole current line .TP .B "\-\-cycle" Enable cyclic scroll .TP .B "\-\-wrap" Enable line wrap .TP .BI "\-\-wrap\-sign" "=INDICATOR" Indicator for wrapped lines. The default is 'โ†ณ ' or '> ' depending on \fB\-\-no\-unicode\fR. .TP .B "\-\-no\-multi\-line" Disable multi-line display of items when using \fB\-\-read0\fR .TP .B "\-\-track" Make fzf track the current selection when the result list is updated. This can be useful when browsing logs using fzf with sorting disabled. It is not recommended to use this option with \fB\-\-tac\fR as the resulting behavior can be confusing. Also, consider using \fBtrack\fR action instead of this option. .RS e.g. \fBgit log \-\-oneline \-\-graph \-\-color=always | nl | fzf \-\-ansi \-\-track \-\-no\-sort \-\-layout=reverse\-list\fR .RE .TP .B "\-\-tac" Reverse the order of the input .RS e.g. \fBhistory | fzf \-\-tac \-\-no\-sort\fR .RE .TP .BI "\-\-gap" "[=N]" Render empty lines between each item .TP .BI "\-\-gap\-line" "[=STR]" The given string will be repeated to draw a horizontal line on each gap (default: 'โ”ˆ' or '\-' depending on \fB\-\-no\-unicode\fR). .TP .B "\-\-keep\-right" Keep the right end of the line visible when it's too long. Effective only when the query string is empty. .TP .BI "\-\-scroll\-off=" "LINES" Number of screen lines to keep above or below when scrolling to the top or to the bottom (default: 3). .TP .B "\-\-no\-hscroll" Disable horizontal scroll .TP .BI "\-\-hscroll\-off=" "COLS" Number of screen columns to keep to the right of the highlighted substring (default: 10). Setting it to a large value will cause the text to be positioned on the center of the screen. .TP .BI "\-\-jump\-labels=" "CHARS" Label characters for \fBjump\fR mode. .TP .BI "\-\-pointer=" "STR" Pointer to the current line (default: 'โ–Œ' or '>' depending on \fB\-\-no\-unicode\fR) .TP .BI "\-\-marker=" "STR" Multi-select marker (default: 'โ”ƒ' or '>' depending on \fB\-\-no\-unicode\fR) .TP .BI "\-\-marker\-multi\-line=" "STR" Multi-select marker for multi-line entries. 3 elements for top, middle, and bottom. (default: 'โ•ปโ”ƒโ•น' or '.|'' depending on \fB\-\-no\-unicode\fR) .TP .BI "\-\-ellipsis=" "STR" Ellipsis to show when line is truncated (default: 'ยทยท') .TP .BI "\-\-tabstop=" SPACES Number of spaces for a tab character (default: 8) .TP .BI "\-\-scrollbar=" "CHAR1[CHAR2]" Use the given character to render scrollbar. (default: 'โ”‚' or ':' depending on \fB\-\-no\-unicode\fR). The optional \fBCHAR2\fR is used to render scrollbar of the preview window. .TP .B "\-\-no\-scrollbar" Do not display scrollbar. A synonym for \fB\-\-scrollbar=''\fB .TP .BI "\-\-list\-border" [=STYLE] Draw border around the list section .TP .BI "\-\-list\-label" [=LABEL] Label to print on the list border .TP .BI "\-\-list\-label\-pos" [=N[:top|bottom]] Position of the list label .SS INPUT SECTION .TP .B "\-\-no\-input" Disable and hide the input section. You can no longer type in queries. To trigger a search, use \fBsearch\fR action. You can later show the input section using \fBshow\-input\fR or \fBtoggle\-input\fR action, and hide it again using \fBhide\-input\fR, or \fBtoggle\-input\fR. .TP .BI "\-\-prompt=" "STR" Input prompt (default: '> ') .TP .BI "\-\-info=" "STYLE" Determines the display style of the finder info. (e.g. match counter, loading indicator, etc.) .BR default " On the left end of the horizontal separator" .br .BR right " On the right end of the horizontal separator" .br .BR hidden " Do not display finder info" .br .BR inline " After the prompt with the default prefix ' < '" .br .BR inline:PREFIX " After the prompt with a non-default prefix" .br .BR inline\-right " On the right end of the prompt line" .br .BR inline\-right:PREFIX " On the right end of the prompt line with a custom prefix" .br .TP .BI "\-\-info\-command=" "COMMAND" Command to generate the finder info line. The command runs synchronously and blocks the UI until completion, so make sure that it's fast. ANSI color codes are supported. \fB$FZF_INFO\fR variable is set to the original info text. For additional environment variables available to the command, see the section ENVIRONMENT VARIABLES EXPORTED TO CHILD PROCESSES. e.g. \fB# Prepend the current cursor position in yellow fzf \-\-info\-command='echo \-e "\\x1b[33;1m$FZF_POS\\x1b[m/$FZF_INFO ๐Ÿ’›"'\fR .TP .B "\-\-no\-info" A synonym for \fB\-\-info=hidden\fB .TP .BI "\-\-separator=" "STR" The given string will be repeated to form the horizontal separator on the info line (default: 'โ”€' or '\-' depending on \fB\-\-no\-unicode\fR). ANSI color codes are supported. .TP .B "\-\-no\-separator" Do not display horizontal separator on the info line. A synonym for \fB\-\-separator=''\fB .TP .B "\-\-filepath\-word" Make word-wise movements and actions respect path separators. The following actions are affected: \fBbackward\-kill\-word\fR .br \fBbackward\-word\fR .br \fBforward\-word\fR .br \fBkill\-word\fR .TP .BI "\-\-input\-border" [=STYLE] Draw border around the input section .TP .BI "\-\-input\-label" [=LABEL] Label to print on the input border .TP .BI "\-\-input\-label\-pos" [=N[:top|bottom]] Position of the input label .SS PREVIEW WINDOW .TP .BI "\-\-preview=" "COMMAND" Execute the given command for the current line and display the result on the preview window. \fB{}\fR in the command is the placeholder that is replaced to the single-quoted string of the current line. To transform the replacement string, specify field index expressions between the braces (See \fBFIELD INDEX EXPRESSION\fR for the details). .RS e.g. \fBfzf \-\-preview='head \-$LINES {}' ls \-l | fzf \-\-preview="echo user={3} when={\-4..\-2}; cat {\-1}" \-\-header\-lines=1\fR fzf exports \fB$FZF_PREVIEW_LINES\fR and \fB$FZF_PREVIEW_COLUMNS\fR so that they represent the exact size of the preview window. (It also overrides \fB$LINES\fR and \fB$COLUMNS\fR with the same values but they can be reset by the default shell, so prefer to refer to the ones with \fBFZF_PREVIEW_\fR prefix.) fzf also exports \fB$FZF_PREVIEW_TOP\fR and \fB$FZF_PREVIEW_LEFT\fR so that the preview command can determine the position of the preview window. A placeholder expression starting with \fB+\fR flag will be replaced to the space-separated list of the selected lines (or the current line if no selection was made) individually quoted. e.g. \fBfzf \-\-multi \-\-preview='head \-10 {+}' git log \-\-oneline | fzf \-\-multi \-\-preview 'git show {+1}'\fR When using a field index expression, leading and trailing whitespace is stripped from the replacement string. To preserve the whitespace, use the \fBs\fR flag. A placeholder expression with \fBf\fR flag is replaced to the path of a temporary file that holds the evaluated list. This is useful when you multi-select a large number of items and the length of the evaluated string may exceed \fBARG_MAX\fR. e.g. \fB# Press CTRL\-A to select 100K items and see the sum of all the numbers. # This won't work properly without 'f' flag due to ARG_MAX limit. seq 100000 | fzf \-\-multi \-\-bind ctrl\-a:select\-all \\ \-\-preview "awk '{sum+=\\$1} END {print sum}' {+f}"\fR Also, * \fB{q}\fR is replaced to the current query string .br * \fB{q}\fR can contain field index expressions. e.g. \fB{q:1}\fR, \fB{q:2..}\fR, etc. .br * \fB{n}\fR is replaced to the zero-based ordinal index of the current item. Use \fB{+n}\fR if you want all index numbers when multiple lines are selected. .br Note that you can escape a placeholder pattern by prepending a backslash. Preview window will be updated even when there is no match for the current query if any of the placeholder expressions evaluates to a non-empty string or \fB{q}\fR is in the command template. Since 0.24.0, fzf can render partial preview content before the preview command completes. ANSI escape sequence for clearing the display (\fBCSI 2 J\fR) is supported, so you can use it to implement preview window that is constantly updating. e.g. \fBfzf \-\-preview 'for i in $(seq 100000); do (( i % 200 == 0 )) && printf "\\033[2J" echo "$i" sleep 0.01 done'\fR fzf has experimental support for Kitty graphics protocol and Sixel graphics. The following example uses https://github.com/junegunn/fzf/blob/master/bin/fzf\-preview.sh script to render an image using either of the protocols inside the preview window. e.g. \fBfzf \-\-preview='fzf\-preview.sh {}'\fR .RE .TP .BI "\-\-preview\-border" [=STYLE] Short for \fB\-\-preview\-window=border\-STYLE\fR. In addition to the other styles, \fBline\fR style is also supported for preview border, which draws a single separator line between the preview window and the rest of the interface. .TP .BI "\-\-preview\-label" [=LABEL] Label to print on the horizontal border line of the preview window. Should be used with one of the following \fB\-\-preview\-window\fR options. .br .B * border\-rounded (default on non-Windows platforms) .br .B * border\-sharp (default on Windows) .br .B * border\-bold .br .B * border\-double .br .B * border\-block .br .B * border\-thinblock .br .B * border\-horizontal .br .B * border\-top .br .B * border\-bottom .br .TP .BI "\-\-preview\-label\-pos" [=N[:top|bottom]] Position of the border label on the border line of the preview window. Specify a positive integer as the column position from the left. Specify a negative integer to right-align the label. Label is printed on the top border line by default, add \fB:bottom\fR to put it on the border line on the bottom. The default value 0 (or \fBcenter\fR) will put the label at the center of the border line. .TP .BI "\-\-preview\-window=" "[POSITION][,SIZE[%]][,border\-STYLE][,[no]wrap][,[no]follow][,[no]cycle][,[no]info][,[no]hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default][,