Limit ctrl-r autofill/replace to a single command substitution

As reported on gitter, commands like "rm (...)" sometimes want a previous
command inside the parentheses. Let's try that.  If a user actually wants
to search for a command substitution they can move the cursor outside the
command substitution, or type the search string after pressing ctrl-r?
This commit is contained in:
Johannes Altmanninger 2024-05-01 20:11:52 +02:00
parent a9078769c3
commit 91b007cab7
2 changed files with 19 additions and 3 deletions

View file

@ -62,7 +62,7 @@ Notable improvements and fixes
- :kbd:`ctrl-c` during command input no longer prints ``^C`` and a new prompt but merely clears the command line. This restores the behavior from version 2.2. To revert to the old behavior use ``bind ctrl-c __fish_cancel_commandline`` (:issue:`10213`).
- Undo history is no longer truncated after every command but kept for the lifetime of the shell process.
- The :kbd:`ctrl-r` history search now uses glob syntax (:issue:`10131`).
- The :kbd:`ctrl-r` history search now operates only on the line at cursor, making it easier to quickly compose a multi-line command by recalling previous commands.
- The :kbd:`ctrl-r` history search now operates only on the line or command substitution at cursor, making it easier to combine commands from history.
- Abbreviations can now be restricted to specific commands. For instance::
abbr --add --command git back 'reset --hard HEAD^'

View file

@ -2570,7 +2570,17 @@ impl ReaderData {
let search_string = if !self.history_search.active()
|| self.history_search.search_string().is_empty()
{
parse_util_escape_wildcards(self.command_line.line_at_cursor())
let cmdsub = parse_util_cmdsubst_extent(
self.command_line.text(),
self.command_line.position(),
);
let cmdsub = &self.command_line.text()[cmdsub];
let needle = if !cmdsub.contains('\n') {
cmdsub
} else {
self.command_line.line_at_cursor()
};
parse_util_escape_wildcards(needle)
} else {
// If we have an actual history search already going, reuse that term
// - this is if the user looks around a bit and decides to switch to the pager.
@ -5180,7 +5190,13 @@ pub fn completion_apply_to_command_line(
if do_replace_line {
assert!(!do_escape, "unsupported completion flag");
return replace_line_at_cursor(command_line, inout_cursor_pos, val_str);
let cmdsub = parse_util_cmdsubst_extent(command_line, cursor_pos);
return if !command_line[cmdsub.clone()].contains('\n') {
*inout_cursor_pos = cmdsub.start + val_str.len();
command_line[..cmdsub.start].to_owned() + val_str + &command_line[cmdsub.end..]
} else {
replace_line_at_cursor(command_line, inout_cursor_pos, val_str)
};
}
let mut escape_flags = EscapeFlags::empty();