* [tests] Test fzf's placeholders and escaping on practical commands
This tests some reasonable commands in fzf's templates (for commands,
previews, rebinds etc.), how are those commands escaped (backslashes,
double quotes), and documents if the output is executable in cmd.exe.
Both on Unix and Windows.
* [tests] Add testing of placeholder parsing and matching
Adds tests and bit of docs for the curly brackets placeholders in fzf's
template strings. Also tests the "placeholder" regex.
* [tests] Add more test cases of replacing placeholders focused on flags
Replacing placeholders in templates is already tested, this adds tests
that focus more on the parameters of placeholders - e.g. flags, token
ranges.
There is at least one test for each flag, not all combinations are
tested though.
* [refactoring] Split OS-specific function quoteEntry() to corresponding source file
This is minor refactoring, and also the function's test was made
crossplatform.
* [refactoring] Simplify replacePlaceholder function
Should be equivalent to the original, but has simpler structure.
This contains one test case of each tcell.Key* event type that can be
sent to and subsequently processed in fzf's GetChar(). The test cases
describe status quo, and all of them PASS.
Small function util.ToTty() was added. It is similar to util.IsTty(),
but for stdout (hence the To preposition).
Most of the "expected" strings in terminal.go test were changed to
"text/template" values. Quotes in those string were parametrized in
the templates. Two functions handling templates were added
for convenience.
Templates has the advantage of:
- parametrize repetitive strings inside "expected" values
- inner and outer quotes were parametrized in templates
- long and confusing test values are more readable
- templates can be localized for other operating systems
https://github.com/junegunn/fzf/issues/1360#issuecomment-788178140
# Redirect /dev/tty to suppress "Vim: Warning: Input is not from a terminal"
ls | fzf --bind "enter:execute(vim {} < /dev/tty)"
# With this change, we can omit "< /dev/tty" part
ls | fzf --bind "enter:execute(vim {})"
This commit speeds up the parsing/processing of ANSI escape codes by
roughly 7.5x. The speedup is mostly accomplished by replacing the regex
with dedicated parsing logic (nextAnsiEscapeSequence()) and reducing the
number of allocations in extractColor().
#### Benchmarks
```
name old time/op new time/op delta
ExtractColor-16 4.89µs ± 5% 0.64µs ± 2% -86.87% (p=0.000 n=9+9)
name old speed new speed delta
ExtractColor-16 25.6MB/s ± 5% 194.6MB/s ± 2% +661.43% (p=0.000 n=9+9)
name old alloc/op new alloc/op delta
ExtractColor-16 1.37kB ± 0% 0.31kB ± 0% -77.31% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
ExtractColor-16 48.0 ± 0% 4.0 ± 0% -91.67% (p=0.000 n=10+10)
```
This fixes the following errors with Go 1.15:
```
src/options.go:452:69: conversion from untyped int to string yields a string of one rune, not a string of digits (did you mean fmt.Sprint(x)?)
src/options.go:463:33: conversion from untyped int to string yields a string of one rune, not a string of digits (did you mean fmt.Sprint(x)?)
```
- `--phony` renamed to `--disabled` for consistency
- `--no-phony` is now `--enabled`
- Added `enable-search`, `disable-search`, and `toggle-search` actions
for `--bind`
- Added `--color` options: `query` and `disabled`
Close#2303
So you can override the colors and still have the text attributes
# Default colors and attributes
fzf
export FZF_DEFAULT_OPTS='--color hl👎underline,hl+👎underline:reverse'
# Default colors with underline+reverse attributes
fzf
# Different colors with underline+reverse attributes
fzf --color hl:176,hl+:177
Related: https://github.com/junegunn/fzf.vim/issues/1197#issuecomment-739804363
Some programs use it to set the background color for the whole line.
fzf --preview "printf 'normal \x1b[42mgreen\x1b[0K \x1b[43myellow\x1b[m\nnormal again'"
fzf --preview 'delta <(echo foo) <(echo bar) < /dev/tty'
Fix#2249
Fix#2254
- Properly handle extra chars in the buffer. Patch suggested by @mckelly2833.
- Support alt-arrow sequences in \e[1;3A format
- Support shift-alt-arrow sequences in \e[1;10A format
Fix#2212
# Will start rendering after 200ms, update every 100ms
fzf --preview 'for i in $(seq 100); do echo $i; sleep 0.01; done'
# Should print "Loading .." message after 500ms
fzf --preview 'sleep 1; for i in $(seq 100); do echo $i; sleep 0.01; done'
# The first line should appear after 200ms
fzf --preview 'date; sleep 2; date'
# Should not render before enough lines for the scroll offset are ready
rg --line-number --no-heading --color=always ^ |
fzf --delimiter : --ansi --preview-window '+{2}-/2' \
--preview 'sleep 1; bat --style=numbers --color=always --pager=never --highlight-line={2} {1}'
- Update to latest tcell which has 24 bit Windows support
- light renderer under Windows defaults to Dark256, if possible
- Respect TCELL_TRUECOLOR
- Remove tcell 1.3 references
Use 2-space horizontal padding so that the preview content is aligned
with the candidate list when the position of the preview window is `up`
or `down`.
Close#1057Close#2120
# Initial scroll offset is set to the line number of each line of
# git grep output *minus* 5 lines
git grep --line-number '' |
fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5
- Prefix matcher will trim leading whitespaces only when the pattern
doesn't start with a whitespace
- Suffix matcher will trim trailing whitespaces only when the pattern
doesn't end with a whitespace
- Equal matcher will trim leading whitespaces only when the pattern
doesn't start with a whitespace, and trim trailing whitespaces only
when the pattern doesn't end with a whitespace
Previously, only suffix matcher would trim whitespaces unconditionally.
Fix#1894
With --phony, fzf becomes a simply selector interface without its own
search functionality. The query string is only used for building the
command for preview or execute action.
Close#1723
* Remove 1 unused field and 3 unused functions
unused elements fount by running
golangci-lint run --disable-all --enable unused
src/result.go:19:2: field `index` is unused (unused)
index int32
^
src/tui/light.go:716:23: func `(*LightWindow).stderr` is unused (unused)
func (w *LightWindow) stderr(str string) {
^
src/terminal.go:1015:6: func `numLinesMax` is unused (unused)
func numLinesMax(str string, max int) int {
^
src/tui/tui.go:167:20: func `ColorPair.is24` is unused (unused)
func (p ColorPair) is24() bool {
^
* Address warnings from "gosimple" linter
src/options.go:389:83: S1003: should use strings.Contains(str, ",,,") instead (gosimple)
if str == "," || strings.HasPrefix(str, ",,") || strings.HasSuffix(str, ",,") || strings.Index(str, ",,,") >= 0 {
^
src/options.go:630:18: S1007: should use raw string (`...`) with regexp.MustCompile to avoid having to escape twice (gosimple)
executeRegexp = regexp.MustCompile(
^
src/terminal.go:29:16: S1007: should use raw string (`...`) with regexp.MustCompile to avoid having to escape twice (gosimple)
placeholder = regexp.MustCompile("\\\\?(?:{[+sf]*[0-9,-.]*}|{q}|{\\+?f?nf?})")
^
src/terminal_test.go:92:10: S1007: should use raw string (`...`) with regexp.MustCompile to avoid having to escape twice (gosimple)
regex = regexp.MustCompile("\\w+")
^
* Address warnings from "staticcheck" linter
src/algo/algo.go:374:2: SA4006: this value of `offset32` is never used (staticcheck)
offset32, T := alloc32(offset32, slab, N)
^
src/algo/algo.go:456:2: SA4006: this value of `offset16` is never used (staticcheck)
offset16, C := alloc16(offset16, slab, width*M)
^
src/tui/tui.go:119:2: SA9004: only the first constant in this group has an explicit type (staticcheck)
colUndefined Color = -2
^
- Replaced time.Now().Sub() with time.Since()
- Replaced unnecessary string/byte slice conversions
- Removed obsolete return and value assignment in range loop
- Update preview window even if there is no match for the query string
if any of the placeholder expressions evaluates to a non-empty string.
- Also, if the command template contains {q}, preview window will be
updated if the query string changes even though the focus remains on
the same item.
An example:
git log --oneline --color=always |
fzf --reverse --ansi --preview \
'[ -n {1} ] && git show --color=always {1} || git show --color=always {q}'
Close#1307
fzf used to print non-displayable characters (ascii code < 32) as '?',
but we will simply ignore those characters with this patch, just like
our terminals do.
\n and \r are exceptions. They will be printed as a space character.
TODO: \H should delete the preceding character, but this is not implemented.
Related: #1253
Add String() methods to types, so they can be printed with %s. Change
some %s format specifiers to %v, when the default string representation
is good enough. In Go 1.10, `go test` triggers a parallel `go vet`. So
this also makes fzf pass `go test`.
Close#1236Close#1219
'accept-non-empty' is similar to 'accept' (which is bound to 'enter' and
'double-click' by default) but it prevents fzf from exiting without any
selection.
Close#1162
replace-query action replaces the query string with the current
selection. If the selection is too long, it will be truncated.
If the line contains meta-characters of fzf search syntax, it is
possible that the line is no longer included in the updated result.
e.g.
echo '!hello' | fzf --bind ctrl-v:replace-query
Close#1137
In #1061 we changed the default command to retry with a simpler find
command with fewer arguments if the first find command failed. This was
to support stripped-down verions of find that do not support -fstype
argument.
However, this caused an unwanted side-effect of yielding duplicate
entries when the first command failed after producing some lines.
We revert the change in this commit, so the default command will not
work with find without -fstype support. But we now print better error
message in that case so that the user can set up a working
$FZF_DEFAULT_COMMAND.
Close#1120#1167
Close#1018
Run the command as is in cmd.exe with no parsing and escaping.
Explicity set cmd.SysProcAttr so execCommand does not escape the command.
Technically, the command should be escaped with ^ for special characters,
including ". This allows cmd.exe commands to be chained together.
See https://github.com/neovim/neovim/pull/7343#issuecomment-333350201
This commit also updates quoteEntry to use strings.Replace instead of
strconv.Quote which escapes more than \ and ".
Remove code that is no longer relevant after the removal of ncurses
renderer. This commit also fixes background color issue on tcell-based
FullscreenRenderer (Windows).
Similarly to --bind or --color.
--expect used to replace the previously specified keys, and
fzf#wrap({'options': '--expect=f1'}) wouldn't work as expected. It
forced us to come up with some ugly hacks like the following:
13b27c45c8/autoload/fzf/vim.vim (L1086)
Instead of notifying the event coordinator (EventBox) whenever a new
line is arrived, start a background goroutine that periodically does the
task. Atomic.StoreInt32 is much cheaper than mutex synchronization
that happens during EventBox update.
One can escape meta characters in extended-search mode with backslashes.
Prefixes:
\'
\!
\^
Suffix:
\$
Term separator:
\<SPACE>
To keep things simple, we are not going to support escaping of escaped
sequences (e.g. \\') for matching them literally.
Since this is a breaking change, we will bump the minor version.
Close#444
It is reported that it can have an unwanted side effect of clearing the
screen on terminal emulators that do not properly support it.
Patch suggested by @arya.
Close#1011
Manually inline function calls in a tight loop as Go compiler does not
inline non-leaf functions. It is observed that this unpleasant code
change resulted up to 10% performance improvement.
When --with-nth is used, fzf used to preprocess each line and store the
result as rune array, which was wasteful if the line only contains ascii
characters.
By not storing item index twice, we can cut down the size of Result
struct and now it makes more sense to store and pass Results by values.
Benchmarks show no degradation of performance by additional pointer
indirection for looking up index.
- Update install script to download Windows binary if $TERM == cygwin
- Unset TERM if $TERM == cygwin (#933)
- Always use cmd.exe instead of $SHELL when running commands
Make sure to consistently calculate tiebreak scores based on the
original line.
This change may not be preferable if you filter aligned tabular input on
a subset of columns using --nth. However, if we calculate length
tiebreak only on the matched components instead of the entire line, the
result can be very confusing when multiple --nth components are
specified, so let's keep it simple and consistent.
Close#926
Due to go std lib uses poller for os.File introducing in this commit:
c05b06a12d
There are two changes to watch out:
1. os.File.Fd will always return a blocking fd except on bsd.
2. os.File.Read won't return EAGAIN error for nonblocking fd.
So
For 1, we just get tty's fd in advance and then set its block mode.
For 2, we use read syscall directly to get what we wanted error(EAGAIN).
Fix issue #910.
Signed-off-by: Tw <tw19881113@gmail.com>
Do not automatically decide to use alternate screen when the value of
height exceeds the height of the terminal.
# Use alternate screen
fzf
fzf --height 100%
fzf --no-height
# Still use current screen
fzf --height 10000
Due to performance consideration, FuzzyMatchV2 does not return the exact
positions of the matching characters by default. However, the ommission
caused `--tiebreak=begin` to produce inaccurate result in some cases.
(echo baz foo bar; echo foo bar baz) | fzf --tiebreak=begin -fbar | head -1
# Expected: foo bar baz
# Actual: baz foo bar
This commit fixes the problem by using the end offset which is
guaranteed to be correct.
- Move cursor to the top-left corner when starting a command in
alternate screen
- Fix cursor position when returning to alternate screen when fzf is
running in full screen mode