Skip to content

Commit

Permalink
Fix MacVim Ctrl-C handling in Normal and Command-Line modes
Browse files Browse the repository at this point in the history
Vim has a "ctrl_c_interrupts" mode that gets turned on in misc modes
(e.g. Normal / Command-Line mode) when <C-C> is not mapped. In this
mode, Ctrl-C has special behavior and is hard-coded (i.e. not
remappable).

There is an old bug in how MacVim handles Ctrl-C under this mode. It's
trying to be smart and aggressively clears the input queue (even
non-text-related ones) without adding anything to the input queue.
Previously it kind of worked due to a coincidence in how Vim's GUI
handled input logic, but it was fragile. The recent Vim refactor that
changed Vim GUI's input handling broke this.

Instead, don't do any of these smart input queue clearing and just do
what other Vim GUI code does and call `trash_input_buf()`, set
`set_int`, and then add the Ctrl-C to the input queue. MacVim still has
`Cmd-.` for an aggressive interrupt in case Vim is hung (which shouldn't
happen to begin with).

Fix #846
  • Loading branch information
ychin committed Feb 18, 2019
1 parent 1c34fb4 commit c313b6f
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions src/MacVim/MMBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -1270,17 +1270,19 @@ - (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data
unsigned len = *((unsigned*)bytes); bytes += sizeof(unsigned);

if (ctrl_c_interrupts && 1 == len) {
// NOTE: the flag ctrl_c_interrupts is 0 e.g. when the user has
// mappings to something like <C-c>g. Also it seems the flag
// intr_char is 0 when MacVim was started from Finder whereas it is
// 0x03 (= Ctrl_C) when started from Terminal.
// NOTE: The flag ctrl_c_interrupts is set when it has special
// interrupt behavior in Vim and would cancel all other input. This
// is a hard-coded behavior in Vim. It usually happens when not in
// Insert mode, and when <C-C> is not mapped in the current mode
// (even if <C-C> is mapped to itself, ctrl_c_interrupts would not
// be set).
// Also it seems the flag intr_char is 0 when MacVim was started
// from Finder whereas it is 0x03 (= Ctrl_C) when started from
// Terminal.
char_u *str = (char_u*)bytes;
if (str[0] == Ctrl_C || (str[0] == intr_char && intr_char != 0)) {
ASLogDebug(@"Got INT, str[0]=%#x ctrl_c_interrupts=%d "
"intr_char=%#x", str[0], ctrl_c_interrupts, intr_char);
trash_input_buf();
got_int = TRUE;
[inputQueue removeAllObjects];
return;
}
}

Expand Down

0 comments on commit c313b6f

Please sign in to comment.