Commit Graph
35 Commits
Author SHA1 Message Date
Junegunn Choi 2885df8395 Clean up comments and tests 2026-08-10 22:36:25 +09:00
Junegunn Choi 7b16e44f53 Copy the item text in replace-query
ToRunes aliases the rune array, and the editing actions append into
t.input in place when the cursor is not at the end, so the keystrokes
edit the item. Non-ASCII items only, ASCII gets a fresh slice.

    printf '한글abcde\n' | fzf --bind 'ctrl-y:replace-query'
    ctrl-y, Left, BSpace, ctrl-u  ->  한글abcee

Runes and ToRunes are now documented read-only. A stale fold bit was the
other symptom, letting the prefilter reject an item the general path
matches.
2026-08-08 19:48:04 +09:00
Junegunn Choi a650900eda Prefilter rune-mode input
asciiFuzzyIndex gave up on non-ASCII lines, so every item ran the full
score matrix. A []rune is a fixed 4-byte stride, so the SIMD byte
scanners can run over it directly: find the low byte, then confirm
4-byte alignment and three zero bytes.

Case folding and normalization can turn a non-ASCII rune into the ASCII
char being searched, which the scan cannot see. ToChars now flags lines
holding such a rune and those keep the old path. Normalization is
Latin-only, so Hangul, CJK, Cyrillic, Greek, Hebrew, Arabic, Thai, kana
and emoji never set the flag.

Chars had no spare padding, so inBytes moves into a flags byte.

Measured on 1.4M-line corpora:

- Mostly-ASCII paths behind a Hangul prefix: 'conf' 1.8x, 'binutils'
  2.9x, 'ltversion' 4.0x, no-match 8.4x
- Every line CJK: 17x on both matching and non-matching queries
- ASCII input unchanged, non-ASCII patterns not covered yet
2026-08-08 19:48:04 +09:00
Junegunn Choi 793e58b558 Skip rune decoding for ASCII bytes in ToChars
utf8.DecodeRune already fast-paths ASCII, but it is too complex to inline
(cost 201 against a budget of 80), so a mostly-ASCII line pays one call
per byte just to be told the byte is ASCII.

Only the run after the first non-ASCII byte reaches the decode loop, so
the gain depends on where that byte falls.

- 70-rune ASCII line: 145ns -> 42ns in the decode loop
- Ingestion of 1.4M mostly-ASCII paths behind a Hangul prefix, where the
  loop covers the whole line: 377ms -> 233ms
- The same paths with the Hangul at the end, where it covers six bytes:
  207ms -> 196ms
- Break-even sits at ~100% non-ASCII runes: still 1.01x at 95%. Only a
  line holding no ASCII byte at all loses, by ~0.14ns per rune, ~5% of
  the loop
2026-08-08 19:48:04 +09:00
Junegunn Choi 759b7c3283 Avoid over-allocation in ToChars
- Capacity was byte length, over-allocating by bytes-per-rune (2-4x)
- Count non-continuation bytes with SWAR before allocating
- Invalid bytes undercount, never overcount, so append covers the gap
- Query performance unchanged, this is a memory fix
- The gain tracks bytes-per-rune, the cost tracks how much of the line
  follows the first non-ASCII byte, so the two move independently

Measured on 1.4M-line corpora:

- Every line CJK: RSS 362MB -> 255MB, ingestion -5%
- Mostly-ASCII paths behind a Hangul prefix: RSS 556MB -> 533MB,
  ingestion +3.5%, the counting pass covering the whole line
- The same paths with the Hangul at the end: RSS 563MB -> 535MB,
  ingestion +0.9%, the counting pass covering six bytes
2026-08-08 19:48:04 +09:00
Junegunn Choi 69e9abdab4 Implement word wrapping in the list section
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-02-18 15:20:56 +09:00
Marcel Meyer 14b5e1d88c Replace utils Min, Max with builtin min, max 2025-12-23 09:14:33 +09:00
phanium 91fab3b3c2 Fix lint warnings (#4586)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...
2025-11-12 22:05:17 +09:00
Junegunn Choi 8d81730ec2 with-nth: Do not trim trailing whitespaces with background colors
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Example:
  echo -en '  \e[48;5;232mhello\e[48;5;147m  ' | fzf --ansi --with-nth 1
2025-06-24 20:27:24 +09:00
Junegunn Choi f92f9f137a Fix wrapping of the list section
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
Generate Sponsors README / deploy (push) Has been cancelled
# The first line of the second chunk would prematurely wrap
  printf '%0500s\n\n%0500s' 0 0 | fzf --wrap --read0
2025-03-16 01:57:20 +09:00
Junegunn Choi 639253840f Trim trailing whitespaces after processing ANSI sequences
Close #4282
2025-02-26 16:17:12 +09:00
Junegunn Choi 84e2262ad6 Make --accept-nth and --with-nth support templates 2025-02-12 20:15:04 +09:00
Junegunn Choi 2b584586ed Add --accept-nth option to transform the output
This option can be used to replace a sed or awk in the post-processing step.

  ps -ef | fzf --multi --header-lines 1 | awk '{print $2}'
  ps -ef | fzf --multi --header-lines 1 --accept-nth 2

This may not be a very "Unix-y" thing to do, so I've always felt that fzf
shouldn't have such an option, but I've finally changed my mind because:

* fzf can be configured with a custom delimiter that is a fixed string
  or a regular expression.
* In such cases, you'd need to repeat the delimiter again in the
  post-processing step.
* Also, tools like awk or sed may interpret a regular expression
  differently, causing mismatches.

You can still use sed, cut, or awk if you prefer.

Close #3987
Close #1323
2025-02-09 11:53:35 +09:00
Junegunn Choi 3ec035c68b Fix incorrect overflow detection when --wrap is set
Fix #4083
2024-11-12 00:33:07 +09:00
Junegunn Choi 70bf8bc35d Add --wrap option and 'toggle-wrap' action (#3887)
* `--wrap`
* `--wrap-sign`
* `toggle-wrap`

Close #3619
Close #2236
Close #577
Close #461
2024-06-25 17:08:47 +09:00
Junegunn Choi 2f51eb2b41 Different marker for the first and last line of multi-line entries
Can be configured via `--marker-multi-line`
2024-05-27 01:35:05 +09:00
Junegunn Choi 04db44067d Implement multi-line display of multi-line items 2024-05-20 09:25:30 +09:00
Junegunn Choi e86b81bbf5 Improve search performance by limiting the search scope
Find the last occurrence of the last character in the pattern and
perform the search algorithm only up to that point.

The effectiveness of this mechanism depends a lot on the shape of the
input and the pattern.
2024-04-14 11:48:44 +09:00
Junegunn Choi c30e486b64 Further performance improvements by removing unnecessary copies 2024-04-02 08:43:08 +09:00
Junegunn Choi 4c9cab3f8a Fix prefix/suffix/equal matcher to trim whitespaces
- 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
2020-03-01 12:36:02 +09:00
Junegunn Choi 751aa1944a Remove trailing whitespaces when using --with-nth 2019-11-12 23:20:09 +09:00
Christian Muehlhaeuser a1260feeed Code cleanup (#1640)
- Replaced time.Now().Sub() with time.Since()
- Replaced unnecessary string/byte slice conversions
- Removed obsolete return and value assignment in range loop
2019-07-19 13:22:35 +09:00
Junegunn Choi 85c1f8a9e0 Always prepend ANSI reset code before re-assembling tokens 2019-03-07 15:29:57 +09:00
Junegunn Choi ef577a6509 Preserve the original color of each token when using --with-nth with --ansi
Close #1500
2019-03-06 19:05:05 +09:00
Ryan Boehning 21b94d2de5 Make fzf pass go vet
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 #1236
Close #1219
2018-03-13 14:56:55 +09:00
Junegunn Choi af809c9661 Minor refactorings 2017-08-26 03:24:42 +09:00
Junegunn Choi 99927c7071 Modify loop conditions in checkAscii function 2017-08-01 22:04:42 +09:00
Junegunn Choi 69aa2fea68 Optimize fuzzy search performance for ASCII strings 2017-07-30 17:31:50 +09:00
Junegunn Choi c9f16b6430 Avoid unconditionally storsing input as runes
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.
2017-07-20 02:44:30 +09:00
Junegunn Choi 5e72709613 Speed up initial scanning with bitwise AND operation 2017-07-18 02:17:05 +09:00
Junegunn Choi 9e85cba0d0 Reduce memory footprint of Item struct 2017-07-16 23:34:32 +09:00
Junegunn Choi 04492bab10 Use unicode.IsSpace to cover more whitespace characters 2016-09-29 22:40:22 +09:00
Junegunn Choi d9c8a9a880 [perf] Remove memory copy when using string delimiter 2016-08-14 04:30:55 +09:00
Junegunn Choi ddc7bb9064 [perf] Optimize AWK-style tokenizer for --nth
Approx. 50% less memory footprint and 40% improvement in query time
2016-08-14 02:19:29 +09:00
Junegunn Choi 1d4057c209 [perf] Avoid allocating rune array for ascii string
In the best case (all ascii), this reduces the memory footprint by 60%
and the response time by 15% to 20%. In the worst case (every line has
non-ascii characters), 3 to 4% overhead is observed.
2016-08-14 00:41:30 +09:00