I have Neovim installed on Windows. I use WSL for running Python and C code. So I'd like to map a key to get Neovim to run a shell command in WSL directly from the Neovim editor. But I seem to be running into an issue I haven't been able to fix on my own. When I run :!python3 %, this is the output I get:

enter image description here

I did try to solve this by myself, here's more information.

I added the following two lines to my init.lua.

vim.cmd('set shellcmdflag="-c"')

If I input the :term command, a new WSL instance opens in the editor, in the same directory - just as expected. I know that the shebang is okay because from this newly opened terminal window both python3 code.py and ./code.py execute just as expected. The problem seems to be exclusively with the exclamation mark command.

Could I have some help with this? The end goal is a way to link Neovim key mappings to terminal commands, if there is some other (better?) way to do it.

  • It seems that bash is try to execute the program named python3 code.py, which means the arguments it got from :! weren’t handled right somewhere. Can you share the values of the various shell and redirect options?
    – D. Ben Knoble
    Commented Oct 29, 2023 at 21:36
  • I haven't added any shell and redirect options besides the ones I've mentioned. Are you looking for anything specific? If these are env variables, what commands can I run to show you what you need to see? Another anomaly I noticed - with the exclamation mark method, it seems like /bin/bash is being used. But with the :term method (which has no issues at all), running which bash tells me that /usr/bin/bash is being used. Is this a red herring or might it be related to the issue?
    – vvenk
    Commented Oct 30, 2023 at 5:50
  • I also fail to start commands with arguments on Neovim with WSL as a shell. Commented Oct 30, 2023 at 9:39
  • I found a workaround. I have updated the solution accordingly ;-) Commented Oct 30, 2023 at 9:53

1 Answer 1


With gVim I would do:

set shell=wsl.exe
set shellcmdflag=
set shellquote=
set shellxquote=

With Neovim I suspect there is a weakness in the way arguments are passed to the spawned process.

The workaround I have found is:

Create a wsl.bat file in your path:

wsl.exe %*
set shell=cmd\ /c\ wsl.bat
set shellcmdflag=
set shellquote=
set shellxquote=
  • You guys are absolute legends!! It worked. Quick question, could you break down the set shell= line? I gather the cmd bit at the beginning of the arguments tells Nvim to invoke cmd first, then call a bat file which inserts a wsl.exe before the commands, instructing cmd to invoke those commands with WSL...right? What does the /c do?
    – vvenk
    Commented Oct 30, 2023 at 21:14
  • I didn't had the time to dig into the code of Neovim and I should take the time to fill a big report but it seems that Neovim pass all the arguments as one argument a bit like if it was 'python3 yourscript.py' instead of python3 yourscript.py and wsl get confused. Maybe your trick could work. Worth trying :-) The /c make the cmd standard shell execute the command and return. Commented Oct 30, 2023 at 21:22
  • Thanks for the feedback :-) Commented Oct 30, 2023 at 21:23

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.