From 066dd1f654ca79b7185bb8af62d2706c4cdc31b6 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Mon, 18 Feb 2019 00:49:11 -0800 Subject: [PATCH] Fix MacVim Ctrl-C handling in Normal and Command-Line modes Vim has a "ctrl_c_interrupts" mode that gets turned on in misc modes (e.g. Normal / Command-Line mode) when 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 Vim GUI code in other platforms 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 --- src/MacVim/MMBackend.m | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 6a9dd6cc9a..6b85cbb5e8 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -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 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 is not mapped in the current mode + // (even if 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; } }