Token search commands that only match the last token in each line

This add two commands history-last-token-search-backward and
history-last-token-search-forward which behaves like bash's yank-last-arg. So
similar to history-token-search-* but only considers the last argument for
each command.

Closes #10756
Closes #11258
This commit is contained in:
carsonzhu
2025-03-11 13:19:46 +08:00
committed by Johannes Altmanninger
parent 48306409ef
commit 4ce552bf94
5 changed files with 31 additions and 5 deletions

View File

@@ -265,6 +265,12 @@ The following special input functions are available:
``history-token-search-forward``
search the history for the next matching argument
``history-last-token-search-backward``
search the history for the previous matching last argument
``history-last-token-search-forward``
search the history for the next matching last argument
``forward-jump`` and ``backward-jump``
read another character and jump to its next occurrence after/before the cursor

View File

@@ -175,6 +175,8 @@ const fn make_md(name: &'static wstr, code: ReadlineCmd) -> InputFunctionMetadat
make_md(L!("forward-token"), ReadlineCmd::ForwardToken),
make_md(L!("forward-word"), ReadlineCmd::ForwardWord),
make_md(L!("history-delete"), ReadlineCmd::HistoryDelete),
make_md(L!("history-last-token-search-backward"), ReadlineCmd::HistoryLastTokenSearchBackward),
make_md(L!("history-last-token-search-forward"), ReadlineCmd::HistoryLastTokenSearchForward),
make_md(L!("history-pager"), ReadlineCmd::HistoryPager),
#[allow(deprecated)]
make_md(L!("history-pager-delete"), ReadlineCmd::HistoryPagerDelete),

View File

@@ -90,6 +90,8 @@ pub enum ReadlineCmd {
BackwardKillToken,
HistoryTokenSearchBackward,
HistoryTokenSearchForward,
HistoryLastTokenSearchBackward,
HistoryLastTokenSearchForward,
SelfInsert,
SelfInsertNotFirst,
TransposeChars,

View File

@@ -3000,11 +3000,16 @@ fn handle_readline_command(&mut self, c: ReadlineCmd) {
| rl::HistorySearchBackward
| rl::HistorySearchForward
| rl::HistoryTokenSearchBackward
| rl::HistoryTokenSearchForward => {
| rl::HistoryTokenSearchForward
| rl::HistoryLastTokenSearchBackward
| rl::HistoryLastTokenSearchForward => {
let mode = match c {
rl::HistoryTokenSearchBackward | rl::HistoryTokenSearchForward => {
SearchMode::Token
}
rl::HistoryLastTokenSearchBackward | rl::HistoryLastTokenSearchForward => {
SearchMode::LastToken
}
rl::HistoryPrefixSearchBackward | rl::HistoryPrefixSearchForward => {
SearchMode::Prefix
}
@@ -3016,13 +3021,13 @@ fn handle_readline_command(&mut self, c: ReadlineCmd) {
if self.history_search.is_at_present() && mode != self.history_search.mode() {
let el = &self.data.command_line;
if mode == SearchMode::Token {
if matches!(mode, SearchMode::Token | SearchMode::LastToken) {
// Searching by token.
let (token_range, _) = parse_util_token_extent(el.text(), el.position());
self.data.history_search.reset_to_mode(
el.text()[token_range.clone()].to_owned(),
self.history.clone(),
SearchMode::Token,
mode,
token_range.start,
);
} else {
@@ -3048,9 +3053,11 @@ fn handle_readline_command(&mut self, c: ReadlineCmd) {
let dir = match c {
rl::HistorySearchBackward
| rl::HistoryTokenSearchBackward
| rl::HistoryLastTokenSearchBackward
| rl::HistoryPrefixSearchBackward => SearchDirection::Backward,
rl::HistorySearchForward
| rl::HistoryTokenSearchForward
| rl::HistoryLastTokenSearchForward
| rl::HistoryPrefixSearchForward => SearchDirection::Forward,
_ => unreachable!(),
};
@@ -5536,6 +5543,8 @@ fn command_ends_paging(c: ReadlineCmd, focused_on_search_field: bool) -> bool {
| rl::HistorySearchForward
| rl::HistoryTokenSearchBackward
| rl::HistoryTokenSearchForward
| rl::HistoryLastTokenSearchBackward
| rl::HistoryLastTokenSearchForward
| rl::AcceptAutosuggestion
| rl::DeleteOrExit
| rl::CancelCommandline
@@ -5626,6 +5635,8 @@ fn command_ends_history_search(c: ReadlineCmd) -> bool {
| rl::HistorySearchForward
| rl::HistoryTokenSearchBackward
| rl::HistoryTokenSearchForward
| rl::HistoryLastTokenSearchBackward
| rl::HistoryLastTokenSearchForward
| rl::HistoryDelete
| rl::HistoryPagerDelete
| rl::BeginningOfHistory

View File

@@ -42,6 +42,8 @@ pub enum SearchMode {
Prefix,
/// searching by token
Token,
/// search by the last token of the command
LastToken,
}
/// Encapsulation of the reader's history search functionality.
@@ -71,7 +73,7 @@ pub fn active(&self) -> bool {
self.mode != SearchMode::Inactive
}
pub fn by_token(&self) -> bool {
self.mode == SearchMode::Token
matches!(self.mode, SearchMode::Token | SearchMode::LastToken)
}
pub fn by_line(&self) -> bool {
self.mode == SearchMode::Line
@@ -221,7 +223,7 @@ fn find(zelf: &ReaderHistorySearch, haystack: &wstr, needle: &wstr) -> Option<us
if let Some(offset) = find(self, text, needle) {
self.add_if_new(SearchMatch::new(text.to_owned(), offset));
}
} else if self.mode == SearchMode::Token {
} else if matches!(self.mode, SearchMode::Token | SearchMode::LastToken) {
let mut tok = Tokenizer::new(text, TOK_ACCEPT_UNFINISHED);
let mut local_tokens = vec![];
@@ -238,6 +240,9 @@ fn find(zelf: &ReaderHistorySearch, haystack: &wstr, needle: &wstr) -> Option<us
// Make sure tokens are added in reverse order. See #5150
for tok in local_tokens.into_iter().rev() {
self.add_if_new(tok);
if self.mode == SearchMode::LastToken {
break;
}
}
}
self.matches.len() > before