CLI Apps Not Correctly Receiving Ctrl+Space


New member
Local time
4:36 PM
Windows 11 Pro
I use Windows for development and I noticed that Ctrl+Space isn't being passed correctly to Neovim within my terminal (Windows Terminal 1.19.10821.0).

I have mingw installed, which includes cat, so I used cat -v to see if the ^@ character is being passed into applications, or just being ignored entirely. It seems like it's somewhere in the middle: I don't see the ^@ character immediately when I type it into cat -v, but I do see it echoed back to me after hitting Enter. This problem isn't isolated to Windows Terminal, though; it also happens in Alacritty. In both terminal emulators, this issue stops when I use WSL; WSL immediately receives ^@ and echoes it back to me, both as I type it into cat -v and again after hitting Enter.

To make it even more confusing, Neovim Qt receives Ctrl+Space just fine, just like WSL does. This tells me it isn't a problem with my Neovim config and it isn't a problem with Windows Terminal or Alacritty, but it's likely a problem with some API that they're both using and Neovim Qt isn't. I just have no clue where to go from here, so if anyone can help, I'd really appreciate it!

Edit: I tried out this sample app in Go (Fix Control+Space not sent to program running in terminal by lonnywong · Pull Request #16298 · microsoft/terminal) and it seems to receive the character just fine. I'm thinking maybe this is an issue specific to Neovim's Windows binary, but even more specifically, how the nvim.exe binary receives that particular character.

P.S. Here are the versions and configs:

Alacritty (0.13.2 (bb8ea18)):
bindings = [
  { key = "Space", mods = "Control", chars = "\u0000" }

Neovim (NVIM v0.9.5; Build type: RelWithDebInfo; LuaJIT 2.1.1703942320):
local cmp = require("cmp")
local cmp_select = { behavior = cmp.SelectBehavior.Select }
local lsp = vim.lsp
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },
    { name = 'nvim_lua' },
    { name = 'luasnip', keyword_length = 2 },
    { name = 'nvim_lsp_signature_help' },
  snippet = {
    expand = function(args)
  mapping = cmp.mapping.preset.insert({
    ["<C-p>"] = cmp.mapping.select_prev_item(cmp_select),
    ["<C-n>"] = cmp.mapping.select_next_item(cmp_select),
    ["<C-y>"] = cmp.mapping.confirm({ select = true }),
    ["<Tab>"] = cmp.mapping.confirm({ select = true }),
    ["<CR>"] = cmp.mapping.confirm({ select = true }),
    ["<C-Space>"] = cmp.mapping.complete(),
    ["<C-@>"] = cmp.mapping.complete(),
    -- Everything else in this config works, I double-checked.
    -- All of this code works perfectly when used in Linux (or Neovim Qt).

(Sorry for the lack of syntax highlighting, there were no options for toml or lua)
Windows Build/Version
Version 22H2 (OS Build 22621.3447)
Last edited:

My Computer

System One

  • OS
    Windows 11 Pro
    Computer type
I believe I found the issue; it's apparently a problem with the Windows build of libuv. There's a pull request that mentions this issue and proposes a fix, but it's several years old by now and has likely been forgotten about.

Unfortunately, I'm not experienced enough to compile C++ projects myself, but if anyone out there is and wants a better-working Neovim in Windows, it shouldn't be too hard. The idea is, you can either build Neovim with Cygwin to get the "Linux" version of libuv or you can build the version of libuv for Windows made in the aforementioned pull request and somehow use that for a Windows build of Neovim instead of the official libuv build. Ideally, if there's someone out there who has the time/skill to make a good fix for this, we would all benefit immensely if you propose a new PR for the official libuv repo! If you do, thank you very much in advance!
Last edited:

My Computer

System One

  • OS
    Windows 11 Pro
    Computer type
Top Bottom