mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-15 06:43:47 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a24d274a3c | ||
|
|
dac81432d6 | ||
|
|
309b5081ef | ||
|
|
91bc4f2671 | ||
|
|
4c9d37d919 | ||
|
|
7e9566f66a | ||
|
|
3f7e8a475d | ||
|
|
1cf7c0f334 | ||
|
|
ff8ee9ee4e | ||
|
|
cbbd939a94 | ||
|
|
f232df2887 | ||
|
|
16bfb2c80c | ||
|
|
0ba066123e | ||
|
|
81c51c26cc | ||
|
|
6fa8295ac5 | ||
|
|
f975b40236 | ||
|
|
01d9d9c8c8 | ||
|
|
1eafc4e5d9 | ||
|
|
38e4020aa8 | ||
|
|
ac32fbb3b2 | ||
|
|
7d26eca5cc |
@@ -1,6 +1,13 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
0.60.1
|
||||
------
|
||||
- Bug fixes and minor improvements
|
||||
- Built-in walker now prints directory entries with a trailing slash
|
||||
- Fixed a bug causing unexpected behavior with [fzf-tab](https://github.com/Aloxaf/fzf-tab). Please upgrade if you use it.
|
||||
- Thanks to @alexeisersun, @bitraid, @Lompik, and @fsc0 for the contributions
|
||||
|
||||
0.60.0
|
||||
------
|
||||
_Release highlights: https://junegunn.github.io/fzf/releases/0.60.0/_
|
||||
|
||||
2
install
2
install
@@ -2,7 +2,7 @@
|
||||
|
||||
set -u
|
||||
|
||||
version=0.60.0
|
||||
version=0.60.1
|
||||
auto_completion=
|
||||
key_bindings=
|
||||
update_config=2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$version="0.60.0"
|
||||
$version="0.60.1"
|
||||
|
||||
$fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
..
|
||||
.TH fzf\-tmux 1 "Feb 2025" "fzf 0.60.0" "fzf\-tmux - open fzf in tmux split pane"
|
||||
.TH fzf\-tmux 1 "Feb 2025" "fzf 0.60.1" "fzf\-tmux - open fzf in tmux split pane"
|
||||
|
||||
.SH NAME
|
||||
fzf\-tmux - open fzf in tmux split pane
|
||||
|
||||
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
..
|
||||
.TH fzf 1 "Feb 2025" "fzf 0.60.0" "fzf - a command-line fuzzy finder"
|
||||
.TH fzf 1 "Feb 2025" "fzf 0.60.1" "fzf - a command-line fuzzy finder"
|
||||
|
||||
.SH NAME
|
||||
fzf - a command-line fuzzy finder
|
||||
@@ -56,7 +56,9 @@ Case-insensitive match (default: smart-case match)
|
||||
Case-sensitive match
|
||||
.TP
|
||||
.B "\-\-smart\-case"
|
||||
Smart-case match (default)
|
||||
Smart-case match (default). In this mode, the search is case-insensitive by
|
||||
default, but it becomes case-sensitive if the query contains any uppercase
|
||||
letters.
|
||||
.TP
|
||||
.B "\-\-literal"
|
||||
Do not normalize latin script letters for matching.
|
||||
|
||||
@@ -99,9 +99,9 @@ if [[ -o interactive ]]; then
|
||||
__fzf_defaults() {
|
||||
# $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
# $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
echo "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
|
||||
echo -E "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
|
||||
command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
|
||||
echo "${FZF_DEFAULT_OPTS-} $2"
|
||||
echo -E "${FZF_DEFAULT_OPTS-} $2"
|
||||
}
|
||||
|
||||
__fzf_comprun() {
|
||||
|
||||
@@ -14,102 +14,24 @@
|
||||
|
||||
# Key bindings
|
||||
# ------------
|
||||
# For compatibility with fish versions down to 3.1.2, the script does not use:
|
||||
# - The -f/--function switch of command: set
|
||||
# - The process substitution syntax: $(cmd)
|
||||
# - Ranges that omit start/end indexes: $var[$start..] $var[..$end] $var[..]
|
||||
function fzf_key_bindings
|
||||
|
||||
function __fzf_defaults
|
||||
# $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
# $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
|
||||
echo "--height $FZF_TMUX_HEIGHT --min-height 20+ --bind=ctrl-z:ignore" $argv[1]
|
||||
test -r "$FZF_DEFAULT_OPTS_FILE"; and string collect -N -- <$FZF_DEFAULT_OPTS_FILE
|
||||
echo $FZF_DEFAULT_OPTS $argv[2]
|
||||
end
|
||||
|
||||
# Store current token in $dir as root for the 'find' command
|
||||
function fzf-file-widget -d "List files and folders"
|
||||
set -l commandline (__fzf_parse_commandline)
|
||||
set -lx dir $commandline[1]
|
||||
set -l fzf_query $commandline[2]
|
||||
set -l prefix $commandline[3]
|
||||
set -l result
|
||||
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
|
||||
begin
|
||||
set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path --walker-root=$dir" "$FZF_CTRL_T_OPTS")
|
||||
set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND"
|
||||
set -lx FZF_DEFAULT_OPTS_FILE ''
|
||||
set result (eval (__fzfcmd) -m --query=$fzf_query)
|
||||
end
|
||||
if test -z "$result"
|
||||
commandline -f repaint
|
||||
return
|
||||
else
|
||||
# Remove last token from commandline.
|
||||
commandline -t ""
|
||||
end
|
||||
for i in $result
|
||||
commandline -it -- $prefix
|
||||
commandline -it -- (string escape -- $i)
|
||||
commandline -it -- ' '
|
||||
end
|
||||
commandline -f repaint
|
||||
end
|
||||
|
||||
function fzf-history-widget -d "Show command history"
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
|
||||
begin
|
||||
# merge history from other sessions before searching
|
||||
test -z "$fish_private_mode"; and builtin history merge
|
||||
|
||||
set -lx FZF_DEFAULT_OPTS (__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '"\t"↳ ' --highlight-line +m $FZF_CTRL_R_OPTS")
|
||||
set -lx FZF_DEFAULT_OPTS_FILE ''
|
||||
set -lx FZF_DEFAULT_COMMAND
|
||||
set -a -- FZF_DEFAULT_OPTS --with-shell=(status fish-path)\\ -c
|
||||
|
||||
if type -q perl
|
||||
set -a FZF_DEFAULT_OPTS '--tac'
|
||||
set FZF_DEFAULT_COMMAND 'builtin history -z --reverse | command perl -0 -pe \'s/^/$.\t/g; s/\n/\n\t/gm\''
|
||||
else
|
||||
set FZF_DEFAULT_COMMAND \
|
||||
'set -l h (builtin history -z --reverse | string split0);' \
|
||||
'for i in (seq (count $h) -1 1);' \
|
||||
'string join0 -- $i\t(string replace -a -- \n \n\t $h[$i] | string collect);' \
|
||||
'end'
|
||||
end
|
||||
set -l result (eval $FZF_DEFAULT_COMMAND \| (__fzfcmd) --read0 --print0 -q (commandline | string escape) "--bind=enter:become:'string replace -a -- \n\t \n {2..} | string collect'")
|
||||
and commandline -- $result
|
||||
end
|
||||
commandline -f repaint
|
||||
end
|
||||
|
||||
function fzf-cd-widget -d "Change directory"
|
||||
set -l commandline (__fzf_parse_commandline)
|
||||
set -lx dir $commandline[1]
|
||||
set -l fzf_query $commandline[2]
|
||||
set -l prefix $commandline[3]
|
||||
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
|
||||
begin
|
||||
set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path --walker-root=$dir" "$FZF_ALT_C_OPTS")
|
||||
set -lx FZF_DEFAULT_OPTS_FILE ''
|
||||
set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND"
|
||||
set -l result (eval (__fzfcmd) +m --query=$fzf_query)
|
||||
|
||||
if test -n "$result"
|
||||
cd -- $result
|
||||
|
||||
# Remove last token from commandline.
|
||||
commandline -t ""
|
||||
commandline -it -- $prefix
|
||||
end
|
||||
end
|
||||
|
||||
commandline -f repaint
|
||||
# $argv[1]: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
# $argv[2..]: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set -l FZF_TMUX_HEIGHT 40%
|
||||
string join ' ' -- \
|
||||
"--height $FZF_TMUX_HEIGHT --min-height=20+ --bind=ctrl-z:ignore" $argv[1] \
|
||||
(test -r "$FZF_DEFAULT_OPTS_FILE"; and string join -- ' ' <$FZF_DEFAULT_OPTS_FILE) \
|
||||
$FZF_DEFAULT_OPTS $argv[2..-1]
|
||||
end
|
||||
|
||||
function __fzfcmd
|
||||
test -n "$FZF_TMUX"; or set FZF_TMUX 0
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
|
||||
test -n "$FZF_TMUX_HEIGHT"; or set -l FZF_TMUX_HEIGHT 40%
|
||||
if test -n "$FZF_TMUX_OPTS"
|
||||
echo "fzf-tmux $FZF_TMUX_OPTS -- "
|
||||
else if test "$FZF_TMUX" = "1"
|
||||
@@ -119,56 +41,42 @@ function fzf_key_bindings
|
||||
end
|
||||
end
|
||||
|
||||
bind \cr fzf-history-widget
|
||||
if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
|
||||
bind \ct fzf-file-widget
|
||||
end
|
||||
if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
|
||||
bind \ec fzf-cd-widget
|
||||
end
|
||||
|
||||
bind -M insert \cr fzf-history-widget
|
||||
if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
|
||||
bind -M insert \ct fzf-file-widget
|
||||
end
|
||||
if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
|
||||
bind -M insert \ec fzf-cd-widget
|
||||
end
|
||||
|
||||
function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix'
|
||||
set -l commandline (commandline -t)
|
||||
set -l dir '.'
|
||||
set -l query
|
||||
set -l commandline (commandline -t | string unescape -n)
|
||||
|
||||
# strip -option= from token if present
|
||||
# Strip -option= from token if present
|
||||
set -l prefix (string match -r -- '^-[^\s=]+=' $commandline)
|
||||
set commandline (string replace -- "$prefix" '' $commandline)
|
||||
|
||||
# Enable home directory expansion of leading ~/
|
||||
set commandline (string replace -r -- '^~/' '\$HOME/' $commandline)
|
||||
|
||||
# escape special characters, except for the $ sign of valid variable names,
|
||||
# so that after eval, the original string is returned, but with the
|
||||
# variable names replaced by their values.
|
||||
# Escape special characters, except for the $ sign of valid variable names,
|
||||
# so that the original string with expanded variables is returned after eval.
|
||||
set commandline (string escape -n -- $commandline)
|
||||
set commandline (string replace -r -a -- '\x5c\$(?=[\w])' '\$' $commandline)
|
||||
set commandline (string replace -r -a -- '\\\\\$(?=[\w])' '\$' $commandline)
|
||||
|
||||
# eval is used to do shell expansion on paths
|
||||
eval set commandline $commandline
|
||||
|
||||
# Combine multiple consecutive slashes into one, and unescape.
|
||||
set commandline (string replace -r -a -- '/+' '/' $commandline | string unescape -n)
|
||||
# Combine multiple consecutive slashes into one.
|
||||
set commandline (string replace -r -a -- '/+' '/' $commandline)
|
||||
|
||||
if test -z "$commandline"
|
||||
# Default to current directory with no --query
|
||||
set dir '.'
|
||||
set fzf_query ''
|
||||
else
|
||||
set dir (__fzf_get_dir $commandline)
|
||||
if test -n "$commandline"
|
||||
# Strip trailing slash, unless $dir is root dir (/)
|
||||
set dir (string replace -r -- '(?<!^)/$' '' $commandline)
|
||||
|
||||
# BUG: on combined expressions, if a left argument is a single `!`, the
|
||||
# builtin test command of fish will treat it as the ! operator. To
|
||||
# overcome this, have the variable parts on the right.
|
||||
if test "." = "$dir" -a "./" != (string sub -l 2 -- $commandline)
|
||||
# if $dir is "." but commandline is not a relative path, this means no file path found
|
||||
# Set $dir to the longest existing filepath
|
||||
while not test -d "$dir"
|
||||
# If path is absolute, this can keep going until ends up at /
|
||||
# If path is relative, this can keep going until entire input is consumed, dirname returns "."
|
||||
set dir (dirname -- $dir)
|
||||
end
|
||||
|
||||
if test "$dir" = '.'; and test (string sub -l 2 -- $commandline) != './'
|
||||
# If $dir is "." but commandline is not a relative path, this means no file path found
|
||||
set fzf_query $commandline
|
||||
else
|
||||
# Also remove trailing slash after dir, to "split" input properly
|
||||
@@ -176,25 +84,98 @@ function fzf_key_bindings
|
||||
end
|
||||
end
|
||||
|
||||
echo -- $dir
|
||||
string escape -- $fzf_query
|
||||
echo -- $prefix
|
||||
string escape -n -- "$dir" "$fzf_query" "$prefix"
|
||||
end
|
||||
|
||||
function __fzf_get_dir -d 'Find the longest existing filepath from input string'
|
||||
set dir $argv
|
||||
# Store current token in $dir as root for the 'find' command
|
||||
function fzf-file-widget -d "List files and folders"
|
||||
set -l commandline (__fzf_parse_commandline)
|
||||
set -lx dir $commandline[1]
|
||||
set -l fzf_query $commandline[2]
|
||||
set -l prefix $commandline[3]
|
||||
|
||||
# Strip trailing slash, unless $dir is root dir (/)
|
||||
set dir (string replace -r -- '(?<!^)/$' '' $dir)
|
||||
set -lx FZF_DEFAULT_OPTS (__fzf_defaults \
|
||||
"--reverse --walker=file,dir,follow,hidden --scheme=path --walker-root=$dir" \
|
||||
"$FZF_CTRL_T_OPTS --multi")
|
||||
|
||||
# Iteratively check if dir exists and strip tail end of path
|
||||
while test ! -d "$dir"
|
||||
# If path is absolute, this can keep going until ends up at /
|
||||
# If path is relative, this can keep going until entire input is consumed, dirname returns "."
|
||||
set dir (dirname -- "$dir")
|
||||
set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND"
|
||||
set -lx FZF_DEFAULT_OPTS_FILE
|
||||
|
||||
if set -l result (eval (__fzfcmd) --query=$fzf_query)
|
||||
# Remove last token from commandline.
|
||||
commandline -t ''
|
||||
for i in $result
|
||||
commandline -it -- $prefix(string escape -- $i)' '
|
||||
end
|
||||
end
|
||||
|
||||
string escape -n -- $dir
|
||||
commandline -f repaint
|
||||
end
|
||||
|
||||
function fzf-history-widget -d "Show command history"
|
||||
set -l fzf_query (commandline | string escape)
|
||||
|
||||
set -lx FZF_DEFAULT_OPTS (__fzf_defaults '' \
|
||||
'--nth=2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign="\t↳ "' \
|
||||
"--highlight-line --no-multi $FZF_CTRL_R_OPTS --read0 --print0" \
|
||||
"--bind='enter:become:string replace -a -- \n\t \n {2..} | string collect'" \
|
||||
'--with-shell='(status fish-path)\\ -c)
|
||||
|
||||
set -lx FZF_DEFAULT_OPTS_FILE
|
||||
set -lx FZF_DEFAULT_COMMAND
|
||||
|
||||
if type -q perl
|
||||
set -a FZF_DEFAULT_OPTS '--tac'
|
||||
set FZF_DEFAULT_COMMAND 'builtin history -z --reverse | command perl -0 -pe \'s/^/$.\t/g; s/\n/\n\t/gm\''
|
||||
else
|
||||
set FZF_DEFAULT_COMMAND \
|
||||
'set -l h (builtin history -z --reverse | string split0);' \
|
||||
'for i in (seq (count $h) -1 1);' \
|
||||
'string join0 -- $i\t(string replace -a -- \n \n\t $h[$i] | string collect);' \
|
||||
'end'
|
||||
end
|
||||
|
||||
# Merge history from other sessions before searching
|
||||
test -z "$fish_private_mode"; and builtin history merge
|
||||
|
||||
set -l result (eval $FZF_DEFAULT_COMMAND \| (__fzfcmd) --query=$fzf_query)
|
||||
and commandline -- $result
|
||||
|
||||
commandline -f repaint
|
||||
end
|
||||
|
||||
function fzf-cd-widget -d "Change directory"
|
||||
set -l commandline (__fzf_parse_commandline)
|
||||
set -lx dir $commandline[1]
|
||||
set -l fzf_query $commandline[2]
|
||||
set -l prefix $commandline[3]
|
||||
|
||||
set -lx FZF_DEFAULT_OPTS (__fzf_defaults \
|
||||
"--reverse --walker=dir,follow,hidden --scheme=path --walker-root=$dir" \
|
||||
"$FZF_ALT_C_OPTS --no-multi")
|
||||
|
||||
set -lx FZF_DEFAULT_OPTS_FILE
|
||||
set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND"
|
||||
|
||||
if set -l result (eval (__fzfcmd) --query=$fzf_query)
|
||||
cd -- $result
|
||||
commandline -rt -- $prefix
|
||||
end
|
||||
|
||||
commandline -f repaint
|
||||
end
|
||||
|
||||
bind \cr fzf-history-widget
|
||||
bind -M insert \cr fzf-history-widget
|
||||
|
||||
if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
|
||||
bind \ct fzf-file-widget
|
||||
bind -M insert \ct fzf-file-widget
|
||||
end
|
||||
|
||||
if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
|
||||
bind \ec fzf-cd-widget
|
||||
bind -M insert \ec fzf-cd-widget
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -41,9 +41,9 @@ if [[ -o interactive ]]; then
|
||||
__fzf_defaults() {
|
||||
# $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
# $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
|
||||
echo "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
|
||||
echo -E "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
|
||||
command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
|
||||
echo "${FZF_DEFAULT_OPTS-} $2"
|
||||
echo -E "${FZF_DEFAULT_OPTS-} $2"
|
||||
}
|
||||
|
||||
# CTRL-T - Paste the selected file path(s) into the command line
|
||||
|
||||
@@ -767,6 +767,9 @@ func FuzzyMatchV1(caseSensitive bool, normalize bool, forward bool, text *util.C
|
||||
char = unicode.To(unicode.LowerCase, char)
|
||||
}
|
||||
}
|
||||
if normalize {
|
||||
char = normalizeRune(char)
|
||||
}
|
||||
|
||||
pidx_ := indexAt(pidx, lenPattern, forward)
|
||||
pchar := pattern[pidx_]
|
||||
|
||||
@@ -200,3 +200,12 @@ func TestLongString(t *testing.T) {
|
||||
bytes[math.MaxUint16] = 'z'
|
||||
assertMatch(t, FuzzyMatchV2, true, true, string(bytes), "zx", math.MaxUint16, math.MaxUint16+2, scoreMatch*2+bonusConsecutive)
|
||||
}
|
||||
|
||||
func TestLongStringWithNormalize(t *testing.T) {
|
||||
bytes := make([]byte, 30000)
|
||||
for i := range bytes {
|
||||
bytes[i] = 'x'
|
||||
}
|
||||
unicodeString := string(bytes) + " Minímal example"
|
||||
assertMatch2(t, FuzzyMatchV1, false, true, false, unicodeString, "minim", 30001, 30006, 140)
|
||||
}
|
||||
|
||||
@@ -320,6 +320,7 @@ func (r *Reader) readFiles(roots []string, opts walkerOpts, ignores []string) bo
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
path += sep
|
||||
}
|
||||
if ((opts.file && !isDir) || (opts.dir && isDir)) && r.pusher(stringBytes(path)) {
|
||||
atomic.StoreInt32(&r.event, int32(EvtReadNew))
|
||||
|
||||
@@ -638,6 +638,7 @@ type previewRequest struct {
|
||||
scrollOffset int
|
||||
list []*Item
|
||||
env []string
|
||||
query string
|
||||
}
|
||||
|
||||
type previewResult struct {
|
||||
@@ -3099,8 +3100,15 @@ func (t *Terminal) printHighlighted(result Result, colBase tui.ColorPair, colMat
|
||||
maxWidth := t.window.Width() - (indentSize + 1)
|
||||
wasWrapped := false
|
||||
if wrapped {
|
||||
maxWidth -= t.wrapSignWidth
|
||||
t.window.CPrint(colBase.WithAttr(tui.Dim), t.wrapSign)
|
||||
wrapSign := t.wrapSign
|
||||
if maxWidth < t.wrapSignWidth {
|
||||
runes, _ := util.Truncate(wrapSign, maxWidth)
|
||||
wrapSign = string(runes)
|
||||
maxWidth = 0
|
||||
} else {
|
||||
maxWidth -= t.wrapSignWidth
|
||||
}
|
||||
t.window.CPrint(colBase.WithAttr(tui.Dim), wrapSign)
|
||||
wrapped = false
|
||||
wasWrapped = true
|
||||
}
|
||||
@@ -3165,7 +3173,9 @@ func (t *Terminal) printHighlighted(result Result, colBase tui.ColorPair, colMat
|
||||
displayWidth = t.displayWidthWithLimit(line, 0, displayWidth)
|
||||
}
|
||||
|
||||
t.printColoredString(t.window, line, offsets, colBase)
|
||||
if maxWidth > 0 {
|
||||
t.printColoredString(t.window, line, offsets, colBase)
|
||||
}
|
||||
if postTask != nil {
|
||||
postTask(actualLineNum, displayWidth, wasWrapped, forceRedraw)
|
||||
} else {
|
||||
@@ -3374,8 +3384,10 @@ func (t *Terminal) renderPreviewText(height int, lines []string, lineNo int, unc
|
||||
wiped := false
|
||||
image := false
|
||||
wireframe := false
|
||||
var index int
|
||||
var line string
|
||||
Loop:
|
||||
for _, line := range lines {
|
||||
for index, line = range lines {
|
||||
var lbg tui.Color = -1
|
||||
if ansi != nil {
|
||||
ansi.lbg = -1
|
||||
@@ -3518,6 +3530,7 @@ Loop:
|
||||
}
|
||||
lineNo++
|
||||
}
|
||||
t.previewer.scrollable = t.previewer.scrollable || index < len(lines)-1
|
||||
t.previewed.image = image
|
||||
t.previewed.wireframe = wireframe
|
||||
}
|
||||
@@ -4376,6 +4389,7 @@ func (t *Terminal) Loop() error {
|
||||
var items []*Item
|
||||
var commandTemplate string
|
||||
var env []string
|
||||
var query string
|
||||
initialOffset := 0
|
||||
t.previewBox.Wait(func(events *util.Events) {
|
||||
for req, value := range *events {
|
||||
@@ -4389,6 +4403,7 @@ func (t *Terminal) Loop() error {
|
||||
initialOffset = request.scrollOffset
|
||||
items = request.list
|
||||
env = request.env
|
||||
query = request.query
|
||||
}
|
||||
}
|
||||
events.Clear()
|
||||
@@ -4402,8 +4417,7 @@ func (t *Terminal) Loop() error {
|
||||
version++
|
||||
// We don't display preview window if no match
|
||||
if items[0] != nil {
|
||||
_, query := t.Input()
|
||||
command, tempFiles := t.replacePlaceholder(commandTemplate, false, string(query), items)
|
||||
command, tempFiles := t.replacePlaceholder(commandTemplate, false, query, items)
|
||||
cmd := t.executor.ExecCommand(command, true)
|
||||
cmd.Env = env
|
||||
|
||||
@@ -4531,7 +4545,7 @@ func (t *Terminal) Loop() error {
|
||||
if len(command) > 0 && t.canPreview() {
|
||||
_, list := t.buildPlusList(command, false)
|
||||
t.cancelPreview()
|
||||
t.previewBox.Set(reqPreviewEnqueue, previewRequest{command, t.evaluateScrollOffset(), list, t.environForPreview()})
|
||||
t.previewBox.Set(reqPreviewEnqueue, previewRequest{command, t.evaluateScrollOffset(), list, t.environForPreview(), string(t.input)})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4963,7 +4977,7 @@ func (t *Terminal) Loop() error {
|
||||
if valid {
|
||||
t.cancelPreview()
|
||||
t.previewBox.Set(reqPreviewEnqueue,
|
||||
previewRequest{t.previewOpts.command, t.evaluateScrollOffset(), list, t.environForPreview()})
|
||||
previewRequest{t.previewOpts.command, t.evaluateScrollOffset(), list, t.environForPreview(), string(t.input)})
|
||||
}
|
||||
} else {
|
||||
// Discard the preview content so that it won't accidentally appear
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
|
||||
const consoleDevice string = "/dev/tty"
|
||||
|
||||
var offsetRegexp = regexp.MustCompile("(.*)\x1b\\[([0-9]+);([0-9]+)R")
|
||||
var offsetRegexp = regexp.MustCompile("(.*?)\x00?\x1b\\[([0-9]+);([0-9]+)R")
|
||||
var offsetRegexpBegin = regexp.MustCompile("^\x1b\\[[0-9]+;[0-9]+R")
|
||||
|
||||
func (r *LightRenderer) Bell() {
|
||||
|
||||
@@ -544,4 +544,18 @@ class TestPreview < TestInteractive
|
||||
tmux.send_keys :Up
|
||||
tmux.until { |lines| assert_includes lines, '> 2' }
|
||||
end
|
||||
|
||||
def test_preview_query_should_not_be_affected_by_search
|
||||
tmux.send_keys "seq 1 | #{FZF} --bind 'change:transform-search(echo {q:1})' --preview 'echo [{q}/{}]'", :Enter
|
||||
tmux.until { |lines| assert_equal 1, lines.match_count }
|
||||
tmux.send_keys '1'
|
||||
tmux.until { |lines| assert lines.any_include?('[1/1]') }
|
||||
tmux.send_keys :Space
|
||||
tmux.until { |lines| assert lines.any_include?('[1 /1]') }
|
||||
tmux.send_keys '2'
|
||||
tmux.until do |lines|
|
||||
assert lines.any_include?('[1 2/1]')
|
||||
assert_equal 1, lines.match_count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -73,7 +73,7 @@ module TestShell
|
||||
tmux.prepare
|
||||
tmux.send_keys :Escape, :c
|
||||
lines = tmux.until { |lines| assert_operator lines.match_count, :>, 0 }
|
||||
expected = lines.reverse.find { |l| l.start_with?('> ') }[2..]
|
||||
expected = lines.reverse.find { |l| l.start_with?('> ') }[2..].chomp('/')
|
||||
tmux.send_keys :Enter
|
||||
tmux.prepare
|
||||
tmux.send_keys :pwd, :Enter
|
||||
@@ -241,7 +241,7 @@ module CompletionTest
|
||||
tmux.until do |lines|
|
||||
assert_equal 1, lines.match_count
|
||||
assert_includes lines, '> 55'
|
||||
assert_includes lines, '> /tmp/fzf-test/d55'
|
||||
assert_includes lines, '> /tmp/fzf-test/d55/'
|
||||
end
|
||||
tmux.send_keys :Enter
|
||||
tmux.until(true) { |lines| assert_equal 'cd /tmp/fzf-test/d55/', lines[-1] }
|
||||
|
||||
Reference in New Issue
Block a user