I'm using kitty to run terminal nvim on macOS. I want to use D- (command-key) mappings inside nvim. Because terminals, for reasons I don't understand, don't simply pass command-key chords through to the underlying nvim, this requires a workaround. This is what I currently use in kitty.conf:

map cmd+left  send_text all :call feedkeys("\<D-LEFT>")\r
map cmd+right send_text all :call feedkeys("\<D-RIGHT>")\r
map cmd+up    send_text all :call feedkeys("\<D-UP>")\r
map cmd+down  send_text all :call feedkeys("\<D-DOWN>")\r

This works in normal mode, but not in insert mode due to the colon. Nvim provides the <Cmd> pseudokey (:help <Cmd>) to replace the : for writing mode-agnostic command mappings within Vim. But kitty doesn't know anything about <Cmd>. However, if <Cmd> is just a stand-in for some bytes, I could just specify these bytes directly in kitty.conf.

How can I get the bytes represented by <Cmd>? Or is there another solution?

  • 2
    I am not sure this is a good idea at all, but here we go: :echo "\<Cmd>" Dec 3, 2021 at 15:58
  • Thanks-- yes it's an ugly hack but I'm unaware of a better way to achieve what I'm after. I ran echo "\<Cmd>" and it gives me <80><fd>h. I thought <80> and <fd> were hex representations (which is what I need), but then I tried let @+ = "\<Cmd>", pasted the results into a buffer, and did ga for each character that showed up. The hex was completely different-- there were three characters with 0xc4, 0x02dd, and 0x68. Do you know why these are different and what I should use as the hex rep from kitty? Dec 3, 2021 at 16:52
  • Hm, those should be hex characters after all. Did you clipboard convert them wrongly? If I do :let a="\<Cmd>"|put =a and do ga on each resulting char, I receive exactly 0x80 0xfd 0x67 Dec 3, 2021 at 16:57
  • When I ran your command I got what you report. I guess copying to clipboard performs some transformation I don't understand. Regardless, I managed to solve my problem another way (see my comments on @filbranden's answer), thanks for your help. Dec 3, 2021 at 19:30

2 Answers 2


You can find out which key code is used by Vim (or NeoVim) to represent the <Cmd> sequence with:

:echo "\<Cmd>"

From my own experimentation, it seems that this produces <80><fd>g in Vim and <80><fd>h in NeoVim, where the <80> and <fd> are hexadecimal codes representing keys in the upper half of the first 256 key range.

It seems it's possible to use \x sequences to represent keys by their hex code in the Kitty config file, so it's possible that something like the below might work for the NeoVim sequence:

map cmd+left  send_text all \x80\xfdhcall feedkeys("\<D-LEFT>")\r

(Use \x80\fdgcall ... instead for the Vim sequence.)

It's possible, though, that Vim (and NeoVim) will only use that sequence internally and won't really recognize it even if it's produced by the terminal emulator... So while that's your best shot to send <Cmd> to Vim, it's totally possible that it doesn't really work, perhaps even by design...

Since you're trying to use <Cmd> to actually send a few other different key sequences to Vim, why not try to send those sequences directly?

In both Vim on a Mac, or NeoVim on Linux, I see the following:

:echo "\<D-Left>"

So perhaps mapping it directly with the below would work?

map cmd+left  send_text all \x80\xfc\x80\x80kl
map cmd+right send_text all \x80\xfc\x80\x80kr
map cmd+up    send_text all \x80\xfc\x80\x80ku
map cmd+down  send_text all \x80\xfc\x80\x80kd

(You can confirm these key codes and find additional ones for further mappings you have with the :echo "\<...>" trick in Vim.)

  • @SeanMackesey I'd be curious to know whether any of the two approaches works for you, so please leave a comment indicating what worked, I'd be happy to edit the answer to reflect that!
    – filbranden
    Dec 3, 2021 at 18:06
  • 3
    Thanks for these very clear suggestions. Unfortunately I can't get either of them to work. I suspect that, like you point out in your answer, there is some kind of quirky difference in how internal and external incoming bytes are handled. Ultimately I solved the problem with another approach that took some effort but works flawlessly. I decided to treat command key like alt/meta is treated in some contexts, and use it to generate specially prefixed sequences. I used "vertical tab" (0x0b) for the prefix character since I don't think I've ever used it directly... (see next comment) Dec 3, 2021 at 19:21
  • 2
    So on the kitty end, I have a bunch of mappings like map cmd+a send_text all \x0ba, with corresponding mapping in vim imap <CHAR-0x0b>a <D-a>. I generated a bunch of these mappings so that virtually any key chord with command gets translated into a D-chord in vim. So it's basically a pass-through layer, and I could keep all my existing D-mappings in vim undisturbed. Dec 3, 2021 at 19:24
  • 1
    @Sean Yeah that's a nice workaround... If you have some time, please post an answer yourself detailing a bit of what ended up working for you. That might be useful to others with the same issue in the future, and a posted answer is much more visible than a comment... Thanks!
    – filbranden
    Dec 3, 2021 at 19:40

I was able to solve this problem through an imperfect, laborious, but functional solution.

The basic idea is to map command key chords into specially-prefixed byte sequences that the terminal (and neovim) understand. This requires finding a suitable prefixing scheme using some "safe" byte sequence as a prefix/escape indicator. You can then use different counts of this leading character to represent different modifier combinations.

I chose "vertical tab" (0x0b), which is normally generated by C-k, because I never use vertical tabs or otherwise press C-k. I'm not 100% sure this won't subtly break something else, but if there is an issue, it is simple to switch to a different prefix.

For each command chord to pass through, set up a kitty mapping and a corresponding vim mapping:

# kitty.conf

# A unique number of leading `<0x0b>` is used to represent each modifier
# combination that includes command. The mapping is:
# 0x0b (1x): cmd
# 0x0b (2x): alt+cmd
# 0x0b (3x): shift+cmd
# 0x0b (4x): alt+shift+cmd

map cmd+a send_text all \x0ba
map alt+cmd+a send_text all \x0b\x0ba

# init.vim
imap <CHAR-0x0b>a <D-a>
imap <CHAR-0x0b><CHAR-0x0b>a <D-M-a>

Because the vim mapping is recursive, this should seamlessly work with the existing D- mappings in your init.vim.

You can generate as many of these mappings as you need-- if you want to be comprehensive (and include other modifier combinations with command, for D-M- mappings etc), you can quickly pile up a very long list.

  • PS :help CTRL-K takes one to the digraphs section… so this will likely break any use of digraphs.
    – D. Ben Knoble
    Dec 5, 2021 at 16:29
  • 2
    The solution offered by @sean did it for me. I've substituted the vertical tab key code with the Command key 0x37. All codes to Mac keys: Mac Virtual Key Codes (I don't have reputation to upvote or comment on @sean 's answer.) Jan 19, 2022 at 15:57
  • @MateoPanadero so what does your kitting map look like? Nov 22, 2022 at 0:12
  • 1
    @garrettmaring yes. Nov 23, 2022 at 12:33
  • 1
    @garrettmaring I use different numbers of prefix characters for the different modifier combinations-- see above, I edited my answer. I actually don't use cmd+ctrl and I can't remember why-- it might be that cmd+ctrl doesn't work, but cmd+alt definitely does. Dec 4, 2022 at 11:51

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.