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