Clear the control-C cancel flag earlier, allowing event handlers to run

When the user presses control-C, fish marks a cancellation signal which
prevents fish script from running, allowing it to properly unwind.
Prior to this commit, the signal was cleared in the reader. However this
missed the case where a binding would set $fish_bind_mode which would
trigger event handlers: the event handlers would be skipped because of
the cancellation flag was still set. This is similar to #6937.

Let's clear the flag earlier, as soon as we it's set, in inputter_t.
Fixes #8125.
This commit is contained in:
ridiculousfish 2021-07-11 16:50:21 -07:00
parent c5d4f26b09
commit 179073ce62
4 changed files with 26 additions and 6 deletions

View File

@ -13,6 +13,7 @@ Scripting improvements
Interactive improvements
------------------------
Vi mode cursors are now set properly after control-C. (:issue:`8125`).
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -329,6 +329,10 @@ void inputter_t::prepare_to_select() /* override */ {
}
void inputter_t::select_interrupted() /* override */ {
// Readline commands may be bound to \cc which also sets the cancel flag.
// See #6937, #8125.
signal_clear_cancel();
// Fire any pending events and reap stray processes, including printing exit status messages.
auto &parser = *this->parser_;
event_fire_delayed(parser);

View File

@ -2943,8 +2943,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
set_command_line_and_position(&command_line, L"", 0);
s_reset_abandoning_line(&screen, termsize_last().width - command_line.size());
// Post fish_cancel, allowing it to fire.
signal_clear_cancel();
// Post fish_cancel.
event_fire_generic(parser(), L"fish_cancel");
}
break;
@ -3977,10 +3976,6 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
history_search.reset();
}
// Readline commands may be bound to \cc which also sets the cancel flag.
// See #6937.
signal_clear_cancel();
rls.last_cmd = readline_cmd;
} else {
// Ordinary char.

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3
from pexpect_helper import SpawnedProc
import os
import signal
sp = SpawnedProc()
send, sendline, sleep, expect_prompt = sp.send, sp.sendline, sp.sleep, sp.expect_prompt
@ -33,3 +35,21 @@ sleep(0.050)
send("echo mode changes: $MODE_CHANGES\r")
expect_prompt("\r\nmode changes: default insert default insert\r\n")
# Regression test for #8125.
# Control-C should return us to insert mode.
send("set -e MODE_CHANGES\r")
expect_prompt()
# Put some text on the command line and then go back to normal mode.
send("echo stuff")
sp.expect_str("echo stuff")
send("\033")
sleep(0.050)
os.kill(sp.spawn.pid, signal.SIGINT)
sleep(0.050)
# We should be back in insert mode now.
send("echo mode changes: $MODE_CHANGES\r")
expect_prompt("\r\nmode changes: default insert\r\n")