Hello community,

here is the log from the commit of package fzf for openSUSE:Factory checked in 
at 2020-12-14 18:09:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fzf (Old)
 and      /work/SRC/openSUSE:Factory/.fzf.new.2328 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fzf"

Mon Dec 14 18:09:38 2020 rev:12 rq:855603 version:0.24.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/fzf/fzf.changes  2020-12-04 21:29:35.942217491 
+0100
+++ /work/SRC/openSUSE:Factory/.fzf.new.2328/fzf.changes        2020-12-14 
18:10:11.519689211 +0100
@@ -1,0 +2,16 @@
+Sun Dec 13 19:52:48 UTC 2020 - Matej Cepl <mc...@suse.com>
+
+- Update to 24.4.4:
+  - Added --preview-window option follow
+    # Preview window will automatically scroll to the bottom
+    fzf --preview-window follow --preview 'for i in $(seq 100000); do
+      echo "$i"
+      sleep 0.01
+      (( i % 300 == 0 )) && printf "\033[2J"
+    done'
+  - Added change-prompt action
+    fzf --prompt 'foo> ' --bind $'a:change-prompt:\x1b[31mbar> '
+  - Bug fixes and improvements
+- Enable tests
+
+-------------------------------------------------------------------

Old:
----
  0.24.3.tar.gz

New:
----
  0.24.4.tar.gz

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

Other differences:
------------------
++++++ fzf.spec ++++++
--- /var/tmp/diff_new_pack.6ijAZ9/_old  2020-12-14 18:10:13.027690709 +0100
+++ /var/tmp/diff_new_pack.6ijAZ9/_new  2020-12-14 18:10:13.027690709 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           fzf
-Version:        0.24.3
+Version:        0.24.4
 Release:        0
 Summary:        A command-line fuzzy finder
 License:        MIT
@@ -127,6 +127,22 @@
 install -D -m0644 -t %{buildroot}%{vimplugin_dir}/doc doc/*
 install -D -m0644 -t %{buildroot}%{vimplugin_dir}/plugin plugin/*
 
+%check
+export SHELL=/bin/sh GOOS=
+export GOCACHE=$(readlink -f vendor/)
+%ifarch ppc64
+BUILDMOD=""
+%else
+BUILDMOD="-buildmode=pie"
+%endif
+export RPM_OPT_FLAGS="%{optflags}"
+go test -v -x -mod=vendor ${BUILDMOD} -a \
+    -ldflags "-X main.revision=%{version}" \
+    github.com/junegunn/fzf/src \
+    github.com/junegunn/fzf/src/algo \
+    github.com/junegunn/fzf/src/tui \
+    github.com/junegunn/fzf/src/util
+
 %files
 %doc README.md
 %{_bindir}/fzf

++++++ 0.24.3.tar.gz -> 0.24.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/.travis.yml new/fzf-0.24.4/.travis.yml
--- old/fzf-0.24.3/.travis.yml  2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/.travis.yml  2020-12-05 15:24:55.000000000 +0100
@@ -6,6 +6,7 @@
   - linux
   - osx
 dist: bionic
+osx_image: xcode12.2
 addons:
   apt:
     packages:
@@ -17,7 +18,6 @@
     packages:
       - fish
       - tmux
-    update: true
 install: gem install --no-document minitest:5.14.2 rubocop:1.0.0 
rubocop-minitest:0.10.1 rubocop-performance:1.8.1
 script:
   - make test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/CHANGELOG.md new/fzf-0.24.4/CHANGELOG.md
--- old/fzf-0.24.3/CHANGELOG.md 2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/CHANGELOG.md 2020-12-05 15:24:55.000000000 +0100
@@ -1,6 +1,23 @@
 CHANGELOG
 =========
 
+0.24.4
+------
+- Added `--preview-window` option `follow`
+  ```sh
+  # Preview window will automatically scroll to the bottom
+  fzf --preview-window follow --preview 'for i in $(seq 100000); do
+    echo "$i"
+    sleep 0.01
+    (( i % 300 == 0 )) && printf "\033[2J"
+  done'
+  ```
+- Added `change-prompt` action
+  ```sh
+  fzf --prompt 'foo> ' --bind $'a:change-prompt:\x1b[31mbar> '
+  ```
+- Bug fixes and improvements
+
 0.24.3
 ------
 - Added `--padding` option
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/install new/fzf-0.24.4/install
--- old/fzf-0.24.3/install      2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/install      2020-12-05 15:24:55.000000000 +0100
@@ -2,7 +2,7 @@
 
 set -u
 
-version=0.24.3
+version=0.24.4
 auto_completion=
 key_bindings=
 update_config=2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/install.ps1 new/fzf-0.24.4/install.ps1
--- old/fzf-0.24.3/install.ps1  2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/install.ps1  2020-12-05 15:24:55.000000000 +0100
@@ -1,4 +1,4 @@
-$version="0.24.3"
+$version="0.24.4"
 
 $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/man/man1/fzf-tmux.1 
new/fzf-0.24.4/man/man1/fzf-tmux.1
--- old/fzf-0.24.3/man/man1/fzf-tmux.1  2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/man/man1/fzf-tmux.1  2020-12-05 15:24:55.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 "Nov 2020" "fzf 0.24.3" "fzf-tmux - open fzf in tmux split pane"
+.TH fzf-tmux 1 "Dec 2020" "fzf 0.24.4" "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.24.3/man/man1/fzf.1 
new/fzf-0.24.4/man/man1/fzf.1
--- old/fzf-0.24.3/man/man1/fzf.1       2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/man/man1/fzf.1       2020-12-05 15:24:55.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 "Nov 2020" "fzf 0.24.3" "fzf - a command-line fuzzy finder"
+.TH fzf 1 "Dec 2020" "fzf 0.24.4" "fzf - a command-line fuzzy finder"
 
 .SH NAME
 fzf - a command-line fuzzy finder
@@ -439,7 +439,7 @@
       done'\fR
 .RE
 .TP
-.BI "--preview-window=" 
"[POSITION][:SIZE[%]][:rounded|sharp|noborder][:[no]wrap][:[no]cycle][:[no]hidden][:+SCROLL[-OFFSET]][:default]"
+.BI "--preview-window=" 
"[POSITION][:SIZE[%]][:rounded|sharp|noborder][:[no]wrap][:[no]follow][:[no]cycle][:[no]hidden][:+SCROLL[-OFFSET]][:default]"
 
 .RS
 .B POSITION: (default: right)
@@ -448,27 +448,43 @@
     \fBleft
     \fBright
 
-\fRDetermines the layout of the preview window. If the argument contains
-\fB:hidden\fR, the preview window will be hidden by default until
-\fBtoggle-preview\fR action is triggered. Long lines are truncated by default.
-Line wrap can be enabled with \fB:wrap\fR flag. Cyclic scrolling is enabled
-with \fB:cycle\fR flag.
+\fRDetermines the layout of the preview window.
 
-If size is given as 0, preview window will not be visible, but fzf will still
+* If the argument contains \fB:hidden\fR, the preview window will be hidden by
+default until \fBtoggle-preview\fR action is triggered.
+
+* If size is given as 0, preview window will not be visible, but fzf will still
 execute the command in the background.
 
-To change the style of the border of the preview window, specify one of
+* Long lines are truncated by default. Line wrap can be enabled with
+\fB:wrap\fR flag.
+
+* Preview window will automatically scroll to the bottom when \fB:follow\fR
+flag is set, similarly to how \fBtail -f\fR works.
+
+.RS
+e.g.
+      \fBfzf --preview-window follow --preview 'for i in $(seq 100000); do
+        echo "$i"
+        sleep 0.01
+        (( i % 300 == 0 )) && printf "\\033[2J"
+      done'\fR
+.RE
+
+* Cyclic scrolling is enabled with \fB:cycle\fR flag.
+
+* To change the style of the border of the preview window, specify one of
 \fBrounded\fR (border with rounded edges, default), \fBsharp\fR (border with
 sharp edges), or \fBnoborder\fR (no border).
 
-\fB+SCROLL[-OFFSET]\fR determines the initial scroll offset of the preview
+* \fB+SCROLL[-OFFSET]\fR determines the initial scroll offset of the preview
 window. \fBSCROLL\fR can be either a numeric integer or a single-field index
 expression that refers to a numeric integer. The optional \fB-OFFSET\fR part is
 for adjusting the base offset so that you can see the text above it. It should
 be given as a numeric integer (\fB-INTEGER\fR), or as a denominator form
 (\fB-/INTEGER\fR) for specifying a fraction of the preview window height.
 
-\fBdefault\fR resets all options previously set to the default.
+* \fBdefault\fR resets all options previously set to the default.
 
 .RS
 e.g.
@@ -712,6 +728,14 @@
 .br
 \fIshift-right\fR
 .br
+\fIalt-shift-up\fR
+.br
+\fIalt-shift-down\fR
+.br
+\fIalt-shift-left\fR
+.br
+\fIalt-shift-right\fR
+.br
 \fIleft-click\fR
 .br
 \fIright-click\fR
@@ -753,6 +777,7 @@
     \fBbackward-word\fR             \fIalt-b   shift-left\fR
     \fBbeginning-of-line\fR         \fIctrl-a  home\fR
     \fBcancel\fR                    (clear query string if not empty, abort 
fzf otherwise)
+    \fBchange-prompt(...)\fR        (change prompt to the given string)
     \fBclear-screen\fR              \fIctrl-l\fR
     \fBclear-selection\fR           (clear multi-selection)
     \fBclear-query\fR               (clear query string)
@@ -808,42 +833,51 @@
 Multiple actions can be chained using \fB+\fR separator.
 
 e.g.
-     \fBfzf --bind 'ctrl-a:select-all+accept'\fR
+     \fBfzf --multi --bind 'ctrl-a:select-all+accept'\fR
+     \fBfzf --multi --bind 'ctrl-a:select-all' --bind 'ctrl-a:+accept'\fR
 
-.SS COMMAND EXECUTION
+.SS ACTION ARGUMENT
 
-With \fBexecute(...)\fR action, you can execute arbitrary commands without
-leaving fzf. For example, you can turn fzf into a simple file browser by
-binding \fBenter\fR key to \fBless\fR command like follows.
-
-    \fBfzf --bind "enter:execute(less {})"\fR
+An action denoted with \fB(...)\fR suffix takes an argument.
 
-You can use the same placeholder expressions as in \fB--preview\fR.
+e.g.
+     \fBfzf --bind 'ctrl-a:change-prompt(NewPrompt> )'\fR
+     \fBfzf --bind 'ctrl-v:preview(cat {})' --preview-window hidden\fR
 
-If the command contains parentheses, fzf may fail to parse the expression. In
+If the argument contains parentheses, fzf may fail to parse the expression. In
 that case, you can use any of the following alternative notations to avoid
 parse errors.
 
-    \fBexecute[...]\fR
-    \fBexecute~...~\fR
-    \fBexecute!...!\fR
-    \fBexecute@...@\fR
-    \fBexecute#...#\fR
-    \fBexecute$...$\fR
-    \fBexecute%...%\fR
-    \fBexecute^...^\fR
-    \fBexecute&...&\fR
-    \fBexecute*...*\fR
-    \fBexecute;...;\fR
-    \fBexecute/.../\fR
-    \fBexecute|...|\fR
-    \fBexecute:...\fR
+    \fBaction-name[...]\fR
+    \fBaction-name~...~\fR
+    \fBaction-name!...!\fR
+    \fBaction-name@...@\fR
+    \fBaction-name#...#\fR
+    \fBaction-name$...$\fR
+    \fBaction-name%...%\fR
+    \fBaction-name^...^\fR
+    \fBaction-name&...&\fR
+    \fBaction-name*...*\fR
+    \fBaction-name;...;\fR
+    \fBaction-name/.../\fR
+    \fBaction-name|...|\fR
+    \fBaction-name:...\fR
 .RS
 The last one is the special form that frees you from parse errors as it does
 not expect the closing character. The catch is that it should be the last one
 in the comma-separated list of key-action pairs.
 .RE
 
+.SS COMMAND EXECUTION
+
+With \fBexecute(...)\fR action, you can execute arbitrary commands without
+leaving fzf. For example, you can turn fzf into a simple file browser by
+binding \fBenter\fR key to \fBless\fR command like follows.
+
+    \fBfzf --bind "enter:execute(less {})"\fR
+
+You can use the same placeholder expressions as in \fB--preview\fR.
+
 fzf switches to the alternate screen when executing a command. However, if the
 command is expected to complete quickly, and you are not interested in its
 output, you might want to use \fBexecute-silent\fR instead, which silently
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/plugin/fzf.vim 
new/fzf-0.24.4/plugin/fzf.vim
--- old/fzf-0.24.3/plugin/fzf.vim       2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/plugin/fzf.vim       2020-12-05 15:24:55.000000000 +0100
@@ -645,7 +645,8 @@
   endif
   let exit_status = v:shell_error
   redraw!
-  return s:exit_handler(exit_status, command) ? s:collect(a:temps) : []
+  let lines = s:collect(a:temps)
+  return s:exit_handler(exit_status, command) ? lines : []
 endfunction
 
 function! s:execute_tmux(dict, command, temps) abort
@@ -659,7 +660,8 @@
   call system(command)
   let exit_status = v:shell_error
   redraw!
-  return s:exit_handler(exit_status, command) ? s:collect(a:temps) : []
+  let lines = s:collect(a:temps)
+  return s:exit_handler(exit_status, command) ? lines : []
 endfunction
 
 function! s:calc_size(max, val, dict)
@@ -806,12 +808,12 @@
       execute self.winrest
     endif
 
+    let lines = s:collect(self.temps)
     if !s:exit_handler(a:code, self.command, 1)
       return
     endif
 
     call s:pushd(self.dict)
-    let lines = s:collect(self.temps)
     call s:callback(self.dict, lines)
     call self.switch_back(s:getpos() == self.ppos)
   endfunction
@@ -836,6 +838,9 @@
         let term_opts.curwin = 1
       endif
       let fzf.buf = term_start([&shell, &shellcmdflag, command], term_opts)
+      if exists('&termwinkey')
+        call setbufvar(fzf.buf, '&termwinkey', '<c-z>')
+      endif
       if is_popup && exists('#TerminalWinOpen')
         doautocmd <nomodeline> TerminalWinOpen
       endif
@@ -843,6 +848,7 @@
         call term_wait(fzf.buf, 20)
       endif
     endif
+    tnoremap <buffer> <c-z> <nop>
   finally
     call s:dopopd()
   endtry
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/shell/completion.bash 
new/fzf-0.24.4/shell/completion.bash
--- old/fzf-0.24.3/shell/completion.bash        2020-11-09 12:41:59.000000000 
+0100
+++ new/fzf-0.24.4/shell/completion.bash        2020-12-05 15:24:55.000000000 
+0100
@@ -46,9 +46,20 @@
   fi
 }
 
-__fzf_orig_completion_filter() {
-  sed 's/^\(.*-F\) *\([^ ]*\).* \([^ ]*\)$/export _fzf_orig_completion_\3="\1 
%s \3 #\2"; [[ "\1" = *" -o nospace "* ]] \&\& [[ ! "$__fzf_nospace_commands" = 
*" \3 "* ]] \&\& __fzf_nospace_commands="$__fzf_nospace_commands \3 ";/' |
-  awk -F= '{OFS = FS} {gsub(/[^A-Za-z0-9_= ;]/, "_", $1);}1'
+__fzf_orig_completion() {
+  local l comp f cmd
+  while read -r l; do
+    if [[ "$l" =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
+      comp="${BASH_REMATCH[1]}"
+      f="${BASH_REMATCH[2]}"
+      cmd="${BASH_REMATCH[3]}"
+      [[ "$f" = _fzf_* ]] && continue
+      printf -v "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" "%s" "${comp} 
%s ${cmd} #${f}"
+      if [[ "$l" = *" -o nospace "* ]] && [[ ! "$__fzf_nospace_commands" = *" 
$cmd "* ]]; then
+        __fzf_nospace_commands="$__fzf_nospace_commands $cmd "
+      fi
+    fi
+  done
 }
 
 _fzf_opts_completion() {
@@ -137,7 +148,7 @@
     ret=$?
     # _completion_loader may not have updated completion for the command
     if [ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]; then
-      eval "$(complete | command grep " -F.* $orig_cmd$" | 
__fzf_orig_completion_filter)"
+      __fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
       if [[ "$__fzf_nospace_commands" = *" $orig_cmd "* ]]; then
         eval "${orig_complete/ -F / -o nospace -F }"
       else
@@ -306,9 +317,7 @@
   svn tar unzip zip"
 
 # Preserve existing completion
-eval "$(complete |
-  sed -E '/-F/!d; / _fzf/d; '"/ ($(echo $d_cmds $a_cmds | sed 's/ /|/g; 
s/+/\\+/g'))$/"'!d' |
-  __fzf_orig_completion_filter)"
+__fzf_orig_completion < <(complete -p $d_cmds $a_cmds 2> /dev/null)
 
 if type _completion_loader > /dev/null 2>&1; then
   _fzf_completion_loader=1
@@ -353,7 +362,7 @@
     return 1
   fi
   shift
-  eval "$(complete -p "$@" 2> /dev/null | grep -v "$fn" | 
__fzf_orig_completion_filter)"
+  __fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
   for cmd in "$@"; do
     case "$kind" in
       dir)   __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/shell/key-bindings.zsh 
new/fzf-0.24.4/shell/key-bindings.zsh
--- old/fzf-0.24.3/shell/key-bindings.zsh       2020-11-09 12:41:59.000000000 
+0100
+++ new/fzf-0.24.4/shell/key-bindings.zsh       2020-12-05 15:24:55.000000000 
+0100
@@ -45,6 +45,7 @@
     -o -type d -print \
     -o -type l -print 2> /dev/null | cut -b3-"}"
   setopt localoptions pipefail no_aliases 2> /dev/null
+  local item
   eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse 
$FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS" $(__fzfcmd) -m "$@" | while read item; do
     echo -n "${(q)item} "
   done
@@ -106,6 +107,7 @@
 fzf-history-widget() {
   local selected num
   setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> 
/dev/null
+  [[ -o sharehistory ]] && fc -RI
   selected=( $(fc -rl 1 | perl -ne 'print if !$seen{(/^\s*[0-9]+\**\s+(.*)/, 
$1)}++' |
     FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS 
-n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS 
--query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
   local ret=$?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/ansi.go new/fzf-0.24.4/src/ansi.go
--- old/fzf-0.24.3/src/ansi.go  2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/ansi.go  2020-12-05 15:24:55.000000000 +0100
@@ -19,17 +19,18 @@
        fg   tui.Color
        bg   tui.Color
        attr tui.Attr
+       lbg  tui.Color
 }
 
 func (s *ansiState) colored() bool {
-       return s.fg != -1 || s.bg != -1 || s.attr > 0
+       return s.fg != -1 || s.bg != -1 || s.attr > 0 || s.lbg >= 0
 }
 
 func (s *ansiState) equals(t *ansiState) bool {
        if t == nil {
                return !s.colored()
        }
-       return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr
+       return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr && s.lbg == 
t.lbg
 }
 
 func (s *ansiState) ToString() string {
@@ -195,11 +196,14 @@
        // State
        var state *ansiState
        if prevState == nil {
-               state = &ansiState{-1, -1, 0}
+               state = &ansiState{-1, -1, 0, -1}
        } else {
-               state = &ansiState{prevState.fg, prevState.bg, prevState.attr}
+               state = &ansiState{prevState.fg, prevState.bg, prevState.attr, 
prevState.lbg}
        }
        if ansiCode[0] != '\x1b' || ansiCode[1] != '[' || 
ansiCode[len(ansiCode)-1] != 'm' {
+               if strings.HasSuffix(ansiCode, "0K") {
+                       state.lbg = prevState.bg
+               }
                return state
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/ansi_test.go 
new/fzf-0.24.4/src/ansi_test.go
--- old/fzf-0.24.3/src/ansi_test.go     2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/ansi_test.go     2020-12-05 15:24:55.000000000 +0100
@@ -168,7 +168,7 @@
                }
        }
        assert("\x1b[m", nil, "")
-       assert("\x1b[m", &ansiState{attr: tui.Blink}, "")
+       assert("\x1b[m", &ansiState{attr: tui.Blink, lbg: -1}, "")
 
        assert("\x1b[31m", nil, "\x1b[31;49m")
        assert("\x1b[41m", nil, "\x1b[39;41m")
@@ -176,8 +176,8 @@
        assert("\x1b[92m", nil, "\x1b[92;49m")
        assert("\x1b[102m", nil, "\x1b[39;102m")
 
-       assert("\x1b[31m", &ansiState{fg: 4, bg: 4}, "\x1b[31;44m")
-       assert("\x1b[1;2;31m", &ansiState{fg: 2, bg: -1, attr: tui.Reverse}, 
"\x1b[1;2;7;31;49m")
+       assert("\x1b[31m", &ansiState{fg: 4, bg: 4, lbg: -1}, "\x1b[31;44m")
+       assert("\x1b[1;2;31m", &ansiState{fg: 2, bg: -1, attr: tui.Reverse, 
lbg: -1}, "\x1b[1;2;7;31;49m")
        assert("\x1b[38;5;100;48;5;200m", nil, "\x1b[38;5;100;48;5;200m")
        assert("\x1b[48;5;100;38;5;200m", nil, "\x1b[38;5;200;48;5;100m")
        assert("\x1b[48;5;100;38;2;10;20;30;1m", nil, 
"\x1b[1;38;2;10;20;30;48;5;100m")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/options.go 
new/fzf-0.24.4/src/options.go
--- old/fzf-0.24.3/src/options.go       2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/options.go       2020-12-05 15:24:55.000000000 +0100
@@ -83,7 +83,7 @@
     --preview=COMMAND     Command to preview highlighted line ({})
     --preview-window=OPT  Preview window layout (default: right:50%)
                           [up|down|left|right][:SIZE[%]]
-                          [:[no]wrap][:[no]cycle][:[no]hidden]
+                          [:[no]wrap][:[no]cycle][:[no]follow][:[no]hidden]
                           [:rounded|sharp|noborder]
                           [:+SCROLL[-OFFSET]]
                           [:default]
@@ -169,6 +169,7 @@
        hidden   bool
        wrap     bool
        cycle    bool
+       follow   bool
        border   tui.BorderShape
 }
 
@@ -231,7 +232,7 @@
 }
 
 func defaultPreviewOpts(command string) previewOpts {
-       return previewOpts{command, posRight, sizeSpec{50, true}, "", false, 
false, false, tui.BorderRounded}
+       return previewOpts{command, posRight, sizeSpec{50, true}, "", false, 
false, false, false, tui.BorderRounded}
 }
 
 func defaultOptions() *Options {
@@ -524,6 +525,14 @@
                        chord = tui.PgUp
                case "pgdn", "page-down":
                        chord = tui.PgDn
+               case "alt-shift-up", "shift-alt-up":
+                       chord = tui.AltSUp
+               case "alt-shift-down", "shift-alt-down":
+                       chord = tui.AltSDown
+               case "alt-shift-left", "shift-alt-left":
+                       chord = tui.AltSLeft
+               case "alt-shift-right", "shift-alt-right":
+                       chord = tui.AltSRight
                case "shift-up":
                        chord = tui.SUp
                case "shift-down":
@@ -727,7 +736,7 @@
        // Backreferences are not supported.
        // "~!@#$%^&*;/|".each_char.map { |c| Regexp.escape(c) }.map { |c| 
"#{c}[^#{c}]*#{c}" }.join('|')
        executeRegexp = regexp.MustCompile(
-               
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview):.+|[:+](execute(?:-multi|-silent)?|reload|preview)(\([^)]*\)|\[[^\]]*\]|~[^~]*~|![^!]*!|@[^@]*@|\#[^\#]*\#|\$[^\$]*\$|%[^%]*%|\^[^\^]*\^|&[^&]*&|\*[^\*]*\*|;[^;]*;|/[^/]*/|\|[^\|]*\|)`)
+               
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt):.+|[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt)(\([^)]*\)|\[[^\]]*\]|~[^~]*~|![^!]*!|@[^@]*@|\#[^\#]*\#|\$[^\$]*\$|%[^%]*%|\^[^\^]*\^|&[^&]*&|\*[^\*]*\*|;[^;]*;|/[^/]*/|\|[^\|]*\|)`)
 }
 
 func parseKeymap(keymap map[int][]action, str string) {
@@ -741,6 +750,8 @@
                        prefix = symbol + "reload"
                } else if strings.HasPrefix(src[1:], "preview") {
                        prefix = symbol + "preview"
+               } else if strings.HasPrefix(src[1:], "change-prompt") {
+                       prefix = symbol + "change-prompt"
                } else if src[len(prefix)] == '-' {
                        c := src[len(prefix)+1]
                        if c == 's' || c == 'S' {
@@ -914,6 +925,8 @@
                                                offset = len("reload")
                                        case actPreview:
                                                offset = len("preview")
+                                       case actChangePrompt:
+                                               offset = len("change-prompt")
                                        case actExecuteSilent:
                                                offset = len("execute-silent")
                                        case actExecuteMulti:
@@ -953,6 +966,8 @@
                return actReload
        case "preview":
                return actPreview
+       case "change-prompt":
+               return actChangePrompt
        case "execute":
                return actExecute
        case "execute-silent":
@@ -1067,6 +1082,10 @@
                        opts.border = tui.BorderSharp
                case "noborder":
                        opts.border = tui.BorderNone
+               case "follow":
+                       opts.follow = true
+               case "nofollow":
+                       opts.follow = false
                default:
                        if sizeRegex.MatchString(token) {
                                opts.size = parseSize(token, 99, "window size")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/result.go new/fzf-0.24.4/src/result.go
--- old/fzf-0.24.3/src/result.go        2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/result.go        2020-12-05 15:24:55.000000000 +0100
@@ -160,7 +160,19 @@
                                color := colMatch
                                if curr < -1 && theme.Colored {
                                        origColor := 
ansiToColorPair(itemColors[-curr-2], colMatch)
-                                       color = origColor.MergeNonDefault(color)
+                                       // hl or hl+ only sets the foreground 
color, so colMatch is the
+                                       // combination of either [hl and bg] or 
[hl+ and bg+].
+                                       //
+                                       // If the original text already has 
background color, and the
+                                       // forground color of colMatch is -1, 
we shouldn't only apply the
+                                       // background color of colMatch.
+                                       // e.g. echo -e 
"\x1b[32;7mfoo\x1b[mbar" | fzf --ansi --color bg+:1,hl+:-1:underline
+                                       //      echo -e "\x1b[42mfoo\x1b[mbar" 
| fzf --ansi --color bg+:1,hl+:-1:underline
+                                       if color.Fg().IsDefault() && 
origColor.HasBg() {
+                                               color = origColor
+                                       } else {
+                                               color = 
origColor.MergeNonDefault(color)
+                                       }
                                }
                                colors = append(colors, colorOffset{
                                        offset: [2]int32{int32(start), 
int32(idx)}, color: color})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/result_test.go 
new/fzf-0.24.4/src/result_test.go
--- old/fzf-0.24.3/src/result_test.go   2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/result_test.go   2020-12-05 15:24:55.000000000 +0100
@@ -109,10 +109,10 @@
        item := Result{
                item: &Item{
                        colors: &[]ansiOffset{
-                               {[2]int32{0, 20}, ansiState{1, 5, 0}},
-                               {[2]int32{22, 27}, ansiState{2, 6, tui.Bold}},
-                               {[2]int32{30, 32}, ansiState{3, 7, 0}},
-                               {[2]int32{33, 40}, ansiState{4, 8, tui.Bold}}}}}
+                               {[2]int32{0, 20}, ansiState{1, 5, 0, -1}},
+                               {[2]int32{22, 27}, ansiState{2, 6, tui.Bold, 
-1}},
+                               {[2]int32{30, 32}, ansiState{3, 7, 0, -1}},
+                               {[2]int32{33, 40}, ansiState{4, 8, tui.Bold, 
-1}}}}}
 
        colBase := tui.NewColorPair(89, 189, tui.AttrUndefined)
        colMatch := tui.NewColorPair(99, 199, tui.AttrUndefined)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/terminal.go 
new/fzf-0.24.4/src/terminal.go
--- old/fzf-0.24.3/src/terminal.go      2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/terminal.go      2020-12-05 15:24:55.000000000 +0100
@@ -51,6 +51,7 @@
        enabled    bool
        scrollable bool
        final      bool
+       following  bool
        spinner    string
 }
 
@@ -140,7 +141,7 @@
        selected     map[int32]selectedItem
        version      int64
        reqBox       *util.EventBox
-       preview      previewOpts
+       previewOpts  previewOpts
        previewer    previewer
        previewed    previewed
        previewBox   *util.EventBox
@@ -214,6 +215,7 @@
        actBackwardDeleteCharEOF
        actBackwardWord
        actCancel
+       actChangePrompt
        actClearScreen
        actClearQuery
        actClearSelection
@@ -492,8 +494,8 @@
                merger:      EmptyMerger,
                selected:    make(map[int32]selectedItem),
                reqBox:      util.NewEventBox(),
-               preview:     opts.Preview,
-               previewer:   previewer{0, []string{}, 0, previewBox != nil && 
!opts.Preview.hidden, false, true, ""},
+               previewOpts: opts.Preview,
+               previewer:   previewer{0, []string{}, 0, previewBox != nil && 
!opts.Preview.hidden, false, true, false, ""},
                previewed:   previewed{0, 0, 0, false},
                previewBox:  previewBox,
                eventBox:    eventBox,
@@ -525,7 +527,7 @@
        //             // unless the part has a non-default ANSI state
        loc := whiteSuffix.FindStringIndex(trimmed)
        if loc != nil {
-               blankState := ansiOffset{[2]int32{int32(loc[0]), 
int32(loc[1])}, ansiState{-1, -1, tui.AttrClear}}
+               blankState := ansiOffset{[2]int32{int32(loc[0]), 
int32(loc[1])}, ansiState{-1, -1, tui.AttrClear, -1}}
                if item.colors != nil {
                        lastColor := (*item.colors)[len(*item.colors)-1]
                        if lastColor.offset[1] < int32(loc[1]) {
@@ -656,8 +658,6 @@
 const (
        minWidth  = 4
        minHeight = 4
-
-       maxDisplayWidthCalc = 1024
 )
 
 func calculateSize(base int, size sizeSpec, occupied int, minSize int, pad 
int) int {
@@ -733,11 +733,11 @@
                }
        }
 
-       previewVisible := t.isPreviewEnabled() && t.preview.size.size > 0
+       previewVisible := t.isPreviewEnabled() && t.previewOpts.size.size > 0
        minAreaWidth := minWidth
        minAreaHeight := minHeight
        if previewVisible {
-               switch t.preview.position {
+               switch t.previewOpts.position {
                case posUp, posDown:
                        minAreaHeight *= 2
                case posLeft, posRight:
@@ -806,8 +806,8 @@
                createPreviewWindow := func(y int, x int, w int, h int) {
                        pwidth := w
                        pheight := h
-                       if t.preview.border != tui.BorderNone {
-                               previewBorder := 
tui.MakeBorderStyle(t.preview.border, t.unicode)
+                       if t.previewOpts.border != tui.BorderNone {
+                               previewBorder := 
tui.MakeBorderStyle(t.previewOpts.border, t.unicode)
                                t.pborder = t.tui.NewWindow(y, x, w, h, true, 
previewBorder)
                                pwidth -= 4
                                pheight -= 2
@@ -823,28 +823,28 @@
                }
                verticalPad := 2
                minPreviewHeight := 3
-               if t.preview.border == tui.BorderNone {
+               if t.previewOpts.border == tui.BorderNone {
                        verticalPad = 0
                        minPreviewHeight = 1
                }
-               switch t.preview.position {
+               switch t.previewOpts.position {
                case posUp:
-                       pheight := calculateSize(height, t.preview.size, 
minHeight, minPreviewHeight, verticalPad)
+                       pheight := calculateSize(height, t.previewOpts.size, 
minHeight, minPreviewHeight, verticalPad)
                        t.window = t.tui.NewWindow(
                                marginInt[0]+pheight, marginInt[3], width, 
height-pheight, false, noBorder)
                        createPreviewWindow(marginInt[0], marginInt[3], width, 
pheight)
                case posDown:
-                       pheight := calculateSize(height, t.preview.size, 
minHeight, minPreviewHeight, verticalPad)
+                       pheight := calculateSize(height, t.previewOpts.size, 
minHeight, minPreviewHeight, verticalPad)
                        t.window = t.tui.NewWindow(
                                marginInt[0], marginInt[3], width, 
height-pheight, false, noBorder)
                        createPreviewWindow(marginInt[0]+height-pheight, 
marginInt[3], width, pheight)
                case posLeft:
-                       pwidth := calculateSize(width, t.preview.size, 
minWidth, 5, 4)
+                       pwidth := calculateSize(width, t.previewOpts.size, 
minWidth, 5, 4)
                        t.window = t.tui.NewWindow(
                                marginInt[0], marginInt[3]+pwidth, 
width-pwidth, height, false, noBorder)
                        createPreviewWindow(marginInt[0], marginInt[3], pwidth, 
height)
                case posRight:
-                       pwidth := calculateSize(width, t.preview.size, 
minWidth, 5, 4)
+                       pwidth := calculateSize(width, t.previewOpts.size, 
minWidth, 5, 4)
                        t.window = t.tui.NewWindow(
                                marginInt[0], marginInt[3], width-pwidth, 
height, false, noBorder)
                        createPreviewWindow(marginInt[0], 
marginInt[3]+width-pwidth, pwidth, height)
@@ -1116,13 +1116,16 @@
 }
 
 func (t *Terminal) trimLeft(runes []rune, width int) ([]rune, int32) {
-       if len(runes) > maxDisplayWidthCalc && len(runes) > width {
-               trimmed := len(runes) - width
-               return runes[trimmed:], int32(trimmed)
+       width = util.Max(0, width)
+       var trimmed int32
+       // Assume that each rune takes at least one column on screen
+       if len(runes) > width {
+               diff := len(runes) - width
+               trimmed = int32(diff)
+               runes = runes[diff:]
        }
 
        currentWidth := t.displayWidth(runes)
-       var trimmed int32
 
        for currentWidth > width && len(runes) > 0 {
                runes = runes[1:]
@@ -1277,6 +1280,10 @@
        }
        var ansi *ansiState
        for _, line := range t.previewer.lines {
+               var lbg tui.Color = -1
+               if ansi != nil {
+                       ansi.lbg = -1
+               }
                line = strings.TrimSuffix(line, "\n")
                if lineNo >= height || t.pwindow.Y() == height-1 && 
t.pwindow.X() > 0 {
                        t.previewed.filled = true
@@ -1286,12 +1293,13 @@
                        prefixWidth := 0
                        _, _, ansi = extractColor(line, ansi, func(str string, 
ansi *ansiState) bool {
                                trimmed := []rune(str)
-                               if !t.preview.wrap {
+                               if !t.previewOpts.wrap {
                                        trimmed, _ = 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)
@@ -1308,7 +1316,12 @@
                        if unchanged && lineNo == 0 {
                                break
                        }
-                       t.pwindow.Fill("\n")
+                       if lbg >= 0 {
+                               t.pwindow.CFill(-1, lbg, tui.AttrRegular,
+                                       strings.Repeat(" ", 
t.pwindow.Width()-t.pwindow.X())+"\n")
+                       } else {
+                               t.pwindow.Fill("\n")
+                       }
                }
                lineNo++
        }
@@ -1548,7 +1561,7 @@
 }
 
 func (t *Terminal) evaluateScrollOffset(list []*Item, height int) int {
-       offsetExpr := t.replacePlaceholder(t.preview.scroll, false, "", list)
+       offsetExpr := t.replacePlaceholder(t.previewOpts.scroll, false, "", 
list)
        nums := strings.Split(offsetExpr, "-")
        switch len(nums) {
        case 0:
@@ -2030,7 +2043,7 @@
                                                if focusedIndex != currentIndex 
|| version != t.version {
                                                        version = t.version
                                                        focusedIndex = 
currentIndex
-                                                       
refreshPreview(t.preview.command)
+                                                       
refreshPreview(t.previewOpts.command)
                                                }
                                        case reqJump:
                                                if t.merger.Length() == 0 {
@@ -2055,10 +2068,15 @@
                                                })
                                        case reqPreviewDisplay:
                                                result := value.(previewResult)
-                                               t.previewer.version = 
result.version
+                                               if t.previewer.version != 
result.version {
+                                                       t.previewer.version = 
result.version
+                                                       t.previewer.following = 
t.previewOpts.follow
+                                               }
                                                t.previewer.lines = result.lines
                                                t.previewer.spinner = 
result.spinner
-                                               if result.offset >= 0 {
+                                               if t.previewer.following {
+                                                       t.previewer.offset = 
len(t.previewer.lines) - t.pwindow.Height()
+                                               } else if result.offset >= 0 {
                                                        t.previewer.offset = 
util.Constrain(result.offset, 0, len(t.previewer.lines)-1)
                                                }
                                                t.printPreview()
@@ -2122,9 +2140,10 @@
                        if !t.previewer.scrollable {
                                return
                        }
+                       t.previewer.following = false
                        newOffset := t.previewer.offset + amount
                        numLines := len(t.previewer.lines)
-                       if t.preview.cycle {
+                       if t.previewOpts.cycle {
                                newOffset = (newOffset + numLines) % numLines
                        }
                        newOffset = util.Constrain(newOffset, 0, numLines-1)
@@ -2165,17 +2184,17 @@
                                if t.hasPreviewer() {
                                        togglePreview(!t.previewer.enabled)
                                        if t.previewer.enabled {
-                                               valid, list := 
t.buildPlusList(t.preview.command, false)
+                                               valid, list := 
t.buildPlusList(t.previewOpts.command, false)
                                                if valid {
                                                        t.cancelPreview()
                                                        
t.previewBox.Set(reqPreviewEnqueue,
-                                                               
previewRequest{t.preview.command, t.pwindow, list})
+                                                               
previewRequest{t.previewOpts.command, t.pwindow, list})
                                                }
                                        }
                                }
                        case actTogglePreviewWrap:
                                if t.hasPreviewWindow() {
-                                       t.preview.wrap = !t.preview.wrap
+                                       t.previewOpts.wrap = !t.previewOpts.wrap
                                        req(reqPreviewRefresh)
                                }
                        case actToggleSort:
@@ -2213,11 +2232,14 @@
                                }
                        case actPrintQuery:
                                req(reqPrintQuery)
+                       case actChangePrompt:
+                               t.prompt, t.promptLen = t.parsePrompt(a.a)
+                               req(reqPrompt)
                        case actPreview:
                                togglePreview(true)
                                refreshPreview(a.a)
                        case actRefreshPreview:
-                               refreshPreview(t.preview.command)
+                               refreshPreview(t.previewOpts.command)
                        case actReplaceQuery:
                                if t.cy >= 0 && t.cy < t.merger.Length() {
                                        t.input = 
t.merger.Get(t.cy).item.text.ToRunes()
@@ -2540,7 +2562,7 @@
 
                if queryChanged {
                        if t.isPreviewEnabled() {
-                               _, _, q := hasPreviewFlags(t.preview.command)
+                               _, _, q := 
hasPreviewFlags(t.previewOpts.command)
                                if q {
                                        t.version++
                                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/tui/dummy.go 
new/fzf-0.24.4/src/tui/dummy.go
--- old/fzf-0.24.3/src/tui/dummy.go     2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/tui/dummy.go     2020-12-05 15:24:55.000000000 +0100
@@ -4,7 +4,7 @@
 
 package tui
 
-type Attr int
+type Attr int32
 
 func HasFullscreenRenderer() bool {
        return false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/tui/light.go 
new/fzf-0.24.4/src/tui/light.go
--- old/fzf-0.24.3/src/tui/light.go     2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/tui/light.go     2020-12-05 15:24:55.000000000 +0100
@@ -463,20 +463,54 @@
                                        }
                                        return Event{Invalid, 0, nil}
                                case ';':
-                                       if len(r.buffer) != 6 {
+                                       if len(r.buffer) < 6 {
                                                return Event{Invalid, 0, nil}
                                        }
                                        *sz = 6
                                        switch r.buffer[4] {
-                                       case '2', '5':
-                                               switch r.buffer[5] {
+                                       case '1', '2', '3', '5':
+                                               alt := r.buffer[4] == '3'
+                                               altShift := r.buffer[4] == '1' 
&& r.buffer[5] == '0'
+                                               char := r.buffer[5]
+                                               if altShift {
+                                                       if len(r.buffer) < 7 {
+                                                               return 
Event{Invalid, 0, nil}
+                                                       }
+                                                       *sz = 7
+                                                       char = r.buffer[6]
+                                               }
+                                               switch char {
                                                case 'A':
+                                                       if alt {
+                                                               return 
Event{AltUp, 0, nil}
+                                                       }
+                                                       if altShift {
+                                                               return 
Event{AltSUp, 0, nil}
+                                                       }
                                                        return Event{SUp, 0, 
nil}
                                                case 'B':
+                                                       if alt {
+                                                               return 
Event{AltDown, 0, nil}
+                                                       }
+                                                       if altShift {
+                                                               return 
Event{AltSDown, 0, nil}
+                                                       }
                                                        return Event{SDown, 0, 
nil}
                                                case 'C':
+                                                       if alt {
+                                                               return 
Event{AltRight, 0, nil}
+                                                       }
+                                                       if altShift {
+                                                               return 
Event{AltSRight, 0, nil}
+                                                       }
                                                        return Event{SRight, 0, 
nil}
                                                case 'D':
+                                                       if alt {
+                                                               return 
Event{AltLeft, 0, nil}
+                                                       }
+                                                       if altShift {
+                                                               return 
Event{AltSLeft, 0, nil}
+                                                       }
                                                        return Event{SLeft, 0, 
nil}
                                                }
                                        } // r.buffer[4]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/tui/tcell.go 
new/fzf-0.24.4/src/tui/tcell.go
--- old/fzf-0.24.3/src/tui/tcell.go     2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/tui/tcell.go     2020-12-05 15:24:55.000000000 +0100
@@ -222,7 +222,10 @@
 
                // process keyboard:
        case *tcell.EventKey:
-               alt := (ev.Modifiers() & tcell.ModAlt) > 0
+               mods := ev.Modifiers()
+               alt := (mods & tcell.ModAlt) > 0
+               shift := (mods & tcell.ModShift) > 0
+               altShift := alt && shift
                keyfn := func(r rune) int {
                        if alt {
                                return CtrlAltA - 'a' + int(r)
@@ -297,21 +300,45 @@
                        return Event{BSpace, 0, nil}
 
                case tcell.KeyUp:
+                       if altShift {
+                               return Event{AltSUp, 0, nil}
+                       }
+                       if shift {
+                               return Event{SUp, 0, nil}
+                       }
                        if alt {
                                return Event{AltUp, 0, nil}
                        }
                        return Event{Up, 0, nil}
                case tcell.KeyDown:
+                       if altShift {
+                               return Event{AltSDown, 0, nil}
+                       }
+                       if shift {
+                               return Event{SDown, 0, nil}
+                       }
                        if alt {
                                return Event{AltDown, 0, nil}
                        }
                        return Event{Down, 0, nil}
                case tcell.KeyLeft:
+                       if altShift {
+                               return Event{AltSLeft, 0, nil}
+                       }
+                       if shift {
+                               return Event{SLeft, 0, nil}
+                       }
                        if alt {
                                return Event{AltLeft, 0, nil}
                        }
                        return Event{Left, 0, nil}
                case tcell.KeyRight:
+                       if altShift {
+                               return Event{AltSRight, 0, nil}
+                       }
+                       if shift {
+                               return Event{SRight, 0, nil}
+                       }
                        if alt {
                                return Event{AltRight, 0, nil}
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/src/tui/tui.go 
new/fzf-0.24.4/src/tui/tui.go
--- old/fzf-0.24.3/src/tui/tui.go       2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/src/tui/tui.go       2020-12-05 15:24:55.000000000 +0100
@@ -98,6 +98,11 @@
        AltLeft
        AltRight
 
+       AltSUp
+       AltSDown
+       AltSLeft
+       AltSRight
+
        Alt0
 )
 
@@ -119,6 +124,10 @@
 
 type Color int32
 
+func (c Color) IsDefault() bool {
+       return c == colDefault
+}
+
 func (c Color) is24() bool {
        return c > 0 && (c&(1<<24)) > 0
 }
@@ -185,6 +194,11 @@
        return p.attr
 }
 
+func (p ColorPair) HasBg() bool {
+       return p.attr&Reverse == 0 && p.bg != colDefault ||
+               p.attr&Reverse > 0 && p.fg != colDefault
+}
+
 func (p ColorPair) merge(other ColorPair, except Color) ColorPair {
        dup := p
        dup.attr = dup.attr.Merge(other.attr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fzf-0.24.3/test/test_go.rb 
new/fzf-0.24.4/test/test_go.rb
--- old/fzf-0.24.3/test/test_go.rb      2020-11-09 12:41:59.000000000 +0100
+++ new/fzf-0.24.4/test/test_go.rb      2020-12-05 15:24:55.000000000 +0100
@@ -1823,6 +1823,20 @@
     tmux.until { |lines| lines.item_count == 100 }
     tmux.until { |lines| lines[1]&.include?('[200]') }
   end
+
+  def test_change_prompt
+    tmux.send_keys "#{FZF} --bind 'a:change-prompt(a> ),b:change-prompt:b> ' 
--query foo", :Enter
+    tmux.until { |lines| assert_equal '> foo', lines[-1] }
+    tmux.send_keys 'a'
+    tmux.until { |lines| assert_equal 'a> foo', lines[-1] }
+    tmux.send_keys 'b'
+    tmux.until { |lines| assert_equal 'b> foo', lines[-1] }
+  end
+
+  def test_preview_window_follow
+    tmux.send_keys "#{FZF} --preview 'seq 1000 | nl' --preview-window 
down:noborder:follow", :Enter
+    tmux.until { |lines| assert_equal '1000  1000', lines[-1].strip }
+  end
 end
 
 module TestShell

++++++ vendor.tar.xz ++++++
_______________________________________________
openSUSE Commits mailing list -- commit@lists.opensuse.org
To unsubscribe, email commit-le...@lists.opensuse.org
List Netiquette: https://en.opensuse.org/openSUSE:Mailing_list_netiquette
List Archives: 
https://lists.opensuse.org/archives/list/commit@lists.opensuse.org

Reply via email to