How does Vim/Neovim get input from the user? I am trying to make my input parser but cannot find a way to detect meta keys (Ctrl/Shift/Alt) with mouse input nor can I detect mouse movement - only clicking, but Vim/NVim can do that.

I tried looking through the codebase but only got to input_enqueue, anything besides that already has a string of the input but I cannot find the place it actually gets the input from.

I looked here because these editors are the only tui applications I know that have complete control over the terminal input.

  • I discovered in the xterm docs that \033[?1003h is the setting that gives the most output/constant mouse tracking. Now I would just need everything to have a stable escape sequence output, but I see no way to set a xterm resource from within a running program. Also, then there is the part to find a sensible system of mouse control (having mouse tracking on at all times is a lot of wasted CPU cycles) to use internaly.
    – JosefLitos
    Jul 13, 2023 at 21:28

1 Answer 1


EDIT: it uses libtermkey which is now deprecated and doesn't offer nearly the level of control we can have nowadays.

Original answer:

I made my own simple solution, it supersedes libtermkey by better handling numpad + more modifiers. But multiclick is based on cursor coord identicity, not time difference.

NOTE: kitty's keyboard protocol is now also implemented in wezterm and foot, neovim uses only the bare minimum. My solution can handle key event types and makes good use of alternate keys to give users finer control over their keybind behaviour between layouts.

Here are the key sequences to get more input:

  • to get all modifier keys, correct utf8 and proper keypad distinction, use kitty's extended keyboard protocol - enabled by \033[>1u (\033[<u to disable) - supported by many terminals
  • to distinguish Ctrl+i from Tab ... in other terminals, xterm says to set modifyOtherKeys resource to 2\033[>4;2m
  • to distinguish mouse events more easily, we can prefix them with < by enabling \033[?1006h (\033[?1006l to disable or 1016 for pixel precission tracking)
  • to enable different levels of mouse tracking, we can add movement tracking with \033[?1003h

I also tried to count for the differences and misses in neovim, aside of it ignoring shift modifier and having its own unchangeable format of some escape sequences (broken horizontal scroll), their builtin terminal it is pretty good.

This all applys probbably only to xterm-like terminals, which nowadays is the vast majority, so for future reference I've put up my parser here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.