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