From d19ce0ad8d68ed71fb24ae3287b847186d3a228e Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Wed, 8 Oct 2025 11:08:12 +0900 Subject: [PATCH] Add 'best' action --- CHANGELOG.md | 28 +++++++++++++++++++++++++++ src/actiontype_string.go | 41 ++++++++++++++++++++-------------------- src/options.go | 2 ++ src/terminal.go | 11 +++++++++-- test/test_raw.rb | 8 ++++++++ 5 files changed, 68 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e845abed..d203f62f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,23 @@ respectively, and also to `ALT-DOWN` and `ALT-UP`. > fzf --bind up:up-match,down:down-match > ``` +#### Customizing the behavior + +In raw mode, the input list is presented in its original order, unfiltered, and +your cursor will not move to the matching item automatically. Here are ways to +customize the behavior. + +```sh +# When the result list is updated, move the cursor to the item with the best score +# (assuming sorting is not disabled) +fzf --raw --bind result:best + +# Move to the first matching item in the original list +# - $FZF_RAW is set to 0 when raw mode is enabled and the current item is a non-match +# - $FZF_DIRECTION is set to either 'up' or 'down' depending on the layout direction +fzf --raw --bind 'result:first+transform:[[ $FZF_RAW = 0 ]] && echo $FZF_DIRECTION-match' +``` + #### Customizing the look ##### Gutter @@ -132,6 +149,17 @@ fzf --gutter ' ' --color gutter:reverse As noted above, the `--gutter-raw CHAR` option was also added for customizing the gutter column in raw mode. +### Added actions + +| Action | Description | +| --- | --- | +| `up-match` | Move up to the matching item; identical to `up` if raw mode is disabled | +| `down-match` | Move down to the matching item; identical to `down` if raw mode is disabled | +| `toggle-raw` | Toggle raw mode | +| `enable-raw` | Enable raw mode | +| `disable-raw` | Disable raw mode | +| `best` | Move to the first matching item with the best score; identical to `first` if raw mode is disabled | + ### Added environment variable `$FZF_DIRECTION` is now exported to child processes, indicating the list direction of the current layout. diff --git a/src/actiontype_string.go b/src/actiontype_string.go index dba74540..7ee45ed7 100644 --- a/src/actiontype_string.go +++ b/src/actiontype_string.go @@ -159,29 +159,30 @@ func _() { _ = x[actExecuteSilent-148] _ = x[actExecuteMulti-149] _ = x[actSigStop-150] - _ = x[actFirst-151] - _ = x[actLast-152] - _ = x[actReload-153] - _ = x[actReloadSync-154] - _ = x[actDisableSearch-155] - _ = x[actEnableSearch-156] - _ = x[actSelect-157] - _ = x[actDeselect-158] - _ = x[actUnbind-159] - _ = x[actRebind-160] - _ = x[actToggleBind-161] - _ = x[actBecome-162] - _ = x[actShowHeader-163] - _ = x[actHideHeader-164] - _ = x[actBell-165] - _ = x[actExclude-166] - _ = x[actExcludeMulti-167] - _ = x[actAsync-168] + _ = x[actBest-151] + _ = x[actFirst-152] + _ = x[actLast-153] + _ = x[actReload-154] + _ = x[actReloadSync-155] + _ = x[actDisableSearch-156] + _ = x[actEnableSearch-157] + _ = x[actSelect-158] + _ = x[actDeselect-159] + _ = x[actUnbind-160] + _ = x[actRebind-161] + _ = x[actToggleBind-162] + _ = x[actBecome-163] + _ = x[actShowHeader-164] + _ = x[actHideHeader-165] + _ = x[actBell-166] + _ = x[actExclude-167] + _ = x[actExcludeMulti-168] + _ = x[actAsync-169] } -const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactBackwardSubWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeFooteractChangeHeaderLabelactChangeFooterLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactForwardSubWordactKillLineactKillWordactKillSubWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactBackwardKillSubWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactToggleRawactEnableRawactDisableRawactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactDownMatchactUpactUpMatchactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformFooteractTransformHeaderLabelactTransformFooterLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactTriggeractBgTransformactBgTransformBorderLabelactBgTransformGhostactBgTransformHeaderactBgTransformFooteractBgTransformHeaderLabelactBgTransformFooterLabelactBgTransformInputLabelactBgTransformListLabelactBgTransformNthactBgTransformPointeractBgTransformPreviewLabelactBgTransformPromptactBgTransformQueryactBgTransformSearchactBgCancelactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMultiactAsync" +const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactBackwardSubWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeFooteractChangeHeaderLabelactChangeFooterLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactForwardSubWordactKillLineactKillWordactKillSubWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactBackwardKillSubWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactToggleRawactEnableRawactDisableRawactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactDownMatchactUpactUpMatchactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformFooteractTransformHeaderLabelactTransformFooterLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactTriggeractBgTransformactBgTransformBorderLabelactBgTransformGhostactBgTransformHeaderactBgTransformFooteractBgTransformHeaderLabelactBgTransformFooterLabelactBgTransformInputLabelactBgTransformListLabelactBgTransformNthactBgTransformPointeractBgTransformPreviewLabelactBgTransformPromptactBgTransformQueryactBgTransformSearchactBgCancelactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactBestactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMultiactAsync" -var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 57, 77, 84, 92, 110, 118, 127, 144, 165, 180, 201, 225, 240, 258, 267, 287, 301, 316, 331, 351, 371, 390, 408, 422, 434, 450, 466, 487, 509, 524, 538, 552, 565, 582, 590, 603, 619, 631, 639, 653, 667, 684, 695, 706, 720, 738, 755, 762, 781, 803, 815, 829, 838, 853, 865, 878, 889, 900, 912, 926, 947, 962, 975, 993, 1009, 1021, 1033, 1046, 1061, 1075, 1087, 1099, 1116, 1123, 1135, 1140, 1150, 1159, 1170, 1181, 1194, 1209, 1220, 1233, 1248, 1255, 1268, 1281, 1298, 1313, 1326, 1340, 1354, 1370, 1390, 1402, 1425, 1442, 1460, 1478, 1501, 1524, 1546, 1567, 1582, 1601, 1625, 1643, 1660, 1678, 1688, 1702, 1727, 1746, 1766, 1786, 1811, 1836, 1860, 1883, 1900, 1921, 1947, 1967, 1986, 2006, 2017, 2026, 2036, 2049, 2065, 2077, 2091, 2107, 2125, 2145, 2167, 2181, 2196, 2204, 2210, 2224, 2239, 2249, 2265, 2280, 2290, 2298, 2305, 2314, 2327, 2343, 2358, 2367, 2378, 2387, 2396, 2409, 2418, 2431, 2444, 2451, 2461, 2476, 2484} +var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 57, 77, 84, 92, 110, 118, 127, 144, 165, 180, 201, 225, 240, 258, 267, 287, 301, 316, 331, 351, 371, 390, 408, 422, 434, 450, 466, 487, 509, 524, 538, 552, 565, 582, 590, 603, 619, 631, 639, 653, 667, 684, 695, 706, 720, 738, 755, 762, 781, 803, 815, 829, 838, 853, 865, 878, 889, 900, 912, 926, 947, 962, 975, 993, 1009, 1021, 1033, 1046, 1061, 1075, 1087, 1099, 1116, 1123, 1135, 1140, 1150, 1159, 1170, 1181, 1194, 1209, 1220, 1233, 1248, 1255, 1268, 1281, 1298, 1313, 1326, 1340, 1354, 1370, 1390, 1402, 1425, 1442, 1460, 1478, 1501, 1524, 1546, 1567, 1582, 1601, 1625, 1643, 1660, 1678, 1688, 1702, 1727, 1746, 1766, 1786, 1811, 1836, 1860, 1883, 1900, 1921, 1947, 1967, 1986, 2006, 2017, 2026, 2036, 2049, 2065, 2077, 2091, 2107, 2125, 2145, 2167, 2181, 2196, 2204, 2210, 2224, 2239, 2249, 2265, 2280, 2290, 2297, 2305, 2312, 2321, 2334, 2350, 2365, 2374, 2385, 2394, 2403, 2416, 2425, 2438, 2451, 2458, 2468, 2483, 2491} func (i actionType) String() string { if i < 0 || i >= actionType(len(_actionType_index)-1) { diff --git a/src/options.go b/src/options.go index c2fc562d..a0b6f514 100644 --- a/src/options.go +++ b/src/options.go @@ -1792,6 +1792,8 @@ func parseActionList(masked string, original string, prevActions []*action, putA appendAction(actFirst) case "last": appendAction(actLast) + case "best": + appendAction(actBest) case "page-up": appendAction(actPageUp) case "page-down": diff --git a/src/terminal.go b/src/terminal.go index f9381aa5..7166c2e9 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -663,6 +663,7 @@ const ( actExecuteSilent actExecuteMulti // Deprecated actSigStop + actBest actFirst actLast actReload @@ -6203,8 +6204,14 @@ func (t *Terminal) Loop() error { t.version++ req(reqList, reqInfo) } - case actFirst: - t.vset(0) + case actFirst, actBest: + if t.raw && a.t == actBest { + if t.resultMerger.Length() > 0 { + t.vset(t.merger.FindIndex(t.resultMerger.Get(0).item.Index())) + } + } else { + t.vset(0) + } t.constrain() req(reqList) case actLast: diff --git a/test/test_raw.rb b/test/test_raw.rb index 63b62cc7..f063a90a 100644 --- a/test/test_raw.rb +++ b/test/test_raw.rb @@ -102,4 +102,12 @@ class TestRaw < TestInteractive assert_includes it, '▌ 25' end end + + def test_raw_best + tmux.send_keys %(seq 1000 | #{FZF} --raw --bind space:best), :Enter + tmux.send_keys 999 + tmux.until { assert_includes it, '> 1' } + tmux.send_keys :Space + tmux.until { assert_includes it, '> 999' } + end end