Provide old implementation of cancel-commandline as fallback

__fish_cancel_commandline was unused (even before) and has some issues
on multiline commandlines. Make it use the previously active logic.

Closes #10935
This commit is contained in:
Johannes Altmanninger 2024-12-23 13:51:07 +01:00
parent 54cc932215
commit 5de6f4bb3d
5 changed files with 35 additions and 30 deletions

View File

@ -94,7 +94,7 @@ Notable improvements and fixes
This build system is experimental; the main build system, using ``cmake``, remains the recommended approach for packaging and installation to a prefix.
- A new function ``fish_should_add_to_history`` can be overridden to decide whether a command should be added to the history (:issue:`10302`).
- :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`).
- :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 ``for mode in (bind --list-modes); bind -M $mode ctrl-c cancel-commandline-traditional; end`` (:issue:`10213`).
- Bindings can now mix special input functions and shell commands, so ``bind ctrl-g expand-abbr "commandline -i \n"`` works as expected (:issue:`8186`).
- Special input functions run from bindings via ``commandline -f`` are now applied immediately, instead of after the currently executing binding (:issue:`3031`).
For example, ``commandline -i foo; commandline | grep foo`` succeeds now.

View File

@ -1,30 +1,4 @@
function __fish_setup_cancel_text -v fish_color_cancel -v fish_color_normal
set -g __fish_cancel_text "^C"
if set -q fish_color_cancel
set __fish_cancel_text (echo -sn (set_color $fish_color_cancel) $__fish_cancel_text (set_color normal))
end
if command -sq tput
# Clear to EOL (to erase any autosuggestions)
set __fish_cancel_text (echo -sn $__fish_cancel_text (tput el; or tput ce))
end
end
__fish_setup_cancel_text
# This is meant to be bound to something like \cC.
# This is meant to be bound to something like ctrl-c
function __fish_cancel_commandline
set -l cmd (commandline)
if test -n "$cmd"
echo -sn $__fish_cancel_text
# `commandline -L` prints the line the cursor is on (starting from the prompt), so move the cursor
# "to the end" then call `commandline -L` to get the total number of lines typed in at the prompt.
commandline -C 10000000
printf (string repeat -n (commandline -L) "\n")
commandline ""
emit fish_cancel
end
# cancel: Close the pager if it's open (#4298)
# repaint: Repaint even if we haven't cancelled anything so the prompt refreshes
# and the terminal scrolls to it.
commandline -f cancel -f repaint
commandline -f cancel-commandline-traditional
end

View File

@ -146,6 +146,7 @@ const INPUT_FUNCTION_METADATA: &[InputFunctionMetadata] = &[
make_md(L!("beginning-of-line"), ReadlineCmd::BeginningOfLine),
make_md(L!("cancel"), ReadlineCmd::Cancel),
make_md(L!("cancel-commandline"), ReadlineCmd::CancelCommandline),
make_md(L!("cancel-commandline-traditional"), ReadlineCmd::CancelCommandlineTraditional),
make_md(L!("capitalize-word"), ReadlineCmd::CapitalizeWord),
make_md(L!("clear-screen"), ReadlineCmd::ClearScreenAndRepaint),
make_md(L!("complete"), ReadlineCmd::Complete),

View File

@ -123,6 +123,7 @@ pub enum ReadlineCmd {
DeleteOrExit,
Exit,
CancelCommandline,
CancelCommandlineTraditional,
Cancel,
Undo,
Redo,

View File

@ -87,6 +87,7 @@ use crate::kill::{kill_add, kill_replace, kill_yank, kill_yank_rotate};
use crate::libc::MB_CUR_MAX;
use crate::nix::isatty;
use crate::operation_context::{get_bg_context, OperationContext};
use crate::output::parse_color;
use crate::output::Outputter;
use crate::pager::{PageRendering, Pager, SelectionMotion};
use crate::panic::AT_EXIT;
@ -2305,7 +2306,7 @@ impl<'a> Reader<'a> {
self.data
.update_buff_pos(EditableLineTag::Commandline, Some(self.command_line_len()));
}
rl::CancelCommandline => {
rl::CancelCommandline | rl::CancelCommandlineTraditional => {
if self.conf.exit_on_interrupt {
self.parser
.set_last_statuses(Statuses::just(STATUS_CMD_ERROR.unwrap()));
@ -2315,10 +2316,37 @@ impl<'a> Reader<'a> {
if self.command_line.is_empty() {
return;
}
if c == rl::CancelCommandlineTraditional {
// Move cursor to the end of the line.
let end = self.command_line.len();
self.update_buff_pos(EditableLineTag::Commandline, Some(end));
self.autosuggestion.clear();
// Repaint also changes the actual cursor position
if self.is_repaint_needed(None) {
self.layout_and_repaint(L!("cancel"));
}
let mut outp = Outputter::stdoutput().borrow_mut();
if let Some(fish_color_cancel) = self.vars().get(L!("fish_color_cancel")) {
outp.set_color(
parse_color(&fish_color_cancel, false),
parse_color(&fish_color_cancel, true),
);
}
outp.write_wstr(L!("^C"));
outp.set_color(RgbColor::RESET, RgbColor::RESET);
// We print a newline last so the prompt_sp hack doesn't get us.
outp.push(b'\n');
}
self.push_edit(
EditableLineTag::Commandline,
Edit::new(0..self.command_line_len(), L!("").to_owned()),
);
if c == rl::CancelCommandlineTraditional {
self.screen
.reset_abandoning_line(usize::try_from(termsize_last().width).unwrap());
}
// Post fish_cancel.
event::fire_generic(self.parser, L!("fish_cancel").to_owned(), vec![]);
@ -5002,6 +5030,7 @@ fn command_ends_paging(c: ReadlineCmd, focused_on_search_field: bool) -> bool {
| rl::AcceptAutosuggestion
| rl::DeleteOrExit
| rl::CancelCommandline
| rl::CancelCommandlineTraditional
| rl::Cancel =>
// These commands always end paging.
{