Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fzf for openSUSE:Factory checked in 
at 2023-04-19 17:44:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fzf (Old)
 and      /work/SRC/openSUSE:Factory/.fzf.new.2023 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fzf"

Wed Apr 19 17:44:27 2023 rev:32 rq:1080294 version:0.39.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/fzf/fzf.changes  2023-04-13 14:10:59.432380290 
+0200
+++ /work/SRC/openSUSE:Factory/.fzf.new.2023/fzf.changes        2023-04-19 
17:44:34.680751628 +0200
@@ -1,0 +2,20 @@
+Wed Apr 19 04:26:40 UTC 2023 - Luciano Santos <luc1...@opensuse.org>
+
+- Update to version 0.39.0:
+  * Added 'one' event that is triggered when there's only one
+    match.
+  * Added --track option that makes fzf track the current selection
+    when the result list is updated. This can be useful when
+    browsing logs using fzf with sorting disabled.
+  * If you use --listen option without a port number fzf will
+    automatically allocate an available port and export it as
+    $FZF_PORT environment variable.
+  * A carriage return and a line feed character will be rendered as
+    dim ␍ and ␊ respectively.
+  * fzf will stop rendering a non-displayable characters as a
+    space. This will likely cause less glitches in the preview
+    window.
+  * Other bug fixes and improvements.
+- Update vendor tarball.
+
+-------------------------------------------------------------------

Old:
----
  fzf-0.38.0.tar.gz

New:
----
  fzf-0.39.0.tar.gz

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

Other differences:
------------------
++++++ fzf.spec ++++++
--- /var/tmp/diff_new_pack.VzgyC6/_old  2023-04-19 17:44:38.064771289 +0200
+++ /var/tmp/diff_new_pack.VzgyC6/_new  2023-04-19 17:44:38.072771336 +0200
@@ -18,7 +18,7 @@
 
 %global _lto_cflags %nil
 Name:           fzf
-Version:        0.38.0
+Version:        0.39.0
 Release:        0
 Summary:        A command-line fuzzy finder
 License:        MIT

++++++ fzf-0.38.0.tar.gz -> fzf-0.39.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/.github/workflows/linux.yml 
new/fzf-0.39.0/.github/workflows/linux.yml
--- old/fzf-0.38.0/.github/workflows/linux.yml  2023-02-15 15:24:42.000000000 
+0100
+++ new/fzf-0.39.0/.github/workflows/linux.yml  2023-04-02 16:33:37.000000000 
+0200
@@ -20,7 +20,7 @@
         fetch-depth: 0
 
     - name: Set up Go
-      uses: actions/setup-go@v3
+      uses: actions/setup-go@v4
       with:
         go-version: 1.19
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/.github/workflows/macos.yml 
new/fzf-0.39.0/.github/workflows/macos.yml
--- old/fzf-0.38.0/.github/workflows/macos.yml  2023-02-15 15:24:42.000000000 
+0100
+++ new/fzf-0.39.0/.github/workflows/macos.yml  2023-04-02 16:33:37.000000000 
+0200
@@ -20,7 +20,7 @@
         fetch-depth: 0
 
     - name: Set up Go
-      uses: actions/setup-go@v3
+      uses: actions/setup-go@v4
       with:
         go-version: 1.18
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/.github/workflows/typos.yml 
new/fzf-0.39.0/.github/workflows/typos.yml
--- old/fzf-0.38.0/.github/workflows/typos.yml  1970-01-01 01:00:00.000000000 
+0100
+++ new/fzf-0.39.0/.github/workflows/typos.yml  2023-04-02 16:33:37.000000000 
+0200
@@ -0,0 +1,10 @@
+name: "Spell Check"
+on: [pull_request]
+
+jobs:
+  typos:
+    name: Spell Check with Typos
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    - uses: crate-ci/typos@v1.13.16
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/.goreleaser.yml 
new/fzf-0.39.0/.goreleaser.yml
--- old/fzf-0.38.0/.goreleaser.yml      2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/.goreleaser.yml      2023-04-02 16:33:37.000000000 +0200
@@ -74,6 +74,7 @@
       - arm64
       - loong64
       - ppc64le
+      - s390x
     goarm:
       - 5
       - 6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/.tool-versions 
new/fzf-0.39.0/.tool-versions
--- old/fzf-0.38.0/.tool-versions       2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/.tool-versions       2023-04-02 16:33:37.000000000 +0200
@@ -1 +1 @@
-golang 1.19
+golang 1.20.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/CHANGELOG.md new/fzf-0.39.0/CHANGELOG.md
--- old/fzf-0.38.0/CHANGELOG.md 2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/CHANGELOG.md 2023-04-02 16:33:37.000000000 +0200
@@ -1,6 +1,42 @@
 CHANGELOG
 =========
 
+0.39.0
+------
+- Added `one` event that is triggered when there's only one match
+  ```sh
+  # Automatically select the only match
+  seq 10 | fzf --bind one:accept
+  ```
+- Added `--track` option that makes fzf track the current selection when the
+  result list is updated. This can be useful when browsing logs using fzf with
+  sorting disabled.
+  ```sh
+  git log --oneline --graph --color=always | nl |
+      fzf --ansi --track --no-sort --layout=reverse-list
+  ```
+- If you use `--listen` option without a port number fzf will automatically
+  allocate an available port and export it as `$FZF_PORT` environment
+  variable.
+  ```sh
+  # Automatic port assignment
+  fzf --listen --bind 'start:execute-silent:echo $FZF_PORT > /tmp/fzf-port'
+
+  # Say hello
+  curl "localhost:$(cat /tmp/fzf-port)" -d 'preview:echo Hello, fzf is 
listening on $FZF_PORT.'
+  ```
+- A carriage return and a line feed character will be rendered as dim ␍ and
+  ␊ respectively.
+  ```sh
+  printf "foo\rbar\nbaz" | fzf --read0 --preview 'echo {}'
+  ```
+- fzf will stop rendering a non-displayable characters as a space. This will
+  likely cause less glitches in the preview window.
+  ```sh
+  fzf --preview 'head -1000 /dev/random'
+  ```
+- Bug fixes and improvements
+
 0.38.0
 ------
 - New actions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/Makefile new/fzf-0.39.0/Makefile
--- old/fzf-0.38.0/Makefile     2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/Makefile     2023-04-02 16:33:37.000000000 +0200
@@ -20,7 +20,7 @@
 ifdef FZF_REVISION
 REVISION       := $(FZF_REVISION)
 else
-REVISION       := $(shell git log -n 1 --pretty=format:%h -- $(SOURCES) 2> 
/dev/null)
+REVISION       := $(shell git log -n 1 --pretty=format:%h --abbrev=8 -- 
$(SOURCES) 2> /dev/null)
 endif
 ifeq ($(REVISION),)
 $(error Not on git repository; cannot determine $$FZF_REVISION)
@@ -29,6 +29,7 @@
 
 BINARY32       := fzf-$(GOOS)_386
 BINARY64       := fzf-$(GOOS)_amd64
+BINARYS390     := fzf-$(GOOS)_s390x
 BINARYARM5     := fzf-$(GOOS)_arm5
 BINARYARM6     := fzf-$(GOOS)_arm6
 BINARYARM7     := fzf-$(GOOS)_arm7
@@ -43,6 +44,8 @@
        BINARY := $(BINARY64)
 else ifeq ($(UNAME_M),amd64)
        BINARY := $(BINARY64)
+else ifeq ($(UNAME_M),s390x)
+       BINARY := $(BINARYS390)
 else ifeq ($(UNAME_M),i686)
        BINARY := $(BINARY32)
 else ifeq ($(UNAME_M),i386)
@@ -132,6 +135,8 @@
 target/$(BINARY64): $(SOURCES)
        GOARCH=amd64 $(GO) build $(BUILD_FLAGS) -o $@
 
+target/$(BINARYS390): $(SOURCES)
+       GOARCH=s390x $(GO) build $(BUILD_FLAGS) -o $@
 # https://github.com/golang/go/wiki/GoArm
 target/$(BINARYARM5): $(SOURCES)
        GOARCH=arm GOARM=5 $(GO) build $(BUILD_FLAGS) -o $@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/README-VIM.md new/fzf-0.39.0/README-VIM.md
--- old/fzf-0.38.0/README-VIM.md        2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/README-VIM.md        2023-04-02 16:33:37.000000000 +0200
@@ -15,7 +15,7 @@
 " If installed using Homebrew on Apple Silicon
 set rtp+=/opt/homebrew/opt/fzf
 
-" If installed using git
+" If you have cloned fzf on ~/.fzf directory
 set rtp+=~/.fzf
 ```
 
@@ -26,7 +26,7 @@
 " If installed using Homebrew
 Plug '/usr/local/opt/fzf'
 
-" If installed using git
+" If you have cloned fzf on ~/.fzf directory
 Plug '~/.fzf'
 ```
 
@@ -118,7 +118,7 @@
 
 " An action can be a reference to a function that processes selected lines
 function! s:build_quickfix_list(lines)
-  call setqflist(map(copy(a:lines), '{ "filename": v:val }'))
+  call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }'))
   copen
   cc
 endfunction
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/README.md new/fzf-0.39.0/README.md
--- old/fzf-0.38.0/README.md    2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/README.md    2023-04-02 16:33:37.000000000 +0200
@@ -61,8 +61,8 @@
         * [3. Interactive ripgrep 
integration](#3-interactive-ripgrep-integration)
     * [Preview window](#preview-window)
 * [Tips](#tips)
-        * [Respecting `.gitignore`](#respecting-gitignore)
-        * [Fish shell](#fish-shell)
+    * [Respecting `.gitignore`](#respecting-gitignore)
+    * [Fish shell](#fish-shell)
 * [Related projects](#related-projects)
 * [License](#license)
 
@@ -124,6 +124,7 @@
 | pkg             | FreeBSD                 | `pkg install fzf`                
  |
 | pkgin           | NetBSD                  | `pkgin install fzf`              
  |
 | pkg_add         | OpenBSD                 | `pkg_add fzf`                    
  |
+| Portage         | Gentoo                  | `emerge --ask app-shells/fzf`    
  |
 | XBPS            | Void Linux              | `sudo xbps-install -S fzf`       
  |
 | Zypper          | openSUSE                | `sudo zypper install fzf`        
  |
 
@@ -723,7 +724,7 @@
 Tips
 ----
 
-#### Respecting `.gitignore`
+### Respecting `.gitignore`
 
 You can use [fd](https://github.com/sharkdp/fd),
 [ripgrep](https://github.com/BurntSushi/ripgrep), or [the silver
@@ -752,7 +753,7 @@
 export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow 
--exclude .git'
 ```
 
-#### Fish shell
+### Fish shell
 
 `CTRL-T` key binding of fish, unlike those of bash and zsh, will use the last
 token on the command-line as the root directory for the recursive search. For
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/bin/fzf-tmux new/fzf-0.39.0/bin/fzf-tmux
--- old/fzf-0.38.0/bin/fzf-tmux 2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/bin/fzf-tmux 2023-04-02 16:33:37.000000000 +0200
@@ -179,12 +179,15 @@
 
 envs="export TERM=$TERM "
 if [[ "$opt" =~ "-E" ]]; then
-  tmux_version=$(tmux -V)
-  if [[ $tmux_version =~ ^tmux\ 3\.2[a-z]?$ ]]; then
-    FZF_DEFAULT_OPTS="--margin 0,1 $FZF_DEFAULT_OPTS"
-  else
+  tmux_version=$(tmux -V | sed 's/[^0-9.]//g')
+  if [[ $(bc -l <<< "$tmux_version > 3.2") = 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
   fi
 fi
 [[ -n "$FZF_DEFAULT_OPTS"    ]] && envs="$envs FZF_DEFAULT_OPTS=$(printf %q 
"$FZF_DEFAULT_OPTS")"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/doc/fzf.txt new/fzf-0.39.0/doc/fzf.txt
--- old/fzf-0.38.0/doc/fzf.txt  2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/doc/fzf.txt  2023-04-02 16:33:37.000000000 +0200
@@ -1,4 +1,4 @@
-fzf.txt        fzf     Last change: May 19 2021
+fzf.txt        fzf     Last change: Mar 20 2023
 FZF - TABLE OF CONTENTS                                            *fzf* 
*fzf-toc*
 ==============================================================================
 
@@ -32,7 +32,7 @@
     " If installed using Homebrew
     set rtp+=/usr/local/opt/fzf
 
-    " If installed using git
+    " If you have cloned fzf on ~/.fzf directory
     set rtp+=~/.fzf
 <
 If you use {vim-plug}{1}, the same can be written as:
@@ -40,7 +40,7 @@
     " If installed using Homebrew
     Plug '/usr/local/opt/fzf'
 
-    " If installed using git
+    " If you have cloned fzf on ~/.fzf directory
     Plug '~/.fzf'
 <
 But if you want the latest Vim plugin file from GitHub rather than the one
@@ -143,7 +143,7 @@
 
     " An action can be a reference to a function that processes selected lines
     function! s:build_quickfix_list(lines)
-      call setqflist(map(copy(a:lines), '{ "filename": v:val }'))
+      call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }'))
       copen
       cc
     endfunction
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/go.mod new/fzf-0.39.0/go.mod
--- old/fzf-0.38.0/go.mod       2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/go.mod       2023-04-02 16:33:37.000000000 +0200
@@ -5,10 +5,10 @@
        github.com/mattn/go-isatty v0.0.17
        github.com/mattn/go-runewidth v0.0.14
        github.com/mattn/go-shellwords v1.0.12
-       github.com/rivo/uniseg v0.4.2
+       github.com/rivo/uniseg v0.4.4
        github.com/saracen/walker v0.1.3
-       golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
-       golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
+       golang.org/x/sys v0.6.0
+       golang.org/x/term v0.6.0
 )
 
 require (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/go.sum new/fzf-0.39.0/go.sum
--- old/fzf-0.38.0/go.sum       2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/go.sum       2023-04-02 16:33:37.000000000 +0200
@@ -11,8 +11,8 @@
 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.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
-github.com/rivo/uniseg v0.4.2/go.mod 
h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
+github.com/rivo/uniseg v0.4.4/go.mod 
h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/saracen/walker v0.1.3 
h1:YtcKKmpRPy6XJTHJ75J2QYXXZYWnZNQxPCVqZSHVV/g=
 github.com/saracen/walker v0.1.3/go.mod 
h1:FU+7qU8DeQQgSZDmmThMJi93kPkLFgy0oVAcLxurjIk=
 github.com/yuin/goldmark v1.4.13/go.mod 
h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -31,11 +31,13 @@
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab 
h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 
h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 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.38.0/install new/fzf-0.39.0/install
--- old/fzf-0.38.0/install      2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/install      2023-04-02 16:33:37.000000000 +0200
@@ -2,7 +2,7 @@
 
 set -u
 
-version=0.38.0
+version=0.39.0
 auto_completion=
 key_bindings=
 update_config=2
@@ -178,6 +178,7 @@
   Linux\ loongarch64) download fzf-$version-linux_loong64.tar.gz ;;
   Linux\ ppc64le)     download fzf-$version-linux_ppc64le.tar.gz ;;
   Linux\ *64)         download fzf-$version-linux_amd64.tar.gz   ;;
+  Linux\ s390x)       download fzf-$version-linux_s390x.tar.gz   ;;
   FreeBSD\ *64)       download fzf-$version-freebsd_amd64.tar.gz ;;
   OpenBSD\ *64)       download fzf-$version-openbsd_amd64.tar.gz ;;
   CYGWIN*\ *64)       download fzf-$version-windows_amd64.zip    ;;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/install.ps1 new/fzf-0.39.0/install.ps1
--- old/fzf-0.38.0/install.ps1  2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/install.ps1  2023-04-02 16:33:37.000000000 +0200
@@ -1,4 +1,4 @@
-$version="0.38.0"
+$version="0.39.0"
 
 $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/main.go new/fzf-0.39.0/main.go
--- old/fzf-0.38.0/main.go      2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/main.go      2023-04-02 16:33:37.000000000 +0200
@@ -5,7 +5,7 @@
        "github.com/junegunn/fzf/src/protector"
 )
 
-var version string = "0.38"
+var version string = "0.39"
 var revision string = "devel"
 
 func main() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/man/man1/fzf-tmux.1 
new/fzf-0.39.0/man/man1/fzf-tmux.1
--- old/fzf-0.38.0/man/man1/fzf-tmux.1  2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/man/man1/fzf-tmux.1  2023-04-02 16:33:37.000000000 +0200
@@ -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 2023" "fzf 0.38.0" "fzf-tmux - open fzf in tmux split pane"
+.TH fzf-tmux 1 "Apr 2023" "fzf 0.39.0" "fzf-tmux - open fzf in tmux split pane"
 
 .SH NAME
 fzf-tmux - open fzf in tmux split pane
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/man/man1/fzf.1 
new/fzf-0.39.0/man/man1/fzf.1
--- old/fzf-0.38.0/man/man1/fzf.1       2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/man/man1/fzf.1       2023-04-02 16:33:37.000000000 +0200
@@ -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 2023" "fzf 0.38.0" "fzf - a command-line fuzzy finder"
+.TH fzf 1 "Apr 2023" "fzf 0.39.0" "fzf - a command-line fuzzy finder"
 
 .SH NAME
 fzf - a command-line fuzzy finder
@@ -92,6 +92,16 @@
 .B "+s, --no-sort"
 Do not sort the result
 .TP
+.B "--track"
+Make fzf track the current selection when the result list is updated.
+This can be useful when browsing logs using fzf with sorting disabled.
+
+.RS
+e.g.
+     \fBgit log --oneline --graph --color=always | nl |
+         fzf --ansi --track --no-sort --layout=reverse-list\fR
+.RE
+.TP
 .B "--tac"
 Reverse the order of the input
 
@@ -738,9 +748,12 @@
 e.g. \fBfzf --multi | fzf --sync\fR
 .RE
 .TP
-.B "--listen=HTTP_PORT"
+.B "--listen[=HTTP_PORT]"
 Start HTTP server on the given port. It allows external processes to send
-actions to perform via POST method.
+actions to perform via POST method. If the port number is omitted or given as
+0, fzf will choose the port automatically and export it as \fBFZF_PORT\fR
+environment variable to the child processes started via \fBexecute\fR and
+\fBexecute-silent\fR actions.
 
 e.g.
      \fB# Start HTTP server on port 6266
@@ -748,6 +761,9 @@
 
      # Send action to the server
      curl -XPOST localhost:6266 -d 'reload(seq 100)+change-prompt(hundred> )'
+
+     # Choose port automatically and export it as $FZF_PORT to the child 
process
+     fzf --listen --bind 'start:execute-silent:echo $FZF_PORT > /tmp/fzf-port'
      \fR
 .TP
 .B "--version"
@@ -977,6 +993,17 @@
      # Beware not to introduce an infinite loop
      seq 10 | fzf --bind 'focus:up' --cycle\fR
 .RE
+\fIone\fR
+.RS
+Triggered when there's only one match. \fBone:accept\fR binding is comparable
+to \fB--select-1\fR option, but the difference is that \fB--select-1\fR is only
+effective before the interactive finder starts but \fBone\fR event is triggered
+by the interactive finder.
+
+e.g.
+     \fB# Automatically select the only match
+     seq 10 | fzf --bind one:accept\fR
+.RE
 
 \fIbackward-eof\fR
 .RS
@@ -1145,7 +1172,7 @@
 POSIX-compliant.
 
 \fBbecome(...)\fR action is similar to \fBexecute(...)\fR, but it replaces the
-current fzf process with the specifed command using \fBexecve(2)\fR system
+current fzf process with the specified command using \fBexecve(2)\fR system
 call.
 
     \fBfzf --bind "enter:become(vim {})"\fR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/shell/completion.bash 
new/fzf-0.39.0/shell/completion.bash
--- old/fzf-0.38.0/shell/completion.bash        2023-02-15 15:24:42.000000000 
+0100
+++ new/fzf-0.39.0/shell/completion.bash        2023-04-02 16:33:37.000000000 
+0200
@@ -270,8 +270,9 @@
 }
 
 _fzf_proc_completion() {
-  _fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap 
--min-height 15 -- "$@" < <(
-    command ps -ef | sed 1d
+  _fzf_complete -m --header-lines=1 --preview 'echo {}' --preview-window 
down:3:wrap --min-height 15 -- "$@" < <(
+    command ps -eo user,pid,ppid,start,time,command 2> /dev/null ||
+      command ps -eo user,pid,ppid,time,args # For BusyBox
   )
 }
 
@@ -309,7 +310,7 @@
 
 d_cmds="${FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir}"
 a_cmds="
-  awk cat diff diff3
+  awk bat cat diff diff3
   emacs emacsclient ex file ftp g++ gcc gvim head hg hx java
   javac ld less more mvim nvim patch perl python ruby
   sed sftp sort source tail tee uniq vi view vim wc xdg-open
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/shell/completion.zsh 
new/fzf-0.39.0/shell/completion.zsh
--- old/fzf-0.38.0/shell/completion.zsh 2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/shell/completion.zsh 2023-04-02 16:33:37.000000000 +0200
@@ -251,8 +251,9 @@
 }
 
 _fzf_complete_kill() {
-  _fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap 
--min-height 15 -- "$@" < <(
-    command ps -ef | sed 1d
+  _fzf_complete -m --header-lines=1 --preview 'echo {}' --preview-window 
down:3:wrap --min-height 15 -- "$@" < <(
+    command ps -eo user,pid,ppid,start,time,command 2> /dev/null ||
+      command ps -eo user,pid,ppid,time,args # For BusyBox
   )
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/core.go new/fzf-0.39.0/src/core.go
--- old/fzf-0.38.0/src/core.go  2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/core.go  2023-04-02 16:33:37.000000000 +0200
@@ -219,6 +219,7 @@
        determine := func(final bool) {
                if heightUnknown {
                        if total >= maxFit || final {
+                               deferred = false
                                heightUnknown = false
                                terminal.startChan <- fitpad{util.Min(total, 
maxFit), padHeight}
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/merger.go new/fzf-0.39.0/src/merger.go
--- old/fzf-0.38.0/src/merger.go        2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/merger.go        2023-04-02 16:33:37.000000000 +0200
@@ -17,6 +17,7 @@
        tac     bool
        final   bool
        count   int
+       pass    bool
 }
 
 // PassMerger returns a new Merger that simply returns the items in the
@@ -26,7 +27,8 @@
                pattern: nil,
                chunks:  chunks,
                tac:     tac,
-               count:   0}
+               count:   0,
+               pass:    true}
 
        for _, chunk := range *mg.chunks {
                mg.count += chunk.count
@@ -58,6 +60,19 @@
        return mg.count
 }
 
+// FindIndex returns the index of the item with the given item index
+func (mg *Merger) FindIndex(itemIndex int32) int {
+       if mg.pass {
+               return int(itemIndex)
+       }
+       for i := 0; i < mg.count; i++ {
+               if mg.Get(i).item.Index() == itemIndex {
+                       return i
+               }
+       }
+       return -1
+}
+
 // Get returns the pointer to the Result object indexed by the given integer
 func (mg *Merger) Get(idx int) Result {
        if mg.chunks != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/options.go 
new/fzf-0.39.0/src/options.go
--- old/fzf-0.38.0/src/options.go       2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/options.go       2023-04-02 16:33:37.000000000 +0200
@@ -33,6 +33,7 @@
                            field index expressions
     -d, --delimiter=STR    Field delimiter regex (default: AWK-style)
     +s, --no-sort          Do not sort the result
+    --track                Track the current selection when the result is 
updated
     --tac                  Reverse the order of the input
     --disabled             Do not perform search
     --tiebreak=CRI[,..]    Comma-separated list of sort criteria to apply
@@ -116,7 +117,7 @@
     --read0                Read input delimited by ASCII NUL characters
     --print0               Print output delimited by ASCII NUL characters
     --sync                 Synchronous search for multi-staged filtering
-    --listen=HTTP_PORT     Start HTTP server to receive actions (POST /)
+    --listen[=HTTP_PORT]   Start HTTP server to receive actions (POST /)
     --version              Display version information and exit
 
   Environment variables
@@ -266,6 +267,7 @@
        WithNth      []Range
        Delimiter    Delimiter
        Sort         int
+       Track        bool
        Tac          bool
        Criteria     []criterion
        Multi        int
@@ -316,7 +318,7 @@
        PreviewLabel labelOpts
        Unicode      bool
        Tabstop      int
-       ListenPort   int
+       ListenPort   *int
        ClearOnExit  bool
        Version      bool
 }
@@ -338,6 +340,7 @@
                WithNth:      make([]Range, 0),
                Delimiter:    Delimiter{},
                Sort:         1000,
+               Track:        false,
                Tac:          false,
                Criteria:     []criterion{byScore, byLength},
                Multi:        0,
@@ -619,6 +622,8 @@
                        add(tui.Load)
                case "focus":
                        add(tui.Focus)
+               case "one":
+                       add(tui.One)
                case "alt-enter", "alt-return":
                        chords[tui.CtrlAltKey('m')] = key
                case "alt-space":
@@ -1562,6 +1567,10 @@
                        opts.Sort = optionalNumeric(allArgs, &i, 1)
                case "+s", "--no-sort":
                        opts.Sort = 0
+               case "--track":
+                       opts.Track = true
+               case "--no-track":
+                       opts.Track = false
                case "--tac":
                        opts.Tac = true
                case "--no-tac":
@@ -1756,9 +1765,10 @@
                case "--tabstop":
                        opts.Tabstop = nextInt(allArgs, &i, "tab stop required")
                case "--listen":
-                       opts.ListenPort = nextInt(allArgs, &i, "listen port 
required")
+                       port := optionalNumeric(allArgs, &i, 0)
+                       opts.ListenPort = &port
                case "--no-listen":
-                       opts.ListenPort = 0
+                       opts.ListenPort = nil
                case "--clear":
                        opts.ClearOnExit = true
                case "--no-clear":
@@ -1849,7 +1859,8 @@
                        } else if match, value := optString(arg, "--tabstop="); 
match {
                                opts.Tabstop = atoi(value)
                        } else if match, value := optString(arg, "--listen="); 
match {
-                               opts.ListenPort = atoi(value)
+                               port := atoi(value)
+                               opts.ListenPort = &port
                        } else if match, value := optString(arg, 
"--hscroll-off="); match {
                                opts.HscrollOff = atoi(value)
                        } else if match, value := optString(arg, 
"--scroll-off="); match {
@@ -1879,7 +1890,7 @@
                errorExit("tab stop must be a positive integer")
        }
 
-       if opts.ListenPort < 0 || opts.ListenPort > 65535 {
+       if opts.ListenPort != nil && (*opts.ListenPort < 0 || *opts.ListenPort 
> 65535) {
                errorExit("invalid listen port")
        }
 
@@ -2001,9 +2012,7 @@
                theme := opts.Theme
                boldify := func(c tui.ColorAttr) tui.ColorAttr {
                        dup := c
-                       if !theme.Colored {
-                               dup.Attr |= tui.Bold
-                       } else if (c.Attr & tui.AttrRegular) == 0 {
+                       if (c.Attr & tui.AttrRegular) == 0 {
                                dup.Attr |= tui.Bold
                        }
                        return dup
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/server.go new/fzf-0.39.0/src/server.go
--- old/fzf-0.38.0/src/server.go        2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/server.go        2023-04-02 16:33:37.000000000 +0200
@@ -19,14 +19,26 @@
        maxContentLength = 1024 * 1024
 )
 
-func startHttpServer(port int, channel chan []*action) error {
-       if port == 0 {
-               return nil
+func startHttpServer(port int, channel chan []*action) (error, int) {
+       if port < 0 {
+               return nil, port
        }
 
        listener, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
        if err != nil {
-               return fmt.Errorf("port not available: %d", port)
+               return fmt.Errorf("port not available: %d", port), port
+       }
+       if port == 0 {
+               addr := listener.Addr().String()
+               parts := strings.SplitN(addr, ":", 2)
+               if len(parts) < 2 {
+                       return fmt.Errorf("cannot extract port: %s", addr), port
+               }
+               var err error
+               port, err = strconv.Atoi(parts[1])
+               if err != nil {
+                       return err, port
+               }
        }
 
        go func() {
@@ -45,7 +57,7 @@
                listener.Close()
        }()
 
-       return nil
+       return nil, port
 }
 
 // Here we are writing a simplistic HTTP server without using net/http
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/terminal.go 
new/fzf-0.39.0/src/terminal.go
--- old/fzf-0.38.0/src/terminal.go      2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/terminal.go      2023-04-02 16:33:37.000000000 +0200
@@ -183,6 +183,7 @@
        multi              int
        sort               bool
        toggleSort         bool
+       track              bool
        delimiter          Delimiter
        expect             map[tui.Event]string
        keymap             map[tui.Event][]*action
@@ -201,9 +202,8 @@
        tabstop            int
        margin             [4]sizeSpec
        padding            [4]sizeSpec
-       strong             tui.Attr
        unicode            bool
-       listenPort         int
+       listenPort         *int
        borderShape        tui.BorderShape
        cleanExit          bool
        paused             bool
@@ -538,13 +538,9 @@
        }
        var previewBox *util.EventBox
        // We need to start previewer if HTTP server is enabled even when 
--preview option is not specified
-       if len(opts.Preview.command) > 0 || hasPreviewAction(opts) || 
opts.ListenPort > 0 {
+       if len(opts.Preview.command) > 0 || hasPreviewAction(opts) || 
opts.ListenPort != nil {
                previewBox = util.NewEventBox()
        }
-       strongAttr := tui.Bold
-       if !opts.Bold {
-               strongAttr = tui.AttrRegular
-       }
        var renderer tui.Renderer
        fullscreen := !opts.Height.auto && (opts.Height.size == 0 || 
opts.Height.percent && opts.Height.size == 100)
        if fullscreen {
@@ -604,6 +600,7 @@
                multi:              opts.Multi,
                sort:               opts.Sort > 0,
                toggleSort:         opts.ToggleSort,
+               track:              opts.Track,
                delimiter:          opts.Delimiter,
                expect:             opts.Expect,
                keymap:             opts.Keymap,
@@ -623,7 +620,6 @@
                previewLabelOpts:   opts.PreviewLabel,
                cleanExit:          opts.ClearOnExit,
                paused:             opts.Phony,
-               strong:             strongAttr,
                cycle:              opts.Cycle,
                headerFirst:        opts.HeaderFirst,
                headerLines:        opts.HeaderLines,
@@ -694,13 +690,25 @@
 
        _, t.hasLoadActions = t.keymap[tui.Load.AsEvent()]
 
-       if err := startHttpServer(t.listenPort, t.serverChan); err != nil {
-               errorExit(err.Error())
+       if t.listenPort != nil {
+               err, port := startHttpServer(*t.listenPort, t.serverChan)
+               if err != nil {
+                       errorExit(err.Error())
+               }
+               t.listenPort = &port
        }
 
        return &t
 }
 
+func (t *Terminal) environ() []string {
+       env := os.Environ()
+       if t.listenPort != nil {
+               env = append(env, fmt.Sprintf("FZF_PORT=%d", *t.listenPort))
+       }
+       return env
+}
+
 func borderLines(shape tui.BorderShape) int {
        switch shape {
        case tui.BorderHorizontal, tui.BorderRounded, tui.BorderSharp, 
tui.BorderBold, tui.BorderDouble:
@@ -740,7 +748,7 @@
 
        // Simpler printer for strings without ANSI colors or tab characters
        if colors == nil && strings.IndexRune(str, '\t') < 0 {
-               length := runewidth.StringWidth(str)
+               length := util.StringWidth(str)
                if length == 0 {
                        return nil, 0
                }
@@ -898,6 +906,10 @@
 // UpdateList updates Merger to display the list
 func (t *Terminal) UpdateList(merger *Merger, reset bool) {
        t.mutex.Lock()
+       var prevIndex int32 = -1
+       if !reset && t.track && t.merger.Length() > 0 {
+               prevIndex = t.merger.Get(t.cy).item.Index()
+       }
        t.progress = 100
        t.merger = merger
        if reset {
@@ -908,6 +920,24 @@
                t.triggerLoad = false
                t.eventChan <- tui.Load.AsEvent()
        }
+       if prevIndex >= 0 {
+               pos := t.cy - t.offset
+               count := t.merger.Length()
+               i := t.merger.FindIndex(prevIndex)
+               if i >= 0 {
+                       t.cy = i
+                       t.offset = t.cy - pos
+               } else if t.cy > count {
+                       // Try to keep the vertical position when the list 
shrinks
+                       t.cy = count - util.Min(count, t.maxItems()) + pos
+               }
+       }
+       if !t.reading && t.merger.Length() == 1 {
+               one := tui.One.AsEvent()
+               if _, prs := t.keymap[one]; prs {
+                       t.eventChan <- one
+               }
+       }
        t.mutex.Unlock()
        t.reqBox.Set(reqInfo, nil)
        t.reqBox.Set(reqList, nil)
@@ -1338,8 +1368,7 @@
 
        _, overflow := t.trimLeft(t.input[:t.cx], maxWidth)
        minOffset := int(overflow)
-       maxOffset := util.Min(util.Min(len(t.input), minOffset+maxWidth), t.cx)
-
+       maxOffset := minOffset + (maxWidth-util.Max(0, maxWidth-t.cx))/2
        t.xoffset = util.Constrain(t.xoffset, minOffset, maxOffset)
        before, _ := t.trimLeft(t.input[t.xoffset:t.cx], maxWidth)
        beforeLen := t.displayWidth(before)
@@ -1404,7 +1433,7 @@
                pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
                str := t.infoSep
                maxWidth := t.window.Width() - pos
-               width := runewidth.StringWidth(str)
+               width := util.StringWidth(str)
                if width > maxWidth {
                        trimmed, _ := t.trimRight([]rune(str), maxWidth)
                        str = string(trimmed)
@@ -1829,12 +1858,14 @@
                                        trimmed, isTrimmed = 
t.trimRight(trimmed, maxWidth-t.pwindow.X())
                                }
                                str, width := t.processTabs(trimmed, 
prefixWidth)
-                               prefixWidth += width
-                               if t.theme.Colored && ansi != nil && 
ansi.colored() {
-                                       lbg = ansi.lbg
-                                       fillRet = t.pwindow.CFill(ansi.fg, 
ansi.bg, ansi.attr, str)
-                               } else {
-                                       fillRet = 
t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), tui.AttrRegular, str)
+                               if width > prefixWidth {
+                                       prefixWidth = width
+                                       if t.theme.Colored && ansi != nil && 
ansi.colored() {
+                                               lbg = ansi.lbg
+                                               fillRet = 
t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
+                                       } else {
+                                               fillRet = 
t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), tui.AttrRegular, str)
+                                       }
                                }
                                return !isTrimmed &&
                                        (fillRet == tui.FillContinue || 
t.previewOpts.wrap && fillRet == tui.FillNextLine)
@@ -1937,7 +1968,7 @@
                        w = t.tabstop - l%t.tabstop
                        strbuf.WriteString(strings.Repeat(" ", w))
                } else {
-                       w = runewidth.StringWidth(str)
+                       w = util.StringWidth(str)
                        strbuf.WriteString(str)
                }
                l += w
@@ -2247,6 +2278,7 @@
        }
        command := t.replacePlaceholder(template, forcePlus, string(t.input), 
list)
        cmd := util.ExecCommand(command, false)
+       cmd.Env = t.environ()
        t.executing.Set(true)
        if !background {
                cmd.Stdin = tui.TtyIn()
@@ -2493,17 +2525,17 @@
                                        _, query := t.Input()
                                        command := 
t.replacePlaceholder(commandTemplate, false, string(query), items)
                                        cmd := util.ExecCommand(command, true)
+                                       env := t.environ()
                                        if pwindow != nil {
                                                height := pwindow.Height()
-                                               env := os.Environ()
                                                lines := 
fmt.Sprintf("LINES=%d", height)
                                                columns := 
fmt.Sprintf("COLUMNS=%d", pwindow.Width())
                                                env = append(env, lines)
                                                env = append(env, 
"FZF_PREVIEW_"+lines)
                                                env = append(env, columns)
                                                env = append(env, 
"FZF_PREVIEW_"+columns)
-                                               cmd.Env = env
                                        }
+                                       cmd.Env = env
 
                                        out, _ := cmd.StdoutPipe()
                                        cmd.Stderr = cmd.Stdout
@@ -3289,7 +3321,7 @@
                                        break
                                }
 
-                               // Prevew scrollbar dragging
+                               // Preview scrollbar dragging
                                headerLines := t.previewOpts.headerLines
                                pbarDragging = me.Down && (pbarDragging || 
clicked && t.hasPreviewWindow() && my >= t.pwindow.Top()+headerLines && my < 
t.pwindow.Top()+t.pwindow.Height() && mx == t.pwindow.Left()+t.pwindow.Width())
                                if pbarDragging {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/tui/light.go 
new/fzf-0.39.0/src/tui/light.go
--- old/fzf-0.38.0/src/tui/light.go     2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/tui/light.go     2023-04-02 16:33:37.000000000 +0200
@@ -32,20 +32,26 @@
 var offsetRegexpBegin *regexp.Regexp = 
regexp.MustCompile("^\x1b\\[[0-9]+;[0-9]+R")
 
 func (r *LightRenderer) stderr(str string) {
-       r.stderrInternal(str, true)
+       r.stderrInternal(str, true, "")
 }
 
-// FIXME: Need better handling of non-displayable characters
-func (r *LightRenderer) stderrInternal(str string, allowNLCR bool) {
+const CR string = "\x1b[2m␍"
+const LF string = "\x1b[2m␊"
+
+func (r *LightRenderer) stderrInternal(str string, allowNLCR bool, resetCode 
string) {
        bytes := []byte(str)
        runes := []rune{}
        for len(bytes) > 0 {
                r, sz := utf8.DecodeRune(bytes)
                nlcr := r == '\n' || r == '\r'
                if r >= 32 || r == '\x1b' || nlcr {
-                       if r == utf8.RuneError || nlcr && !allowNLCR {
-                               runes = append(runes, ' ')
-                       } else {
+                       if nlcr && !allowNLCR {
+                               if r == '\r' {
+                                       runes = append(runes, 
[]rune(CR+resetCode)...)
+                               } else {
+                                       runes = append(runes, 
[]rune(LF+resetCode)...)
+                               }
+                       } else if r != utf8.RuneError {
                                runes = append(runes, r)
                        }
                }
@@ -54,8 +60,10 @@
        r.queued.WriteString(string(runes))
 }
 
-func (r *LightRenderer) csi(code string) {
-       r.stderr("\x1b[" + code)
+func (r *LightRenderer) csi(code string) string {
+       fullcode := "\x1b[" + code
+       r.stderr(fullcode)
+       return fullcode
 }
 
 func (r *LightRenderer) flush() {
@@ -825,12 +833,12 @@
        w.CPrint(color, string(w.border.bottomLeft)+repeat(w.border.horizontal, 
(w.width-bcw)/hw)+repeat(' ', rem)+string(w.border.bottomRight))
 }
 
-func (w *LightWindow) csi(code string) {
-       w.renderer.csi(code)
+func (w *LightWindow) csi(code string) string {
+       return w.renderer.csi(code)
 }
 
-func (w *LightWindow) stderrInternal(str string, allowNLCR bool) {
-       w.renderer.stderrInternal(str, allowNLCR)
+func (w *LightWindow) stderrInternal(str string, allowNLCR bool, resetCode 
string) {
+       w.renderer.stderrInternal(str, allowNLCR, resetCode)
 }
 
 func (w *LightWindow) Top() int {
@@ -936,10 +944,10 @@
        return codes
 }
 
-func (w *LightWindow) csiColor(fg Color, bg Color, attr Attr) bool {
+func (w *LightWindow) csiColor(fg Color, bg Color, attr Attr) (bool, string) {
        codes := append(attrCodes(attr), colorCodes(fg, bg)...)
-       w.csi(";" + strings.Join(codes, ";") + "m")
-       return len(codes) > 0
+       code := w.csi(";" + strings.Join(codes, ";") + "m")
+       return len(codes) > 0, code
 }
 
 func (w *LightWindow) Print(text string) {
@@ -951,16 +959,17 @@
 }
 
 func (w *LightWindow) CPrint(pair ColorPair, text string) {
-       w.csiColor(pair.Fg(), pair.Bg(), pair.Attr())
-       w.stderrInternal(cleanse(text), false)
+       _, code := w.csiColor(pair.Fg(), pair.Bg(), pair.Attr())
+       w.stderrInternal(cleanse(text), false, code)
        w.csi("m")
 }
 
 func (w *LightWindow) cprint2(fg Color, bg Color, attr Attr, text string) {
-       if w.csiColor(fg, bg, attr) {
+       hasColors, code := w.csiColor(fg, bg, attr)
+       if hasColors {
                defer w.csi("m")
        }
-       w.stderrInternal(cleanse(text), false)
+       w.stderrInternal(cleanse(text), false, code)
 }
 
 type wrappedLine struct {
@@ -980,6 +989,8 @@
                if len(rs) == 1 && rs[0] == '\t' {
                        w = tabstop - (prefixLength+width)%tabstop
                        str = repeat(' ', w)
+               } else if rs[0] == '\r' {
+                       w++
                } else {
                        w = runewidth.StringWidth(str)
                }
@@ -998,12 +1009,12 @@
        return lines
 }
 
-func (w *LightWindow) fill(str string, onMove func()) FillReturn {
+func (w *LightWindow) fill(str string, resetCode string) FillReturn {
        allLines := strings.Split(str, "\n")
        for i, line := range allLines {
                lines := wrapLine(line, w.posx, w.width, w.tabstop)
                for j, wl := range lines {
-                       w.stderrInternal(wl.text, false)
+                       w.stderrInternal(wl.text, false, resetCode)
                        w.posx += wl.displayWidth
 
                        // Wrap line
@@ -1013,7 +1024,7 @@
                                }
                                w.MoveAndClear(w.posy, w.posx)
                                w.Move(w.posy+1, 0)
-                               onMove()
+                               w.renderer.stderr(resetCode)
                        }
                }
        }
@@ -1022,22 +1033,26 @@
                        return FillSuspend
                }
                w.Move(w.posy+1, 0)
-               onMove()
+               w.renderer.stderr(resetCode)
                return FillNextLine
        }
        return FillContinue
 }
 
-func (w *LightWindow) setBg() {
+func (w *LightWindow) setBg() string {
        if w.bg != colDefault {
-               w.csiColor(colDefault, w.bg, AttrRegular)
+               _, code := w.csiColor(colDefault, w.bg, AttrRegular)
+               return code
        }
+       // Should clear dim attribute after ␍ in the preview window
+       // e.g. printf "foo\rbar" | fzf --ansi --preview 'printf "foo\rbar"'
+       return "\x1b[m"
 }
 
 func (w *LightWindow) Fill(text string) FillReturn {
        w.Move(w.posy, w.posx)
-       w.setBg()
-       return w.fill(text, w.setBg)
+       code := w.setBg()
+       return w.fill(text, code)
 }
 
 func (w *LightWindow) CFill(fg Color, bg Color, attr Attr, text string) 
FillReturn {
@@ -1048,11 +1063,11 @@
        if bg == colDefault {
                bg = w.bg
        }
-       if w.csiColor(fg, bg, attr) {
+       if hasColors, resetCode := w.csiColor(fg, bg, attr); hasColors {
                defer w.csi("m")
-               return w.fill(text, func() { w.csiColor(fg, bg, attr) })
+               return w.fill(text, resetCode)
        }
-       return w.fill(text, w.setBg)
+       return w.fill(text, w.setBg())
 }
 
 func (w *LightWindow) FinishFill() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/tui/tcell.go 
new/fzf-0.39.0/src/tui/tcell.go
--- old/fzf-0.38.0/src/tui/tcell.go     2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/tui/tcell.go     2023-04-02 16:33:37.000000000 +0200
@@ -8,6 +8,7 @@
 
        "github.com/gdamore/tcell/v2"
        "github.com/gdamore/tcell/v2/encoding"
+       "github.com/junegunn/fzf/src/util"
 
        "github.com/mattn/go-runewidth"
        "github.com/rivo/uniseg"
@@ -572,26 +573,27 @@
 
        gr := uniseg.NewGraphemes(text)
        for gr.Next() {
+               st := style
                rs := gr.Runes()
 
                if len(rs) == 1 {
                        r := rs[0]
-                       if r < rune(' ') { // ignore control characters
-                               continue
+                       if r == '\r' {
+                               st = style.Dim(true)
+                               rs[0] = '␍'
                        } else if r == '\n' {
-                               w.lastY++
-                               lx = 0
-                               continue
-                       } else if r == '\u000D' { // skip carriage return
+                               st = style.Dim(true)
+                               rs[0] = '␊'
+                       } else if r < rune(' ') { // ignore control characters
                                continue
                        }
                }
                var xPos = w.left + w.lastX + lx
                var yPos = w.top + w.lastY
                if xPos < (w.left+w.width) && yPos < (w.top+w.height) {
-                       _screen.SetContent(xPos, yPos, rs[0], rs[1:], style)
+                       _screen.SetContent(xPos, yPos, rs[0], rs[1:], st)
                }
-               lx += runewidth.StringWidth(string(rs))
+               lx += util.StringWidth(string(rs))
        }
        w.lastX += lx
 }
@@ -620,13 +622,22 @@
                Italic(a&Attr(tcell.AttrItalic) != 0)
 
        gr := uniseg.NewGraphemes(text)
+Loop:
        for gr.Next() {
+               st := style
                rs := gr.Runes()
-               if len(rs) == 1 && rs[0] == '\n' {
-                       w.lastY++
-                       w.lastX = 0
-                       lx = 0
-                       continue
+               if len(rs) == 1 {
+                       r := rs[0]
+                       switch r {
+                       case '\r':
+                               st = style.Dim(true)
+                               rs[0] = '␍'
+                       case '\n':
+                               w.lastY++
+                               w.lastX = 0
+                               lx = 0
+                               continue Loop
+                       }
                }
 
                // word wrap:
@@ -643,8 +654,8 @@
                        return FillSuspend
                }
 
-               _screen.SetContent(xPos, yPos, rs[0], rs[1:], style)
-               lx += runewidth.StringWidth(string(rs))
+               _screen.SetContent(xPos, yPos, rs[0], rs[1:], st)
+               lx += util.StringWidth(string(rs))
        }
        w.lastX += lx
        if w.lastX == w.width {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/tui/tui.go 
new/fzf-0.39.0/src/tui/tui.go
--- old/fzf-0.38.0/src/tui/tui.go       2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/tui/tui.go       2023-04-02 16:33:37.000000000 +0200
@@ -93,6 +93,7 @@
        Start
        Load
        Focus
+       One
 
        AltBS
 
@@ -525,28 +526,28 @@
 func NoColorTheme() *ColorTheme {
        return &ColorTheme{
                Colored:      false,
-               Input:        ColorAttr{colDefault, AttrRegular},
-               Fg:           ColorAttr{colDefault, AttrRegular},
-               Bg:           ColorAttr{colDefault, AttrRegular},
-               DarkBg:       ColorAttr{colDefault, AttrRegular},
-               Prompt:       ColorAttr{colDefault, AttrRegular},
+               Input:        ColorAttr{colDefault, AttrUndefined},
+               Fg:           ColorAttr{colDefault, AttrUndefined},
+               Bg:           ColorAttr{colDefault, AttrUndefined},
+               DarkBg:       ColorAttr{colDefault, AttrUndefined},
+               Prompt:       ColorAttr{colDefault, AttrUndefined},
                Match:        ColorAttr{colDefault, Underline},
                Current:      ColorAttr{colDefault, Reverse},
                CurrentMatch: ColorAttr{colDefault, Reverse | Underline},
-               Spinner:      ColorAttr{colDefault, AttrRegular},
-               Info:         ColorAttr{colDefault, AttrRegular},
-               Cursor:       ColorAttr{colDefault, AttrRegular},
-               Selected:     ColorAttr{colDefault, AttrRegular},
-               Header:       ColorAttr{colDefault, AttrRegular},
-               Border:       ColorAttr{colDefault, AttrRegular},
-               BorderLabel:  ColorAttr{colDefault, AttrRegular},
-               Disabled:     ColorAttr{colDefault, AttrRegular},
-               PreviewFg:    ColorAttr{colDefault, AttrRegular},
-               PreviewBg:    ColorAttr{colDefault, AttrRegular},
-               Gutter:       ColorAttr{colDefault, AttrRegular},
-               PreviewLabel: ColorAttr{colDefault, AttrRegular},
-               Separator:    ColorAttr{colDefault, AttrRegular},
-               Scrollbar:    ColorAttr{colDefault, AttrRegular},
+               Spinner:      ColorAttr{colDefault, AttrUndefined},
+               Info:         ColorAttr{colDefault, AttrUndefined},
+               Cursor:       ColorAttr{colDefault, AttrUndefined},
+               Selected:     ColorAttr{colDefault, AttrUndefined},
+               Header:       ColorAttr{colDefault, AttrUndefined},
+               Border:       ColorAttr{colDefault, AttrUndefined},
+               BorderLabel:  ColorAttr{colDefault, AttrUndefined},
+               Disabled:     ColorAttr{colDefault, AttrUndefined},
+               PreviewFg:    ColorAttr{colDefault, AttrUndefined},
+               PreviewBg:    ColorAttr{colDefault, AttrUndefined},
+               Gutter:       ColorAttr{colDefault, AttrUndefined},
+               PreviewLabel: ColorAttr{colDefault, AttrUndefined},
+               Separator:    ColorAttr{colDefault, AttrUndefined},
+               Scrollbar:    ColorAttr{colDefault, AttrUndefined},
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/util/util.go 
new/fzf-0.39.0/src/util/util.go
--- old/fzf-0.38.0/src/util/util.go     2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/src/util/util.go     2023-04-02 16:33:37.000000000 +0200
@@ -11,6 +11,11 @@
        "github.com/rivo/uniseg"
 )
 
+// StringWidth returns string width where each CR/LF character takes 1 column
+func StringWidth(s string) int {
+       return runewidth.StringWidth(s) + strings.Count(s, "\n") + 
strings.Count(s, "\r")
+}
+
 // RunesWidth returns runes width
 func RunesWidth(runes []rune, prefixWidth int, tabstop int, limit int) (int, 
int) {
        width := 0
@@ -22,8 +27,7 @@
                if len(rs) == 1 && rs[0] == '\t' {
                        w = tabstop - (prefixWidth+width)%tabstop
                } else {
-                       s := string(rs)
-                       w = runewidth.StringWidth(s) + strings.Count(s, "\n")
+                       w = StringWidth(string(rs))
                }
                width += w
                if width > limit {
@@ -41,7 +45,7 @@
        gr := uniseg.NewGraphemes(input)
        for gr.Next() {
                rs := gr.Runes()
-               w := runewidth.StringWidth(string(rs))
+               w := StringWidth(string(rs))
                if width+w > limit {
                        return runes, width
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/src/util/util_test.go 
new/fzf-0.39.0/src/util/util_test.go
--- old/fzf-0.38.0/src/util/util_test.go        2023-02-15 15:24:42.000000000 
+0100
+++ new/fzf-0.39.0/src/util/util_test.go        2023-04-02 16:33:37.000000000 
+0200
@@ -70,7 +70,7 @@
        }
 }
 
-func TestContrain(t *testing.T) {
+func TestConstrain(t *testing.T) {
        if Constrain(-3, -1, 3) != -1 {
                t.Error("Expected", -1)
        }
@@ -83,7 +83,7 @@
        }
 }
 
-func TestContrain32(t *testing.T) {
+func TestConstrain32(t *testing.T) {
        if Constrain32(-3, -1, 3) != -1 {
                t.Error("Expected", -1)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/test/test_go.rb 
new/fzf-0.39.0/test/test_go.rb
--- old/fzf-0.38.0/test/test_go.rb      2023-02-15 15:24:42.000000000 +0100
+++ new/fzf-0.39.0/test/test_go.rb      2023-04-02 16:33:37.000000000 +0200
@@ -1930,7 +1930,7 @@
 
   def test_keep_right
     tmux.send_keys "seq 10000 | #{FZF} --read0 --keep-right", :Enter
-    tmux.until { |lines| assert lines.any_include?('9999 10000') }
+    tmux.until { |lines| assert lines.any_include?('9999␊10000') }
   end
 
   def test_backward_eof
@@ -2629,11 +2629,17 @@
   end
 
   def test_listen
-    tmux.send_keys 'seq 10 | fzf --listen 6266', :Enter
-    tmux.until { |lines| assert_equal 10, lines.item_count }
-    Net::HTTP.post(URI('http://localhost:6266'), 'change-query(yo)+reload(seq 
100)+change-prompt:hundred> ')
-    tmux.until { |lines| assert_equal 100, lines.item_count }
-    tmux.until { |lines| assert_equal 'hundred> yo', lines[-1] }
+    { '--listen 6266' => -> { URI('http://localhost:6266') },
+      "--listen --sync --bind 'start:execute-silent:echo $FZF_PORT > 
/tmp/fzf-port'" =>
+        -> { URI("http://localhost:#{File.read('/tmp/fzf-port').chomp}") } 
}.each do |opts, fn|
+      tmux.send_keys "seq 10 | fzf #{opts}", :Enter
+      tmux.until { |lines| assert_equal 10, lines.item_count }
+      Net::HTTP.post(fn.call, 'change-query(yo)+reload(seq 
100)+change-prompt:hundred> ')
+      tmux.until { |lines| assert_equal 100, lines.item_count }
+      tmux.until { |lines| assert_equal 'hundred> yo', lines[-1] }
+      teardown
+      setup
+    end
   end
 
   def test_toggle_alternative_preview_window
@@ -2656,6 +2662,67 @@
     tmux.send_keys :Enter
     tmux.until { |lines| assert_equal 99, lines.item_count }
   end
+
+  def test_no_extra_newline_issue_3209
+    tmux.send_keys(%(seq 100 | #{FZF} --height 10 --preview-window up,wrap 
--preview 'printf "─%.0s" $(seq 1 "$((FZF_PREVIEW_COLUMNS - 5))"); printf 
$"\\e[7m%s\\e[0m" title; echo; echo something'), :Enter)
+    expected = <<~OUTPUT
+      ╭──────────
+      │ ─────────
+      │ something
+      │
+      ╰──────────
+        3
+        2
+      > 1
+        100/100 ─
+      >
+    OUTPUT
+    tmux.until { assert_block(expected, _1) }
+  end
+
+  def test_track
+    tmux.send_keys "seq 1000 | #{FZF} --query 555 --track", :Enter
+    tmux.until do |lines|
+      assert_equal 1, lines.match_count
+      assert_includes lines, '> 555'
+    end
+    tmux.send_keys :BSpace
+    index = tmux.until do |lines|
+      assert_equal 28, lines.match_count
+      assert_includes lines, '> 555'
+    end.index('> 555')
+    tmux.send_keys :BSpace
+    tmux.until do |lines|
+      assert_equal 271, lines.match_count
+      assert_equal '> 555', lines[index]
+    end
+    tmux.send_keys :BSpace
+    tmux.until do |lines|
+      assert_equal 1000, lines.match_count
+      assert_equal '> 555', lines[index]
+    end
+  end
+
+  def test_one
+    tmux.send_keys "seq 10 | #{FZF} --bind 'one:preview:echo {} is the only 
match'", :Enter
+    tmux.send_keys '1'
+    tmux.until do |lines|
+      assert_equal 2, lines.match_count
+      refute(lines.any? { _1.include?('only match') })
+    end
+    tmux.send_keys '0'
+    tmux.until do |lines|
+      assert_equal 1, lines.match_count
+      assert(lines.any? { _1.include?('only match') })
+    end
+  end
+
+  def test_height_range_with_exit_0
+    tmux.send_keys "seq 10 | #{FZF} --height ~10% --exit-0", :Enter
+    tmux.until { |lines| assert_equal 10, lines.item_count }
+    tmux.send_keys :c
+    tmux.until { |lines| assert_equal 0, lines.match_count }
+  end
 end
 
 module TestShell
@@ -2784,9 +2851,9 @@
     tmux.send_keys 'C-r'
     tmux.until { |lines| assert_equal '>', lines[-1] }
     tmux.send_keys 'foo bar'
-    tmux.until { |lines| assert lines[-3]&.end_with?('bar"') }
+    tmux.until { |lines| assert lines[-3]&.match?(/bar"␊?/) }
     tmux.send_keys :Enter
-    tmux.until { |lines| assert lines[-1]&.end_with?('bar"') }
+    tmux.until { |lines| assert lines[-1]&.match?(/bar"␊?/) }
     tmux.send_keys :Enter
     tmux.until { |lines| assert_equal %w[foo bar], lines[-2..] }
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.38.0/typos.toml new/fzf-0.39.0/typos.toml
--- old/fzf-0.38.0/typos.toml   1970-01-01 01:00:00.000000000 +0100
+++ new/fzf-0.39.0/typos.toml   2023-04-02 16:33:37.000000000 +0200
@@ -0,0 +1,6 @@
+# See https://github.com/crate-ci/typos/blob/master/docs/reference.md to 
configure typos
+[default.extend-words]
+ba = "ba"
+fo = "fo"
+enew = "enew"
+tabe = "tabe"

++++++ vendor.tar.zst ++++++
Binary files /var/tmp/diff_new_pack.VzgyC6/_old and 
/var/tmp/diff_new_pack.VzgyC6/_new differ

Reply via email to