diff --git a/src/actiontype_string.go b/src/actiontype_string.go index e163f746a89..d07980249ef 100644 --- a/src/actiontype_string.go +++ b/src/actiontype_string.go @@ -140,38 +140,40 @@ func _() { _ = x[actPreviewHalfPageUp-129] _ = x[actPreviewHalfPageDown-130] _ = x[actPrevHistory-131] - _ = x[actPrevSelected-132] - _ = x[actPrint-133] - _ = x[actPut-134] - _ = x[actNextHistory-135] - _ = x[actNextSelected-136] - _ = x[actExecute-137] - _ = x[actExecuteSilent-138] - _ = x[actExecuteMulti-139] - _ = x[actSigStop-140] - _ = x[actFirst-141] - _ = x[actLast-142] - _ = x[actReload-143] - _ = x[actReloadSync-144] - _ = x[actDisableSearch-145] - _ = x[actEnableSearch-146] - _ = x[actSelect-147] - _ = x[actDeselect-148] - _ = x[actUnbind-149] - _ = x[actRebind-150] - _ = x[actToggleBind-151] - _ = x[actBecome-152] - _ = x[actShowHeader-153] - _ = x[actHideHeader-154] - _ = x[actBell-155] - _ = x[actExclude-156] - _ = x[actExcludeMulti-157] - _ = x[actAsync-158] + _ = x[actPrevHistorySearch-132] + _ = x[actPrevSelected-133] + _ = x[actPrint-134] + _ = x[actPut-135] + _ = x[actNextHistory-136] + _ = x[actNextHistorySearch-137] + _ = x[actNextSelected-138] + _ = x[actExecute-139] + _ = x[actExecuteSilent-140] + _ = x[actExecuteMulti-141] + _ = x[actSigStop-142] + _ = x[actFirst-143] + _ = x[actLast-144] + _ = x[actReload-145] + _ = x[actReloadSync-146] + _ = x[actDisableSearch-147] + _ = x[actEnableSearch-148] + _ = x[actSelect-149] + _ = x[actDeselect-150] + _ = x[actUnbind-151] + _ = x[actRebind-152] + _ = x[actToggleBind-153] + _ = x[actBecome-154] + _ = x[actShowHeader-155] + _ = x[actHideHeader-156] + _ = x[actBell-157] + _ = x[actExclude-158] + _ = x[actExcludeMulti-159] + _ = x[actAsync-160] } -const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeFooteractChangeHeaderLabelactChangeFooterLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformFooteractTransformHeaderLabelactTransformFooterLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactBgTransformactBgTransformBorderLabelactBgTransformGhostactBgTransformHeaderactBgTransformFooteractBgTransformHeaderLabelactBgTransformFooterLabelactBgTransformInputLabelactBgTransformListLabelactBgTransformNthactBgTransformPointeractBgTransformPreviewLabelactBgTransformPromptactBgTransformQueryactBgTransformSearchactBgCancelactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMultiactAsync" +const _actionType_name = "actIgnoreactStartactClickactInvalidactBracketedPasteBeginactBracketedPasteEndactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeGhostactChangeHeaderactChangeFooteractChangeHeaderLabelactChangeFooterLabelactChangeInputLabelactChangeListLabelactChangeMultiactChangeNthactChangePointeractChangePreviewactChangePreviewLabelactChangePreviewWindowactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactToggleInputactHideInputactShowInputactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformGhostactTransformHeaderactTransformFooteractTransformHeaderLabelactTransformFooterLabelactTransformInputLabelactTransformListLabelactTransformNthactTransformPointeractTransformPreviewLabelactTransformPromptactTransformQueryactTransformSearchactBgTransformactBgTransformBorderLabelactBgTransformGhostactBgTransformHeaderactBgTransformFooteractBgTransformHeaderLabelactBgTransformFooterLabelactBgTransformInputLabelactBgTransformListLabelactBgTransformNthactBgTransformPointeractBgTransformPreviewLabelactBgTransformPromptactBgTransformQueryactBgTransformSearchactBgCancelactSearchactPreviewactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevHistorySearchactPrevSelectedactPrintactPutactNextHistoryactNextHistorySearchactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactToggleBindactBecomeactShowHeaderactHideHeaderactBellactExcludeactExcludeMultiactAsync" -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, 1562, 1587, 1606, 1626, 1646, 1671, 1696, 1720, 1743, 1760, 1781, 1807, 1827, 1846, 1866, 1877, 1886, 1896, 1909, 1925, 1937, 1951, 1967, 1985, 2005, 2027, 2041, 2056, 2064, 2070, 2084, 2099, 2109, 2125, 2140, 2150, 2158, 2165, 2174, 2187, 2203, 2218, 2227, 2238, 2247, 2256, 2269, 2278, 2291, 2304, 2311, 2321, 2336, 2344} +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, 1562, 1587, 1606, 1626, 1646, 1671, 1696, 1720, 1743, 1760, 1781, 1807, 1827, 1846, 1866, 1877, 1886, 1896, 1909, 1925, 1937, 1951, 1967, 1985, 2005, 2027, 2041, 2061, 2076, 2084, 2090, 2104, 2124, 2139, 2149, 2165, 2180, 2190, 2198, 2205, 2214, 2227, 2243, 2258, 2267, 2278, 2287, 2296, 2309, 2318, 2331, 2344, 2351, 2361, 2376, 2384} func (i actionType) String() string { if i < 0 || i >= actionType(len(_actionType_index)-1) { diff --git a/src/history.go b/src/history.go index 1e66c721468..e53e42c791e 100644 --- a/src/history.go +++ b/src/history.go @@ -8,11 +8,12 @@ import ( // History struct represents input history type History struct { - path string - lines []string - modified map[int]string - maxSize int - cursor int + path string + lines []string + modified map[int]string + maxSize int + cursor int + lastSearch string } // NewHistory returns the pointer to a new History struct @@ -43,11 +44,12 @@ func NewHistory(path string, maxSize int) (*History, error) { lines = append(lines, "") } return &History{ - path: path, - maxSize: maxSize, - lines: lines, - modified: make(map[int]string), - cursor: len(lines) - 1}, nil + path: path, + maxSize: maxSize, + lines: lines, + modified: make(map[int]string), + cursor: len(lines) - 1, + lastSearch: ""}, nil } func (h *History) append(line string) error { @@ -93,3 +95,37 @@ func (h *History) next() string { } return h.current() } + +func (h *History) prevSearch(substr string) string { + if substr == "" { + return h.previous() + } + for { + if h.cursor > 0 { + h.cursor-- + } else { + return "" + } + curstr := h.current() + if strings.Contains(curstr, substr) { + return curstr + } + } +} + +func (h *History) nextSearch(substr string) string { + if substr == "" { + return h.next() + } + for { + if h.cursor < len(h.lines)-1 { + h.cursor++ + } else { + return "" + } + curstr := h.current() + if strings.Contains(curstr, substr) { + return curstr + } + } +} diff --git a/src/options.go b/src/options.go index c724f2ebc85..09821a18e53 100644 --- a/src/options.go +++ b/src/options.go @@ -1435,7 +1435,7 @@ const ( func init() { executeRegexp = regexp.MustCompile( - `(?si)[:+](become|execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|bg-transform|transform)-(?:query|prompt|(?:border|list|preview|input|header|footer)-label|header|footer|search|nth|pointer|ghost)|bg-transform|transform|change-(?:preview-window|preview|multi)|(?:re|un|toggle-)bind|pos|put|print|search)`) + `(?si)[:+](become|execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|bg-transform|transform)-(?:query|prompt|(?:border|list|preview|input|header|footer)-label|header|footer|search|nth|pointer|ghost)|bg-transform|transform|change-(?:preview-window|preview|multi)|(?:re|un|toggle-)bind|pos|put|print|search)|((?:prev|next)-history-search)`) splitRegexp = regexp.MustCompile("[,:]+") actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+") } @@ -1864,6 +1864,10 @@ func isExecuteAction(str string) actionType { return actPrint case "put": return actPut + case "prev-history-search": + return actPrevHistorySearch + case "next-history-search": + return actNextHistorySearch case "transform": return actTransform case "transform-list-label": diff --git a/src/terminal.go b/src/terminal.go index f5ded439e7a..e8aae83b128 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -627,10 +627,12 @@ const ( actPreviewHalfPageUp actPreviewHalfPageDown actPrevHistory + actPrevHistorySearch actPrevSelected actPrint actPut actNextHistory + actNextHistorySearch actNextSelected actExecute actExecuteSilent @@ -6081,6 +6083,9 @@ func (t *Terminal) Loop() error { prefix := copySlice(t.input[:t.cx]) t.input = append(append(prefix, event.Char), t.input[t.cx:]...) t.cx++ + if t.history != nil { + t.history.lastSearch = "" + } case actPrevHistory: if t.history != nil { t.history.override(string(t.input)) @@ -6093,6 +6098,28 @@ func (t *Terminal) Loop() error { t.input = trimQuery(t.history.next()) t.cx = len(t.input) } + case actNextHistorySearch, actPrevHistorySearch: + if t.history != nil { + t.history.override(string(t.input)) + histSearch := t.history.nextSearch + if a.t == actPrevHistorySearch { + histSearch = t.history.prevSearch + } + toSearch := t.history.lastSearch + if len(toSearch) == 0 { + toSearch = a.a + if len(toSearch) == 0 { + toSearch = string(t.input) + } + t.history.lastSearch = toSearch + } + hist := histSearch(toSearch) + fmt.Fprintf(os.Stderr, "DEBUGPRINT[2]: terminal.go:6116: toSearch=%+v\n", toSearch) + if len(hist) != 0 { + t.input = trimQuery(hist) + t.cx = len(t.input) + } + } case actToggleSearch: t.paused = !t.paused changed = !t.paused @@ -6610,6 +6637,13 @@ func (t *Terminal) Loop() error { } } + // if t.history != nil && + // a.t != actPrevHistory && + // a.t != actNextHistory && + // a.t != actPrevHistorySearch && + // a.t != actNextHistorySearch { + // t.history.lastSearch = "" + // } if !processExecution(a.t) { t.lastAction = a.t }