Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fzf for openSUSE:Factory checked in 
at 2025-03-18 17:41:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fzf (Old)
 and      /work/SRC/openSUSE:Factory/.fzf.new.19136 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fzf"

Tue Mar 18 17:41:51 2025 rev:66 rq:1253955 version:0.60.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/fzf/fzf.changes  2025-02-16 22:49:49.103277422 
+0100
+++ /work/SRC/openSUSE:Factory/.fzf.new.19136/fzf.changes       2025-03-18 
17:43:52.712012621 +0100
@@ -1,0 +2,23 @@
+Mon Mar 17 21:55:35 UTC 2025 - Avindra Goolcharan <avin...@opensuse.org>
+
+- Update to 0.60.3:
+  * [fish] Enable multiple history commands insertion (#4280) (@bitraid)
+  * [walker] Append '/' to directory entries on MSYS2 (#4281)
+  * Trim trailing whitespaces after processing ANSI sequences (#4282)
+  * Remove temp files before `become` when using `--tmux` option (#4283)
+  * Fix condition for using item numlines cache (#4285)
+  * Make `--accept-nth` compatible with `--select-1` (#4287)
+  * Increase the query length limit from 300 to 1000 (#4292)
+  * [windows] Prevent fzf from consuming user input while paused (#4260)
+- Updates from 0.60.2:
+  * Template for `--with-nth` and `--accept-nth` now supports `{n }`
+    which evaluates to the zero-based ordinal index of the item
+  * Fixed a regression that caused the last field in the "nth"
+    expression to be trimmed when a regular expression delimiter is used
+  * Fixed 'jump' action when the pointer is an empty string
+- Updates from 0.60.1:
+  * Built-in walker now prints directory entries with a trailing slash
+  * Fixed a bug causing unexpected behavior with [fzf-tab](https
+    ://github.com/Aloxaf/fzf-tab). Please upgrade if you use it.
+
+-------------------------------------------------------------------

Old:
----
  fzf-0.60.0.tar.gz

New:
----
  fzf-0.60.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fzf.spec ++++++
--- /var/tmp/diff_new_pack.7j66Nv/_old  2025-03-18 17:43:53.208033433 +0100
+++ /var/tmp/diff_new_pack.7j66Nv/_new  2025-03-18 17:43:53.212033601 +0100
@@ -18,7 +18,7 @@
 
 %global _lto_cflags %{nil}
 Name:           fzf
-Version:        0.60.0
+Version:        0.60.3
 Release:        0
 Summary:        A command-line fuzzy finder
 License:        MIT

++++++ fzf-0.60.0.tar.gz -> fzf-0.60.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/CHANGELOG.md new/fzf-0.60.3/CHANGELOG.md
--- old/fzf-0.60.0/CHANGELOG.md 2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/CHANGELOG.md 2025-03-03 09:10:49.000000000 +0100
@@ -1,6 +1,32 @@
 CHANGELOG
 =========
 
+0.60.3
+------
+- Bug fixes and improvements
+    - [fish] Enable multiple history commands insertion (#4280) (@bitraid)
+    - [walker] Append '/' to directory entries on MSYS2 (#4281)
+    - Trim trailing whitespaces after processing ANSI sequences (#4282)
+    - Remove temp files before `become` when using `--tmux` option (#4283)
+    - Fix condition for using item numlines cache (#4285) (@alex-huff)
+    - Make `--accept-nth` compatible with `--select-1` (#4287)
+    - Increase the query length limit from 300 to 1000 (#4292)
+    - [windows] Prevent fzf from consuming user input while paused (#4260)
+
+0.60.2
+------
+- Template for `--with-nth` and `--accept-nth` now supports `{n}` which 
evaluates to the zero-based ordinal index of the item
+- Fixed a regression that caused the last field in the "nth" expression to be 
trimmed when a regular expression delimiter is used
+    - Thanks to @phanen for the fix
+- Fixed 'jump' action when the pointer is an empty string
+
+0.60.1
+------
+- Bug fixes and minor improvements
+    - Built-in walker now prints directory entries with a trailing slash
+    - Fixed a bug causing unexpected behavior with 
[fzf-tab](https://github.com/Aloxaf/fzf-tab). Please upgrade if you use it.
+- Thanks to @alexeisersun, @bitraid, @Lompik, and @fsc0 for the contributions
+
 0.60.0
 ------
 _Release highlights: https://junegunn.github.io/fzf/releases/0.60.0/_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/README.md new/fzf-0.60.3/README.md
--- old/fzf-0.60.0/README.md    2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/README.md    2025-03-03 09:10:49.000000000 +0100
@@ -7,7 +7,7 @@
    </a>
 
 ### [Warp, the intelligent terminal for 
developers](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=fzf)
-[Available for MacOS and 
Linux](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=fzf)<br>
+[Available for MacOS, Linux, & 
Windows](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=fzf)<br>
 
 </div>
 <hr>
@@ -39,7 +39,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:&#x2F;&#x2F;github.com&#x2F;miyanokomiya.png" width="60px" alt="User 
avatar: miyanokomiya" /></a><a href="https://github.com/jonhoo";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jonhoo.png" width="60px" alt="User 
avatar: Jon Gjengset" /></a><a href="https://github.com/AceofSpades5757";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;AceofSpades5757.png" width="60px" 
alt="User avatar: Kyle L. Davis" /></a><a 
href="https://github.com/Frederick888";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;Frederick888.png" width="60px" alt="User 
avatar: Frederick Zhang" /></a><a href="https://github.com/moritzdietz";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;moritzdietz.png" width="60px" alt="User 
avatar: Moritz Dietz" /></a><a href="https://github.com/mikker";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;mikker.png" width="60px" alt="User 
avatar: Mikkel Malmberg" /></a><a href="https://github.com/pldubouilh";><img 
src="https:&#x2F;&
 #x2F;github.com&#x2F;pldubouilh.png" width="60px" alt="User avatar: Pierre 
Dubouilh" /></a><a href="https://github.com/trantor";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;trantor.png" width="60px" alt="User 
avatar: Fulvio Scapin" /></a><a href="https://github.com/rcorre";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rcorre.png" width="60px" alt="User 
avatar: Ryan Roden-Corrent" /></a><a href="https://github.com/blissdev";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;blissdev.png" width="60px" alt="User 
avatar: Jordan Arentsen" /></a><a href="https://github.com/aexvir";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;aexvir.png" width="60px" alt="User 
avatar: Alex Viscreanu" /></a><a href="https://github.com/dbalatero";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;dbalatero.png" width="60px" alt="User 
avatar: David Balatero" /></a><a href="https://github.com/moobar";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;moobar.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/benela
 n"><img src="https:&#x2F;&#x2F;github.com&#x2F;benelan.png" width="60px" 
alt="User avatar: Ben Elan" /></a><a href="https://github.com/pawelduda";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;pawelduda.png" width="60px" alt="User 
avatar: Paweł Duda" /></a><a href="https://github.com/pbwn";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;pbwn.png" width="60px" alt="User avatar: 
" /></a><a href="https://github.com/pyrho";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;pyrho.png" width="60px" alt="User 
avatar: Damien Rajon" /></a><a href="https://github.com/ArtBIT";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;ArtBIT.png" width="60px" alt="User 
avatar: ArtBIT" /></a><a href="https://github.com/da-moon";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;da-moon.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/hovissimo";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;hovissimo.png" width="60px" alt="User 
avatar: Hovis" /></a><a href="https://github.com/dariusjonda";><img 
src="https:&#x2F
 ;&#x2F;github.com&#x2F;dariusjonda.png" width="60px" alt="User avatar: Darius 
Jonda" /></a><a href="https://github.com/cristiand391";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;cristiand391.png" width="60px" alt="User 
avatar: Cristian Dominguez" /></a><a href="https://github.com/eliangcs";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;eliangcs.png" width="60px" alt="User 
avatar: Chang-Hung Liang" /></a><a href="https://github.com/asphaltbuffet";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;asphaltbuffet.png" width="60px" 
alt="User avatar: Ben Lechlitner" /></a><a 
href="https://github.com/looshch";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;looshch.png" width="60px" alt="User 
avatar: george looshch" /></a><a href="https://github.com/kg8m";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;kg8m.png" width="60px" alt="User avatar: 
Takumi KAGIYAMA" /></a><a href="https://github.com/polm";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;polm.png" width="60px" alt="User avatar: 
Paul OLeary McCann" /></a><
 a href="https://github.com/rbeeger";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rbeeger.png" width="60px" alt="User 
avatar: Robert Beeger" /></a><a href="https://github.com/yowayb";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;yowayb.png" width="60px" alt="User 
avatar: Yoway Buorn" /></a><a href="https://github.com/scalisi";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;scalisi.png" width="60px" alt="User 
avatar: Josh Scalisi" /></a><a href="https://github.com/alecbcs";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;alecbcs.png" width="60px" alt="User 
avatar: Alec Scott" /></a><a href="https://github.com/thnxdev";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;thnxdev.png" width="60px" alt="User 
avatar: thanks.dev" /></a><a href="https://github.com/artursapek";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;artursapek.png" width="60px" alt="User 
avatar: Artur Sapek" /></a><a href="https://github.com/ramnes";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;ramnes.png" width="60px" alt="User 
avatar: Guilla
 ume Gelin" /></a><a href="https://github.com/jyc";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jyc.png" width="60px" alt="User avatar: 
" /></a><a href="https://github.com/roblevy";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;roblevy.png" width="60px" alt="User 
avatar: Rob Levy" /></a><a href="https://github.com/glozow";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;glozow.png" width="60px" alt="User 
avatar: Gloria Zhao" /></a><a href="https://github.com/toupeira";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;toupeira.png" width="60px" alt="User 
avatar: Markus Koller" /></a><a href="https://github.com/rkpatel33";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rkpatel33.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/jamesob";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jamesob.png" width="60px" alt="User 
avatar: jamesob" /></a><a href="https://github.com/jlebray";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jlebray.png" width="60px" alt="User 
avatar: Johan Le Bray" /></a><
 a href="https://github.com/panosl1";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;panosl1.png" width="60px" alt="User 
avatar: Panos Lampropoulos" /></a><a href="https://github.com/bespinian";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;bespinian.png" width="60px" alt="User 
avatar: bespinian" /></a><a href="https://github.com/scosu";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;scosu.png" width="60px" alt="User 
avatar: Markus Schneider-Pargmann" /></a><a 
href="https://github.com/smithbm2316";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;smithbm2316.png" width="60px" alt="User 
avatar: Ben Smith" /></a><a href="https://github.com/charlieegan3";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;charlieegan3.png" width="60px" alt="User 
avatar: Charlie Egan" /></a><a href="https://github.com/thobbs";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;thobbs.png" width="60px" alt="User 
avatar: Tyler Hobbs" /></a><a href="https://github.com/neilparikh";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;neilparikh.png" 
 width="60px" alt="User avatar: Neil Parikh" /></a><a 
href="https://github.com/shkm";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;shkm.png" width="60px" alt="User avatar: 
Jamie Schembri" /></a><a href="https://github.com/BasedScience";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;BasedScience.png" width="60px" alt="User 
avatar: dockien" /></a><a href="https://github.com/RussellGilmore";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;RussellGilmore.png" width="60px" 
alt="User avatar: Russell Gilmore" /></a><a 
href="https://github.com/meribold";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;meribold.png" width="60px" alt="User 
avatar: Lukas Waymann" /></a><a href="https://github.com/terminaldweller";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;terminaldweller.png" width="60px" 
alt="User avatar: Farzad Sadeghi" /></a><a 
href="https://github.com/jaydee-coder";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jaydee-coder.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/brpaz";><img 
 src="https:&#x2F;&#x2F;github.com&#x2F;brpaz.png" width="60px" alt="User 
avatar: Bruno Paz" /></a><a href="https://github.com/timobenn";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;timobenn.png" width="60px" alt="User 
avatar: Timothy Bennett" /></a><a href="https://github.com/danhorner";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;danhorner.png" width="60px" alt="User 
avatar: Daniel Horner" /></a><a href="https://github.com/rdmarsh";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rdmarsh.png" width="60px" alt="User 
avatar: David Marsh" /></a><a href="https://github.com/Sacquer";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;Sacquer.png" width="60px" alt="User 
avatar: Gökhan Alkacir" /></a><a href="https://github.com/bitlux";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;bitlux.png" width="60px" alt="User 
avatar: Adam" /></a><!-- sponsors -->
+<!-- sponsors --><a href="https://github.com/miyanokomiya";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;miyanokomiya.png" width="60px" alt="User 
avatar: miyanokomiya" /></a><a href="https://github.com/jonhoo";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jonhoo.png" width="60px" alt="User 
avatar: Jon Gjengset" /></a><a href="https://github.com/AceofSpades5757";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;AceofSpades5757.png" width="60px" 
alt="User avatar: Kyle L. Davis" /></a><a 
href="https://github.com/Frederick888";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;Frederick888.png" width="60px" alt="User 
avatar: Frederick Zhang" /></a><a href="https://github.com/moritzdietz";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;moritzdietz.png" width="60px" alt="User 
avatar: Moritz Dietz" /></a><a href="https://github.com/mikker";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;mikker.png" width="60px" alt="User 
avatar: Mikkel Malmberg" /></a><a href="https://github.com/pldubouilh";><img 
src="https:&#x2F;&
 #x2F;github.com&#x2F;pldubouilh.png" width="60px" alt="User avatar: Pierre 
Dubouilh" /></a><a href="https://github.com/trantor";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;trantor.png" width="60px" alt="User 
avatar: Fulvio Scapin" /></a><a href="https://github.com/rcorre";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rcorre.png" width="60px" alt="User 
avatar: Ryan Roden-Corrent" /></a><a href="https://github.com/blissdev";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;blissdev.png" width="60px" alt="User 
avatar: Jordan Arentsen" /></a><a href="https://github.com/aexvir";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;aexvir.png" width="60px" alt="User 
avatar: Alex Viscreanu" /></a><a href="https://github.com/dbalatero";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;dbalatero.png" width="60px" alt="User 
avatar: David Balatero" /></a><a href="https://github.com/moobar";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;moobar.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/benela
 n"><img src="https:&#x2F;&#x2F;github.com&#x2F;benelan.png" width="60px" 
alt="User avatar: Ben Elan" /></a><a href="https://github.com/pawelduda";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;pawelduda.png" width="60px" alt="User 
avatar: Paweł Duda" /></a><a href="https://github.com/pyrho";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;pyrho.png" width="60px" alt="User 
avatar: Damien Rajon" /></a><a href="https://github.com/ArtBIT";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;ArtBIT.png" width="60px" alt="User 
avatar: ArtBIT" /></a><a href="https://github.com/da-moon";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;da-moon.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/hovissimo";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;hovissimo.png" width="60px" alt="User 
avatar: Hovis" /></a><a href="https://github.com/dariusjonda";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;dariusjonda.png" width="60px" alt="User 
avatar: Darius Jonda" /></a><a href="https://github.com/cristian
 d391"><img src="https:&#x2F;&#x2F;github.com&#x2F;cristiand391.png" 
width="60px" alt="User avatar: Cristian Dominguez" /></a><a 
href="https://github.com/eliangcs";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;eliangcs.png" width="60px" alt="User 
avatar: Chang-Hung Liang" /></a><a href="https://github.com/asphaltbuffet";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;asphaltbuffet.png" width="60px" 
alt="User avatar: Ben Lechlitner" /></a><a 
href="https://github.com/looshch";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;looshch.png" width="60px" alt="User 
avatar: george looshch" /></a><a href="https://github.com/kg8m";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;kg8m.png" width="60px" alt="User avatar: 
Takumi KAGIYAMA" /></a><a href="https://github.com/polm";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;polm.png" width="60px" alt="User avatar: 
Paul OLeary McCann" /></a><a href="https://github.com/rbeeger";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rbeeger.png" width="60px" alt="User 
avatar: Rob
 ert Beeger" /></a><a href="https://github.com/yowayb";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;yowayb.png" width="60px" alt="User 
avatar: Yoway Buorn" /></a><a href="https://github.com/scalisi";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;scalisi.png" width="60px" alt="User 
avatar: Josh Scalisi" /></a><a href="https://github.com/alecbcs";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;alecbcs.png" width="60px" alt="User 
avatar: Alec Scott" /></a><a href="https://github.com/thnxdev";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;thnxdev.png" width="60px" alt="User 
avatar: thanks.dev" /></a><a href="https://github.com/artursapek";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;artursapek.png" width="60px" alt="User 
avatar: Artur Sapek" /></a><a href="https://github.com/ramnes";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;ramnes.png" width="60px" alt="User 
avatar: Guillaume Gelin" /></a><a href="https://github.com/jyc";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jyc.png" width="60px" alt="User a
 vatar: " /></a><a href="https://github.com/roblevy";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;roblevy.png" width="60px" alt="User 
avatar: Rob Levy" /></a><a href="https://github.com/glozow";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;glozow.png" width="60px" alt="User 
avatar: Gloria Zhao" /></a><a href="https://github.com/toupeira";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;toupeira.png" width="60px" alt="User 
avatar: Markus Koller" /></a><a href="https://github.com/rkpatel33";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;rkpatel33.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/jamesob";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jamesob.png" width="60px" alt="User 
avatar: jamesob" /></a><a href="https://github.com/jlebray";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jlebray.png" width="60px" alt="User 
avatar: Johan Le Bray" /></a><a href="https://github.com/panosl1";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;panosl1.png" width="60px" alt="User 
avatar: Pan
 os Lampropoulos" /></a><a href="https://github.com/bespinian";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;bespinian.png" width="60px" alt="User 
avatar: bespinian" /></a><a href="https://github.com/scosu";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;scosu.png" width="60px" alt="User 
avatar: Markus Schneider-Pargmann" /></a><a 
href="https://github.com/smithbm2316";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;smithbm2316.png" width="60px" alt="User 
avatar: Ben Smith" /></a><a href="https://github.com/charlieegan3";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;charlieegan3.png" width="60px" alt="User 
avatar: Charlie Egan" /></a><a href="https://github.com/thobbs";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;thobbs.png" width="60px" alt="User 
avatar: Tyler Hobbs" /></a><a href="https://github.com/neilparikh";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;neilparikh.png" width="60px" alt="User 
avatar: Neil Parikh" /></a><a href="https://github.com/shkm";><img 
src="https:&#x2F;&#x2F;github.com&#x2F
 ;shkm.png" width="60px" alt="User avatar: Jamie Schembri" /></a><a 
href="https://github.com/BasedScience";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;BasedScience.png" width="60px" alt="User 
avatar: dockien" /></a><a href="https://github.com/RussellGilmore";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;RussellGilmore.png" width="60px" 
alt="User avatar: Russell Gilmore" /></a><a 
href="https://github.com/meribold";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;meribold.png" width="60px" alt="User 
avatar: Lukas Waymann" /></a><a href="https://github.com/terminaldweller";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;terminaldweller.png" width="60px" 
alt="User avatar: Farzad Sadeghi" /></a><a 
href="https://github.com/jaydee-coder";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;jaydee-coder.png" width="60px" alt="User 
avatar: " /></a><a href="https://github.com/brpaz";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;brpaz.png" width="60px" alt="User 
avatar: Bruno Paz" /></a><a href="https://github.com/t
 imobenn"><img src="https:&#x2F;&#x2F;github.com&#x2F;timobenn.png" 
width="60px" alt="User avatar: Timothy Bennett" /></a><a 
href="https://github.com/danhorner";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;danhorner.png" width="60px" alt="User 
avatar: Daniel Horner" /></a><a href="https://github.com/bitlux";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;bitlux.png" width="60px" alt="User 
avatar: Adam" /></a><a href="https://github.com/syeo66";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;syeo66.png" width="60px" alt="User 
avatar: Red Ochsenbein" /></a><a href="https://github.com/nekhaevskiy";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;nekhaevskiy.png" width="60px" alt="User 
avatar: Yury" /></a><a href="https://github.com/cange";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;cange.png" width="60px" alt="User 
avatar: Christian Angermann" /></a><a href="https://github.com/lajarre";><img 
src="https:&#x2F;&#x2F;github.com&#x2F;lajarre.png" width="60px" alt="User 
avatar: " /></a><!-- sponsors -->
 
 Table of Contents
 -----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/install new/fzf-0.60.3/install
--- old/fzf-0.60.0/install      2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/install      2025-03-03 09:10:49.000000000 +0100
@@ -2,7 +2,7 @@
 
 set -u
 
-version=0.60.0
+version=0.60.3
 auto_completion=
 key_bindings=
 update_config=2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/install.ps1 new/fzf-0.60.3/install.ps1
--- old/fzf-0.60.0/install.ps1  2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/install.ps1  2025-03-03 09:10:49.000000000 +0100
@@ -1,4 +1,4 @@
-$version="0.60.0"
+$version="0.60.3"
 
 $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/man/man1/fzf-tmux.1 
new/fzf-0.60.3/man/man1/fzf-tmux.1
--- old/fzf-0.60.0/man/man1/fzf-tmux.1  2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/man/man1/fzf-tmux.1  2025-03-03 09:10:49.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 "Feb 2025" "fzf 0.60.0" "fzf\-tmux - open fzf in tmux split 
pane"
+.TH fzf\-tmux 1 "Mar 2025" "fzf 0.60.3" "fzf\-tmux - open fzf in tmux split 
pane"
 
 .SH NAME
 fzf\-tmux - open fzf in tmux split pane
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/man/man1/fzf.1 
new/fzf-0.60.3/man/man1/fzf.1
--- old/fzf-0.60.0/man/man1/fzf.1       2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/man/man1/fzf.1       2025-03-03 09:10:49.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 "Feb 2025" "fzf 0.60.0" "fzf - a command-line fuzzy finder"
+.TH fzf 1 "Mar 2025" "fzf 0.60.3" "fzf - a command-line fuzzy finder"
 
 .SH NAME
 fzf - a command-line fuzzy finder
@@ -56,7 +56,9 @@
 Case-sensitive match
 .TP
 .B "\-\-smart\-case"
-Smart-case match (default)
+Smart-case match (default). In this mode, the search is case-insensitive by
+default, but it becomes case-sensitive if the query contains any uppercase
+letters.
 .TP
 .B "\-\-literal"
 Do not normalize latin script letters for matching.
@@ -120,7 +122,9 @@
 .BI "\-\-with\-nth=" "N[,..] or TEMPLATE"
 Transform the presentation of each line using the field index expressions.
 For advanced transformation, you can provide a template containing field index
-expressions in curly braces.
+expressions in curly braces. When you use a template, the trailing delimiter is
+stripped from each expression, giving you more control over the output.
+\fB{n}\fR in template evaluates to the zero-based ordinal index of the line.
 
 .RS
 e.g.
@@ -128,13 +132,16 @@
      echo foo bar baz | fzf --with-nth 2..
 
      # Use template to rearrange fields
-     echo foo,bar,baz | fzf --delimiter , --with-nth '{1},{3},{2},{1..2}'
+     echo foo,bar,baz | fzf --delimiter , --with-nth '{n},{1},{3},{2},{1..2}'
 .RE
 .TP
 .BI "\-\-accept\-nth=" "N[,..] or TEMPLATE"
 Define which fields to print on accept. The last delimiter is stripped from the
 output. For advanced transformation, you can provide a template containing
-field index expressions in curly braces.
+field index expressions in curly braces. When you use a template, the trailing
+delimiter is stripped from each expression, giving you more control over the
+output. \fB{n}\fR in template evaluates to the zero-based ordinal index of the
+line.
 
 .RS
 e.g.
@@ -142,7 +149,7 @@
      echo foo bar baz | fzf --accept-nth 2
 
      # Template
-     echo foo bar baz | fzf --accept-nth '1st: {1}, 2nd: {2}, 3rd: {3}'
+     echo foo bar baz | fzf --accept-nth 'Index: {n}, 1st: {1}, 2nd: {2}, 3rd: 
{3}'
 .RE
 .TP
 .B "+s, \-\-no\-sort"
@@ -1717,6 +1724,9 @@
      \fBfzf \-\-multi \-\-bind 'ctrl\-a:select\-all+accept'\fR
      \fBfzf \-\-multi \-\-bind 'ctrl\-a:select\-all' \-\-bind 
'ctrl\-a:+accept'\fR
 
+Any action after a terminal action that exits fzf, such as \fBaccept\fR or
+\fBabort\fR, is ignored.
+
 .SS ACTION ARGUMENT
 
 An action denoted with \fB(...)\fR suffix takes an argument.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/shell/completion.zsh 
new/fzf-0.60.3/shell/completion.zsh
--- old/fzf-0.60.0/shell/completion.zsh 2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/shell/completion.zsh 2025-03-03 09:10:49.000000000 +0100
@@ -99,9 +99,9 @@
 __fzf_defaults() {
   # $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
   # $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
-  echo "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore 
$1"
+  echo -E "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ 
--bind=ctrl-z:ignore $1"
   command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
-  echo "${FZF_DEFAULT_OPTS-} $2"
+  echo -E "${FZF_DEFAULT_OPTS-} $2"
 }
 
 __fzf_comprun() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/shell/key-bindings.fish 
new/fzf-0.60.3/shell/key-bindings.fish
--- old/fzf-0.60.0/shell/key-bindings.fish      2025-02-12 16:54:21.000000000 
+0100
+++ new/fzf-0.60.3/shell/key-bindings.fish      2025-03-03 09:10:49.000000000 
+0100
@@ -14,102 +14,24 @@
 
 # Key bindings
 # ------------
+# For compatibility with fish versions down to 3.1.2, the script does not use:
+# - The -f/--function switch of command: set
+# - The process substitution syntax: $(cmd)
+# - Ranges that omit start/end indexes: $var[$start..] $var[..$end] $var[..]
 function fzf_key_bindings
 
   function __fzf_defaults
-    # $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
-    # $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
-    test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
-    echo "--height $FZF_TMUX_HEIGHT --min-height 20+ --bind=ctrl-z:ignore" 
$argv[1]
-    test -r "$FZF_DEFAULT_OPTS_FILE"; and string collect -N -- 
<$FZF_DEFAULT_OPTS_FILE
-    echo $FZF_DEFAULT_OPTS $argv[2]
-  end
-
-  # Store current token in $dir as root for the 'find' command
-  function fzf-file-widget -d "List files and folders"
-    set -l commandline (__fzf_parse_commandline)
-    set -lx dir $commandline[1]
-    set -l fzf_query $commandline[2]
-    set -l prefix $commandline[3]
-    set -l result
-
-    test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
-    begin
-      set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse 
--walker=file,dir,follow,hidden --scheme=path --walker-root=$dir" 
"$FZF_CTRL_T_OPTS")
-      set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND"
-      set -lx FZF_DEFAULT_OPTS_FILE ''
-      set result (eval (__fzfcmd) -m --query=$fzf_query)
-    end
-    if test -z "$result"
-      commandline -f repaint
-      return
-    else
-      # Remove last token from commandline.
-      commandline -t ""
-    end
-    for i in $result
-      commandline -it -- $prefix
-      commandline -it -- (string escape -- $i)
-      commandline -it -- ' '
-    end
-    commandline -f repaint
-  end
-
-  function fzf-history-widget -d "Show command history"
-    test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
-    begin
-      # merge history from other sessions before searching
-      test -z "$fish_private_mode"; and builtin history merge
-
-      set -lx FZF_DEFAULT_OPTS (__fzf_defaults "" "-n2..,.. --scheme=history 
--bind=ctrl-r:toggle-sort --wrap-sign '"\t"↳ ' --highlight-line +m 
$FZF_CTRL_R_OPTS")
-      set -lx FZF_DEFAULT_OPTS_FILE ''
-      set -lx FZF_DEFAULT_COMMAND
-      set -a -- FZF_DEFAULT_OPTS --with-shell=(status fish-path)\\ -c
-
-      if type -q perl
-        set -a FZF_DEFAULT_OPTS '--tac'
-        set FZF_DEFAULT_COMMAND 'builtin history -z --reverse | command perl 
-0 -pe \'s/^/$.\t/g; s/\n/\n\t/gm\''
-      else
-        set FZF_DEFAULT_COMMAND \
-          'set -l h (builtin history -z --reverse | string split0);' \
-          'for i in (seq (count $h) -1 1);' \
-          'string join0 -- $i\t(string replace -a -- \n \n\t $h[$i] | string 
collect);' \
-          'end'
-      end
-      set -l result (eval $FZF_DEFAULT_COMMAND \| (__fzfcmd) --read0 --print0 
-q (commandline | string escape) "--bind=enter:become:'string replace -a -- 
\n\t \n {2..} | string collect'")
-      and commandline -- $result
-    end
-    commandline -f repaint
-  end
-
-  function fzf-cd-widget -d "Change directory"
-    set -l commandline (__fzf_parse_commandline)
-    set -lx dir $commandline[1]
-    set -l fzf_query $commandline[2]
-    set -l prefix $commandline[3]
-
-    test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
-    begin
-      set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse 
--walker=dir,follow,hidden --scheme=path --walker-root=$dir" "$FZF_ALT_C_OPTS")
-      set -lx FZF_DEFAULT_OPTS_FILE ''
-      set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND"
-      set -l result (eval (__fzfcmd) +m --query=$fzf_query)
-
-      if test -n "$result"
-        cd -- $result
-
-        # Remove last token from commandline.
-        commandline -t ""
-        commandline -it -- $prefix
-      end
-    end
-
-    commandline -f repaint
+    # $argv[1]: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
+    # $argv[2..]: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
+    test -n "$FZF_TMUX_HEIGHT"; or set -l FZF_TMUX_HEIGHT 40%
+    string join ' ' -- \
+      "--height $FZF_TMUX_HEIGHT --min-height=20+ --bind=ctrl-z:ignore" 
$argv[1] \
+      (test -r "$FZF_DEFAULT_OPTS_FILE"; and string join -- ' ' 
<$FZF_DEFAULT_OPTS_FILE) \
+      $FZF_DEFAULT_OPTS $argv[2..-1]
   end
 
   function __fzfcmd
-    test -n "$FZF_TMUX"; or set FZF_TMUX 0
-    test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
+    test -n "$FZF_TMUX_HEIGHT"; or set -l FZF_TMUX_HEIGHT 40%
     if test -n "$FZF_TMUX_OPTS"
       echo "fzf-tmux $FZF_TMUX_OPTS -- "
     else if test "$FZF_TMUX" = "1"
@@ -119,56 +41,42 @@
     end
   end
 
-  bind \cr fzf-history-widget
-  if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
-    bind \ct fzf-file-widget
-  end
-  if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
-    bind \ec fzf-cd-widget
-  end
-
-  bind -M insert \cr fzf-history-widget
-  if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
-    bind -M insert \ct fzf-file-widget
-  end
-  if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
-    bind -M insert \ec fzf-cd-widget
-  end
-
   function __fzf_parse_commandline -d 'Parse the current command line token 
and return split of existing filepath, fzf query, and optional -option= prefix'
-    set -l commandline (commandline -t)
+    set -l dir '.'
+    set -l query
+    set -l commandline (commandline -t | string unescape -n)
 
-    # strip -option= from token if present
+    # Strip -option= from token if present
     set -l prefix (string match -r -- '^-[^\s=]+=' $commandline)
     set commandline (string replace -- "$prefix" '' $commandline)
 
     # Enable home directory expansion of leading ~/
     set commandline (string replace -r -- '^~/' '\$HOME/' $commandline)
 
-    # escape special characters, except for the $ sign of valid variable names,
-    # so that after eval, the original string is returned, but with the
-    # variable names replaced by their values.
+    # Escape special characters, except for the $ sign of valid variable names,
+    # so that the original string with expanded variables is returned after 
eval.
     set commandline (string escape -n -- $commandline)
-    set commandline (string replace -r -a -- '\x5c\$(?=[\w])' '\$' 
$commandline)
+    set commandline (string replace -r -a -- '\\\\\$(?=[\w])' '\$' 
$commandline)
 
     # eval is used to do shell expansion on paths
     eval set commandline $commandline
 
-    # Combine multiple consecutive slashes into one, and unescape.
-    set commandline (string replace -r -a -- '/+' '/' $commandline | string 
unescape -n)
+    # Combine multiple consecutive slashes into one.
+    set commandline (string replace -r -a -- '/+' '/' $commandline)
 
-    if test -z "$commandline"
-      # Default to current directory with no --query
-      set dir '.'
-      set fzf_query ''
-    else
-      set dir (__fzf_get_dir $commandline)
+    if test -n "$commandline"
+      # Strip trailing slash, unless $dir is root dir (/)
+      set dir (string replace -r -- '(?<!^)/$' '' $commandline)
+
+      # Set $dir to the longest existing filepath
+      while not test -d "$dir"
+        # If path is absolute, this can keep going until ends up at /
+        # If path is relative, this can keep going until entire input is 
consumed, dirname returns "."
+        set dir (dirname -- $dir)
+      end
 
-      # BUG: on combined expressions, if a left argument is a single `!`, the
-      # builtin test command of fish will treat it as the ! operator. To
-      # overcome this, have the variable parts on the right.
-      if test "." = "$dir" -a "./" != (string sub -l 2 -- $commandline)
-        # if $dir is "." but commandline is not a relative path, this means no 
file path found
+      if test "$dir" = '.'; and test (string sub -l 2 -- $commandline) != './'
+        # If $dir is "." but commandline is not a relative path, this means no 
file path found
         set fzf_query $commandline
       else
         # Also remove trailing slash after dir, to "split" input properly
@@ -176,25 +84,101 @@
       end
     end
 
-    echo -- $dir
-    string escape -- $fzf_query
-    echo -- $prefix
+    string escape -n -- "$dir" "$fzf_query" "$prefix"
+  end
+
+  # Store current token in $dir as root for the 'find' command
+  function fzf-file-widget -d "List files and folders"
+    set -l commandline (__fzf_parse_commandline)
+    set -lx dir $commandline[1]
+    set -l fzf_query $commandline[2]
+    set -l prefix $commandline[3]
+
+    set -lx FZF_DEFAULT_OPTS (__fzf_defaults \
+      "--reverse --walker=file,dir,follow,hidden --scheme=path 
--walker-root=$dir" \
+      "$FZF_CTRL_T_OPTS --multi")
+
+    set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND"
+    set -lx FZF_DEFAULT_OPTS_FILE
+
+    if set -l result (eval (__fzfcmd) --query=$fzf_query)
+      # Remove last token from commandline.
+      commandline -t ''
+      for i in $result
+        commandline -it -- $prefix(string escape -- $i)' '
+      end
+    end
+
+    commandline -f repaint
   end
 
-  function __fzf_get_dir -d 'Find the longest existing filepath from input 
string'
-    set dir $argv
+  function fzf-history-widget -d "Show command history"
+    set -l fzf_query (commandline | string escape)
+
+    set -lx FZF_DEFAULT_OPTS (__fzf_defaults '' \
+      '--nth=2..,.. --scheme=history --multi --wrap-sign="\t↳ "' \
+      "--bind=ctrl-r:toggle-sort --highlight-line $FZF_CTRL_R_OPTS" \
+      '--accept-nth=2.. --read0 --print0 --with-shell='(status fish-path)\\ -c)
+
+    set -lx FZF_DEFAULT_OPTS_FILE
+    set -lx FZF_DEFAULT_COMMAND
+
+    if type -q perl
+      set -a FZF_DEFAULT_OPTS '--tac'
+      set FZF_DEFAULT_COMMAND 'builtin history -z --reverse | command perl -0 
-pe \'s/^/$.\t/g; s/\n/\n\t/gm\''
+    else
+      set FZF_DEFAULT_COMMAND \
+        'set -l h (builtin history -z --reverse | string split0);' \
+        'for i in (seq (count $h) -1 1);' \
+        'string join0 -- $i\t(string replace -a -- \n \n\t $h[$i] | string 
collect);' \
+        'end'
+    end
+
+    # Merge history from other sessions before searching
+    test -z "$fish_private_mode"; and builtin history merge
+
+    if set -l result (eval $FZF_DEFAULT_COMMAND \| (__fzfcmd) 
--query=$fzf_query | string split0)
+      commandline -- (string replace -a -- \n\t \n $result[1])
+      test (count $result) -gt 1; and for i in $result[2..-1]
+        commandline -i -- (string replace -a -- \n\t \n \n$i)
+      end
+    end
+
+    commandline -f repaint
+  end
 
-    # Strip trailing slash, unless $dir is root dir (/)
-    set dir (string replace -r -- '(?<!^)/$' '' $dir)
+  function fzf-cd-widget -d "Change directory"
+    set -l commandline (__fzf_parse_commandline)
+    set -lx dir $commandline[1]
+    set -l fzf_query $commandline[2]
+    set -l prefix $commandline[3]
 
-    # Iteratively check if dir exists and strip tail end of path
-    while test ! -d "$dir"
-      # If path is absolute, this can keep going until ends up at /
-      # If path is relative, this can keep going until entire input is 
consumed, dirname returns "."
-      set dir (dirname -- "$dir")
+    set -lx FZF_DEFAULT_OPTS (__fzf_defaults \
+      "--reverse --walker=dir,follow,hidden --scheme=path --walker-root=$dir" \
+      "$FZF_ALT_C_OPTS --no-multi")
+
+    set -lx FZF_DEFAULT_OPTS_FILE
+    set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND"
+
+    if set -l result (eval (__fzfcmd) --query=$fzf_query)
+      cd -- $result
+      commandline -rt -- $prefix
     end
 
-    string escape -n -- $dir
+    commandline -f repaint
+  end
+
+  bind \cr fzf-history-widget
+  bind -M insert \cr fzf-history-widget
+
+  if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
+    bind \ct fzf-file-widget
+    bind -M insert \ct fzf-file-widget
+  end
+
+  if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
+    bind \ec fzf-cd-widget
+    bind -M insert \ec fzf-cd-widget
   end
 
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/shell/key-bindings.zsh 
new/fzf-0.60.3/shell/key-bindings.zsh
--- old/fzf-0.60.0/shell/key-bindings.zsh       2025-02-12 16:54:21.000000000 
+0100
+++ new/fzf-0.60.3/shell/key-bindings.zsh       2025-03-03 09:10:49.000000000 
+0100
@@ -41,9 +41,9 @@
 __fzf_defaults() {
   # $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
   # $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
-  echo "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore 
$1"
+  echo -E "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ 
--bind=ctrl-z:ignore $1"
   command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
-  echo "${FZF_DEFAULT_OPTS-} $2"
+  echo -E "${FZF_DEFAULT_OPTS-} $2"
 }
 
 # CTRL-T - Paste the selected file path(s) into the command line
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/algo/algo.go 
new/fzf-0.60.3/src/algo/algo.go
--- old/fzf-0.60.0/src/algo/algo.go     2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/algo/algo.go     2025-03-03 09:10:49.000000000 +0100
@@ -767,6 +767,9 @@
                                        char = unicode.To(unicode.LowerCase, 
char)
                                }
                        }
+                       if normalize {
+                               char = normalizeRune(char)
+                       }
 
                        pidx_ := indexAt(pidx, lenPattern, forward)
                        pchar := pattern[pidx_]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/algo/algo_test.go 
new/fzf-0.60.3/src/algo/algo_test.go
--- old/fzf-0.60.0/src/algo/algo_test.go        2025-02-12 16:54:21.000000000 
+0100
+++ new/fzf-0.60.3/src/algo/algo_test.go        2025-03-03 09:10:49.000000000 
+0100
@@ -200,3 +200,12 @@
        bytes[math.MaxUint16] = 'z'
        assertMatch(t, FuzzyMatchV2, true, true, string(bytes), "zx", 
math.MaxUint16, math.MaxUint16+2, scoreMatch*2+bonusConsecutive)
 }
+
+func TestLongStringWithNormalize(t *testing.T) {
+       bytes := make([]byte, 30000)
+       for i := range bytes {
+               bytes[i] = 'x'
+       }
+       unicodeString := string(bytes) + " Minímal example"
+       assertMatch2(t, FuzzyMatchV1, false, true, false, unicodeString, 
"minim", 30001, 30006, 140)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/constants.go 
new/fzf-0.60.3/src/constants.go
--- old/fzf-0.60.0/src/constants.go     2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/constants.go     2025-03-03 09:10:49.000000000 +0100
@@ -26,7 +26,7 @@
        previewCancelWait = 500 * time.Millisecond
        previewChunkDelay = 100 * time.Millisecond
        previewDelayed    = 500 * time.Millisecond
-       maxPatternLength  = 300
+       maxPatternLength  = 1000
        maxMulti          = math.MaxInt32
 
        // Matcher
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/core.go new/fzf-0.60.3/src/core.go
--- old/fzf-0.60.0/src/core.go  2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/core.go  2025-03-03 09:10:49.000000000 +0100
@@ -128,13 +128,14 @@
                                        }
                                }
                        }
-                       transformed := nthTransformer(tokens)
+                       transformed := nthTransformer(tokens, itemIndex)
                        if len(header) < opts.HeaderLines {
                                header = append(header, transformed)
                                eventBox.Set(EvtHeader, header)
                                return false
                        }
                        item.text, item.colors = 
ansiProcessor(stringBytes(transformed))
+                       item.text.TrimTrailingWhitespaces()
                        item.text.Index = itemIndex
                        item.origText = &data
                        itemIndex++
@@ -476,8 +477,17 @@
                                                                        if 
len(opts.Expect) > 0 {
                                                                                
opts.Printer("")
                                                                        }
+                                                                       
transformer := func(item *Item) string {
+                                                                               
return item.AsString(opts.Ansi)
+                                                                       }
+                                                                       if 
opts.AcceptNth != nil {
+                                                                               
fn := opts.AcceptNth(opts.Delimiter)
+                                                                               
transformer = func(item *Item) string {
+                                                                               
        return item.acceptNth(opts.Ansi, opts.Delimiter, fn)
+                                                                               
}
+                                                                       }
                                                                        for i 
:= 0; i < count; i++ {
-                                                                               
opts.Printer(val.Get(i).item.AsString(opts.Ansi))
+                                                                               
opts.Printer(transformer(val.Get(i).item))
                                                                        }
                                                                        if 
count == 0 {
                                                                                
exitCode = ExitNoMatch
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/item.go new/fzf-0.60.3/src/item.go
--- old/fzf-0.60.0/src/item.go  2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/item.go  2025-03-03 09:10:49.000000000 +0100
@@ -51,3 +51,9 @@
        }
        return item.text.ToString()
 }
+
+func (item *Item) acceptNth(stripAnsi bool, delimiter Delimiter, transformer 
func([]Token, int32) string) string {
+       tokens := Tokenize(item.AsString(stripAnsi), delimiter)
+       transformed := transformer(tokens, item.Index())
+       return StripLastDelimiter(transformed, delimiter)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/options.go 
new/fzf-0.60.3/src/options.go
--- old/fzf-0.60.0/src/options.go       2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/options.go       2025-03-03 09:10:49.000000000 +0100
@@ -544,8 +544,8 @@
        Case              Case
        Normalize         bool
        Nth               []Range
-       WithNth           func(Delimiter) func([]Token) string
-       AcceptNth         func(Delimiter) func([]Token) string
+       WithNth           func(Delimiter) func([]Token, int32) string
+       AcceptNth         func(Delimiter) func([]Token, int32) string
        Delimiter         Delimiter
        Sort              int
        Track             trackOption
@@ -769,30 +769,31 @@
        return ranges, nil
 }
 
-func nthTransformer(str string) (func(Delimiter) func([]Token) string, error) {
+func nthTransformer(str string) (func(Delimiter) func([]Token, int32) string, 
error) {
        // ^[0-9,-.]+$"
        if match, _ := regexp.MatchString("^[0-9,-.]+$", str); match {
                nth, err := splitNth(str)
                if err != nil {
                        return nil, err
                }
-               return func(Delimiter) func([]Token) string {
-                       return func(tokens []Token) string {
+               return func(Delimiter) func([]Token, int32) string {
+                       return func(tokens []Token, index int32) string {
                                return JoinTokens(Transform(tokens, nth))
                        }
                }, nil
        }
 
        // {...} {...} ...
-       placeholder := regexp.MustCompile("{[0-9,-.]+}")
+       placeholder := regexp.MustCompile("{[0-9,-.]+}|{n}")
        indexes := placeholder.FindAllStringIndex(str, -1)
        if indexes == nil {
                return nil, errors.New("template should include at least 1 
placeholder: " + str)
        }
 
        type NthParts struct {
-               str string
-               nth []Range
+               str   string
+               index bool
+               nth   []Range
        }
 
        parts := make([]NthParts, len(indexes))
@@ -801,7 +802,10 @@
                if idx < index[0] {
                        parts = append(parts, NthParts{str: str[idx:index[0]]})
                }
-               if nth, err := splitNth(str[index[0]+1 : index[1]-1]); err == 
nil {
+               expr := str[index[0]+1 : index[1]-1]
+               if expr == "n" {
+                       parts = append(parts, NthParts{index: true})
+               } else if nth, err := splitNth(expr); err == nil {
                        parts = append(parts, NthParts{nth: nth})
                }
                idx = index[1]
@@ -810,12 +814,16 @@
                parts = append(parts, NthParts{str: str[idx:]})
        }
 
-       return func(delimiter Delimiter) func([]Token) string {
-               return func(tokens []Token) string {
+       return func(delimiter Delimiter) func([]Token, int32) string {
+               return func(tokens []Token, index int32) string {
                        str := ""
                        for _, holder := range parts {
                                if holder.nth != nil {
                                        str += 
StripLastDelimiter(JoinTokens(Transform(tokens, holder.nth)), delimiter)
+                               } else if holder.index {
+                                       if index >= 0 {
+                                               str += strconv.Itoa(int(index))
+                                       }
                                } else {
                                        str += holder.str
                                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/proxy.go new/fzf-0.60.3/src/proxy.go
--- old/fzf-0.60.0/src/proxy.go 2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/proxy.go 2025-03-03 09:10:49.000000000 +0100
@@ -59,12 +59,12 @@
                })
        }()
 
-       var command string
+       var command, input string
        commandPrefix += ` --no-force-tty-in --proxy-script "$0"`
        if opts.Input == nil && (opts.ForceTtyIn || util.IsTty(os.Stdin)) {
                command = fmt.Sprintf(`%s > %q`, commandPrefix, output)
        } else {
-               input, err := fifo("proxy-input")
+               input, err = fifo("proxy-input")
                if err != nil {
                        return ExitError, err
                }
@@ -148,6 +148,9 @@
                                if err != nil {
                                        return ExitError, err
                                }
+                               os.Remove(temp)
+                               os.Remove(input)
+                               os.Remove(output)
                                executor.Become(ttyin, env, command)
                        }
                        return code, err
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/reader.go new/fzf-0.60.3/src/reader.go
--- old/fzf-0.60.0/src/reader.go        2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/reader.go        2025-03-03 09:10:49.000000000 +0100
@@ -277,6 +277,9 @@
        ignoresFull := []string{}
        ignoresSuffix := []string{}
        sep := string(os.PathSeparator)
+       if _, ok := os.LookupEnv("MSYSTEM"); ok {
+               sep = "/"
+       }
        for _, ignore := range ignores {
                if strings.ContainsRune(ignore, os.PathSeparator) {
                        if strings.HasPrefix(ignore, sep) {
@@ -320,6 +323,7 @@
                                                return filepath.SkipDir
                                        }
                                }
+                               path += sep
                        }
                        if ((opts.file && !isDir) || (opts.dir && isDir)) && 
r.pusher(stringBytes(path)) {
                                atomic.StoreInt32(&r.event, int32(EvtReadNew))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/terminal.go 
new/fzf-0.60.3/src/terminal.go
--- old/fzf-0.60.0/src/terminal.go      2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/terminal.go      2025-03-03 09:10:49.000000000 +0100
@@ -305,7 +305,7 @@
        nthAttr            tui.Attr
        nth                []Range
        nthCurrent         []Range
-       acceptNth          func([]Token) string
+       acceptNth          func([]Token, int32) string
        tabstop            int
        margin             [4]sizeSpec
        padding            [4]sizeSpec
@@ -638,6 +638,7 @@
        scrollOffset int
        list         []*Item
        env          []string
+       query        string
 }
 
 type previewResult struct {
@@ -1346,7 +1347,7 @@
        }
        if cached, prs := t.numLinesCache[item.Index()]; prs {
                // Can we use this cache? Let's be conservative.
-               if cached.atMost >= atMost {
+               if cached.atMost <= atMost {
                        return cached.numLines, false
                }
        }
@@ -1574,9 +1575,7 @@
        }
        if t.acceptNth != nil {
                transform = func(item *Item) string {
-                       tokens := Tokenize(item.AsString(t.ansi), t.delimiter)
-                       transformed := t.acceptNth(tokens)
-                       return StripLastDelimiter(transformed, t.delimiter)
+                       return item.acceptNth(t.ansi, t.delimiter, t.acceptNth)
                }
        }
        found := len(t.selected) > 0
@@ -2287,7 +2286,11 @@
 }
 
 func (t *Terminal) truncateQuery() {
-       t.input, _ = t.trimRight(t.input, maxPatternLength)
+       // We're limiting the length of the query not to make fzf unresponsive 
when
+       // the user accidentally pastes a huge chunk of text. Therefore, we're 
not
+       // interested in the exact display width of the query. We just limit the
+       // number of runes.
+       t.input = t.input[:util.Min(len(t.input), maxPatternLength)]
        t.cx = util.Constrain(t.cx, 0, len(t.input))
 }
 
@@ -2754,11 +2757,15 @@
        item := result.item
        _, selected := t.selected[item.Index()]
        label := ""
+       extraWidth := 0
        if t.jumping != jumpDisabled {
                if index < len(t.jumpLabels) {
                        // Striped
                        current = index%2 == 0
-                       label = t.jumpLabels[index:index+1] + strings.Repeat(" 
", t.pointerLen-1)
+                       label = t.jumpLabels[index:index+1] + strings.Repeat(" 
", util.Max(0, t.pointerLen-1))
+                       if t.pointerLen == 0 {
+                               extraWidth = 1
+                       }
                }
        } else if current {
                label = t.pointer
@@ -2787,6 +2794,7 @@
 
        maxWidth := t.window.Width() - (t.pointerLen + t.markerLen + 1)
        postTask := func(lineNum int, width int, wrapped bool, forceRedraw 
bool) {
+               width += extraWidth
                if (current || selected) && t.highlightLine {
                        color := tui.ColSelected
                        if current {
@@ -3099,8 +3107,15 @@
                maxWidth := t.window.Width() - (indentSize + 1)
                wasWrapped := false
                if wrapped {
-                       maxWidth -= t.wrapSignWidth
-                       t.window.CPrint(colBase.WithAttr(tui.Dim), t.wrapSign)
+                       wrapSign := t.wrapSign
+                       if maxWidth < t.wrapSignWidth {
+                               runes, _ := util.Truncate(wrapSign, maxWidth)
+                               wrapSign = string(runes)
+                               maxWidth = 0
+                       } else {
+                               maxWidth -= t.wrapSignWidth
+                       }
+                       t.window.CPrint(colBase.WithAttr(tui.Dim), wrapSign)
                        wrapped = false
                        wasWrapped = true
                }
@@ -3165,7 +3180,9 @@
                        displayWidth = t.displayWidthWithLimit(line, 0, 
displayWidth)
                }
 
-               t.printColoredString(t.window, line, offsets, colBase)
+               if maxWidth > 0 {
+                       t.printColoredString(t.window, line, offsets, colBase)
+               }
                if postTask != nil {
                        postTask(actualLineNum, displayWidth, wasWrapped, 
forceRedraw)
                } else {
@@ -3374,8 +3391,10 @@
        wiped := false
        image := false
        wireframe := false
+       var index int
+       var line string
 Loop:
-       for _, line := range lines {
+       for index, line = range lines {
                var lbg tui.Color = -1
                if ansi != nil {
                        ansi.lbg = -1
@@ -3518,6 +3537,7 @@
                }
                lineNo++
        }
+       t.previewer.scrollable = t.previewer.scrollable || index < len(lines)-1
        t.previewed.image = image
        t.previewed.wireframe = wireframe
 }
@@ -4376,6 +4396,7 @@
                                var items []*Item
                                var commandTemplate string
                                var env []string
+                               var query string
                                initialOffset := 0
                                t.previewBox.Wait(func(events *util.Events) {
                                        for req, value := range *events {
@@ -4389,6 +4410,7 @@
                                                        initialOffset = 
request.scrollOffset
                                                        items = request.list
                                                        env = request.env
+                                                       query = request.query
                                                }
                                        }
                                        events.Clear()
@@ -4402,8 +4424,7 @@
                                version++
                                // We don't display preview window if no match
                                if items[0] != nil {
-                                       _, query := t.Input()
-                                       command, tempFiles := 
t.replacePlaceholder(commandTemplate, false, string(query), items)
+                                       command, tempFiles := 
t.replacePlaceholder(commandTemplate, false, query, items)
                                        cmd := t.executor.ExecCommand(command, 
true)
                                        cmd.Env = env
 
@@ -4531,7 +4552,7 @@
                if len(command) > 0 && t.canPreview() {
                        _, list := t.buildPlusList(command, false)
                        t.cancelPreview()
-                       t.previewBox.Set(reqPreviewEnqueue, 
previewRequest{command, t.evaluateScrollOffset(), list, t.environForPreview()})
+                       t.previewBox.Set(reqPreviewEnqueue, 
previewRequest{command, t.evaluateScrollOffset(), list, t.environForPreview(), 
string(t.input)})
                }
        }
 
@@ -4963,7 +4984,7 @@
                                                if valid {
                                                        t.cancelPreview()
                                                        
t.previewBox.Set(reqPreviewEnqueue,
-                                                               
previewRequest{t.previewOpts.command, t.evaluateScrollOffset(), list, 
t.environForPreview()})
+                                                               
previewRequest{t.previewOpts.command, t.evaluateScrollOffset(), list, 
t.environForPreview(), string(t.input)})
                                                }
                                        } else {
                                                // Discard the preview content 
so that it won't accidentally appear
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/tokenizer.go 
new/fzf-0.60.3/src/tokenizer.go
--- old/fzf-0.60.0/src/tokenizer.go     2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/tokenizer.go     2025-03-03 09:10:49.000000000 +0100
@@ -225,7 +225,9 @@
                locs := delimiter.regex.FindAllStringIndex(str, -1)
                if len(locs) > 0 {
                        lastLoc := locs[len(locs)-1]
-                       str = str[:lastLoc[0]]
+                       if lastLoc[1] == len(str) {
+                               str = str[:lastLoc[0]]
+                       }
                }
        }
        return strings.TrimRightFunc(str, unicode.IsSpace)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/tui/light.go 
new/fzf-0.60.3/src/tui/light.go
--- old/fzf-0.60.0/src/tui/light.go     2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/tui/light.go     2025-03-03 09:10:49.000000000 +0100
@@ -8,6 +8,7 @@
        "regexp"
        "strconv"
        "strings"
+       "sync"
        "time"
        "unicode/utf8"
 
@@ -29,7 +30,7 @@
 
 const consoleDevice string = "/dev/tty"
 
-var offsetRegexp = regexp.MustCompile("(.*)\x1b\\[([0-9]+);([0-9]+)R")
+var offsetRegexp = regexp.MustCompile("(.*?)\x00?\x1b\\[([0-9]+);([0-9]+)R")
 var offsetRegexpBegin = regexp.MustCompile("^\x1b\\[[0-9]+;[0-9]+R")
 
 func (r *LightRenderer) Bell() {
@@ -95,7 +96,6 @@
 
 // Light renderer
 type LightRenderer struct {
-       closed        *util.AtomicBool
        theme         *ColorTheme
        mouse         bool
        forceBlack    bool
@@ -120,6 +120,7 @@
        showCursor    bool
 
        // Windows only
+       mutex           sync.Mutex
        ttyinChannel    chan byte
        inHandle        uintptr
        outHandle       uintptr
@@ -151,7 +152,6 @@
                out = os.Stderr
        }
        r := LightRenderer{
-               closed:        util.NewAtomicBool(false),
                theme:         theme,
                forceBlack:    forceBlack,
                mouse:         mouse,
@@ -775,9 +775,8 @@
        }
        r.disableMouse()
        r.flush()
-       r.closePlatform()
        r.restoreTerminal()
-       r.closed.Set(true)
+       r.closePlatform()
 }
 
 func (r *LightRenderer) Top() int {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/tui/light_windows.go 
new/fzf-0.60.3/src/tui/light_windows.go
--- old/fzf-0.60.0/src/tui/light_windows.go     2025-02-12 16:54:21.000000000 
+0100
+++ new/fzf-0.60.3/src/tui/light_windows.go     2025-03-03 09:10:49.000000000 
+0100
@@ -18,6 +18,7 @@
 var (
        consoleFlagsInput  = uint32(windows.ENABLE_VIRTUAL_TERMINAL_INPUT | 
windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_EXTENDED_FLAGS)
        consoleFlagsOutput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING 
| windows.ENABLE_PROCESSED_OUTPUT | windows.DISABLE_NEWLINE_AUTO_RETURN)
+       counter            = uint64(0)
 )
 
 // IsLightRendererSupported checks to see if the Light renderer is supported
@@ -61,27 +62,11 @@
        }
        r.inHandle = uintptr(inHandle)
 
-       r.setupTerminal()
-
        // channel for non-blocking reads. Buffer to make sure
        // we get the ESC sets:
        r.ttyinChannel = make(chan byte, 1024)
 
-       // the following allows for non-blocking IO.
-       // syscall.SetNonblock() is a NOOP under Windows.
-       go func() {
-               fd := int(r.inHandle)
-               b := make([]byte, 1)
-               for !r.closed.Get() {
-                       // HACK: if run from PSReadline, something resets 
ConsoleMode to remove ENABLE_VIRTUAL_TERMINAL_INPUT.
-                       _ = windows.SetConsoleMode(windows.Handle(r.inHandle), 
consoleFlagsInput)
-
-                       _, err := util.Read(fd, b)
-                       if err == nil {
-                               r.ttyinChannel <- b[0]
-                       }
-               }
-       }()
+       r.setupTerminal()
 
        return nil
 }
@@ -100,18 +85,42 @@
        return os.Stderr, nil
 }
 
-func (r *LightRenderer) setupTerminal() error {
-       if err := windows.SetConsoleMode(windows.Handle(r.outHandle), 
consoleFlagsOutput); err != nil {
-               return err
-       }
-       return windows.SetConsoleMode(windows.Handle(r.inHandle), 
consoleFlagsInput)
+func (r *LightRenderer) setupTerminal() {
+       windows.SetConsoleMode(windows.Handle(r.outHandle), consoleFlagsOutput)
+       windows.SetConsoleMode(windows.Handle(r.inHandle), consoleFlagsInput)
+
+       // The following allows for non-blocking IO.
+       // syscall.SetNonblock() is a NOOP under Windows.
+       current := counter
+       go func() {
+               fd := int(r.inHandle)
+               b := make([]byte, 1)
+               for {
+                       if _, err := util.Read(fd, b); err == nil {
+                               r.mutex.Lock()
+                               // This condition prevents the goroutine from 
running after the renderer
+                               // has been closed or paused.
+                               if current != counter {
+                                       r.mutex.Unlock()
+                                       break
+                               }
+                               r.ttyinChannel <- b[0]
+                               // HACK: if run from PSReadline, something 
resets ConsoleMode to remove ENABLE_VIRTUAL_TERMINAL_INPUT.
+                               
windows.SetConsoleMode(windows.Handle(r.inHandle), consoleFlagsInput)
+                               r.mutex.Unlock()
+                       }
+               }
+       }()
 }
 
-func (r *LightRenderer) restoreTerminal() error {
-       if err := windows.SetConsoleMode(windows.Handle(r.inHandle), 
r.origStateInput); err != nil {
-               return err
-       }
-       return windows.SetConsoleMode(windows.Handle(r.outHandle), 
r.origStateOutput)
+func (r *LightRenderer) restoreTerminal() {
+       r.mutex.Lock()
+       counter++
+       // We're setting ENABLE_VIRTUAL_TERMINAL_INPUT to allow escape 
sequences to be read during 'execute'.
+       // e.g. fzf --bind 'enter:execute:less {}'
+       windows.SetConsoleMode(windows.Handle(r.inHandle), 
r.origStateInput|windows.ENABLE_VIRTUAL_TERMINAL_INPUT)
+       windows.SetConsoleMode(windows.Handle(r.outHandle), r.origStateOutput)
+       r.mutex.Unlock()
 }
 
 func (r *LightRenderer) Size() TermSize {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/src/util/chars.go 
new/fzf-0.60.3/src/util/chars.go
--- old/fzf-0.60.0/src/util/chars.go    2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/src/util/chars.go    2025-03-03 09:10:49.000000000 +0100
@@ -184,6 +184,11 @@
        return whitespaces
 }
 
+func (chars *Chars) TrimTrailingWhitespaces() {
+       whitespaces := chars.TrailingWhitespaces()
+       chars.slice = chars.slice[0 : len(chars.slice)-whitespaces]
+}
+
 func (chars *Chars) TrimSuffix(runes []rune) {
        lastIdx := len(chars.slice)
        firstIdx := lastIdx - len(runes)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/test/test_core.rb 
new/fzf-0.60.3/test/test_core.rb
--- old/fzf-0.60.0/test/test_core.rb    2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/test/test_core.rb    2025-03-03 09:10:49.000000000 +0100
@@ -238,6 +238,11 @@
     assert_equal %w[5555 55], fzf_output_lines
   end
 
+  def test_select_1_accept_nth
+    tmux.send_keys "seq 1 100 | #{fzf(:with_nth, '..,..', :print_query, :q, 
5555, :'1', :accept_nth, '"{1} // {1}"')}", :Enter
+    assert_equal ['5555', '55 // 55'], fzf_output_lines
+  end
+
   def test_exit_0
     tmux.send_keys "seq 1 100 | #{fzf(:with_nth, '..,..', :print_query, :q, 
555_555, :'0')}", :Enter
     assert_equal %w[555555], fzf_output_lines
@@ -827,6 +832,24 @@
     tmux.until { |lines| assert(lines.any? { it.include?('jump cancelled at 
3') }) }
   end
 
+  def test_jump_no_pointer
+    tmux.send_keys "seq 100 | #{FZF} --pointer= --jump-labels 12345 --bind 
ctrl-j:jump", :Enter
+    tmux.until { |lines| assert_equal 100, lines.match_count }
+    tmux.send_keys 'C-j'
+    tmux.until { |lines| assert_equal '5 5', lines[-7] }
+    tmux.send_keys 'C-c'
+    tmux.until { |lines| assert_equal ' 5', lines[-7] }
+  end
+
+  def test_jump_no_pointer_no_marker
+    tmux.send_keys "seq 100 | #{FZF} --pointer= --marker= --jump-labels 12345 
--bind ctrl-j:jump", :Enter
+    tmux.until { |lines| assert_equal 100, lines.match_count }
+    tmux.send_keys 'C-j'
+    tmux.until { |lines| assert_equal '55', lines[-7] }
+    tmux.send_keys 'C-c'
+    tmux.until { |lines| assert_equal '5', lines[-7] }
+  end
+
   def test_pointer
     tmux.send_keys "seq 10 | #{fzf("--pointer '>>'")}", :Enter
     # Assert that specified pointer is displayed
@@ -1773,12 +1796,21 @@
     end
   end
 
+  def test_accept_nth_regex_delimiter_strip_last
+    tmux.send_keys %((echo "foo:,bar:,baz"; echo "foo:,bar:,baz:,qux:,") | 
#{FZF} --multi --delimiter='[:,]+' --accept-nth 2.. --sync --bind 
'load:select-all+accept' > #{tempname}), :Enter
+    wait do
+      assert_path_exists tempname
+      # Last delimiter and the whitespaces are removed
+      assert_equal ['bar:,baz', 'bar:,baz:,qux'], File.readlines(tempname, 
chomp: true)
+    end
+  end
+
   def test_accept_nth_template
-    tmux.send_keys %(echo "foo  ,bar,baz" | #{FZF} -d, --accept-nth '1st: {1}, 
3rd: {3}, 2nd: {2}' --sync --bind start:accept > #{tempname}), :Enter
+    tmux.send_keys %(echo "foo  ,bar,baz" | #{FZF} -d, --accept-nth '[{n}] 
1st: {1}, 3rd: {3}, 2nd: {2}' --sync --bind start:accept > #{tempname}), :Enter
     wait do
       assert_path_exists tempname
       # Last delimiter and the whitespaces are removed
-      assert_equal ['1st: foo, 3rd: baz, 2nd: bar'], File.readlines(tempname, 
chomp: true)
+      assert_equal ['[0] 1st: foo, 3rd: baz, 2nd: bar'], 
File.readlines(tempname, chomp: true)
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/test/test_preview.rb 
new/fzf-0.60.3/test/test_preview.rb
--- old/fzf-0.60.0/test/test_preview.rb 2025-02-12 16:54:21.000000000 +0100
+++ new/fzf-0.60.3/test/test_preview.rb 2025-03-03 09:10:49.000000000 +0100
@@ -544,4 +544,18 @@
     tmux.send_keys :Up
     tmux.until { |lines| assert_includes lines, '> 2' }
   end
+
+  def test_preview_query_should_not_be_affected_by_search
+    tmux.send_keys "seq 1 | #{FZF} --bind 'change:transform-search(echo 
{q:1})' --preview 'echo [{q}/{}]'", :Enter
+    tmux.until { |lines| assert_equal 1, lines.match_count }
+    tmux.send_keys '1'
+    tmux.until { |lines| assert lines.any_include?('[1/1]') }
+    tmux.send_keys :Space
+    tmux.until { |lines| assert lines.any_include?('[1 /1]') }
+    tmux.send_keys '2'
+    tmux.until do |lines|
+      assert lines.any_include?('[1 2/1]')
+      assert_equal 1, lines.match_count
+    end
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.60.0/test/test_shell_integration.rb 
new/fzf-0.60.3/test/test_shell_integration.rb
--- old/fzf-0.60.0/test/test_shell_integration.rb       2025-02-12 
16:54:21.000000000 +0100
+++ new/fzf-0.60.3/test/test_shell_integration.rb       2025-03-03 
09:10:49.000000000 +0100
@@ -73,7 +73,7 @@
     tmux.prepare
     tmux.send_keys :Escape, :c
     lines = tmux.until { |lines| assert_operator lines.match_count, :>, 0 }
-    expected = lines.reverse.find { |l| l.start_with?('> ') }[2..]
+    expected = lines.reverse.find { |l| l.start_with?('> ') }[2..].chomp('/')
     tmux.send_keys :Enter
     tmux.prepare
     tmux.send_keys :pwd, :Enter
@@ -241,7 +241,7 @@
     tmux.until do |lines|
       assert_equal 1, lines.match_count
       assert_includes lines, '> 55'
-      assert_includes lines, '> /tmp/fzf-test/d55'
+      assert_includes lines, '> /tmp/fzf-test/d55/'
     end
     tmux.send_keys :Enter
     tmux.until(true) { |lines| assert_equal 'cd /tmp/fzf-test/d55/', lines[-1] 
}
@@ -482,4 +482,36 @@
     tmux.send_keys "set -g #{name} '#{val}'", :Enter
     tmux.prepare
   end
+
+  def test_ctrl_r_multi
+    tmux.send_keys ':', :Enter
+    tmux.send_keys 'echo "foo', :Enter, 'bar"', :Enter
+    tmux.prepare
+    tmux.send_keys 'echo "bar', :Enter, 'foo"', :Enter
+    tmux.prepare
+    tmux.send_keys 'C-l', 'C-r'
+    block = <<~BLOCK
+      echo "foo
+      bar"
+      echo "bar
+      foo"
+    BLOCK
+    tmux.until do |lines|
+      block.lines.each_with_index do |line, idx|
+        assert_includes lines[-6 + idx], line.chomp
+      end
+    end
+    tmux.send_keys :BTab, :BTab
+    tmux.until { |lines| assert_includes lines[-2], '(2)' }
+    tmux.send_keys :Enter
+    block = <<~BLOCK
+      echo "bar
+      foo"
+      echo "foo
+      bar"
+    BLOCK
+    tmux.until do |lines|
+      assert_equal block.lines.map(&:chomp), lines
+    end
+  end
 end

Reply via email to