Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fzf for openSUSE:Factory checked in at 2024-01-23 22:57:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fzf (Old) and /work/SRC/openSUSE:Factory/.fzf.new.16006 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fzf" Tue Jan 23 22:57:32 2024 rev:41 rq:1141046 version:0.46.0 Changes: -------- --- /work/SRC/openSUSE:Factory/fzf/fzf.changes 2024-01-03 12:27:39.949345779 +0100 +++ /work/SRC/openSUSE:Factory/.fzf.new.16006/fzf.changes 2024-01-23 22:57:40.527774316 +0100 @@ -1,0 +2,13 @@ +Tue Jan 23 19:48:30 UTC 2024 - Joshua Smith <jsmith...@gmail.com> + +- Update to version 0.46.0: + * Added new events, result and resize + * fzf now exports many new environment variables to the child + processes. + * fzf:prompt and fzf:action are being phased out + * Changed mattn/go-runewidth dependency to rivo/uniseg for + accurate results. Set --ambidouble if your terminal displays + ambigous width characters + * Bug fixes + +------------------------------------------------------------------- Old: ---- fzf-0.45.0.tar.gz New: ---- fzf-0.46.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fzf.spec ++++++ --- /var/tmp/diff_new_pack.qC6RY4/_old 2024-01-23 22:57:41.023792452 +0100 +++ /var/tmp/diff_new_pack.qC6RY4/_new 2024-01-23 22:57:41.023792452 +0100 @@ -18,7 +18,7 @@ %global _lto_cflags %{nil} Name: fzf -Version: 0.45.0 +Version: 0.46.0 Release: 0 Summary: A command-line fuzzy finder License: MIT ++++++ fzf-0.45.0.tar.gz -> fzf-0.46.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/.github/workflows/depsreview.yaml new/fzf-0.46.0/.github/workflows/depsreview.yaml --- old/fzf-0.45.0/.github/workflows/depsreview.yaml 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/.github/workflows/depsreview.yaml 2024-01-23 15:47:24.000000000 +0100 @@ -11,4 +11,4 @@ - name: 'Checkout Repository' uses: actions/checkout@v3 - name: 'Dependency Review' - uses: actions/dependency-review-action@v3 + uses: actions/dependency-review-action@v4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/.github/workflows/typos.yml new/fzf-0.46.0/.github/workflows/typos.yml --- old/fzf-0.45.0/.github/workflows/typos.yml 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/.github/workflows/typos.yml 2024-01-23 15:47:24.000000000 +0100 @@ -7,4 +7,4 @@ runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: crate-ci/typos@v1.16.4 + - uses: crate-ci/typos@v1.17.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/.tool-versions new/fzf-0.46.0/.tool-versions --- old/fzf-0.45.0/.tool-versions 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/.tool-versions 2024-01-23 15:47:24.000000000 +0100 @@ -1 +1 @@ -golang 1.20.4 +golang 1.21.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/ADVANCED.md new/fzf-0.46.0/ADVANCED.md --- old/fzf-0.45.0/ADVANCED.md 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/ADVANCED.md 2024-01-23 15:47:24.000000000 +0100 @@ -1,8 +1,8 @@ Advanced fzf examples ====================== -* *Last update: 2023/12/29* -* *Requires fzf 0.45.0 or above* +* *Last update: 2024/01/20* +* *Requires fzf 0.46.0 or above* --- @@ -22,12 +22,14 @@ * [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) * [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) <!-- vim-markdown-toc --> @@ -220,17 +222,17 @@ 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 +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 ]] && + --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 {}' + --preview '[[ $FZF_PROMPT =~ Files ]] && bat --color=always {} || tree -C {}' ``` Ripgrep integration @@ -467,6 +469,41 @@ [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})' +``` + Log tailing ----------- @@ -596,6 +633,12 @@ ![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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/BUILD.md new/fzf-0.46.0/BUILD.md --- old/fzf-0.45.0/BUILD.md 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/BUILD.md 2024-01-23 15:47:24.000000000 +0100 @@ -34,8 +34,8 @@ Third-party libraries used -------------------------- -- [mattn/go-runewidth](https://github.com/mattn/go-runewidth) - - Licensed under [MIT](http://mattn.mit-license.org) +- [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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/CHANGELOG.md new/fzf-0.46.0/CHANGELOG.md --- old/fzf-0.45.0/CHANGELOG.md 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/CHANGELOG.md 2024-01-23 15:47:24.000000000 +0100 @@ -1,6 +1,46 @@ CHANGELOG ========= +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 @@ -92,7 +132,7 @@ # --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 --stdin=no --place=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}@0x0 {} | sed \$d + 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/Dockerfile new/fzf-0.46.0/Dockerfile --- old/fzf-0.45.0/Dockerfile 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/Dockerfile 2024-01-23 15:47:24.000000000 +0100 @@ -1,5 +1,5 @@ -FROM --platform=linux/amd64 archlinux -RUN pacman -Sy && pacman --noconfirm -S awk git tmux zsh fish ruby procps go make gcc +FROM --platform=linux/amd64 ubuntu:22.04 +RUN apt-get update -y && apt install -y git make golang zsh fish ruby tmux RUN gem install --no-document -v 5.14.2 minitest RUN echo '. /usr/share/bash-completion/completions/git' >> ~/.bashrc RUN echo '. ~/.bashrc' >> ~/.bash_profile @@ -8,4 +8,5 @@ RUN rm -f /etc/bash.bashrc COPY . /fzf RUN cd /fzf && make install && ./install --all +ENV LANG C.UTF-8 CMD tmux new 'set -o pipefail; ruby /fzf/test/test_go.rb | tee out && touch ok' && cat out && [ -e ok ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/Makefile new/fzf-0.46.0/Makefile --- old/fzf-0.45.0/Makefile 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/Makefile 2024-01-23 15:47:24.000000000 +0100 @@ -93,7 +93,7 @@ PATH=$(PATH):$(GOPATH)/bin $(GO) generate ./... build: - goreleaser build --rm-dist --snapshot --skip-post-hooks + goreleaser build --clean --snapshot --skip=post-hooks release: # Make sure that the tests pass and the build works @@ -126,7 +126,7 @@ git push origin temp --follow-tags --force # Make a GitHub release - goreleaser --rm-dist --release-notes tmp/release-note + goreleaser --clean --release-notes tmp/release-note # Push to master git checkout master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/README.md new/fzf-0.46.0/README.md --- old/fzf-0.45.0/README.md 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/README.md 2024-01-23 15:47:24.000000000 +0100 @@ -26,7 +26,7 @@ If you'd like to sponsor this project, please visit https://github.com/sponsors/junegunn. -<!-- sponsors --><a href="https://github.com/miyanokomiya"><img src="https://github.com/miyanokomiya.png" width="60px" alt="miyanokomiya" /></a><a href="https://github.com/jonhoo"><img src="https://github.com/jonhoo.png" width="60px" alt="Jon Gjengset" /></a><a href="https://github.com/AceofSpades5757"><img src="https://github.com/AceofSpades5757.png" width="60px" alt="Kyle L. Davis" /></a><a href="https://github.com/Frederick888"><img src="https://github.com/Frederick888.png" width="60px" alt="Frederick Zhang" /></a><a href="https://github.com/moritzdietz"><img src="https://github.com/moritzdietz.png" width="60px" alt="Moritz Dietz" /></a><a href="https://github.com/mikker"><img src="https://github.com/mikker.png" width="60px" alt="Mikkel Malmberg" /></a><a href="https://github.com/pldubouilh"><img src="https://github.com/pldubouilh.png" width="60px" alt="Pierre Dubouilh" /></a><a href="https://github.com/rcorre"><img src="https://github.com/rcorre.png" width="60px" alt="Ryan Roden -Corrent" /></a><a href="https://github.com/blissdev"><img src="https://github.com/blissdev.png" width="60px" alt="Jordan Arentsen" /></a><a href="https://github.com/mislav"><img src="https://github.com/mislav.png" width="60px" alt="Mislav MarohniÄ" /></a><a href="https://github.com/aexvir"><img src="https://github.com/aexvir.png" width="60px" alt="Alex Viscreanu" /></a><a href="https://github.com/dbalatero"><img src="https://github.com/dbalatero.png" width="60px" alt="David Balatero" /></a><a href="https://github.com/comatory"><img src="https://github.com/comatory.png" width="60px" alt="Ondrej Synacek" /></a><a href="https://github.com/moobar"><img src="https://github.com/moobar.png" width="60px" alt="" /></a><a href="https://github.com/majjoha"><img src="https://github.com/majjoha.png" width="60px" alt="Mathias Jean Johansen" /></a><a href="https://github.com/benelan"><img src="https://github.com/benelan.png" width="60px" alt="Ben Elan" /></a><a href="https://github.com/jryom"><i mg src="https://github.com/jryom.png" width="60px" alt="Jesper" /></a><a href="https://github.com/pawelduda"><img src="https://github.com/pawelduda.png" width="60px" alt="PaweÅ Duda" /></a><a href="https://github.com/slezica"><img src="https://github.com/slezica.png" width="60px" alt="Santiago Lezica" /></a><a href="https://github.com/pbwn"><img src="https://github.com/pbwn.png" width="60px" alt="" /></a><a href="https://github.com/timgluz"><img src="https://github.com/timgluz.png" width="60px" alt="Timo Sulg" /></a><a href="https://github.com/seanmorton"><img src="https://github.com/seanmorton.png" width="60px" alt="Sean Morton" /></a><a href="https://github.com/pyrho"><img src="https://github.com/pyrho.png" width="60px" alt="Damien Rajon" /></a><a href="https://github.com/ArtBIT"><img src="https://github.com/ArtBIT.png" width="60px" alt="ArtBIT" /></a><a href="https://github.com/da-moon"><img src="https://github.com/da-moon.png" width="60px" alt="" /></a><a href="https://github.c om/hovissimo"><img src="https://github.com/hovissimo.png" width="60px" alt="Hovis" /></a><a href="https://github.com/dariusjonda"><img src="https://github.com/dariusjonda.png" width="60px" alt="Darius Jonda" /></a><a href="https://github.com/cristiand391"><img src="https://github.com/cristiand391.png" width="60px" alt="Cristian Dominguez" /></a><a href="https://github.com/eliangcs"><img src="https://github.com/eliangcs.png" width="60px" alt="Chang-Hung Liang" /></a><a href="https://github.com/asphaltbuffet"><img src="https://github.com/asphaltbuffet.png" width="60px" alt="Ben Lechlitner" /></a><a href="https://github.com/yash1th"><img src="https://github.com/yash1th.png" width="60px" alt="yash" /></a><a href="https://github.com/looshch"><img src="https://github.com/looshch.png" width="60px" alt="george looshch" /></a><a href="https://github.com/kg8m"><img src="https://github.com/kg8m.png" width="60px" alt="Takumi KAGIYAMA" /></a><a href="https://github.com/polm"><img src="https://gi thub.com/polm.png" width="60px" alt="Paul O'Leary McCann" /></a><a href="https://github.com/rbeeger"><img src="https://github.com/rbeeger.png" width="60px" alt="Robert Beeger" /></a><a href="https://github.com/veebch"><img src="https://github.com/veebch.png" width="60px" alt="VEEB Projects" /></a><a href="https://github.com/khuedoan"><img src="https://github.com/khuedoan.png" width="60px" alt="Khue Doan" /></a><a href="https://github.com/yowayb"><img src="https://github.com/yowayb.png" width="60px" alt="Yoway Buorn" /></a><a href="https://github.com/scalisi"><img src="https://github.com/scalisi.png" width="60px" alt="Josh Scalisi" /></a><a href="https://github.com/alecbcs"><img src="https://github.com/alecbcs.png" width="60px" alt="Alec Scott" /></a><a href="https://github.com/the-shank"><img src="https://github.com/the-shank.png" width="60px" alt="theshank" /></a><a href="https://github.com/thnxdev"><img src="https://github.com/thnxdev.png" width="60px" alt="thanks.dev" /></a><a hr ef="https://github.com/tamirzb"><img src="https://github.com/tamirzb.png" width="60px" alt="Tamir Zahavi-Brunner" /></a><a href="https://github.com/artursapek"><img src="https://github.com/artursapek.png" width="60px" alt="Artur Sapek" /></a><a href="https://github.com/ramnes"><img src="https://github.com/ramnes.png" width="60px" alt="Guillaume Gelin" /></a><a href="https://github.com/Akron"><img src="https://github.com/Akron.png" width="60px" alt="Nils Diewald" /></a><a href="https://github.com/mikkifr"><img src="https://github.com/mikkifr.png" width="60px" alt="Mikki Freeman" /></a><a href="https://github.com/lukeswissman"><img src="https://github.com/lukeswissman.png" width="60px" alt="Lukas Schweizer" /></a><!-- sponsors --> +<!-- sponsors --><a href="https://github.com/miyanokomiya"><img src="https://github.com/miyanokomiya.png" width="60px" alt="miyanokomiya" /></a><a href="https://github.com/jonhoo"><img src="https://github.com/jonhoo.png" width="60px" alt="Jon Gjengset" /></a><a href="https://github.com/AceofSpades5757"><img src="https://github.com/AceofSpades5757.png" width="60px" alt="Kyle L. Davis" /></a><a href="https://github.com/Frederick888"><img src="https://github.com/Frederick888.png" width="60px" alt="Frederick Zhang" /></a><a href="https://github.com/moritzdietz"><img src="https://github.com/moritzdietz.png" width="60px" alt="Moritz Dietz" /></a><a href="https://github.com/mikker"><img src="https://github.com/mikker.png" width="60px" alt="Mikkel Malmberg" /></a><a href="https://github.com/pldubouilh"><img src="https://github.com/pldubouilh.png" width="60px" alt="Pierre Dubouilh" /></a><a href="https://github.com/rcorre"><img src="https://github.com/rcorre.png" width="60px" alt="Ryan Roden -Corrent" /></a><a href="https://github.com/blissdev"><img src="https://github.com/blissdev.png" width="60px" alt="Jordan Arentsen" /></a><a href="https://github.com/mislav"><img src="https://github.com/mislav.png" width="60px" alt="Mislav MarohniÄ" /></a><a href="https://github.com/aexvir"><img src="https://github.com/aexvir.png" width="60px" alt="Alex Viscreanu" /></a><a href="https://github.com/dbalatero"><img src="https://github.com/dbalatero.png" width="60px" alt="David Balatero" /></a><a href="https://github.com/comatory"><img src="https://github.com/comatory.png" width="60px" alt="Ondrej Synacek" /></a><a href="https://github.com/moobar"><img src="https://github.com/moobar.png" width="60px" alt="" /></a><a href="https://github.com/majjoha"><img src="https://github.com/majjoha.png" width="60px" alt="Mathias Jean Johansen" /></a><a href="https://github.com/benelan"><img src="https://github.com/benelan.png" width="60px" alt="Ben Elan" /></a><a href="https://github.com/pawelduda "><img src="https://github.com/pawelduda.png" width="60px" alt="PaweÅ Duda" /></a><a href="https://github.com/slezica"><img src="https://github.com/slezica.png" width="60px" alt="Santiago Lezica" /></a><a href="https://github.com/pbwn"><img src="https://github.com/pbwn.png" width="60px" alt="" /></a><a href="https://github.com/timgluz"><img src="https://github.com/timgluz.png" width="60px" alt="Timo Sulg" /></a><a href="https://github.com/pyrho"><img src="https://github.com/pyrho.png" width="60px" alt="Damien Rajon" /></a><a href="https://github.com/ArtBIT"><img src="https://github.com/ArtBIT.png" width="60px" alt="ArtBIT" /></a><a href="https://github.com/da-moon"><img src="https://github.com/da-moon.png" width="60px" alt="" /></a><a href="https://github.com/hovissimo"><img src="https://github.com/hovissimo.png" width="60px" alt="Hovis" /></a><a href="https://github.com/dariusjonda"><img src="https://github.com/dariusjonda.png" width="60px" alt="Darius Jonda" /></a><a href="https: //github.com/cristiand391"><img src="https://github.com/cristiand391.png" width="60px" alt="Cristian Dominguez" /></a><a href="https://github.com/eliangcs"><img src="https://github.com/eliangcs.png" width="60px" alt="Chang-Hung Liang" /></a><a href="https://github.com/asphaltbuffet"><img src="https://github.com/asphaltbuffet.png" width="60px" alt="Ben Lechlitner" /></a><a href="https://github.com/yash1th"><img src="https://github.com/yash1th.png" width="60px" alt="yash" /></a><a href="https://github.com/looshch"><img src="https://github.com/looshch.png" width="60px" alt="george looshch" /></a><a href="https://github.com/kg8m"><img src="https://github.com/kg8m.png" width="60px" alt="Takumi KAGIYAMA" /></a><a href="https://github.com/polm"><img src="https://github.com/polm.png" width="60px" alt="Paul O'Leary McCann" /></a><a href="https://github.com/rbeeger"><img src="https://github.com/rbeeger.png" width="60px" alt="Robert Beeger" /></a><a href="https://github.com/veebch"><img src="h ttps://github.com/veebch.png" width="60px" alt="VEEB Projects" /></a><a href="https://github.com/khuedoan"><img src="https://github.com/khuedoan.png" width="60px" alt="Khue Doan" /></a><a href="https://github.com/yowayb"><img src="https://github.com/yowayb.png" width="60px" alt="Yoway Buorn" /></a><a href="https://github.com/scalisi"><img src="https://github.com/scalisi.png" width="60px" alt="Josh Scalisi" /></a><a href="https://github.com/alecbcs"><img src="https://github.com/alecbcs.png" width="60px" alt="Alec Scott" /></a><a href="https://github.com/the-shank"><img src="https://github.com/the-shank.png" width="60px" alt="theshank" /></a><a href="https://github.com/thnxdev"><img src="https://github.com/thnxdev.png" width="60px" alt="thanks.dev" /></a><a href="https://github.com/artursapek"><img src="https://github.com/artursapek.png" width="60px" alt="Artur Sapek" /></a><a href="https://github.com/ramnes"><img src="https://github.com/ramnes.png" width="60px" alt="Guillaume Gelin" /></a><a href="https://github.com/mikkifr"><img src="https://github.com/mikkifr.png" width="60px" alt="Mikki Freeman" /></a><a href="https://github.com/aldosch"><img src="https://github.com/aldosch.png" width="60px" alt="Aldo Schumann" /></a><a href="https://github.com/jyc"><img src="https://github.com/jyc.png" width="60px" alt="" /></a><a href="https://github.com/Bombycinous"><img src="https://github.com/Bombycinous.png" width="60px" alt="" /></a><a href="https://github.com/mrcnski"><img src="https://github.com/mrcnski.png" width="60px" alt="Marcin S." /></a><a href="https://github.com/roblevy"><img src="https://github.com/roblevy.png" width="60px" alt="Rob Levy" /></a><!-- sponsors --> Table of Contents ----------------- @@ -73,6 +73,7 @@ * [Tips](#tips) * [Respecting `.gitignore`](#respecting-gitignore) * [Fish shell](#fish-shell) + * [fzf Theme Playground](#fzf-theme-playground) * [Related projects](#related-projects) * [License](#license) @@ -734,18 +735,16 @@ ### Previewing an image -Since 0.43.0, fzf has experimental support for [Kitty graphics -protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/), so if you use -Kitty, you can make fzf display an image in the preview window. +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=' - if file --mime-type {} | grep -qF image/; then - kitty icat --clear --transfer-mode=memory --stdin=no --place=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}@0x0 {} | sed \$d - else - bat --color=always {} - fi -' +fzf --preview 'fzf-preview.sh {}' ``` Tips @@ -800,6 +799,12 @@ 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 ---------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/bin/fzf-preview.sh new/fzf-0.46.0/bin/fzf-preview.sh --- old/fzf-0.45.0/bin/fzf-preview.sh 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/bin/fzf-preview.sh 2024-01-23 15:47:24.000000000 +0100 @@ -53,7 +53,7 @@ # 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. - kitty icat --clear --transfer-mode=memory --stdin=no --place="$dim@0x0" "$file" | sed '$d' | sed $'$s/$/\e[m/' + kitty 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/go.mod new/fzf-0.46.0/go.mod --- old/fzf-0.45.0/go.mod 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/go.mod 2024-01-23 15:47:24.000000000 +0100 @@ -2,22 +2,21 @@ require ( github.com/gdamore/tcell/v2 v2.5.4 + github.com/junegunn/uniseg v0.0.0-20240120174029-b504da4f6ed2 github.com/mattn/go-isatty v0.0.17 - github.com/mattn/go-runewidth v0.0.14 github.com/mattn/go-shellwords v1.0.12 - github.com/rivo/uniseg v0.4.4 github.com/saracen/walker v0.1.3 - golang.org/x/sys v0.15.0 - golang.org/x/term v0.15.0 + golang.org/x/sys v0.16.0 + golang.org/x/term v0.16.0 ) require ( github.com/gdamore/encoding v1.0.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - golang.org/x/mod v0.14.0 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/rivo/uniseg v0.4.4 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/text v0.5.0 // indirect - golang.org/x/tools v0.16.1 // indirect ) go 1.17 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/go.sum new/fzf-0.46.0/go.sum --- old/fzf-0.45.0/go.sum 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/go.sum 2024-01-23 15:47:24.000000000 +0100 @@ -2,6 +2,8 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.5.4 h1:TGU4tSjD3sCL788vFNeJnTdzpNKIw1H5dgLnJRQVv/k= github.com/gdamore/tcell/v2 v2.5.4/go.mod h1:dZgRy5v4iMobMEcWNYBtREnDZAT9DYmfqIkrgEMxLyw= +github.com/junegunn/uniseg v0.0.0-20240120174029-b504da4f6ed2 h1:oEwPBh29BPu1MaTsz2dM9bDrkOgKBoYFC0u6uY2izWo= +github.com/junegunn/uniseg v0.0.0-20240120174029-b504da4f6ed2/go.mod h1:ywqF55XaSE3/uS2tkJqVFKiE0oIYAXRvU2N7DU4y3XQ= 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.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= @@ -19,14 +21,11 @@ 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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -36,12 +35,12 @@ 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.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= 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= @@ -50,6 +49,4 @@ 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.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/install new/fzf-0.46.0/install --- old/fzf-0.45.0/install 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/install 2024-01-23 15:47:24.000000000 +0100 @@ -2,7 +2,7 @@ set -u -version=0.45.0 +version=0.46.0 auto_completion= key_bindings= update_config=2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/install.ps1 new/fzf-0.46.0/install.ps1 --- old/fzf-0.45.0/install.ps1 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/install.ps1 2024-01-23 15:47:24.000000000 +0100 @@ -1,4 +1,4 @@ -$version="0.45.0" +$version="0.46.0" $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/main.go new/fzf-0.46.0/main.go --- old/fzf-0.45.0/main.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/main.go 2024-01-23 15:47:24.000000000 +0100 @@ -5,7 +5,7 @@ "github.com/junegunn/fzf/src/protector" ) -var version string = "0.45" +var version string = "0.46" var revision string = "devel" func main() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/man/man1/fzf-tmux.1 new/fzf-0.46.0/man/man1/fzf-tmux.1 --- old/fzf-0.45.0/man/man1/fzf-tmux.1 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/man/man1/fzf-tmux.1 2024-01-23 15:47:24.000000000 +0100 @@ -21,7 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf-tmux 1 "Jan 2024" "fzf 0.45.0" "fzf-tmux - open fzf in tmux split pane" +.TH fzf-tmux 1 "Jan 2024" "fzf 0.46.0" "fzf-tmux - open fzf in tmux split pane" .SH NAME fzf-tmux - open fzf in tmux split pane diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/man/man1/fzf.1 new/fzf-0.46.0/man/man1/fzf.1 --- old/fzf-0.45.0/man/man1/fzf.1 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/man/man1/fzf.1 2024-01-23 15:47:24.000000000 +0100 @@ -21,7 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf 1 "Jan 2024" "fzf 0.45.0" "fzf - a command-line fuzzy finder" +.TH fzf 1 "Jan 2024" "fzf 0.46.0" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder @@ -260,9 +260,8 @@ .br If you use a terminal emulator where each box-drawing character takes -2 columns, try setting \fBRUNEWIDTH_EASTASIAN\fR environment variable to -\fB0\fR or \fB1\fR. If the border is still not properly rendered, set -\fB--no-unicode\fR. +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] @@ -314,6 +313,11 @@ the spinner and the horizontal separator. .TP +.B "--ambidouble" +Set this option if your terminal displays ambiguous width characters (e.g. +box-drawing characters for borders) as 2 columns. + +.TP .BI "--margin=" MARGIN Comma-separated expression for margins around the finder. .br @@ -592,8 +596,6 @@ * \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 -* \fB{fzf:action}\fR is replaced to to the name of the last action performed -* \fB{fzf:prompt}\fR is replaced to to the prompt string Note that you can escape a placeholder pattern by prepending a backslash. @@ -829,12 +831,14 @@ \fB# Start HTTP server on port 6266 fzf --listen 6266 - # Get program state in JSON format (experimental) - curl localhost:6266 - # Send action to the server curl -XPOST localhost:6266 -d 'reload(seq 100)+change-prompt(hundred> )' + # Get program state in JSON format (experimental) + # * Make sure NOT to access this endpoint from execute/transform actions + # as it will result in a timeout + curl localhost:6266 + # Start HTTP server on port 6266 with remote connections allowed # * Listening on non-localhost address requires using an API key export FZF_API_KEY="$(head -c 32 /dev/urandom | base64)" @@ -901,6 +905,39 @@ .BR .. " All the fields" .br +.SH ENVIRONMENT VARIABLES EXPORTED TO CHILD PROCESSES + +fzf exports the following environment variables to its child processes. + +.BR FZF_LINES " Number of lines fzf takes up excluding padding and margin" +.br +.BR FZF_COLUMNS " Number of columns fzf takes up excluding padding and margin" +.br +.BR FZF_TOTAL_COUNT " Total number of items" +.br +.BR FZF_MATCH_COUNT " Number of matched items" +.br +.BR FZF_SELECT_COUNT " Number of selected items" +.br +.BR FZF_QUERY " Current query string" +.br +.BR FZF_PROMPT " Prompt string" +.br +.BR FZF_ACTION " The name of the last action performed" +.br +.BR FZF_PORT " Port number when --listen option is used" +.br + +The following variables are additionally exported to the preview commands. + +.BR FZF_PREVIEW_TOP " Top position of the preview window" +.br +.BR FZF_PREVIEW_LEFT " Left position of the preview window" +.br +.BR FZF_PREVIEW_LINES " Number of lines in the preview window" +.br +.BR FZF_PREVIEW_COLUMNS " Number of columns in the preview window" + .SH EXTENDED SEARCH MODE Unless specified otherwise, fzf will start in "extended-search mode". In this @@ -1075,6 +1112,22 @@ \fB# 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> '\fR .RE +\fIresize\fR +.RS +Triggered when the terminal size is changed. + +e.g. + \fBfzf --bind 'resize:transform-header:echo Resized: ${FZF_COLUMNS}x${FZF_LINES}'\fR +.RE +\fIresult\fR +.RS +Triggered when the filtering for the current query is complete and the result list is ready. + +e.g. + \fB# Put the cursor on the second item when the query string is empty + # * Note that you can't use 'change' event in this case because the second position may not be available + fzf --sync --bind 'result:transform:[[ -z {fzf:query} ]] && echo "pos(2)"'\fR +.RE \fIchange\fR .RS Triggered whenever the query string is changed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/shell/key-bindings.zsh new/fzf-0.46.0/shell/key-bindings.zsh --- old/fzf-0.45.0/shell/key-bindings.zsh 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/shell/key-bindings.zsh 2024-01-23 15:47:24.000000000 +0100 @@ -98,13 +98,15 @@ fzf-history-widget() { local selected num setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null - selected=( $(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' | - FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) ) + selected="$(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' | + FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m" $(__fzfcmd))" local ret=$? if [ -n "$selected" ]; then - num=$selected[1] - if [ -n "$num" ]; then - zle vi-fetch-history -n $num + num=$(awk '{print $1}' <<< "$selected") + if [[ "$num" =~ '^[1-9][0-9]*\*?$' ]]; then + zle vi-fetch-history -n ${num%\*} + else # selected is a custom query, not from history + LBUFFER="$selected" fi fi zle reset-prompt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/options.go new/fzf-0.46.0/src/options.go --- old/fzf-0.45.0/src/options.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/options.go 2024-01-23 15:47:24.000000000 +0100 @@ -11,8 +11,8 @@ "github.com/junegunn/fzf/src/algo" "github.com/junegunn/fzf/src/tui" "github.com/junegunn/fzf/src/util" + "github.com/junegunn/uniseg" - "github.com/mattn/go-runewidth" "github.com/mattn/go-shellwords" ) @@ -337,6 +337,7 @@ BorderLabel labelOpts PreviewLabel labelOpts Unicode bool + Ambidouble bool Tabstop int ListenAddr *listenAddress Unsafe bool @@ -406,6 +407,7 @@ Margin: defaultMargin(), Padding: defaultMargin(), Unicode: true, + Ambidouble: os.Getenv("RUNEWIDTH_EASTASIAN") == "1", Tabstop: 8, BorderLabel: labelOpts{}, PreviewLabel: labelOpts{}, @@ -650,6 +652,10 @@ add(tui.Load) case "focus": add(tui.Focus) + case "result": + add(tui.Result) + case "resize": + add(tui.Resize) case "one": add(tui.One) case "zero": @@ -1591,8 +1597,6 @@ } } validateJumpLabels := false - validatePointer := false - validateMarker := false for i := 0; i < len(allArgs); i++ { arg := allArgs[i] switch arg { @@ -1772,10 +1776,8 @@ opts.Prompt = nextString(allArgs, &i, "prompt string required") case "--pointer": opts.Pointer = firstLine(nextString(allArgs, &i, "pointer sign string required")) - validatePointer = true case "--marker": opts.Marker = firstLine(nextString(allArgs, &i, "selected sign string required")) - validateMarker = true case "--sync": opts.Sync = true case "--no-sync": @@ -1843,6 +1845,10 @@ opts.Unicode = false case "--unicode": opts.Unicode = true + case "--ambidouble": + opts.Ambidouble = true + case "--no-ambidouble": + opts.Ambidouble = false case "--margin": opts.Margin = parseMargin( "margin", @@ -1901,10 +1907,8 @@ opts.Prompt = value } else if match, value := optString(arg, "--pointer="); match { opts.Pointer = firstLine(value) - validatePointer = true } else if match, value := optString(arg, "--marker="); match { opts.Marker = firstLine(value) - validateMarker = true } else if match, value := optString(arg, "-n", "--nth="); match { opts.Nth = splitNth(value) } else if match, value := optString(arg, "--with-nth="); match { @@ -2011,31 +2015,31 @@ } } } - - if validatePointer { - if err := validateSign(opts.Pointer, "pointer"); err != nil { - errorExit(err.Error()) - } - } - - if validateMarker { - if err := validateSign(opts.Marker, "marker"); err != nil { - errorExit(err.Error()) - } - } } func validateSign(sign string, signOptName string) error { if sign == "" { return fmt.Errorf("%v cannot be empty", signOptName) } - if runewidth.StringWidth(sign) > 2 { + if uniseg.StringWidth(sign) > 2 { return fmt.Errorf("%v display width should be up to 2", signOptName) } return nil } func postProcessOptions(opts *Options) { + if opts.Ambidouble { + uniseg.EastAsianAmbiguousWidth = 2 + } + + if err := validateSign(opts.Pointer, "pointer"); err != nil { + errorExit(err.Error()) + } + + if err := validateSign(opts.Marker, "marker"); err != nil { + errorExit(err.Error()) + } + if !opts.Version && !tui.IsLightRendererSupported() && opts.Height.size > 0 { errorExit("--height option is currently not supported on this platform") } @@ -2046,7 +2050,7 @@ errorExit("--scrollbar should be given one or two characters") } for _, r := range runes { - if runewidth.RuneWidth(r) != 1 { + if uniseg.StringWidth(string(r)) != 1 { errorExit("scrollbar display width should be 1") } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/result.go new/fzf-0.46.0/src/result.go --- old/fzf-0.45.0/src/result.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/result.go 2024-01-23 15:47:24.000000000 +0100 @@ -138,7 +138,9 @@ for i := off[0]; i < off[1]; i++ { // Negative of 1-based index of itemColors // - The extra -1 means highlighted - cols[i] = cols[i]*-1 - 1 + if cols[i] >= 0 { + cols[i] = cols[i]*-1 - 1 + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/result_test.go new/fzf-0.46.0/src/result_test.go --- old/fzf-0.45.0/src/result_test.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/result_test.go 2024-01-23 15:47:24.000000000 +0100 @@ -120,7 +120,7 @@ // ++++++++ ++++++++++ // --++++++++-- --++++++++++--- - offsets := []Offset{{5, 15}, {25, 35}} + offsets := []Offset{{5, 15}, {10, 12}, {25, 35}} item := Result{ item: &Item{ colors: &[]ansiOffset{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/server.go new/fzf-0.46.0/src/server.go --- old/fzf-0.45.0/src/server.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/server.go 2024-01-23 15:47:24.000000000 +0100 @@ -30,7 +30,9 @@ httpOk = "HTTP/1.1 200 OK" + crlf httpBadRequest = "HTTP/1.1 400 Bad Request" + crlf httpUnauthorized = "HTTP/1.1 401 Unauthorized" + crlf + httpUnavailable = "HTTP/1.1 503 Service Unavailable" + crlf httpReadTimeout = 10 * time.Second + jsonContentType = "Content-Type: application/json" + crlf maxContentLength = 1024 * 1024 ) @@ -141,7 +143,7 @@ return answer(httpBadRequest, message) } good := func(message string) string { - return answer(httpOk+"Content-Type: application/json"+crlf, message) + return answer(httpOk+jsonContentType, message) } conn.SetReadDeadline(time.Now().Add(httpReadTimeout)) scanner := bufio.NewScanner(conn) @@ -165,8 +167,16 @@ getMatch := getRegex.FindStringSubmatch(text) if len(getMatch) > 0 { server.actionChannel <- []*action{{t: actResponse, a: getMatch[1]}} - response := <-server.responseChannel - return good(response) + select { + case response := <-server.responseChannel: + return good(response) + case <-time.After(2 * time.Second): + go func() { + // Drain the channel + <-server.responseChannel + }() + return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`) + } } else if !strings.HasPrefix(text, "POST / HTTP") { return bad("invalid request method") } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/terminal.go new/fzf-0.46.0/src/terminal.go --- old/fzf-0.45.0/src/terminal.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/terminal.go 2024-01-23 15:47:24.000000000 +0100 @@ -17,8 +17,7 @@ "syscall" "time" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" + "github.com/junegunn/uniseg" "github.com/junegunn/fzf/src/tui" "github.com/junegunn/fzf/src/util" @@ -251,7 +250,10 @@ borderWidth int count int progress int + hasResultActions bool + hasFocusActions bool hasLoadActions bool + hasResizeActions bool triggerLoad bool reading bool running bool @@ -289,6 +291,8 @@ termSize tui.TermSize lastAction actionType lastFocus int32 + areaLines int + areaColumns int } type selectedItem struct { @@ -449,6 +453,17 @@ actHideHeader ) +func (a actionType) Name() string { + name := "" + for i, r := range a.String()[3:] { + if i > 0 && r >= 'A' && r <= 'Z' { + name += "-" + } + name += string(r) + } + return strings.ToLower(name) +} + func processExecution(action actionType) bool { switch action { case actTransform, @@ -519,7 +534,6 @@ } add(tui.Invalid, actInvalid) - add(tui.Resize, actClearScreen) add(tui.CtrlA, actBeginningOfLine) add(tui.CtrlB, actBackwardChar) add(tui.CtrlC, actAbort) @@ -730,6 +744,8 @@ ellipsis: opts.Ellipsis, ansi: opts.Ansi, tabstop: opts.Tabstop, + hasResultActions: false, + hasFocusActions: false, hasLoadActions: false, triggerLoad: false, reading: true, @@ -757,7 +773,7 @@ killChan: make(chan int), serverInputChan: make(chan []*action, 10), serverOutputChan: make(chan string), - eventChan: make(chan tui.Event, 3), // load / zero|one | GetChar + eventChan: make(chan tui.Event, 6), // (load + result + zero|one) | (focus) | (resize) | (GetChar) tui: renderer, initFunc: func() { renderer.Init() }, executing: util.NewAtomicBool(false), @@ -781,7 +797,7 @@ t.separator, t.separatorLen = t.ansiLabelPrinter(bar, &tui.ColSeparator, true) } if t.unicode { - t.borderWidth = runewidth.RuneWidth('â') + t.borderWidth = uniseg.StringWidth("â") } if opts.Scrollbar == nil { if t.unicode && t.borderWidth == 1 { @@ -801,6 +817,9 @@ } } + _, t.hasResizeActions = t.keymap[tui.Resize.AsEvent()] + _, t.hasResultActions = t.keymap[tui.Result.AsEvent()] + _, t.hasFocusActions = t.keymap[tui.Focus.AsEvent()] _, t.hasLoadActions = t.keymap[tui.Load.AsEvent()] if t.listenAddr != nil { @@ -819,6 +838,14 @@ if t.listenPort != nil { env = append(env, fmt.Sprintf("FZF_PORT=%d", *t.listenPort)) } + env = append(env, "FZF_QUERY="+string(t.input)) + env = append(env, "FZF_ACTION="+t.lastAction.Name()) + env = append(env, "FZF_PROMPT="+string(t.promptString)) + env = append(env, fmt.Sprintf("FZF_TOTAL_COUNT=%d", t.count)) + env = append(env, fmt.Sprintf("FZF_MATCH_COUNT=%d", t.merger.Length())) + env = append(env, fmt.Sprintf("FZF_SELECT_COUNT=%d", len(t.selected))) + env = append(env, fmt.Sprintf("FZF_LINES=%d", t.areaLines)) + env = append(env, fmt.Sprintf("FZF_COLUMNS=%d", t.areaColumns)) return env } @@ -1073,6 +1100,9 @@ t.eventChan <- one } } + if t.hasResultActions { + t.eventChan <- tui.Result.AsEvent() + } } t.mutex.Unlock() t.reqBox.Set(reqInfo, nil) @@ -1282,6 +1312,9 @@ width -= paddingInt[1] + paddingInt[3] height -= paddingInt[0] + paddingInt[2] + t.areaLines = height + t.areaColumns = width + // Set up preview window noBorder := tui.MakeBorderStyle(tui.BorderNone, t.unicode) if forcePreview || t.needPreviewWindow() { @@ -2534,14 +2567,7 @@ } } case match == "{fzf:action}": - name := "" - for i, r := range params.lastAction.String()[3:] { - if i > 0 && r >= 'A' && r <= 'Z' { - name += "-" - } - name += string(r) - } - return strings.ToLower(name) + return params.lastAction.Name() case match == "{fzf:prompt}": return quoteEntry(params.prompt) default: @@ -3070,9 +3096,9 @@ t.track = trackDisabled t.printInfo() } - if onFocus, prs := t.keymap[tui.Focus.AsEvent()]; prs && focusChanged && currentIndex != t.lastFocus { - t.lastFocus = focusedIndex - t.serverInputChan <- onFocus + if t.hasFocusActions && focusChanged && currentIndex != t.lastFocus { + t.lastFocus = currentIndex + t.eventChan <- tui.Focus.AsEvent() } if focusChanged || version != t.version { version = t.version @@ -3104,6 +3130,9 @@ if wasHidden && t.hasPreviewWindow() { refreshPreview(t.previewOpts.command) } + if req == reqResize && t.hasResizeActions { + t.eventChan <- tui.Resize.AsEvent() + } case reqClose: exit(func() int { if t.output() { @@ -3186,7 +3215,7 @@ } select { case event = <-t.eventChan: - needBarrier = !event.Is(tui.Load, tui.One, tui.Zero) + needBarrier = !event.Is(tui.Load, tui.Result, tui.Focus, tui.One, tui.Zero, tui.Resize) case serverActions := <-t.serverInputChan: event = tui.Invalid.AsEvent() if t.listenAddr == nil || t.listenAddr.IsLocal() || t.listenUnsafe { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/tui/light.go new/fzf-0.46.0/src/tui/light.go --- old/fzf-0.45.0/src/tui/light.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/tui/light.go 2024-01-23 15:47:24.000000000 +0100 @@ -10,8 +10,7 @@ "time" "unicode/utf8" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" + "github.com/junegunn/uniseg" "golang.org/x/term" ) @@ -804,7 +803,7 @@ if w.preview { color = ColPreviewBorder } - hw := runewidth.RuneWidth(w.border.top) + hw := runeWidth(w.border.top) if top { w.Move(0, 0) w.CPrint(color, repeat(w.border.top, w.width/hw)) @@ -842,13 +841,13 @@ if w.preview { color = ColPreviewBorder } - hw := runewidth.RuneWidth(w.border.top) - tcw := runewidth.RuneWidth(w.border.topLeft) + runewidth.RuneWidth(w.border.topRight) - bcw := runewidth.RuneWidth(w.border.bottomLeft) + runewidth.RuneWidth(w.border.bottomRight) + hw := runeWidth(w.border.top) + tcw := runeWidth(w.border.topLeft) + runeWidth(w.border.topRight) + bcw := runeWidth(w.border.bottomLeft) + runeWidth(w.border.bottomRight) rem := (w.width - tcw) % hw w.CPrint(color, string(w.border.topLeft)+repeat(w.border.top, (w.width-tcw)/hw)+repeat(' ', rem)+string(w.border.topRight)) if !onlyHorizontal { - vw := runewidth.RuneWidth(w.border.left) + vw := runeWidth(w.border.left) for y := 1; y < w.height-1; y++ { w.Move(y, 0) w.CPrint(color, string(w.border.left)) @@ -1020,7 +1019,7 @@ } else if rs[0] == '\r' { w++ } else { - w = runewidth.StringWidth(str) + w = uniseg.StringWidth(str) } width += w diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/tui/tcell.go new/fzf-0.46.0/src/tui/tcell.go --- old/fzf-0.45.0/src/tui/tcell.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/tui/tcell.go 2024-01-23 15:47:24.000000000 +0100 @@ -10,8 +10,7 @@ "github.com/gdamore/tcell/v2/encoding" "github.com/junegunn/fzf/src/util" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" + "github.com/junegunn/uniseg" ) func HasFullscreenRenderer() bool { @@ -738,7 +737,7 @@ style = w.normal.style() } - hw := runewidth.RuneWidth(w.borderStyle.top) + hw := runeWidth(w.borderStyle.top) switch shape { case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble, BorderHorizontal, BorderTop: max := right - 2*hw @@ -773,7 +772,7 @@ } switch shape { case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble, BorderVertical, BorderRight: - vw := runewidth.RuneWidth(w.borderStyle.right) + vw := runeWidth(w.borderStyle.right) for y := top; y < bot; y++ { _screen.SetContent(right-vw, y, w.borderStyle.right, nil, style) } @@ -782,8 +781,8 @@ switch shape { case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble: _screen.SetContent(left, top, w.borderStyle.topLeft, nil, style) - _screen.SetContent(right-runewidth.RuneWidth(w.borderStyle.topRight), top, w.borderStyle.topRight, nil, style) + _screen.SetContent(right-runeWidth(w.borderStyle.topRight), top, w.borderStyle.topRight, nil, style) _screen.SetContent(left, bot-1, w.borderStyle.bottomLeft, nil, style) - _screen.SetContent(right-runewidth.RuneWidth(w.borderStyle.bottomRight), bot-1, w.borderStyle.bottomRight, nil, style) + _screen.SetContent(right-runeWidth(w.borderStyle.bottomRight), bot-1, w.borderStyle.bottomRight, nil, style) } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/tui/tui.go new/fzf-0.46.0/src/tui/tui.go --- old/fzf-0.45.0/src/tui/tui.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/tui/tui.go 2024-01-23 15:47:24.000000000 +0100 @@ -5,6 +5,8 @@ "os" "strconv" "time" + + "github.com/junegunn/uniseg" ) // Types of user action @@ -105,6 +107,7 @@ Focus One Zero + Result AltBS @@ -811,3 +814,7 @@ ColPreviewScrollbar = pair(theme.PreviewScrollbar, theme.PreviewBg) ColPreviewSpinner = pair(theme.Spinner, theme.PreviewBg) } + +func runeWidth(r rune) int { + return uniseg.StringWidth(string(r)) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/util/util.go new/fzf-0.46.0/src/util/util.go --- old/fzf-0.45.0/src/util/util.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/util/util.go 2024-01-23 15:47:24.000000000 +0100 @@ -6,14 +6,13 @@ "strings" "time" + "github.com/junegunn/uniseg" "github.com/mattn/go-isatty" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" ) // StringWidth returns string width where each CR/LF character takes 1 column func StringWidth(s string) int { - return runewidth.StringWidth(s) + strings.Count(s, "\n") + strings.Count(s, "\r") + return uniseg.StringWidth(s) + strings.Count(s, "\n") + strings.Count(s, "\r") } // RunesWidth returns runes width @@ -165,7 +164,7 @@ output := strings.Repeat(str, times) if rest > 0 { for _, r := range str { - rest -= runewidth.RuneWidth(r) + rest -= uniseg.StringWidth(string(r)) if rest < 0 { break } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/src/util/util_test.go new/fzf-0.46.0/src/util/util_test.go --- old/fzf-0.45.0/src/util/util_test.go 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/src/util/util_test.go 2024-01-23 15:47:24.000000000 +0100 @@ -164,6 +164,18 @@ t.Errorf("Expected overflow index: %d, actual: %d", args[2], overflowIdx) } } + for _, input := range []struct { + s string + w int + }{ + {"â¶", 1}, + {"â¶ï¸", 2}, + } { + width, _ := RunesWidth([]rune(input.s), 0, 0, 100) + if width != input.w { + t.Errorf("Expected width of %s: %d, actual: %d", input.s, input.w, width) + } + } } func TestTruncate(t *testing.T) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.45.0/test/test_go.rb new/fzf-0.46.0/test/test_go.rb --- old/fzf-0.45.0/test/test_go.rb 2024-01-01 07:38:35.000000000 +0100 +++ new/fzf-0.46.0/test/test_go.rb 2024-01-23 15:47:24.000000000 +0100 @@ -2711,12 +2711,26 @@ tmux.until { |lines| assert_includes(lines[-1], '[[2]]') } tmux.send_keys :X tmux.until { |lines| assert_includes(lines[-1], '[[]]') } + tmux.send_keys :BSpace + tmux.until { |lines| assert_includes(lines[-1], '[[1]]') } + tmux.send_keys :X + tmux.until { |lines| assert_includes(lines[-1], '[[]]') } tmux.send_keys '?' tmux.send_keys :BSpace tmux.until { |lines| assert_equal 100, lines.match_count } tmux.until { |lines| refute_includes(lines[-1], '[[1]]') } end + def test_result_event + tmux.send_keys '(echo 0; seq 10) | fzf --bind "result:pos(2)"', :Enter + tmux.until { |lines| assert_equal 11, lines.item_count } + tmux.until { |lines| assert_includes lines, '> 1' } + tmux.send_keys '9' + tmux.until { |lines| assert_includes lines, '> 9' } + tmux.send_keys :BSpace + tmux.until { |lines| assert_includes lines, '> 1' } + end + def test_labels_center tmux.send_keys 'echo x | fzf --border --border-label foobar --preview : --preview-label barfoo --bind "space:change-border-label(foobarfoo)+change-preview-label(barfoobar),enter:transform-border-label(echo foo{}foo)+transform-preview-label(echo bar{}bar)"', :Enter tmux.until do ++++++ vendor.tar.zst ++++++ Binary files /var/tmp/diff_new_pack.qC6RY4/_old and /var/tmp/diff_new_pack.qC6RY4/_new differ