Add sub-word actions (#3997)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled

Add `backward-subword`, `forward-subword`, `kill-subword`, `backward-kill-subword` actions.
This commit is contained in:
Massimo Mund
2025-09-05 12:38:22 +02:00
committed by GitHub
parent 9ed971cc90
commit ae12e94b1f
5 changed files with 221 additions and 145 deletions

View File

@@ -1807,7 +1807,9 @@ A key or an event can be bound to one or more of the following actions.
\fBbackward\-char\fR \fIctrl\-b left\fR \fBbackward\-char\fR \fIctrl\-b left\fR
\fBbackward\-delete\-char\fR \fIctrl\-h ctrl\-bspace bspace\fR \fBbackward\-delete\-char\fR \fIctrl\-h ctrl\-bspace bspace\fR
\fBbackward\-delete\-char/eof\fR (same as \fBbackward\-delete\-char\fR except aborts fzf if query is empty) \fBbackward\-delete\-char/eof\fR (same as \fBbackward\-delete\-char\fR except aborts fzf if query is empty)
\fBbackward\-kill\-subword\fR
\fBbackward\-kill\-word\fR \fIalt\-bs\fR \fBbackward\-kill\-word\fR \fIalt\-bs\fR
\fBbackward\-subword\fR
\fBbackward\-word\fR \fIalt\-b shift\-left\fR \fBbackward\-word\fR \fIalt\-b shift\-left\fR
\fBbecome(...)\fR (replace fzf process with the specified command; see below for the details) \fBbecome(...)\fR (replace fzf process with the specified command; see below for the details)
\fBbeginning\-of\-line\fR \fIctrl\-a home\fR \fBbeginning\-of\-line\fR \fIctrl\-a home\fR
@@ -1847,10 +1849,12 @@ A key or an event can be bound to one or more of the following actions.
\fBexecute\-silent(...)\fR (see below for the details) \fBexecute\-silent(...)\fR (see below for the details)
\fBfirst\fR (move to the first match; same as \fBpos(1)\fR) \fBfirst\fR (move to the first match; same as \fBpos(1)\fR)
\fBforward\-char\fR \fIctrl\-f right\fR \fBforward\-char\fR \fIctrl\-f right\fR
\fBforward\-subword\fR
\fBforward\-word\fR \fIalt\-f shift\-right\fR \fBforward\-word\fR \fIalt\-f shift\-right\fR
\fBignore\fR \fBignore\fR
\fBjump\fR (EasyMotion-like 2-keystroke movement) \fBjump\fR (EasyMotion-like 2-keystroke movement)
\fBkill\-line\fR \fBkill\-line\fR
\fBkill\-subword\fR
\fBkill\-word\fR \fIalt\-d\fR \fBkill\-word\fR \fIalt\-d\fR
\fBlast\fR (move to the last match; same as \fBpos(\-1)\fR) \fBlast\fR (move to the last match; same as \fBpos(\-1)\fR)
\fBnext\-history\fR (\fIctrl\-n\fR on \fB\-\-history\fR) \fBnext\-history\fR (\fIctrl\-n\fR on \fB\-\-history\fR)

View File

@@ -25,154 +25,158 @@ func _() {
_ = x[actBackwardDeleteChar-14] _ = x[actBackwardDeleteChar-14]
_ = x[actBackwardDeleteCharEof-15] _ = x[actBackwardDeleteCharEof-15]
_ = x[actBackwardWord-16] _ = x[actBackwardWord-16]
_ = x[actCancel-17] _ = x[actBackwardSubWord-17]
_ = x[actChangeBorderLabel-18] _ = x[actCancel-18]
_ = x[actChangeGhost-19] _ = x[actChangeBorderLabel-19]
_ = x[actChangeHeader-20] _ = x[actChangeGhost-20]
_ = x[actChangeFooter-21] _ = x[actChangeHeader-21]
_ = x[actChangeHeaderLabel-22] _ = x[actChangeFooter-22]
_ = x[actChangeFooterLabel-23] _ = x[actChangeHeaderLabel-23]
_ = x[actChangeInputLabel-24] _ = x[actChangeFooterLabel-24]
_ = x[actChangeListLabel-25] _ = x[actChangeInputLabel-25]
_ = x[actChangeMulti-26] _ = x[actChangeListLabel-26]
_ = x[actChangeNth-27] _ = x[actChangeMulti-27]
_ = x[actChangePointer-28] _ = x[actChangeNth-28]
_ = x[actChangePreview-29] _ = x[actChangePointer-29]
_ = x[actChangePreviewLabel-30] _ = x[actChangePreview-30]
_ = x[actChangePreviewWindow-31] _ = x[actChangePreviewLabel-31]
_ = x[actChangePrompt-32] _ = x[actChangePreviewWindow-32]
_ = x[actChangeQuery-33] _ = x[actChangePrompt-33]
_ = x[actClearScreen-34] _ = x[actChangeQuery-34]
_ = x[actClearQuery-35] _ = x[actClearScreen-35]
_ = x[actClearSelection-36] _ = x[actClearQuery-36]
_ = x[actClose-37] _ = x[actClearSelection-37]
_ = x[actDeleteChar-38] _ = x[actClose-38]
_ = x[actDeleteCharEof-39] _ = x[actDeleteChar-39]
_ = x[actEndOfLine-40] _ = x[actDeleteCharEof-40]
_ = x[actFatal-41] _ = x[actEndOfLine-41]
_ = x[actForwardChar-42] _ = x[actFatal-42]
_ = x[actForwardWord-43] _ = x[actForwardChar-43]
_ = x[actKillLine-44] _ = x[actForwardWord-44]
_ = x[actKillWord-45] _ = x[actForwardSubWord-45]
_ = x[actUnixLineDiscard-46] _ = x[actKillLine-46]
_ = x[actUnixWordRubout-47] _ = x[actKillWord-47]
_ = x[actYank-48] _ = x[actKillSubWord-48]
_ = x[actBackwardKillWord-49] _ = x[actUnixLineDiscard-49]
_ = x[actSelectAll-50] _ = x[actUnixWordRubout-50]
_ = x[actDeselectAll-51] _ = x[actYank-51]
_ = x[actToggle-52] _ = x[actBackwardKillWord-52]
_ = x[actToggleSearch-53] _ = x[actBackwardKillSubWord-53]
_ = x[actToggleAll-54] _ = x[actSelectAll-54]
_ = x[actToggleDown-55] _ = x[actDeselectAll-55]
_ = x[actToggleUp-56] _ = x[actToggle-56]
_ = x[actToggleIn-57] _ = x[actToggleSearch-57]
_ = x[actToggleOut-58] _ = x[actToggleAll-58]
_ = x[actToggleTrack-59] _ = x[actToggleDown-59]
_ = x[actToggleTrackCurrent-60] _ = x[actToggleUp-60]
_ = x[actToggleHeader-61] _ = x[actToggleIn-61]
_ = x[actToggleWrap-62] _ = x[actToggleOut-62]
_ = x[actToggleMultiLine-63] _ = x[actToggleTrack-63]
_ = x[actToggleHscroll-64] _ = x[actToggleTrackCurrent-64]
_ = x[actTrackCurrent-65] _ = x[actToggleHeader-65]
_ = x[actToggleInput-66] _ = x[actToggleWrap-66]
_ = x[actHideInput-67] _ = x[actToggleMultiLine-67]
_ = x[actShowInput-68] _ = x[actToggleHscroll-68]
_ = x[actUntrackCurrent-69] _ = x[actTrackCurrent-69]
_ = x[actDown-70] _ = x[actToggleInput-70]
_ = x[actUp-71] _ = x[actHideInput-71]
_ = x[actPageUp-72] _ = x[actShowInput-72]
_ = x[actPageDown-73] _ = x[actUntrackCurrent-73]
_ = x[actPosition-74] _ = x[actDown-74]
_ = x[actHalfPageUp-75] _ = x[actUp-75]
_ = x[actHalfPageDown-76] _ = x[actPageUp-76]
_ = x[actOffsetUp-77] _ = x[actPageDown-77]
_ = x[actOffsetDown-78] _ = x[actPosition-78]
_ = x[actOffsetMiddle-79] _ = x[actHalfPageUp-79]
_ = x[actJump-80] _ = x[actHalfPageDown-80]
_ = x[actJumpAccept-81] _ = x[actOffsetUp-81]
_ = x[actPrintQuery-82] _ = x[actOffsetDown-82]
_ = x[actRefreshPreview-83] _ = x[actOffsetMiddle-83]
_ = x[actReplaceQuery-84] _ = x[actJump-84]
_ = x[actToggleSort-85] _ = x[actJumpAccept-85]
_ = x[actShowPreview-86] _ = x[actPrintQuery-86]
_ = x[actHidePreview-87] _ = x[actRefreshPreview-87]
_ = x[actTogglePreview-88] _ = x[actReplaceQuery-88]
_ = x[actTogglePreviewWrap-89] _ = x[actToggleSort-89]
_ = x[actTransform-90] _ = x[actShowPreview-90]
_ = x[actTransformBorderLabel-91] _ = x[actHidePreview-91]
_ = x[actTransformGhost-92] _ = x[actTogglePreview-92]
_ = x[actTransformHeader-93] _ = x[actTogglePreviewWrap-93]
_ = x[actTransformFooter-94] _ = x[actTransform-94]
_ = x[actTransformHeaderLabel-95] _ = x[actTransformBorderLabel-95]
_ = x[actTransformFooterLabel-96] _ = x[actTransformGhost-96]
_ = x[actTransformInputLabel-97] _ = x[actTransformHeader-97]
_ = x[actTransformListLabel-98] _ = x[actTransformFooter-98]
_ = x[actTransformNth-99] _ = x[actTransformHeaderLabel-99]
_ = x[actTransformPointer-100] _ = x[actTransformFooterLabel-100]
_ = x[actTransformPreviewLabel-101] _ = x[actTransformInputLabel-101]
_ = x[actTransformPrompt-102] _ = x[actTransformListLabel-102]
_ = x[actTransformQuery-103] _ = x[actTransformNth-103]
_ = x[actTransformSearch-104] _ = x[actTransformPointer-104]
_ = x[actTrigger-105] _ = x[actTransformPreviewLabel-105]
_ = x[actBgTransform-106] _ = x[actTransformPrompt-106]
_ = x[actBgTransformBorderLabel-107] _ = x[actTransformQuery-107]
_ = x[actBgTransformGhost-108] _ = x[actTransformSearch-108]
_ = x[actBgTransformHeader-109] _ = x[actTrigger-109]
_ = x[actBgTransformFooter-110] _ = x[actBgTransform-110]
_ = x[actBgTransformHeaderLabel-111] _ = x[actBgTransformBorderLabel-111]
_ = x[actBgTransformFooterLabel-112] _ = x[actBgTransformGhost-112]
_ = x[actBgTransformInputLabel-113] _ = x[actBgTransformHeader-113]
_ = x[actBgTransformListLabel-114] _ = x[actBgTransformFooter-114]
_ = x[actBgTransformNth-115] _ = x[actBgTransformHeaderLabel-115]
_ = x[actBgTransformPointer-116] _ = x[actBgTransformFooterLabel-116]
_ = x[actBgTransformPreviewLabel-117] _ = x[actBgTransformInputLabel-117]
_ = x[actBgTransformPrompt-118] _ = x[actBgTransformListLabel-118]
_ = x[actBgTransformQuery-119] _ = x[actBgTransformNth-119]
_ = x[actBgTransformSearch-120] _ = x[actBgTransformPointer-120]
_ = x[actBgCancel-121] _ = x[actBgTransformPreviewLabel-121]
_ = x[actSearch-122] _ = x[actBgTransformPrompt-122]
_ = x[actPreview-123] _ = x[actBgTransformQuery-123]
_ = x[actPreviewTop-124] _ = x[actBgTransformSearch-124]
_ = x[actPreviewBottom-125] _ = x[actBgCancel-125]
_ = x[actPreviewUp-126] _ = x[actSearch-126]
_ = x[actPreviewDown-127] _ = x[actPreview-127]
_ = x[actPreviewPageUp-128] _ = x[actPreviewTop-128]
_ = x[actPreviewPageDown-129] _ = x[actPreviewBottom-129]
_ = x[actPreviewHalfPageUp-130] _ = x[actPreviewUp-130]
_ = x[actPreviewHalfPageDown-131] _ = x[actPreviewDown-131]
_ = x[actPrevHistory-132] _ = x[actPreviewPageUp-132]
_ = x[actPrevSelected-133] _ = x[actPreviewPageDown-133]
_ = x[actPrint-134] _ = x[actPreviewHalfPageUp-134]
_ = x[actPut-135] _ = x[actPreviewHalfPageDown-135]
_ = x[actNextHistory-136] _ = x[actPrevHistory-136]
_ = x[actNextSelected-137] _ = x[actPrevSelected-137]
_ = x[actExecute-138] _ = x[actPrint-138]
_ = x[actExecuteSilent-139] _ = x[actPut-139]
_ = x[actExecuteMulti-140] _ = x[actNextHistory-140]
_ = x[actSigStop-141] _ = x[actNextSelected-141]
_ = x[actFirst-142] _ = x[actExecute-142]
_ = x[actLast-143] _ = x[actExecuteSilent-143]
_ = x[actReload-144] _ = x[actExecuteMulti-144]
_ = x[actReloadSync-145] _ = x[actSigStop-145]
_ = x[actDisableSearch-146] _ = x[actFirst-146]
_ = x[actEnableSearch-147] _ = x[actLast-147]
_ = x[actSelect-148] _ = x[actReload-148]
_ = x[actDeselect-149] _ = x[actReloadSync-149]
_ = x[actUnbind-150] _ = x[actDisableSearch-150]
_ = x[actRebind-151] _ = x[actEnableSearch-151]
_ = x[actToggleBind-152] _ = x[actSelect-152]
_ = x[actBecome-153] _ = x[actDeselect-153]
_ = x[actShowHeader-154] _ = x[actUnbind-154]
_ = x[actHideHeader-155] _ = x[actRebind-155]
_ = x[actBell-156] _ = x[actToggleBind-156]
_ = x[actExclude-157] _ = x[actBecome-157]
_ = x[actExcludeMulti-158] _ = x[actShowHeader-158]
_ = x[actAsync-159] _ = x[actHideHeader-159]
_ = x[actBell-160]
_ = x[actExclude-161]
_ = x[actExcludeMulti-162]
_ = x[actAsync-163]
} }
const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeFooteractChangeHeaderLabelactChangeFooterLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformFooteractTransformHeaderLabelactTransformFooterLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactTriggeractBgTransformactBgTransformBorderLabelactBgTransformGhostactBgTransformHeaderactBgTransformFooteractBgTransformHeaderLabelactBgTransformFooterLabelactBgTransformInputLabelactBgTransformListLabelactBgTransformNthactBgTransformPointeractBgTransformPreviewLabelactBgTransformPromptactBgTransformQueryactBgTransformSearchactBgCancelactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMultiactAsync" const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactBackwardSubWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeFooteractChangeHeaderLabelactChangeFooterLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactForwardSubWordactKillLineactKillWordactKillSubWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactBackwardKillSubWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformFooteractTransformHeaderLabelactTransformFooterLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactTriggeractBgTransformactBgTransformBorderLabelactBgTransformGhostactBgTransformHeaderactBgTransformFooteractBgTransformHeaderLabelactBgTransformFooterLabelactBgTransformInputLabelactBgTransformListLabelactBgTransformNthactBgTransformPointeractBgTransformPreviewLabelactBgTransformPromptactBgTransformQueryactBgTransformSearchactBgCancelactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMultiactAsync"
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, 313, 333, 353, 372, 390, 404, 416, 432, 448, 469, 491, 506, 520, 534, 547, 564, 572, 585, 601, 613, 621, 635, 649, 660, 671, 689, 706, 713, 732, 744, 758, 767, 782, 794, 807, 818, 829, 841, 855, 876, 891, 904, 922, 938, 953, 967, 979, 991, 1008, 1015, 1020, 1029, 1040, 1051, 1064, 1079, 1090, 1103, 1118, 1125, 1138, 1151, 1168, 1183, 1196, 1210, 1224, 1240, 1260, 1272, 1295, 1312, 1330, 1348, 1371, 1394, 1416, 1437, 1452, 1471, 1495, 1513, 1530, 1548, 1558, 1572, 1597, 1616, 1636, 1656, 1681, 1706, 1730, 1753, 1770, 1791, 1817, 1837, 1856, 1876, 1887, 1896, 1906, 1919, 1935, 1947, 1961, 1977, 1995, 2015, 2037, 2051, 2066, 2074, 2080, 2094, 2109, 2119, 2135, 2150, 2160, 2168, 2175, 2184, 2197, 2213, 2228, 2237, 2248, 2257, 2266, 2279, 2288, 2301, 2314, 2321, 2331, 2346, 2354} 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, 1024, 1038, 1050, 1062, 1079, 1086, 1091, 1100, 1111, 1122, 1135, 1150, 1161, 1174, 1189, 1196, 1209, 1222, 1239, 1254, 1267, 1281, 1295, 1311, 1331, 1343, 1366, 1383, 1401, 1419, 1442, 1465, 1487, 1508, 1523, 1542, 1566, 1584, 1601, 1619, 1629, 1643, 1668, 1687, 1707, 1727, 1752, 1777, 1801, 1824, 1841, 1862, 1888, 1908, 1927, 1947, 1958, 1967, 1977, 1990, 2006, 2018, 2032, 2048, 2066, 2086, 2108, 2122, 2137, 2145, 2151, 2165, 2180, 2190, 2206, 2221, 2231, 2239, 2246, 2255, 2268, 2284, 2299, 2308, 2319, 2328, 2337, 2350, 2359, 2372, 2385, 2392, 2402, 2417, 2425}
func (i actionType) String() string { func (i actionType) String() string {
if i < 0 || i >= actionType(len(_actionType_index)-1) { if i < 0 || i >= actionType(len(_actionType_index)-1) {

View File

@@ -1663,6 +1663,8 @@ func parseActionList(masked string, original string, prevActions []*action, putA
appendAction(actBackwardDeleteCharEof) appendAction(actBackwardDeleteCharEof)
case "backward-word": case "backward-word":
appendAction(actBackwardWord) appendAction(actBackwardWord)
case "backward-subword":
appendAction(actBackwardSubWord)
case "clear-screen": case "clear-screen":
appendAction(actClearScreen) appendAction(actClearScreen)
case "delete-char": case "delete-char":
@@ -1683,6 +1685,8 @@ func parseActionList(masked string, original string, prevActions []*action, putA
appendAction(actForwardChar) appendAction(actForwardChar)
case "forward-word": case "forward-word":
appendAction(actForwardWord) appendAction(actForwardWord)
case "forward-subword":
appendAction(actForwardSubWord)
case "jump": case "jump":
appendAction(actJump) appendAction(actJump)
case "jump-accept": case "jump-accept":
@@ -1691,6 +1695,8 @@ func parseActionList(masked string, original string, prevActions []*action, putA
appendAction(actKillLine) appendAction(actKillLine)
case "kill-word": case "kill-word":
appendAction(actKillWord) appendAction(actKillWord)
case "kill-subword":
appendAction(actKillSubWord)
case "unix-line-discard", "line-discard": case "unix-line-discard", "line-discard":
appendAction(actUnixLineDiscard) appendAction(actUnixLineDiscard)
case "unix-word-rubout", "word-rubout": case "unix-word-rubout", "word-rubout":
@@ -1699,6 +1705,8 @@ func parseActionList(masked string, original string, prevActions []*action, putA
appendAction(actYank) appendAction(actYank)
case "backward-kill-word": case "backward-kill-word":
appendAction(actBackwardKillWord) appendAction(actBackwardKillWord)
case "backward-kill-subword":
appendAction(actBackwardKillSubWord)
case "toggle-down": case "toggle-down":
appendAction(actToggle, actDown) appendAction(actToggle, actDown)
case "toggle-up": case "toggle-up":

View File

@@ -291,6 +291,8 @@ type Terminal struct {
gapLineLen int gapLineLen int
wordRubout string wordRubout string
wordNext string wordNext string
subWordRubout string
subWordNext string
cx int cx int
cy int cy int
offset int offset int
@@ -512,6 +514,7 @@ const (
actBackwardDeleteChar actBackwardDeleteChar
actBackwardDeleteCharEof actBackwardDeleteCharEof
actBackwardWord actBackwardWord
actBackwardSubWord
actCancel actCancel
actChangeBorderLabel actChangeBorderLabel
@@ -541,12 +544,15 @@ const (
actFatal actFatal
actForwardChar actForwardChar
actForwardWord actForwardWord
actForwardSubWord
actKillLine actKillLine
actKillWord actKillWord
actKillSubWord
actUnixLineDiscard actUnixLineDiscard
actUnixWordRubout actUnixWordRubout
actYank actYank
actBackwardKillWord actBackwardKillWord
actBackwardKillSubWord
actSelectAll actSelectAll
actDeselectAll actDeselectAll
actToggle actToggle
@@ -937,6 +943,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
} }
wordRubout := "[^\\pL\\pN][\\pL\\pN]" wordRubout := "[^\\pL\\pN][\\pL\\pN]"
wordNext := "[\\pL\\pN][^\\pL\\pN]|(.$)" wordNext := "[\\pL\\pN][^\\pL\\pN]|(.$)"
subWordRubout := "[a-z][A-Z]|[^\\pL\\pN][\\pL\\pN]"
subWordNext := "[a-z][A-Z]|[\\pL\\pN][^\\pL\\pN]|(.$)"
if opts.FileWord { if opts.FileWord {
sep := regexp.QuoteMeta(string(os.PathSeparator)) sep := regexp.QuoteMeta(string(os.PathSeparator))
wordRubout = fmt.Sprintf("%s[^%s]", sep, sep) wordRubout = fmt.Sprintf("%s[^%s]", sep, sep)
@@ -970,6 +978,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
markerMultiLine: *opts.MarkerMulti, markerMultiLine: *opts.MarkerMulti,
wordRubout: wordRubout, wordRubout: wordRubout,
wordNext: wordNext, wordNext: wordNext,
subWordRubout: subWordRubout,
subWordNext: subWordNext,
cx: len(input), cx: len(input),
cy: 0, cy: 0,
offset: 0, offset: 0,
@@ -6021,6 +6031,11 @@ func (t *Terminal) Loop() error {
if t.cx > 0 { if t.cx > 0 {
t.rubout(t.wordRubout) t.rubout(t.wordRubout)
} }
case actBackwardKillSubWord:
beof = len(t.input) == 0
if t.cx > 0 {
t.rubout(t.subWordRubout)
}
case actYank: case actYank:
suffix := copySlice(t.input[t.cx:]) suffix := copySlice(t.input[t.cx:])
t.input = append(append(t.input[:t.cx], t.yanked...), suffix...) t.input = append(append(t.input[:t.cx], t.yanked...), suffix...)
@@ -6132,6 +6147,10 @@ func (t *Terminal) Loop() error {
t.cx = findLastMatch(t.wordRubout, string(t.input[:t.cx])) + 1 t.cx = findLastMatch(t.wordRubout, string(t.input[:t.cx])) + 1
case actForwardWord: case actForwardWord:
t.cx += findFirstMatch(t.wordNext, string(t.input[t.cx:])) + 1 t.cx += findFirstMatch(t.wordNext, string(t.input[t.cx:])) + 1
case actBackwardSubWord:
t.cx = findLastMatch(t.subWordRubout, string(t.input[:t.cx])) + 1
case actForwardSubWord:
t.cx += findFirstMatch(t.subWordNext, string(t.input[t.cx:])) + 1
case actKillWord: case actKillWord:
ncx := t.cx + ncx := t.cx +
findFirstMatch(t.wordNext, string(t.input[t.cx:])) + 1 findFirstMatch(t.wordNext, string(t.input[t.cx:])) + 1
@@ -6139,6 +6158,13 @@ func (t *Terminal) Loop() error {
t.yanked = copySlice(t.input[t.cx:ncx]) t.yanked = copySlice(t.input[t.cx:ncx])
t.input = append(t.input[:t.cx], t.input[ncx:]...) t.input = append(t.input[:t.cx], t.input[ncx:]...)
} }
case actKillSubWord:
ncx := t.cx +
findFirstMatch(t.subWordNext, string(t.input[t.cx:])) + 1
if ncx > t.cx {
t.yanked = copySlice(t.input[t.cx:ncx])
t.input = append(t.input[:t.cx], t.input[ncx:]...)
}
case actKillLine: case actKillLine:
if t.cx < len(t.input) { if t.cx < len(t.input) {
t.yanked = copySlice(t.input[t.cx:]) t.yanked = copySlice(t.input[t.cx:])

View File

@@ -108,6 +108,40 @@ class TestCore < TestInteractive
assert_equal %w[3 2 5 6 8 7], fzf_output_lines assert_equal %w[3 2 5 6 8 7], fzf_output_lines
end end
def test_subword_forward
tmux.send_keys "#{FZF} --bind K:kill-subword,F:forward-subword -q 'foo bar foo-bar fooFooBar'", :Enter, :Home
tmux.until { |lines| assert_equal '> foo bar foo-bar fooFooBar', lines.last }
tmux.send_keys 'F', :Delete
tmux.until { |lines| assert_equal '> foobar foo-bar fooFooBar', lines.last }
tmux.send_keys 'K'
tmux.until { |lines| assert_equal '> foo foo-bar fooFooBar', lines.last }
tmux.send_keys 'F', 'K'
tmux.until { |lines| assert_equal '> foo foo fooFooBar', lines.last }
tmux.send_keys 'F', 'F', 'K'
tmux.until { |lines| assert_equal '> foo foo fooFoo', lines.last }
end
def test_subword_backward
tmux.send_keys "#{FZF} --bind K:backward-kill-subword,B:backward-subword -q 'foo bar foo-bar fooBar'", :Enter
tmux.until { |lines| assert_equal '> foo bar foo-bar fooBar', lines.last }
tmux.send_keys 'B', :BSpace
tmux.until { |lines| assert_equal '> foo bar foo-bar foBar', lines.last }
tmux.send_keys 'K'
tmux.until { |lines| assert_equal '> foo bar foo-bar Bar', lines.last }
tmux.send_keys 'B', :BSpace
tmux.until { |lines| assert_equal '> foo bar foobar Bar', lines.last }
tmux.send_keys 'B', 'B', :BSpace
tmux.until { |lines| assert_equal '> foobar foobar Bar', lines.last }
end
def test_multi_max def test_multi_max
tmux.send_keys "seq 1 10 | #{FZF} -m 3 --bind A:select-all,T:toggle-all --preview 'echo [{+}]/{}'", :Enter tmux.send_keys "seq 1 10 | #{FZF} -m 3 --bind A:select-all,T:toggle-all --preview 'echo [{+}]/{}'", :Enter