summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2025-03-28 23:35:20 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2025-03-28 23:35:20 +0900
commitba6d1b8772ce5e75ff999dcca21c0fadb689d7bf (patch)
tree5f03736a621f7ca1b13361606d544fb0db8dd67e
parent0dce561ec9894781bb356e12f4adef0686421bb7 (diff)
downloadfzf-ba6d1b8772ce5e75ff999dcca21c0fadb689d7bf.tar.gz
Add change-ghost and transform-ghost
-rw-r--r--CHANGELOG.md1
-rw-r--r--man/man1/fzf.12
-rw-r--r--src/actiontype_string.go240
-rw-r--r--src/options.go6
-rw-r--r--src/terminal.go27
-rw-r--r--test/test_core.rb6
6 files changed, 153 insertions, 129 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 06dc3e77..0011c134 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ CHANGELOG
# Display "Type to search" when the input is empty
fzf --ghost "Type to search"
```
+- Added `change-ghost` and `transform-ghost` actions for dynamically changing the ghost text
- Added `change-pointer` and `transform-pointer` actions for dynamically changing the pointer sign
- Bug fixes and improvements
diff --git a/man/man1/fzf.1 b/man/man1/fzf.1
index 33ea2609..4b2c5896 100644
--- a/man/man1/fzf.1
+++ b/man/man1/fzf.1
@@ -1609,6 +1609,7 @@ A key or an event can be bound to one or more of the following actions.
\fBbell\fR (ring the terminal bell)
\fBcancel\fR (clear query string if not empty, abort fzf otherwise)
\fBchange\-border\-label(...)\fR (change \fB\-\-border\-label\fR to the given string)
+ \fBchange\-ghost(...)\fR (change ghost text to the given string)
\fBchange\-header(...)\fR (change header to the given string; doesn't affect \fB\-\-header\-lines\fR)
\fBchange\-header\-label(...)\fR (change \fB\-\-header\-label\fR to the given string)
\fBchange\-input\-label(...)\fR (change \fB\-\-input\-label\fR to the given string)
@@ -1705,6 +1706,7 @@ A key or an event can be bound to one or more of the following actions.
\fBtrack\-current\fR (track the current item; automatically disabled if focus changes)
\fBtransform(...)\fR (transform states using the output of an external command)
\fBtransform\-border\-label(...)\fR (transform border label using an external command)
+ \fBtransform\-ghost(...)\fR (transform ghost text using an external command)
\fBtransform\-header(...)\fR (transform header using an external command)
\fBtransform\-header\-label(...)\fR (transform header label using an external command)
\fBtransform\-input\-label(...)\fR (transform input label using an external command)
diff --git a/src/actiontype_string.go b/src/actiontype_string.go
index 19b5ea72..8b78008f 100644
--- a/src/actiontype_string.go
+++ b/src/actiontype_string.go
@@ -27,128 +27,130 @@ func _() {
_ = x[actBackwardWord-16]
_ = x[actCancel-17]
_ = x[actChangeBorderLabel-18]
- _ = x[actChangeListLabel-19]
- _ = x[actChangeInputLabel-20]
- _ = x[actChangeHeader-21]
- _ = x[actChangeHeaderLabel-22]
- _ = x[actChangeMulti-23]
- _ = x[actChangePreviewLabel-24]
- _ = x[actChangePrompt-25]
- _ = x[actChangeQuery-26]
- _ = x[actChangeNth-27]
- _ = x[actClearScreen-28]
- _ = x[actClearQuery-29]
- _ = x[actClearSelection-30]
- _ = x[actClose-31]
- _ = x[actDeleteChar-32]
- _ = x[actDeleteCharEof-33]
- _ = x[actEndOfLine-34]
- _ = x[actFatal-35]
- _ = x[actForwardChar-36]
- _ = x[actForwardWord-37]
- _ = x[actKillLine-38]
- _ = x[actKillWord-39]
- _ = x[actUnixLineDiscard-40]
- _ = x[actUnixWordRubout-41]
- _ = x[actYank-42]
- _ = x[actBackwardKillWord-43]
- _ = x[actSelectAll-44]
- _ = x[actDeselectAll-45]
- _ = x[actToggle-46]
- _ = x[actToggleSearch-47]
- _ = x[actToggleAll-48]
- _ = x[actToggleDown-49]
- _ = x[actToggleUp-50]
- _ = x[actToggleIn-51]
- _ = x[actToggleOut-52]
- _ = x[actToggleTrack-53]
- _ = x[actToggleTrackCurrent-54]
- _ = x[actToggleHeader-55]
- _ = x[actToggleWrap-56]
- _ = x[actToggleMultiLine-57]
- _ = x[actToggleHscroll-58]
- _ = x[actTrackCurrent-59]
- _ = x[actToggleInput-60]
- _ = x[actHideInput-61]
- _ = x[actShowInput-62]
- _ = x[actUntrackCurrent-63]
- _ = x[actDown-64]
- _ = x[actUp-65]
- _ = x[actPageUp-66]
- _ = x[actPageDown-67]
- _ = x[actPosition-68]
- _ = x[actHalfPageUp-69]
- _ = x[actHalfPageDown-70]
- _ = x[actOffsetUp-71]
- _ = x[actOffsetDown-72]
- _ = x[actOffsetMiddle-73]
- _ = x[actJump-74]
- _ = x[actJumpAccept-75]
- _ = x[actPrintQuery-76]
- _ = x[actRefreshPreview-77]
- _ = x[actReplaceQuery-78]
- _ = x[actToggleSort-79]
- _ = x[actShowPreview-80]
- _ = x[actHidePreview-81]
- _ = x[actTogglePreview-82]
- _ = x[actTogglePreviewWrap-83]
- _ = x[actTransform-84]
- _ = x[actTransformBorderLabel-85]
- _ = x[actTransformListLabel-86]
- _ = x[actTransformInputLabel-87]
- _ = x[actTransformHeader-88]
- _ = x[actTransformHeaderLabel-89]
- _ = x[actTransformNth-90]
- _ = x[actTransformPointer-91]
- _ = x[actTransformPreviewLabel-92]
- _ = x[actTransformPrompt-93]
- _ = x[actTransformQuery-94]
- _ = x[actTransformSearch-95]
- _ = x[actSearch-96]
- _ = x[actPreview-97]
- _ = x[actChangePointer-98]
- _ = x[actChangePreview-99]
- _ = x[actChangePreviewWindow-100]
- _ = x[actPreviewTop-101]
- _ = x[actPreviewBottom-102]
- _ = x[actPreviewUp-103]
- _ = x[actPreviewDown-104]
- _ = x[actPreviewPageUp-105]
- _ = x[actPreviewPageDown-106]
- _ = x[actPreviewHalfPageUp-107]
- _ = x[actPreviewHalfPageDown-108]
- _ = x[actPrevHistory-109]
- _ = x[actPrevSelected-110]
- _ = x[actPrint-111]
- _ = x[actPut-112]
- _ = x[actNextHistory-113]
- _ = x[actNextSelected-114]
- _ = x[actExecute-115]
- _ = x[actExecuteSilent-116]
- _ = x[actExecuteMulti-117]
- _ = x[actSigStop-118]
- _ = x[actFirst-119]
- _ = x[actLast-120]
- _ = x[actReload-121]
- _ = x[actReloadSync-122]
- _ = x[actDisableSearch-123]
- _ = x[actEnableSearch-124]
- _ = x[actSelect-125]
- _ = x[actDeselect-126]
- _ = x[actUnbind-127]
- _ = x[actRebind-128]
- _ = x[actToggleBind-129]
- _ = x[actBecome-130]
- _ = x[actShowHeader-131]
- _ = x[actHideHeader-132]
- _ = x[actBell-133]
- _ = x[actExclude-134]
- _ = x[actExcludeMulti-135]
+ _ = x[actChangeGhost-19]
+ _ = x[actChangeHeader-20]
+ _ = x[actChangeHeaderLabel-21]
+ _ = x[actChangeInputLabel-22]
+ _ = x[actChangeListLabel-23]
+ _ = x[actChangeMulti-24]
+ _ = x[actChangeNth-25]
+ _ = x[actChangePointer-26]
+ _ = x[actChangePreview-27]
+ _ = x[actChangePreviewLabel-28]
+ _ = x[actChangePreviewWindow-29]
+ _ = x[actChangePrompt-30]
+ _ = x[actChangeQuery-31]
+ _ = x[actClearScreen-32]
+ _ = x[actClearQuery-33]
+ _ = x[actClearSelection-34]
+ _ = x[actClose-35]
+ _ = x[actDeleteChar-36]
+ _ = x[actDeleteCharEof-37]
+ _ = x[actEndOfLine-38]
+ _ = x[actFatal-39]
+ _ = x[actForwardChar-40]
+ _ = x[actForwardWord-41]
+ _ = x[actKillLine-42]
+ _ = x[actKillWord-43]
+ _ = x[actUnixLineDiscard-44]
+ _ = x[actUnixWordRubout-45]
+ _ = x[actYank-46]
+ _ = x[actBackwardKillWord-47]
+ _ = x[actSelectAll-48]
+ _ = x[actDeselectAll-49]
+ _ = x[actToggle-50]
+ _ = x[actToggleSearch-51]
+ _ = x[actToggleAll-52]
+ _ = x[actToggleDown-53]
+ _ = x[actToggleUp-54]
+ _ = x[actToggleIn-55]
+ _ = x[actToggleOut-56]
+ _ = x[actToggleTrack-57]
+ _ = x[actToggleTrackCurrent-58]
+ _ = x[actToggleHeader-59]
+ _ = x[actToggleWrap-60]
+ _ = x[actToggleMultiLine-61]
+ _ = x[actToggleHscroll-62]
+ _ = x[actTrackCurrent-63]
+ _ = x[actToggleInput-64]
+ _ = x[actHideInput-65]
+ _ = x[actShowInput-66]
+ _ = x[actUntrackCurrent-67]
+ _ = x[actDown-68]
+ _ = x[actUp-69]
+ _ = x[actPageUp-70]
+ _ = x[actPageDown-71]
+ _ = x[actPosition-72]
+ _ = x[actHalfPageUp-73]
+ _ = x[actHalfPageDown-74]
+ _ = x[actOffsetUp-75]
+ _ = x[actOffsetDown-76]
+ _ = x[actOffsetMiddle-77]
+ _ = x[actJump-78]
+ _ = x[actJumpAccept-79]
+ _ = x[actPrintQuery-80]
+ _ = x[actRefreshPreview-81]
+ _ = x[actReplaceQuery-82]
+ _ = x[actToggleSort-83]
+ _ = x[actShowPreview-84]
+ _ = x[actHidePreview-85]
+ _ = x[actTogglePreview-86]
+ _ = x[actTogglePreviewWrap-87]
+ _ = x[actTransform-88]
+ _ = x[actTransformBorderLabel-89]
+ _ = x[actTransformGhost-90]
+ _ = x[actTransformHeader-91]
+ _ = x[actTransformHeaderLabel-92]
+ _ = x[actTransformInputLabel-93]
+ _ = x[actTransformListLabel-94]
+ _ = x[actTransformNth-95]
+ _ = x[actTransformPointer-96]
+ _ = x[actTransformPreviewLabel-97]
+ _ = x[actTransformPrompt-98]
+ _ = x[actTransformQuery-99]
+ _ = x[actTransformSearch-100]
+ _ = x[actSearch-101]
+ _ = x[actPreview-102]
+ _ = x[actPreviewTop-103]
+ _ = x[actPreviewBottom-104]
+ _ = x[actPreviewUp-105]
+ _ = x[actPreviewDown-106]
+ _ = x[actPreviewPageUp-107]
+ _ = x[actPreviewPageDown-108]
+ _ = x[actPreviewHalfPageUp-109]
+ _ = x[actPreviewHalfPageDown-110]
+ _ = x[actPrevHistory-111]
+ _ = x[actPrevSelected-112]
+ _ = x[actPrint-113]
+ _ = x[actPut-114]
+ _ = x[actNextHistory-115]
+ _ = x[actNextSelected-116]
+ _ = x[actExecute-117]
+ _ = x[actExecuteSilent-118]
+ _ = x[actExecuteMulti-119]
+ _ = x[actSigStop-120]
+ _ = x[actFirst-121]
+ _ = x[actLast-122]
+ _ = x[actReload-123]
+ _ = x[actReloadSync-124]
+ _ = x[actDisableSearch-125]
+ _ = x[actEnableSearch-126]
+ _ = x[actSelect-127]
+ _ = x[actDeselect-128]
+ _ = x[actUnbind-129]
+ _ = x[actRebind-130]
+ _ = x[actToggleBind-131]
+ _ = x[actBecome-132]
+ _ = x[actShowHeader-133]
+ _ = x[actHideHeader-134]
+ _ = x[actBell-135]
+ _ = x[actExclude-136]
+ _ = x[actExcludeMulti-137]
}
-const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeListLabelactChangeInputLabelactChangeHeaderactChangeHeaderLabelactChangeMultiactChangePreviewLabelactChangePromptactChangeQueryactChangeNthactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformListLabelactTransformInputLabelactTransformHeaderactTransformHeaderLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactSearchactPreviewactChangePointeractChangePreviewactChangePreviewWindowactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMulti"
+const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeHeaderLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformHeaderLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMulti"
-var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 57, 77, 84, 92, 110, 118, 127, 144, 165, 180, 201, 225, 240, 249, 269, 287, 306, 321, 341, 355, 376, 391, 405, 417, 431, 444, 461, 469, 482, 498, 510, 518, 532, 546, 557, 568, 586, 603, 610, 629, 641, 655, 664, 679, 691, 704, 715, 726, 738, 752, 773, 788, 801, 819, 835, 850, 864, 876, 888, 905, 912, 917, 926, 937, 948, 961, 976, 987, 1000, 1015, 1022, 1035, 1048, 1065, 1080, 1093, 1107, 1121, 1137, 1157, 1169, 1192, 1213, 1235, 1253, 1276, 1291, 1310, 1334, 1352, 1369, 1387, 1396, 1406, 1422, 1438, 1460, 1473, 1489, 1501, 1515, 1531, 1549, 1569, 1591, 1605, 1620, 1628, 1634, 1648, 1663, 1673, 1689, 1704, 1714, 1722, 1729, 1738, 1751, 1767, 1782, 1791, 1802, 1811, 1820, 1833, 1842, 1855, 1868, 1875, 1885, 1900}
+var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 57, 77, 84, 92, 110, 118, 127, 144, 165, 180, 201, 225, 240, 249, 269, 283, 298, 318, 337, 355, 369, 381, 397, 413, 434, 456, 471, 485, 499, 512, 529, 537, 550, 566, 578, 586, 600, 614, 625, 636, 654, 671, 678, 697, 709, 723, 732, 747, 759, 772, 783, 794, 806, 820, 841, 856, 869, 887, 903, 918, 932, 944, 956, 973, 980, 985, 994, 1005, 1016, 1029, 1044, 1055, 1068, 1083, 1090, 1103, 1116, 1133, 1148, 1161, 1175, 1189, 1205, 1225, 1237, 1260, 1277, 1295, 1318, 1340, 1361, 1376, 1395, 1419, 1437, 1454, 1472, 1481, 1491, 1504, 1520, 1532, 1546, 1562, 1580, 1600, 1622, 1636, 1651, 1659, 1665, 1679, 1694, 1704, 1720, 1735, 1745, 1753, 1760, 1769, 1782, 1798, 1813, 1822, 1833, 1842, 1851, 1864, 1873, 1886, 1899, 1906, 1916, 1931}
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 80e428e3..c250fb59 100644
--- a/src/options.go
+++ b/src/options.go
@@ -1404,7 +1404,7 @@ const (
func init() {
executeRegexp = regexp.MustCompile(
- `(?si)[:+](become|execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:query|prompt|(?:border|list|preview|input|header)-label|header|search|nth|pointer)|transform|change-(?:preview-window|preview|multi)|(?:re|un|toggle-)bind|pos|put|print|search)`)
+ `(?si)[:+](become|execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:query|prompt|(?:border|list|preview|input|header)-label|header|search|nth|pointer|ghost)|transform|change-(?:preview-window|preview|multi)|(?:re|un|toggle-)bind|pos|put|print|search)`)
splitRegexp = regexp.MustCompile("[,:]+")
actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+")
}
@@ -1799,6 +1799,8 @@ func isExecuteAction(str string) actionType {
return actChangeInputLabel
case "change-header-label":
return actChangeHeaderLabel
+ case "change-ghost":
+ return actChangeGhost
case "change-pointer":
return actChangePointer
case "change-preview-window":
@@ -1839,6 +1841,8 @@ func isExecuteAction(str string) actionType {
return actTransformHeaderLabel
case "transform-header":
return actTransformHeader
+ case "transform-ghost":
+ return actTransformGhost
case "transform-nth":
return actTransformNth
case "transform-pointer":
diff --git a/src/terminal.go b/src/terminal.go
index ad5ad628..8b4651c1 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -475,15 +475,19 @@ const (
actBackwardWord
actCancel
actChangeBorderLabel
- actChangeListLabel
- actChangeInputLabel
+ actChangeGhost
actChangeHeader
actChangeHeaderLabel
+ actChangeInputLabel
+ actChangeListLabel
actChangeMulti
+ actChangeNth
+ actChangePointer
+ actChangePreview
actChangePreviewLabel
+ actChangePreviewWindow
actChangePrompt
actChangeQuery
- actChangeNth
actClearScreen
actClearQuery
actClearSelection
@@ -542,10 +546,11 @@ const (
actTogglePreviewWrap
actTransform
actTransformBorderLabel
- actTransformListLabel
- actTransformInputLabel
+ actTransformGhost
actTransformHeader
actTransformHeaderLabel
+ actTransformInputLabel
+ actTransformListLabel
actTransformNth
actTransformPointer
actTransformPreviewLabel
@@ -554,9 +559,6 @@ const (
actTransformSearch
actSearch
actPreview
- actChangePointer
- actChangePreview
- actChangePreviewWindow
actPreviewTop
actPreviewBottom
actPreviewUp
@@ -5958,6 +5960,15 @@ func (t *Terminal) Loop() error {
}
}
}
+ case actChangeGhost, actTransformGhost:
+ ghost := a.a
+ if a.t == actTransformGhost {
+ ghost = t.captureLine(a.a)
+ }
+ t.ghost = ghost
+ if len(t.input) == 0 {
+ req(reqPrompt)
+ }
case actChangePointer, actTransformPointer:
pointer := a.a
if a.t == actTransformPointer {
diff --git a/test/test_core.rb b/test/test_core.rb
index c8b73f23..f8a182f8 100644
--- a/test/test_core.rb
+++ b/test/test_core.rb
@@ -1815,7 +1815,7 @@ class TestCore < TestInteractive
end
def test_ghost
- tmux.send_keys %(seq 100 | #{FZF} --prompt 'X ' --ghost 'Type in query ...'), :Enter
+ tmux.send_keys %(seq 100 | #{FZF} --prompt 'X ' --ghost 'Type in query ...' --bind 'space:change-ghost:Y Z' --bind 'enter:transform-ghost:echo Z Y'), :Enter
tmux.until do |lines|
assert_equal 100, lines.match_count
assert_includes lines, 'X Type in query ...'
@@ -1830,6 +1830,10 @@ class TestCore < TestInteractive
assert_equal 100, lines.match_count
assert_includes lines, 'X Type in query ...'
end
+ tmux.send_keys :Space
+ tmux.until { |lines| assert_includes lines, 'X Y Z' }
+ tmux.send_keys :Enter
+ tmux.until { |lines| assert_includes lines, 'X Z Y' }
end
def test_ghost_inline