diff options
author | Matthieu Coudron <mattator@gmail.com> | 2020-05-26 11:03:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-26 11:03:50 +0200 |
commit | 618e9a769220ffe331cc554c51485f9230a544ec (patch) | |
tree | 4ba237ecf32e967e752829fda321b805777b1622 /src | |
parent | 8c588246a505e4fcd3d28e6d1f670e834c918529 (diff) | |
parent | bb2be0de38c46f683bda45a32cf47493cf4db411 (diff) | |
download | rneovim-618e9a769220ffe331cc554c51485f9230a544ec.tar.gz rneovim-618e9a769220ffe331cc554c51485f9230a544ec.tar.bz2 rneovim-618e9a769220ffe331cc554c51485f9230a544ec.zip |
Merge pull request #11803 from erw7/virtual-terminal-input
[RDY] win/TUI: Use virtual terminal input if available
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/event/stream.c | 8 | ||||
-rw-r--r-- | src/nvim/os/os_win_console.c | 32 | ||||
-rw-r--r-- | src/nvim/os/os_win_console.h | 4 | ||||
-rw-r--r-- | src/nvim/os/tty.c | 4 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 31 |
5 files changed, 77 insertions, 2 deletions
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 0e87f7c6c1..1e9e530a42 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -11,6 +11,9 @@ #include "nvim/rbuffer.h" #include "nvim/macros.h" #include "nvim/event/stream.h" +#ifdef WIN32 +# include "nvim/os/os_win_console.h" +#endif #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/stream.c.generated.h" @@ -62,6 +65,11 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream) if (type == UV_TTY) { uv_tty_init(&loop->uv, &stream->uv.tty, fd, 0); uv_tty_set_mode(&stream->uv.tty, UV_TTY_MODE_RAW); + DWORD dwMode; + if (GetConsoleMode(stream->uv.tty.handle, &dwMode)) { + dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode(stream->uv.tty.handle, dwMode); + } stream->uvstream = STRUCT_CAST(uv_stream_t, &stream->uv.tty); } else { #endif diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 8a0aa2f5ae..18dcfeafa0 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -2,8 +2,14 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include "nvim/vim.h" +#include "nvim/os/input.h" #include "nvim/os/os_win_console.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/os_win_console.c.generated.h" +#endif + + int os_get_conin_fd(void) { const HANDLE conin_handle = CreateFile("CONIN$", @@ -40,3 +46,29 @@ void os_replace_stdout_and_stderr_to_conout(void) const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0); assert(conerr_fd == STDERR_FILENO); } + +void os_set_vtp(bool enable) +{ + static TriState is_legacy = kNone; + if (is_legacy == kNone) { + uv_tty_vtermstate_t state; + uv_tty_get_vterm_state(&state); + is_legacy = (state == UV_TTY_UNSUPPORTED) ? kTrue : kFalse; + } + if (!is_legacy && !os_has_vti()) { + uv_tty_set_vterm_state(enable ? UV_TTY_SUPPORTED : UV_TTY_UNSUPPORTED); + } +} + +static bool os_has_vti(void) +{ + static TriState has_vti = kNone; + if (has_vti == kNone) { + HANDLE handle = (HANDLE)_get_osfhandle(input_global_fd()); + DWORD dwMode; + if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { + has_vti = !!(dwMode & ENABLE_VIRTUAL_TERMINAL_INPUT) ? kTrue : kFalse; + } + } + return has_vti == kTrue; +} diff --git a/src/nvim/os/os_win_console.h b/src/nvim/os/os_win_console.h index 154ec83d8a..7b5800afa8 100644 --- a/src/nvim/os/os_win_console.h +++ b/src/nvim/os/os_win_console.h @@ -5,4 +5,8 @@ # include "os/os_win_console.h.generated.h" #endif +#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT +# define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 +#endif + #endif // NVIM_OS_OS_WIN_CONSOLE_H diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c index 4f525bed9a..c80ef99084 100644 --- a/src/nvim/os/tty.c +++ b/src/nvim/os/tty.c @@ -28,7 +28,7 @@ void os_tty_guess_term(const char **term, int out_fd) if (winpty) { // Force TERM=win32con when running in winpty. *term = "win32con"; - uv_set_vterm_state(UV_UNSUPPORTED); + uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED); return; } @@ -55,7 +55,7 @@ void os_tty_guess_term(const char **term, int out_fd) } if (conemu_ansi) { - uv_set_vterm_state(UV_SUPPORTED); + uv_tty_set_vterm_state(UV_TTY_SUPPORTED); } } #endif diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 2c4d02812b..b4d91a01fc 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -33,6 +33,9 @@ #include "nvim/os/os.h" #include "nvim/os/signal.h" #include "nvim/os/tty.h" +#ifdef WIN32 +# include "nvim/os/os_win_console.h" +#endif #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/ui_bridge.h" @@ -1015,8 +1018,22 @@ static void tui_mouse_on(UI *ui) { TUIData *data = ui->data; if (!data->mouse_enabled) { +#ifdef WIN32 + // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and + // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse traking of + // libuv. For this reason, vtp (vterm) state of libuv is temporarily + // disabled because the control sequence needs to be processed by libuv + // instead of Windows vtp. + // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode + flush_buf(ui); + os_set_vtp(false); +#endif unibi_out_ext(ui, data->unibi_ext.enable_mouse); data->mouse_enabled = true; +#ifdef WIN32 + flush_buf(ui); + os_set_vtp(true); +#endif } } @@ -1024,8 +1041,22 @@ static void tui_mouse_off(UI *ui) { TUIData *data = ui->data; if (data->mouse_enabled) { +#ifdef WIN32 + // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and + // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse traking of + // libuv. For this reason, vtp (vterm) state of libuv is temporarily + // disabled because the control sequence needs to be processed by libuv + // instead of Windows vtp. + // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode + flush_buf(ui); + os_set_vtp(false); +#endif unibi_out_ext(ui, data->unibi_ext.disable_mouse); data->mouse_enabled = false; +#ifdef WIN32 + flush_buf(ui); + os_set_vtp(true); +#endif } } |