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-09-10 21:13:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fzf (Old) and /work/SRC/openSUSE:Factory/.fzf.new.17570 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fzf" Tue Sep 10 21:13:23 2024 rev:58 rq:1199735 version:0.55.0 Changes: -------- --- /work/SRC/openSUSE:Factory/fzf/fzf.changes 2024-08-01 22:05:01.401936484 +0200 +++ /work/SRC/openSUSE:Factory/.fzf.new.17570/fzf.changes 2024-09-10 21:14:43.053747880 +0200 @@ -1,0 +2,24 @@ +Mon Sep 9 19:25:13 UTC 2024 - Joshua Smith <smolsh...@opensuse.org> + +- Update to 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. + * [bash] Fuzzy path completion is enabled for all commands: + a. If the default completion is not already set + b. And if the current bash supports complete -D option + * Comments are now allowed in $FZF_DEFAULT_OPTS and + $FZF_DEFAULT_OPTS_FILE, e.g. + --info=inline-right # Show info on the right of prompt line + * Hyperlinks (OSC 8) are now supported in the preview window + and in the main window + * 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) + +------------------------------------------------------------------- Old: ---- fzf-0.54.3.tar.gz New: ---- fzf-0.55.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fzf.spec ++++++ --- /var/tmp/diff_new_pack.8oo04a/_old 2024-09-10 21:14:43.725775880 +0200 +++ /var/tmp/diff_new_pack.8oo04a/_new 2024-09-10 21:14:43.729776047 +0200 @@ -18,7 +18,7 @@ %global _lto_cflags %{nil} Name: fzf -Version: 0.54.3 +Version: 0.55.0 Release: 0 Summary: A command-line fuzzy finder License: MIT ++++++ fzf-0.54.3.tar.gz -> fzf-0.55.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/.github/workflows/linux.yml new/fzf-0.55.0/.github/workflows/linux.yml --- old/fzf-0.54.3/.github/workflows/linux.yml 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/.github/workflows/linux.yml 2024-08-29 10:10:58.000000000 +0200 @@ -36,7 +36,7 @@ run: sudo apt-get install --yes zsh fish tmux - name: Install Ruby gems - run: sudo gem install --no-document minitest:5.17.0 rubocop:1.43.0 rubocop-minitest:0.25.1 rubocop-performance:1.15.2 + run: sudo gem install --no-document minitest:5.25.1 rubocop:1.65.0 rubocop-minitest:0.35.1 rubocop-performance:1.21.1 - name: Rubocop run: rubocop --require rubocop-minitest --require rubocop-performance diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/.github/workflows/typos.yml new/fzf-0.55.0/.github/workflows/typos.yml --- old/fzf-0.54.3/.github/workflows/typos.yml 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/.github/workflows/typos.yml 2024-08-29 10:10:58.000000000 +0200 @@ -7,4 +7,4 @@ runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.23.1 + - uses: crate-ci/typos@v1.24.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/.rubocop.yml new/fzf-0.55.0/.rubocop.yml --- old/fzf-0.54.3/.rubocop.yml 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/.rubocop.yml 2024-08-29 10:10:58.000000000 +0200 @@ -6,7 +6,7 @@ Enabled: false Style/MethodCallWithArgsParentheses: Enabled: true - IgnoredMethods: + AllowedMethods: - assert - exit - paste @@ -15,7 +15,7 @@ - refute - require - send_keys - IgnoredPatterns: + AllowedPatterns: - ^assert_ - ^refute_ Style/NumericPredicate: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/CHANGELOG.md new/fzf-0.55.0/CHANGELOG.md --- old/fzf-0.54.3/CHANGELOG.md 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/CHANGELOG.md 2024-08-29 10:10:58.000000000 +0200 @@ -1,6 +1,44 @@ CHANGELOG ========= +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' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/Makefile new/fzf-0.55.0/Makefile --- old/fzf-0.54.3/Makefile 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/Makefile 2024-08-29 10:10:58.000000000 +0200 @@ -77,7 +77,6 @@ all: target/$(BINARY) test: $(SOURCES) - [ -z "$$(gofmt -s -d src)" ] || (gofmt -s -d src; exit 1) SHELL=/bin/sh GOOS= $(GO) test -v -tags "$(TAGS)" \ github.com/junegunn/fzf/src \ github.com/junegunn/fzf/src/algo \ @@ -87,6 +86,10 @@ bench: cd src && SHELL=/bin/sh GOOS= $(GO) test -v -tags "$(TAGS)" -run=Bench -bench=. -benchmem +lint: $(SOURCES) test/test_go.rb + [ -z "$$(gofmt -s -d src)" ] || (gofmt -s -d src; exit 1) + rubocop --require rubocop-minitest --require rubocop-performance + install: bin/fzf generate: @@ -184,4 +187,4 @@ $(GO) get -u $(GO) mod tidy -.PHONY: all generate build release test bench install clean docker docker-test update +.PHONY: all generate build release test bench lint install clean docker docker-test update diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/README-VIM.md new/fzf-0.55.0/README-VIM.md --- old/fzf-0.54.3/README-VIM.md 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/README-VIM.md 2024-08-29 10:10:58.000000000 +0200 @@ -289,8 +289,9 @@ | `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 | Reference to function to process each selected item | +| `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%`) | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/README.md new/fzf-0.55.0/README.md --- old/fzf-0.54.3/README.md 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/README.md 2024-08-29 10:10:58.000000000 +0200 @@ -44,7 +44,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/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="https://github.com/veebch.png" width="60px" alt="VEEB Projects" /></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/jyc"><img src="https://github.com/jyc.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://git hub.com/roblevy"><img src="https://github.com/roblevy.png" width="60px" alt="Rob Levy" /></a><a href="https://github.com/glozow"><img src="https://github.com/glozow.png" width="60px" alt="Gloria Zhao" /></a><a href="https://github.com/wjt"><img src="https://github.com/wjt.png" width="60px" alt="Will Thompson" /></a><a href="https://github.com/toupeira"><img src="https://github.com/toupeira.png" width="60px" alt="Markus Koller" /></a><a href="https://github.com/rkpatel33"><img src="https://github.com/rkpatel33.png" width="60px" alt="" /></a><a href="https://github.com/jamesob"><img src="https://github.com/jamesob.png" width="60px" alt="James O'Beirne" /></a><a href="https://github.com/jlebray"><img src="https://github.com/jlebray.png" width="60px" alt="Johan Le Bray" /></a><a href="https://github.com/panosl1"><img src="https://github.com/panosl1.png" width="60px" alt="Panos Lampropoulos" /></a><a href="https://github.com/bespinian"><img src="https://github.com/bespinian.png" width="6 0px" alt="bespinian" /></a><a href="https://github.com/xordspar0"><img src="https://github.com/xordspar0.png" width="60px" alt="Jordan Christiansen" /></a><a href="https://github.com/scosu"><img src="https://github.com/scosu.png" width="60px" alt="Markus Schneider-Pargmann" /></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/trantor"><img src="https://github.com/trantor.png" width="60px" alt="Fulvio S capin" /></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/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/jiangyinzuo"><img src="https://github.com/jiangyinzuo.png" width="60px" alt="Yinzuo Jiang" /></a><a href="https://github.com/hovissimo"><img src="https://github.com/hovissimo.png" width="60px" alt="Hovis" /></a><a href="https://g ithub.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 OLeary McCann" /></a><a href="https://github.com/rbeeger"><img sr c="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/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/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/jyc"><img src="https://github.com/jyc.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><a href="https://github.com/glozow"><img src="https://github.com/glozow.png" width="60px" alt="Gloria Zhao" /></a><a href="https://github.com/wjt"><img src="https://github.com/wjt.png" width="60px" alt="Will Thompson" /></a><a href="https://github.com/toupeira"><img src="https://github.com/toupeira.png" width="60px" alt="Markus Koller" /></a><a href="https://github.com/rkpatel33"><img src="https://github.com/rkpatel33.png" width="60px" alt="" /></a><a href="https://github.com/jamesob"><img src="https://github.com/jamesob.png" width="60px" alt="jamesob" /></a><a href="https://github.com/jlebray"><img src="https://github.com/jlebray.png" width="60px" alt="Johan Le Bray" /></a><a href="https://github.com/panosl1"><img src="https://github.com/panosl1.png" width="60px" alt= "Panos Lampropoulos" /></a><a href="https://github.com/bespinian"><img src="https://github.com/bespinian.png" width="60px" alt="bespinian" /></a><a href="https://github.com/scosu"><img src="https://github.com/scosu.png" width="60px" alt="Markus Schneider-Pargmann" /></a><a href="https://github.com/smithbm2316"><img src="https://github.com/smithbm2316.png" width="60px" alt="Ben Smith" /></a><a href="https://github.com/mywang-berk"><img src="https://github.com/mywang-berk.png" width="60px" alt="" /></a><a href="https://github.com/charlieegan3"><img src="https://github.com/charlieegan3.png" width="60px" alt="Charlie Egan" /></a><a href="https://github.com/thobbs"><img src="https://github.com/thobbs.png" width="60px" alt="Tyler Hobbs" /></a><a href="https://github.com/neilparikh"><img src="https://github.com/neilparikh.png" width="60px" alt="Neil Parikh" /></a><a href="https://github.com/gongahkia"><img src="https://github.com/gongahkia.png" width="60px" alt="Gabriel Ong" /></a><!-- spo nsors --> Table of Contents ----------------- @@ -376,15 +376,16 @@ 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` | -| `^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` | +| 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, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/bin/fzf-tmux new/fzf-0.55.0/bin/fzf-tmux --- old/fzf-0.54.3/bin/fzf-tmux 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/bin/fzf-tmux 2024-08-29 10:10:58.000000000 +0200 @@ -19,6 +19,9 @@ [[ -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] @@ -94,10 +97,18 @@ opt="$opt ${arg:0:2}$size" elif [[ "$size" =~ %$ ]]; then size=${size:0:((${#size}-1))} - if [[ -n "$swap" ]]; then - opt="$opt -l $(( 100 - size ))%" + if [[ $tmux_32 = 1 ]]; then + if [[ -n "$swap" ]]; then + opt="$opt -l $(( 100 - size ))%" + else + opt="$opt -l $size%" + fi else - opt="$opt -l $size%" + if [[ -n "$swap" ]]; then + opt="$opt -p $(( 100 - size ))" + else + opt="$opt -p $size" + fi fi else if [[ -n "$swap" ]]; then @@ -187,12 +198,11 @@ envs="export TERM=$TERM " if [[ "$opt" =~ "-E" ]]; then - tmux_version=$(tmux -V | sed 's/[^0-9.]//g') - if [[ $(awk '{print ($1 > 3.2)}' <<< "$tmux_version" 2> /dev/null || bc -l <<< "$tmux_version > 3.2") = 1 ]]; 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" - elif [[ $tmux_version = 3.2 ]]; then - FZF_DEFAULT_OPTS="--margin 0,1 $FZF_DEFAULT_OPTS" else echo "fzf-tmux: tmux 3.2 or above is required for popup mode" >&2 exit 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/doc/fzf.txt new/fzf-0.55.0/doc/fzf.txt --- old/fzf-0.54.3/doc/fzf.txt 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/doc/fzf.txt 2024-08-29 10:10:58.000000000 +0200 @@ -306,8 +306,9 @@ `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 | Reference to function to process each selected item + `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%` ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/go.mod new/fzf-0.55.0/go.mod --- old/fzf-0.54.3/go.mod 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/go.mod 2024-08-29 10:10:58.000000000 +0200 @@ -3,11 +3,11 @@ require ( github.com/charlievieth/fastwalk v1.0.8 github.com/gdamore/tcell/v2 v2.7.4 + github.com/junegunn/go-shellwords v0.0.0-20240813092932-a62c48c52e97 github.com/mattn/go-isatty v0.0.20 - github.com/mattn/go-shellwords v1.0.12 github.com/rivo/uniseg v0.4.7 - golang.org/x/sys v0.22.0 - golang.org/x/term v0.22.0 + golang.org/x/sys v0.24.0 + golang.org/x/term v0.23.0 ) require ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/go.sum new/fzf-0.55.0/go.sum --- old/fzf-0.54.3/go.sum 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/go.sum 2024-08-29 10:10:58.000000000 +0200 @@ -4,14 +4,14 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.7.4 h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU= github.com/gdamore/tcell/v2 v2.7.4/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg= +github.com/junegunn/go-shellwords v0.0.0-20240813092932-a62c48c52e97 h1:rqzLixVo1c/GQW6px9j1xQmlvQIn+lf/V6M1UQ7IFzw= +github.com/junegunn/go-shellwords v0.0.0-20240813092932-a62c48c52e97/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.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= 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= @@ -36,14 +36,14 @@ 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.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/install new/fzf-0.55.0/install --- old/fzf-0.54.3/install 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/install 2024-08-29 10:10:58.000000000 +0200 @@ -2,7 +2,7 @@ set -u -version=0.54.3 +version=0.55.0 auto_completion= key_bindings= update_config=2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/install.ps1 new/fzf-0.55.0/install.ps1 --- old/fzf-0.54.3/install.ps1 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/install.ps1 2024-08-29 10:10:58.000000000 +0200 @@ -1,4 +1,4 @@ -$version="0.54.3" +$version="0.55.0" $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/main.go new/fzf-0.55.0/main.go --- old/fzf-0.54.3/main.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/main.go 2024-08-29 10:10:58.000000000 +0200 @@ -11,7 +11,7 @@ "github.com/junegunn/fzf/src/protector" ) -var version = "0.54" +var version = "0.55" var revision = "devel" //go:embed shell/key-bindings.bash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/man/man1/fzf-tmux.1 new/fzf-0.55.0/man/man1/fzf-tmux.1 --- old/fzf-0.54.3/man/man1/fzf-tmux.1 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/man/man1/fzf-tmux.1 2024-08-29 10:10:58.000000000 +0200 @@ -21,13 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf\-tmux 1 "Jul 2024" "fzf 0.54.3" "fzf\-tmux - open fzf in tmux split pane" +.TH fzf\-tmux 1 "Aug 2024" "fzf 0.55.0" "fzf\-tmux - open fzf in tmux split pane" .SH NAME fzf\-tmux - open fzf in tmux split pane .SH SYNOPSIS -.B fzf\-tmux [LAYOUT OPTIONS] [\-\-] [FZF OPTIONS] +.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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/man/man1/fzf.1 new/fzf-0.55.0/man/man1/fzf.1 --- old/fzf-0.54.3/man/man1/fzf.1 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/man/man1/fzf.1 2024-08-29 10:10:58.000000000 +0200 @@ -21,13 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf 1 "Jul 2024" "fzf 0.54.3" "fzf - a command-line fuzzy finder" +.TH fzf 1 "Aug 2024" "fzf 0.55.0" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder .SH SYNOPSIS -fzf [options] +fzf [\fIoptions\fR] .SH DESCRIPTION fzf is an interactive filter program for any kind of list. @@ -526,7 +526,7 @@ Print header before the prompt line .TP .BI "\-\-ellipsis=" "STR" -Ellipsis to show when line is truncated (default: '..') +Ellipsis to show when line is truncated (default: '··') .SS Display .TP .B "\-\-ansi" @@ -1146,6 +1146,22 @@ anchored-match term. Then fzf will search for the lines that start with or end with the given string. An anchored-match term is also an exact-match term. +.SS Exact\-boundary\-match (quoted both ends) +A single-quoted term is interpreted as an "exact\-boundary\-match". fzf will +search for the exact occurrences of the string with both ends at the word +boundaries. Unlike in regular expressions, this also sees an underscore as +a word boundary. But the words around underscores are ranked lower and appear +later in the result than the other words around the other types of word +boundaries. + +1. xxx foo xxx (highest score) +.br +2. xxx foo_xxx +.br +3. xxx_foo xxx +.br +4. xxx_foo_xxx (lowest score) + .SS Negation If a term is prefixed by \fB!\fR, fzf will exclude the lines that satisfy the term from the result. In this case, fzf performs exact match by default. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/plugin/fzf.vim new/fzf-0.55.0/plugin/fzf.vim --- old/fzf-0.54.3/plugin/fzf.vim 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/plugin/fzf.vim 2024-08-29 10:10:58.000000000 +0200 @@ -198,6 +198,7 @@ return s:compare_versions(s:get_version(a:a), s:get_version(a:b)) endfunction +let s:min_version = '0.53.0' let s:checked = {} function! fzf#exec(...) if !exists('s:exec') @@ -225,7 +226,11 @@ let s:exec = binaries[-1] endif - if a:0 && !has_key(s:checked, a:1) + let min_version = s:min_version + if a:0 && s:compare_versions(a:1, min_version) > 0 + let min_version = a:1 + endif + if !has_key(s:checked, min_version) let fzf_version = s:get_version(s:exec) if empty(fzf_version) let message = printf('Failed to run "%s --version"', s:exec) @@ -233,17 +238,17 @@ throw message end - if s:compare_versions(fzf_version, a:1) >= 0 - let s:checked[a:1] = 1 + if s:compare_versions(fzf_version, min_version) >= 0 + let s:checked[min_version] = 1 return s:exec - elseif a:0 < 2 && input(printf('You need fzf %s or above. Found: %s. Download binary? (y/n) ', a:1, fzf_version)) =~? '^y' + elseif a:0 < 2 && input(printf('You need fzf %s or above. Found: %s. Download binary? (y/n) ', min_version, fzf_version)) =~? '^y' let s:versions = {} unlet s:exec redraw call fzf#install() - return fzf#exec(a:1, 1) + return fzf#exec(min_version, 1) else - throw printf('You need to upgrade fzf (required: %s or above)', a:1) + throw printf('You need to upgrade fzf (required: %s or above)', min_version) endif endif @@ -665,21 +670,17 @@ let s:launcher = function('s:xterm_launcher') endif -function! s:exit_handler(code, command, ...) - if a:code == 130 - return 0 - elseif has('nvim') && a:code == 129 - " When deleting the terminal buffer while fzf is still running, - " Nvim sends SIGHUP. - return 0 - elseif a:code > 1 +function! s:exit_handler(dict, code, command, ...) + if has_key(a:dict, 'exit') + call a:dict.exit(a:code) + endif + if a:code == 2 call s:error('Error running ' . a:command) if !empty(a:000) sleep endif - return 0 endif - return 1 + return a:code endfunction function! s:execute(dict, command, use_height, temps) abort @@ -731,7 +732,7 @@ let exit_status = v:shell_error redraw! let lines = s:collect(a:temps) - return s:exit_handler(exit_status, command) ? lines : [] + return s:exit_handler(a:dict, exit_status, command) < 2 ? lines : [] endfunction function! s:execute_tmux(dict, command, temps) abort @@ -746,7 +747,7 @@ let exit_status = v:shell_error redraw! let lines = s:collect(a:temps) - return s:exit_handler(exit_status, command) ? lines : [] + return s:exit_handler(a:dict, exit_status, command) < 2 ? lines : [] endfunction function! s:calc_size(max, val, dict) @@ -912,7 +913,7 @@ endif let lines = s:collect(self.temps) - if !s:exit_handler(a:code, self.command, 1) + if s:exit_handler(self.dict, a:code, self.command, 1) >= 2 return endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/shell/completion.bash new/fzf-0.55.0/shell/completion.bash --- old/fzf-0.54.3/shell/completion.bash 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/shell/completion.bash 2024-08-29 10:10:58.000000000 +0200 @@ -289,7 +289,7 @@ fi COMPREPLY=() trigger=${FZF_COMPLETION_TRIGGER-'**'} - cur="${COMP_WORDS[COMP_CWORD]}" + [[ $COMP_CWORD -ge 0 ]] && cur="${COMP_WORDS[COMP_CWORD]}" if [[ "$cur" == *"$trigger" ]] && [[ $cur != *'$('* ]] && [[ $cur != *':='* ]] && [[ $cur != *'`'* ]]; then base=${cur:0:${#cur}-${#trigger}} eval "base=$base" 2> /dev/null || return @@ -410,7 +410,8 @@ _fzf_proc_completion() { _fzf_complete -m --header-lines=1 --no-preview --wrap -- "$@" < <( command ps -eo user,pid,ppid,start,time,command 2> /dev/null || - command ps -eo user,pid,ppid,time,args # For BusyBox + command ps -eo user,pid,ppid,time,args 2> /dev/null || # For BusyBox + command ps --everyone --full --windows # For cygwin ) } @@ -480,10 +481,36 @@ # fzf-tmux specific options (like `-w WIDTH`) are left as a future patch. complete -o default -F _fzf_opts_completion fzf-tmux +# Default path completion +__fzf_default_completion() { + __fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@" + + # Dynamic completion loader has updated the completion for the command + if [[ $? -eq 124 ]]; then + # We trigger _fzf_setup_completion so that fuzzy completion for the command + # still works. However, loader can update the completion for multiple + # commands at once, and fuzzy completion will no longer work for those + # other commands. e.g. pytest -> py.test, pytest-2, pytest-3, etc + _fzf_setup_completion path "$1" + return 124 + fi +} + +# Set fuzzy path completion as the default completion for all commands. +# We can't set up default completion, +# 1. if it's already set up by another script +# 2. or if the current version of bash doesn't support -D option +complete | command grep -q __fzf_default_completion || + complete | command grep -- '-D$' | command grep -qv _comp_complete_load || + complete -D -F __fzf_default_completion -o default -o bashdefault 2> /dev/null + d_cmds="${FZF_COMPLETION_DIR_COMMANDS-cd pushd rmdir}" # NOTE: $FZF_COMPLETION_PATH_COMMANDS and $FZF_COMPLETION_VAR_COMMANDS are # undocumented and subject to change in the future. +# +# NOTE: Although we have default completion, we still need to set up completion +# for each command in case they already have completion set up by another script. a_cmds="${FZF_COMPLETION_PATH_COMMANDS-" awk bat cat code diff diff3 emacs emacsclient ex file ftp g++ gcc gvim head hg hx java diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/shell/completion.zsh new/fzf-0.55.0/shell/completion.zsh --- old/fzf-0.54.3/shell/completion.zsh 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/shell/completion.zsh 2024-08-29 10:10:58.000000000 +0200 @@ -300,7 +300,8 @@ _fzf_complete_kill() { _fzf_complete -m --header-lines=1 --no-preview --wrap -- "$@" < <( command ps -eo user,pid,ppid,start,time,command 2> /dev/null || - command ps -eo user,pid,ppid,time,args # For BusyBox + command ps -eo user,pid,ppid,time,args 2> /dev/null || # For BusyBox + command ps --everyone --full --windows # For cygwin ) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/algo/algo.go new/fzf-0.55.0/src/algo/algo.go --- old/fzf-0.54.3/src/algo/algo.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/algo/algo.go 2024-08-29 10:10:58.000000000 +0200 @@ -798,6 +798,14 @@ // The solution is much cheaper since there is only one possible alignment of // the pattern. func ExactMatchNaive(caseSensitive bool, normalize bool, forward bool, text *util.Chars, pattern []rune, withPos bool, slab *util.Slab) (Result, *[]int) { + return exactMatchNaive(caseSensitive, normalize, forward, false, text, pattern, withPos, slab) +} + +func ExactMatchBoundary(caseSensitive bool, normalize bool, forward bool, text *util.Chars, pattern []rune, withPos bool, slab *util.Slab) (Result, *[]int) { + return exactMatchNaive(caseSensitive, normalize, forward, true, text, pattern, withPos, slab) +} + +func exactMatchNaive(caseSensitive bool, normalize bool, forward bool, boundaryCheck bool, text *util.Chars, pattern []rune, withPos bool, slab *util.Slab) (Result, *[]int) { if len(pattern) == 0 { return Result{0, 0, 0}, nil } @@ -832,10 +840,22 @@ } pidx_ := indexAt(pidx, lenPattern, forward) pchar := pattern[pidx_] - if pchar == char { + ok := pchar == char + if ok { if pidx_ == 0 { bonus = bonusAt(text, index_) } + if boundaryCheck { + ok = bonus >= bonusBoundary + if ok && pidx_ == 0 { + ok = index_ == 0 || charClassOf(text.Get(index_-1)) <= charDelimiter + } + if ok && pidx_ == len(pattern)-1 { + ok = index_ == lenRunes-1 || charClassOf(text.Get(index_+1)) <= charDelimiter + } + } + } + if ok { pidx++ if pidx == lenPattern { if bonus > bestBonus { @@ -861,7 +881,23 @@ sidx = lenRunes - (bestPos + 1) eidx = lenRunes - (bestPos - lenPattern + 1) } - score, _ := calculateScore(caseSensitive, normalize, text, pattern, sidx, eidx, false) + var score int + if boundaryCheck { + // Underscore boundaries should be ranked lower than the other types of boundaries + score = int(bonus) + deduct := int(bonus-bonusBoundary) + 1 + if sidx > 0 && text.Get(sidx-1) == '_' { + score -= deduct + 1 + deduct = 1 + } + if eidx < lenRunes && text.Get(eidx) == '_' { + score -= deduct + } + // Add base score so that this can compete with other match types e.g. 'foo' | bar + score += scoreMatch*lenPattern + int(bonusBoundaryWhite)*(lenPattern+1) + } else { + score, _ = calculateScore(caseSensitive, normalize, text, pattern, sidx, eidx, false) + } return Result{sidx, eidx, score}, nil } return Result{-1, -1, 0}, nil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/ansi.go new/fzf-0.55.0/src/ansi.go --- old/fzf-0.54.3/src/ansi.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/ansi.go 2024-08-29 10:10:58.000000000 +0200 @@ -1,6 +1,7 @@ package fzf import ( + "fmt" "strconv" "strings" "unicode/utf8" @@ -13,22 +14,28 @@ color ansiState } +type url struct { + uri string + params string +} + type ansiState struct { fg tui.Color bg tui.Color attr tui.Attr lbg tui.Color + url *url } func (s *ansiState) colored() bool { - return s.fg != -1 || s.bg != -1 || s.attr > 0 || s.lbg >= 0 + return s.fg != -1 || s.bg != -1 || s.attr > 0 || s.lbg >= 0 || s.url != nil } func (s *ansiState) equals(t *ansiState) bool { if t == nil { return !s.colored() } - return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr && s.lbg == t.lbg + return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr && s.lbg == t.lbg && s.url == t.url } func (s *ansiState) ToString() string { @@ -60,7 +67,11 @@ } ret += toAnsiString(s.fg, 30) + toAnsiString(s.bg, 40) - return "\x1b[" + strings.TrimSuffix(ret, ";") + "m" + ret = "\x1b[" + strings.TrimSuffix(ret, ";") + "m" + if s.url != nil { + ret = fmt.Sprintf("\x1b]8;%s;%s\x1b\\%s\x1b]8;;\x1b", s.url.params, s.url.uri, ret) + } + return ret } func toAnsiString(color tui.Color, offset int) string { @@ -98,10 +109,19 @@ if s[i] == '\x07' { return i + 1 } + // `\x1b]8;PARAMS;URI\x1b\\TITLE\x1b]8;;\x1b` + // ------ if s[i] == '\x1b' && i < len(s)-1 && s[i+1] == '\\' { return i + 2 } } + + // `\x1b]8;PARAMS;URI\x1b\\TITLE\x1b]8;;\x1b` + // ------------ + if i < len(s) && s[:i+1] == "\x1b]8;;\x1b" { + return i + 1 + } + return -1 } @@ -328,13 +348,21 @@ func interpretCode(ansiCode string, prevState *ansiState) ansiState { var state ansiState if prevState == nil { - state = ansiState{-1, -1, 0, -1} + state = ansiState{-1, -1, 0, -1, nil} } else { - state = ansiState{prevState.fg, prevState.bg, prevState.attr, prevState.lbg} + state = ansiState{prevState.fg, prevState.bg, prevState.attr, prevState.lbg, prevState.url} } if ansiCode[0] != '\x1b' || ansiCode[1] != '[' || ansiCode[len(ansiCode)-1] != 'm' { if prevState != nil && strings.HasSuffix(ansiCode, "0K") { state.lbg = prevState.bg + } else if ansiCode == "\x1b]8;;\x1b\\" { // End of a hyperlink + state.url = nil + } else if strings.HasPrefix(ansiCode, "\x1b]8;") && strings.HasSuffix(ansiCode, "\x1b\\") { + if paramsEnd := strings.IndexRune(ansiCode[4:], ';'); paramsEnd >= 0 { + params := ansiCode[4 : 4+paramsEnd] + uri := ansiCode[5+paramsEnd : len(ansiCode)-2] + state.url = &url{uri: uri, params: params} + } } return state } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/options.go new/fzf-0.55.0/src/options.go --- old/fzf-0.54.3/src/options.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/options.go 2024-08-29 10:10:58.000000000 +0200 @@ -12,7 +12,7 @@ "github.com/junegunn/fzf/src/algo" "github.com/junegunn/fzf/src/tui" - "github.com/mattn/go-shellwords" + "github.com/junegunn/go-shellwords" "github.com/rivo/uniseg" ) @@ -103,7 +103,7 @@ --header=STR String to print as header --header-lines=N The first N lines of the input are treated as header --header-first Print header before the prompt line - --ellipsis=STR Ellipsis to show when line is truncated (default: '..') + --ellipsis=STR Ellipsis to show when line is truncated (default: '··') Display --ansi Enable processing of ANSI color codes @@ -472,7 +472,7 @@ Header []string HeaderLines int HeaderFirst bool - Ellipsis string + Ellipsis *string Scrollbar *string Margin [4]sizeSpec Padding [4]sizeSpec @@ -578,7 +578,7 @@ Header: make([]string, 0), HeaderLines: 0, HeaderFirst: false, - Ellipsis: "..", + Ellipsis: nil, Scrollbar: nil, Margin: defaultMargin(), Padding: defaultMargin(), @@ -2339,9 +2339,12 @@ case "--no-header-first": opts.HeaderFirst = false case "--ellipsis": - if opts.Ellipsis, err = nextString(allArgs, &i, "ellipsis string required"); err != nil { + str, err := nextString(allArgs, &i, "ellipsis string required") + if err != nil { return err } + str = firstLine(str) + opts.Ellipsis = &str case "--preview": if opts.Preview.command, err = nextString(allArgs, &i, "preview command required"); err != nil { return err @@ -2623,7 +2626,8 @@ return err } } else if match, value := optString(arg, "--ellipsis="); match { - opts.Ellipsis = value + str := firstLine(value) + opts.Ellipsis = &str } else if match, value := optString(arg, "--preview="); match { opts.Preview.command = value } else if match, value := optString(arg, "--preview-window="); match { @@ -2915,6 +2919,12 @@ return processScheme(opts) } +func parseShellWords(str string) ([]string, error) { + parser := shellwords.NewParser() + parser.ParseComment = true + return parser.Parse(str) +} + // ParseOptions parses command-line options func ParseOptions(useDefaults bool, args []string) (*Options, error) { opts := defaultOptions() @@ -2928,7 +2938,7 @@ return nil, errors.New("$FZF_DEFAULT_OPTS_FILE: " + err.Error()) } - words, parseErr := shellwords.Parse(string(bytes)) + words, parseErr := parseShellWords(string(bytes)) if parseErr != nil { return nil, errors.New(path + ": " + parseErr.Error()) } @@ -2940,7 +2950,7 @@ } // 2. Options from $FZF_DEFAULT_OPTS string - words, parseErr := shellwords.Parse(os.Getenv("FZF_DEFAULT_OPTS")) + words, parseErr := parseShellWords(os.Getenv("FZF_DEFAULT_OPTS")) if parseErr != nil { return nil, errors.New("$FZF_DEFAULT_OPTS: " + parseErr.Error()) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/pattern.go new/fzf-0.55.0/src/pattern.go --- old/fzf-0.54.3/src/pattern.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/pattern.go 2024-08-29 10:10:58.000000000 +0200 @@ -23,6 +23,7 @@ const ( termFuzzy termType = iota termExact + termExactBoundary termPrefix termSuffix termEqual @@ -147,6 +148,7 @@ ptr.procFun[termFuzzy] = fuzzyAlgo ptr.procFun[termEqual] = algo.EqualMatch ptr.procFun[termExact] = algo.ExactMatchNaive + ptr.procFun[termExactBoundary] = algo.ExactMatchBoundary ptr.procFun[termPrefix] = algo.PrefixMatch ptr.procFun[termSuffix] = algo.SuffixMatch @@ -193,7 +195,10 @@ text = text[:len(text)-1] } - if strings.HasPrefix(text, "'") { + if len(text) > 2 && strings.HasPrefix(text, "'") && strings.HasSuffix(text, "'") { + typ = termExactBoundary + text = text[1 : len(text)-1] + } else if strings.HasPrefix(text, "'") { // Flip exactness if fuzzy && !inv { typ = termExact diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/result.go new/fzf-0.55.0/src/result.go --- old/fzf-0.54.3/src/result.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/result.go 2024-08-29 10:10:58.000000000 +0200 @@ -16,6 +16,7 @@ offset [2]int32 color tui.ColorPair match bool + url *url } type Result struct { @@ -177,8 +178,11 @@ if curr != 0 && idx > start { if curr < 0 { color := colMatch + var url *url if curr < -1 && theme.Colored { - origColor := ansiToColorPair(itemColors[-curr-2], colMatch) + ansi := itemColors[-curr-2] + url = ansi.color.url + origColor := ansiToColorPair(ansi, colMatch) // hl or hl+ only sets the foreground color, so colMatch is the // combination of either [hl and bg] or [hl+ and bg+]. // @@ -194,13 +198,14 @@ } } colors = append(colors, colorOffset{ - offset: [2]int32{int32(start), int32(idx)}, color: color, match: true}) + offset: [2]int32{int32(start), int32(idx)}, color: color, match: true, url: url}) } else { ansi := itemColors[curr-1] colors = append(colors, colorOffset{ offset: [2]int32{int32(start), int32(idx)}, color: ansiToColorPair(ansi, colBase), - match: false}) + match: false, + url: ansi.color.url}) } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/result_test.go new/fzf-0.55.0/src/result_test.go --- old/fzf-0.54.3/src/result_test.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/result_test.go 2024-08-29 10:10:58.000000000 +0200 @@ -124,10 +124,10 @@ item := Result{ item: &Item{ colors: &[]ansiOffset{ - {[2]int32{0, 20}, ansiState{1, 5, 0, -1}}, - {[2]int32{22, 27}, ansiState{2, 6, tui.Bold, -1}}, - {[2]int32{30, 32}, ansiState{3, 7, 0, -1}}, - {[2]int32{33, 40}, ansiState{4, 8, tui.Bold, -1}}}}} + {[2]int32{0, 20}, ansiState{1, 5, 0, -1, nil}}, + {[2]int32{22, 27}, ansiState{2, 6, tui.Bold, -1, nil}}, + {[2]int32{30, 32}, ansiState{3, 7, 0, -1, nil}}, + {[2]int32{33, 40}, ansiState{4, 8, tui.Bold, -1, nil}}}}} colBase := tui.NewColorPair(89, 189, tui.AttrUndefined) colMatch := tui.NewColorPair(99, 199, tui.AttrUndefined) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/terminal.go new/fzf-0.55.0/src/terminal.go --- old/fzf-0.54.3/src/terminal.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/terminal.go 2024-08-29 10:10:58.000000000 +0200 @@ -382,6 +382,7 @@ reqRedrawPreviewLabel reqClose reqPrintQuery + reqPreviewReady reqPreviewEnqueue reqPreviewDisplay reqPreviewRefresh @@ -826,7 +827,6 @@ headerLines: opts.HeaderLines, header: []string{}, header0: opts.Header, - ellipsis: opts.Ellipsis, ansi: opts.Ansi, tabstop: opts.Tabstop, hasStartActions: false, @@ -854,7 +854,6 @@ mutex: sync.Mutex{}, uiMutex: sync.Mutex{}, suppress: true, - sigstop: false, slab: util.MakeSlab(slab16Size, slab32Size), theme: opts.Theme, startChan: make(chan fitpad, 1), @@ -883,6 +882,15 @@ } t.separator, t.separatorLen = t.ansiLabelPrinter(bar, &tui.ColSeparator, true) } + + if opts.Ellipsis != nil { + t.ellipsis = *opts.Ellipsis + } else if t.unicode { + t.ellipsis = "··" + } else { + t.ellipsis = ".." + } + if t.unicode { t.wrapSign = "â³ " t.borderWidth = uniseg.StringWidth("â") @@ -1067,7 +1075,7 @@ // // unless the part has a non-default ANSI state loc := whiteSuffix.FindStringIndex(trimmed) if loc != nil { - blankState := ansiOffset{[2]int32{int32(loc[0]), int32(loc[1])}, ansiState{-1, -1, tui.AttrClear, -1}} + blankState := ansiOffset{[2]int32{int32(loc[0]), int32(loc[1])}, ansiState{-1, -1, tui.AttrClear, -1, nil}} if item.colors != nil { lastColor := (*item.colors)[len(*item.colors)-1] if lastColor.offset[1] < int32(loc[1]) { @@ -2459,15 +2467,24 @@ var substr string var prefixWidth int maxOffset := int32(len(text)) + var url *url for _, offset := range offsets { b := util.Constrain32(offset.offset[0], index, maxOffset) e := util.Constrain32(offset.offset[1], index, maxOffset) + if url != nil && offset.url == nil { + url = nil + window.LinkEnd() + } substr, prefixWidth = t.processTabs(text[index:b], prefixWidth) window.CPrint(colBase, substr) if b < e { substr, prefixWidth = t.processTabs(text[b:e], prefixWidth) + if url == nil && offset.url != nil { + url = offset.url + window.LinkBegin(url.uri, url.params) + } window.CPrint(offset.color, substr) } @@ -2476,6 +2493,9 @@ break } } + if url != nil { + window.LinkEnd() + } if index < maxOffset { substr, _ = t.processTabs(text[index:], prefixWidth) window.CPrint(colBase, substr) @@ -2667,12 +2687,21 @@ var fillRet tui.FillReturn prefixWidth := 0 + var url *url _, _, ansi = extractColor(line, ansi, func(str string, ansi *ansiState) bool { trimmed := []rune(str) isTrimmed := false if !t.previewOpts.wrap { trimmed, isTrimmed = t.trimRight(trimmed, maxWidth-t.pwindow.X()) } + if url == nil && ansi != nil && ansi.url != nil { + url = ansi.url + t.pwindow.LinkBegin(url.uri, url.params) + } + if url != nil && (ansi == nil || ansi.url == nil) { + url = nil + t.pwindow.LinkEnd() + } str, width := t.processTabs(trimmed, prefixWidth) if width > prefixWidth { prefixWidth = width @@ -2686,6 +2715,9 @@ return !isTrimmed && (fillRet == tui.FillContinue || t.previewOpts.wrap && fillRet == tui.FillNextLine) }) + if url != nil { + t.pwindow.LinkEnd() + } t.previewer.scrollable = t.previewer.scrollable || t.pwindow.Y() == height-1 && t.pwindow.X() == t.pwindow.Width() if fillRet == tui.FillNextLine { continue @@ -2697,10 +2729,14 @@ break } if lbg >= 0 { - t.pwindow.CFill(-1, lbg, tui.AttrRegular, + fillRet = t.pwindow.CFill(-1, lbg, tui.AttrRegular, strings.Repeat(" ", t.pwindow.Width()-t.pwindow.X())+"\n") } else { - t.pwindow.Fill("\n") + fillRet = t.pwindow.Fill("\n") + } + if fillRet == tui.FillSuspend { + t.previewed.filled = true + break } } lineNo++ @@ -3400,19 +3436,6 @@ } }() - contChan := make(chan os.Signal, 1) - notifyOnCont(contChan) - go func() { - for { - select { - case <-ctx.Done(): - return - case <-contChan: - t.reqBox.Set(reqReinit, nil) - } - } - }() - if !t.tui.ShouldEmitResizeEvent() { resizeChan := make(chan os.Signal, 1) notifyOnResize(resizeChan) // Non-portable @@ -3469,6 +3492,7 @@ go func() { var version int64 stop := false + t.previewBox.WaitFor(reqPreviewReady) for { var items []*Item var commandTemplate string @@ -3497,6 +3521,9 @@ if stop { break } + if items == nil { + continue + } version++ // We don't display preview window if no match if items[0] != nil { @@ -3738,12 +3765,15 @@ t.printHeader() case reqActivate: t.suppress = false + if t.hasPreviewer() { + t.previewBox.Set(reqPreviewReady, nil) + } case reqRedrawBorderLabel: t.printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape, true) case reqRedrawPreviewLabel: t.printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.previewOpts.border, true) case reqReinit: - t.tui.Resume(t.fullscreen, t.sigstop) + t.tui.Resume(t.fullscreen, true) t.fullRedraw() case reqResize, reqFullRedraw: if req == reqResize { @@ -4483,11 +4513,11 @@ case actSigStop: p, err := os.FindProcess(os.Getpid()) if err == nil { - t.sigstop = true t.tui.Clear() t.tui.Pause(t.fullscreen) notifyStop(p) t.mutex.Unlock() + t.reqBox.Set(reqReinit, nil) return false } case actMouse: @@ -4850,11 +4880,18 @@ linesSum := 0 add := func(i int) bool { - lines, _ := t.numItemLines(t.merger.Get(i).item, numItems-linesSum) + lines, overflow := t.numItemLines(t.merger.Get(i).item, numItems-linesSum) linesSum += lines if linesSum >= numItems { - if numItemsFound == 0 { - numItemsFound = 1 + /* + # Should show all 3 items + printf "file1\0file2\0file3\0" | fzf --height=5 --read0 --bind load:last --reverse + + # Should not truncate the last item + printf "file\n1\0file\n2\0file\n3\0" | fzf --height=5 --read0 --bind load:last --reverse + */ + if numItemsFound == 0 || !overflow { + numItemsFound++ } return false } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/terminal_unix.go new/fzf-0.55.0/src/terminal_unix.go --- old/fzf-0.54.3/src/terminal_unix.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/terminal_unix.go 2024-08-29 10:10:58.000000000 +0200 @@ -20,9 +20,5 @@ if err == nil { pid = pgid * -1 } - unix.Kill(pid, syscall.SIGSTOP) -} - -func notifyOnCont(resizeChan chan<- os.Signal) { - signal.Notify(resizeChan, syscall.SIGCONT) + unix.Kill(pid, syscall.SIGTSTP) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/terminal_windows.go new/fzf-0.55.0/src/terminal_windows.go --- old/fzf-0.54.3/src/terminal_windows.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/terminal_windows.go 2024-08-29 10:10:58.000000000 +0200 @@ -13,7 +13,3 @@ func notifyStop(p *os.Process) { // NOOP } - -func notifyOnCont(resizeChan chan<- os.Signal) { - // NOOP -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/tmux.go new/fzf-0.55.0/src/tmux.go --- old/fzf-0.54.3/src/tmux.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/tmux.go 2024-08-29 10:10:58.000000000 +0200 @@ -38,7 +38,7 @@ case posUp: tmuxArgs = append(tmuxArgs, "-xC", "-y0") case posDown: - tmuxArgs = append(tmuxArgs, "-xC", "-yS") + tmuxArgs = append(tmuxArgs, "-xC", "-y9999") case posLeft: tmuxArgs = append(tmuxArgs, "-x0", "-yC") case posRight: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/tui/light.go new/fzf-0.55.0/src/tui/light.go --- old/fzf-0.54.3/src/tui/light.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/tui/light.go 2024-08-29 10:10:58.000000000 +0200 @@ -1030,13 +1030,13 @@ func (w *LightWindow) CPrint(pair ColorPair, text string) { _, code := w.csiColor(pair.Fg(), pair.Bg(), pair.Attr()) w.stderrInternal(cleanse(text), false, code) - w.csi("m") + w.csi("0m") } func (w *LightWindow) cprint2(fg Color, bg Color, attr Attr, text string) { hasColors, code := w.csiColor(fg, bg, attr) if hasColors { - defer w.csi("m") + defer w.csi("0m") } w.stderrInternal(cleanse(text), false, code) } @@ -1118,6 +1118,14 @@ return "\x1b[m" } +func (w *LightWindow) LinkBegin(uri string, params string) { + w.renderer.queued.WriteString("\x1b]8;" + params + ";" + uri + "\x1b\\") +} + +func (w *LightWindow) LinkEnd() { + w.renderer.queued.WriteString("\x1b]8;;\x1b\\") +} + func (w *LightWindow) Fill(text string) FillReturn { w.Move(w.posy, w.posx) code := w.setBg() @@ -1133,7 +1141,7 @@ bg = w.bg } if hasColors, resetCode := w.csiColor(fg, bg, attr); hasColors { - defer w.csi("m") + defer w.csi("0m") return w.fill(text, resetCode) } return w.fill(text, w.setBg()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/tui/tcell.go new/fzf-0.55.0/src/tui/tcell.go --- old/fzf-0.54.3/src/tui/tcell.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/tui/tcell.go 2024-08-29 10:10:58.000000000 +0200 @@ -4,6 +4,7 @@ import ( "os" + "regexp" "time" "github.com/gdamore/tcell/v2" @@ -49,6 +50,8 @@ lastY int moveCursor bool borderStyle BorderStyle + uri *string + params *string } func (w *TcellWindow) Top() int { @@ -601,6 +604,16 @@ w.printString(text, w.normal) } +func (w *TcellWindow) withUrl(style tcell.Style) tcell.Style { + if w.uri != nil { + style = style.Url(*w.uri) + if md := regexp.MustCompile(`id=([^:]+)`).FindStringSubmatch(*w.params); len(md) > 1 { + style = style.UrlId(md[1]) + } + } + return style +} + func (w *TcellWindow) printString(text string, pair ColorPair) { lx := 0 a := pair.Attr() @@ -615,6 +628,7 @@ Blink(a&Attr(tcell.AttrBlink) != 0). Dim(a&Attr(tcell.AttrDim) != 0) } + style = w.withUrl(style) gr := uniseg.NewGraphemes(text) for gr.Next() { @@ -665,6 +679,7 @@ Underline(a&Attr(tcell.AttrUnderline) != 0). StrikeThrough(a&Attr(tcell.AttrStrikeThrough) != 0). Italic(a&Attr(tcell.AttrItalic) != 0) + style = w.withUrl(style) gr := uniseg.NewGraphemes(text) Loop: @@ -716,6 +731,16 @@ return w.fillString(str, w.normal) } +func (w *TcellWindow) LinkBegin(uri string, params string) { + w.uri = &uri + w.params = ¶ms +} + +func (w *TcellWindow) LinkEnd() { + w.uri = nil + w.params = nil +} + func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) FillReturn { if fg == colDefault { fg = w.normal.Fg() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/src/tui/tui.go new/fzf-0.55.0/src/tui/tui.go --- old/fzf-0.54.3/src/tui/tui.go 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/src/tui/tui.go 2024-08-29 10:10:58.000000000 +0200 @@ -564,6 +564,8 @@ CPrint(color ColorPair, text string) Fill(text string) FillReturn CFill(fg Color, bg Color, attr Attr, text string) FillReturn + LinkBegin(uri string, params string) + LinkEnd() Erase() EraseMaybe() bool } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fzf-0.54.3/test/test_go.rb new/fzf-0.55.0/test/test_go.rb --- old/fzf-0.54.3/test/test_go.rb 2024-07-31 14:51:54.000000000 +0200 +++ new/fzf-0.55.0/test/test_go.rb 2024-08-29 10:10:58.000000000 +0200 @@ -1443,7 +1443,7 @@ [0, 3, 6].each do |off| tmux.prepare tmux.send_keys "#{FZF} --hscroll-off=#{off} -q 0 < #{tempname}", :Enter - tmux.until { |lines| assert lines[-3]&.end_with?((0..off).to_a.join + '..') } + tmux.until { |lines| assert lines[-3]&.end_with?((0..off).to_a.join + '··') } tmux.send_keys '9' tmux.until { |lines| assert lines[-3]&.end_with?('789') } tmux.send_keys :Enter @@ -3366,6 +3366,18 @@ tmux.send_keys :Space tmux.until { |lines| assert_includes lines[-3], 'bar' } end + + def test_boundary_match + # Underscore boundaries should be ranked lower + { + default: [' x '] + %w[/x/ [x] -x- -x_ _x- _x_], + path: ['/x/', ' x '] + %w[[x] -x- -x_ _x- _x_], + history: ['[x]', '-x-', ' x '] + %w[/x/ -x_ _x- _x_] + }.each do |scheme, expected| + result = `printf -- 'xxx\n-xx\nxx-\n_x_\n_x-\n-x_\n[x]\n-x-\n x \n/x/\n' | #{FZF} -f"'x'" --scheme=#{scheme}`.lines(chomp: true) + assert_equal expected, result + end + end end module TestShell ++++++ vendor.tar.zst ++++++ ++++ 2414 lines of diff (skipped)