Skip to content

Commit

Permalink
add bashism !term to prefix search for last command beginning with …
Browse files Browse the repository at this point in the history
…`term` (#779)

* add bashism `!term` to prefix search for last command beginning with `term`

* missed doc comment

* one more try with doc comments

* add ability to search session first, then globally

* unrelates types for list_menu test

* missed on
  • Loading branch information
fdncred authored Apr 12, 2024
1 parent 9853df3 commit 46f410b
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ descriptio = "descriptio"
ot = "ot"
# for sqlite backed history
wheres = "wheres"
# for list_menu tests
an1other = "an1other"
ver2y = "ver2y"
l3ine = "l3ine"
4should = "4should"
wr5ap = "wr5ap"
ine = "ine"
41 changes: 41 additions & 0 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,8 @@ impl Reedline {
fn parse_bang_command(&mut self) -> Option<ReedlineEvent> {
let buffer = self.editor.get_buffer();
let parsed = parse_selection_char(buffer, '!');
let parsed_prefix = parsed.prefix.unwrap_or_default().to_string();
let parsed_marker = parsed.marker.unwrap_or_default().to_string();

if let Some(last) = parsed.remainder.chars().last() {
if last != ' ' {
Expand Down Expand Up @@ -1546,6 +1548,44 @@ impl Reedline {
history.command_line.clone(),
)
}),
ParseAction::BackwardPrefixSearch => {
let history_search_by_session = self
.history
.search(SearchQuery::last_with_prefix_and_cwd(
parsed.prefix.unwrap().to_string(),
self.get_history_session_id(),
))
.unwrap_or_else(|_| Vec::new())
.get(index.saturating_sub(1))
.map(|history| {
(
parsed.remainder.len(),
parsed_prefix.len() + parsed_marker.len(),
history.command_line.clone(),
)
});
// If we don't find any history searching by session id, then let's
// search everything, otherwise use the result from the session search
if history_search_by_session.is_none() {
eprintln!("Using global search");
self.history
.search(SearchQuery::last_with_prefix(
parsed_prefix.clone(),
self.get_history_session_id(),
))
.unwrap_or_else(|_| Vec::new())
.get(index.saturating_sub(1))
.map(|history| {
(
parsed.remainder.len(),
parsed_prefix.len() + parsed_marker.len(),
history.command_line.clone(),
)
})
} else {
history_search_by_session
}
}
ParseAction::ForwardSearch => self
.history
.search(SearchQuery {
Expand Down Expand Up @@ -1573,6 +1613,7 @@ impl Reedline {
)))
.unwrap_or_else(|_| Vec::new())
.first()
//BUGBUG: This returns the wrong results with paths with spaces in them
.and_then(|history| history.command_line.split_whitespace().next_back())
.map(|token| (parsed.remainder.len(), indicator.len(), token.to_string())),
});
Expand Down
24 changes: 23 additions & 1 deletion src/menu/menu_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub struct ParseResult<'buffer> {
pub marker: Option<&'buffer str>,
/// Direction of the search based on the marker
pub action: ParseAction,
/// Prefix to search for
pub prefix: Option<&'buffer str>,
}

/// Direction of the index found in the string
Expand All @@ -30,6 +32,8 @@ pub enum ParseAction {
LastToken,
/// Last executed command.
LastCommand,
/// Backward search for a prefix
BackwardPrefixSearch,
}

/// Splits a string that contains a marker character
Expand All @@ -46,7 +50,8 @@ pub enum ParseAction {
/// remainder: "this is an example",
/// index: Some(10),
/// marker: Some("!10"),
/// action: ParseAction::ForwardSearch
/// action: ParseAction::ForwardSearch,
/// prefix: None,
/// }
/// )
///
Expand All @@ -58,6 +63,7 @@ pub fn parse_selection_char(buffer: &str, marker: char) -> ParseResult {
index: None,
marker: None,
action: ParseAction::ForwardSearch,
prefix: None,
};
}

Expand All @@ -75,6 +81,7 @@ pub fn parse_selection_char(buffer: &str, marker: char) -> ParseResult {
index: Some(0),
marker: Some(&buffer[index..index + 2 * marker.len_utf8()]),
action: ParseAction::LastCommand,
prefix: None,
}
}
#[cfg(feature = "bashisms")]
Expand All @@ -84,6 +91,7 @@ pub fn parse_selection_char(buffer: &str, marker: char) -> ParseResult {
index: Some(0),
marker: Some(&buffer[index..index + 2]),
action: ParseAction::LastToken,
prefix: None,
}
}
Some(&x) if x.is_ascii_digit() || x == '-' => {
Expand All @@ -106,6 +114,7 @@ pub fn parse_selection_char(buffer: &str, marker: char) -> ParseResult {
index: Some(count),
marker: Some(&buffer[index..index + size]),
action,
prefix: None,
};
}
}
Expand All @@ -114,14 +123,26 @@ pub fn parse_selection_char(buffer: &str, marker: char) -> ParseResult {
index: Some(count),
marker: Some(&buffer[index..index + size]),
action,
prefix: None,
};
}
#[cfg(feature = "bashisms")]
Some(&x) if x.is_ascii_alphabetic() => {
return ParseResult {
remainder: &buffer[0..index],
index: Some(0),
marker: Some(&buffer[index..index + marker.len_utf8()]),
action: ParseAction::BackwardPrefixSearch,
prefix: Some(&buffer[index + marker.len_utf8()..buffer.len()]),
}
}
None => {
return ParseResult {
remainder: &buffer[0..index],
index: Some(0),
marker: Some(&buffer[index..buffer.len()]),
action,
prefix: Some(&buffer[index..buffer.len()]),
}
}
_ => {}
Expand All @@ -135,6 +156,7 @@ pub fn parse_selection_char(buffer: &str, marker: char) -> ParseResult {
index: None,
marker: None,
action,
prefix: None,
}
}

Expand Down

0 comments on commit 46f410b

Please sign in to comment.