Neoterm error when default shell is changed to pwsh/powershell
I am uncertain as to if this could be related to #246 but it was the only issue I saw within the same vein. Thanks in advanced for any information! 🎉
Describe the bug
Upfront, it's important to know: I'm running Windows 10.
Following the help documentation :h shell-powershell. I changed the default shell for Neovim to pwsh/powershell.
This allows me to use PowerShell aliases in command mode such as !ls or !mv % ~/Desktop and have a fairly consistent command structure to bash. While commands in cmd.exe are slightly diffrent: !dir and !move % ~/Desktop <- doesn't seem to work.
Unfortunately, regardless of if I use powershell or pwsh as the new default, and regardless of how I set my g:neoterm_shell.
This breaks Neoterm, resulting in an error when running :Tnew or :T ls.
To Reproduce Steps to reproduce the behavior:
- Be on Windows 10
- Change default shell to powershell
:h shell-powershell - Create new Neoterm
:Tnew||:T ls - See error
Expected behavior Neoterm should still function under these conditions. But cannot handle this modification.
Screenshots/gifs
Windows PowerShell: I struggled to copy the text before the term window closed
powershell.exe

PowerShell Core: The error output is slightly different from powershell.exe
pwsh.exe
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man…
::neoterm-1: The term '::neoterm-1' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Versions Information:
-
Vim or Neovim
- [ ] Vim
- [x] Neovim
-
Version: NVIM v0.5.0
-
OS: Windows 10 21H1 Build: 19043.1237
-
Neoterm commit master/e78179a9ceb98de8d0c37bdda435a5deab4d5e71 Installed/Updated via vim-plug, so I assume it's the newest commit.
-
All configurations related to neoterm - See Below
nvim/plugin/neoterm.vim
" File: neoterm.vim
" Desc: Configs for neoterm plugin
" --- Initialization ---
" Prevent this file from loading without plugin
if empty('g:neoterm_loaded') | finish | endif
" Windows - Powershell
if has("win32")
" Use pwsh if available, else use windows PowerShell
let g:neoterm_shell = executable('pwsh') ? 'pwsh' : 'powershell'
let g:neoterm_eof = "\r"
else " Use whatever shell you prefer, default to bash
let g:neoterm_shell = executable('zsh') ? 'zsh' : 'bash'
endif
" Neoterm Options
let g:neoterm_default_mod = "botright"
let g:neoterm_size = 25
let g:neoterm_autoscroll = 1
let g:neoterm_keep_term_open = 1
let g:neoterm_autoinsert = 1
let g:neoterm_fixedsize = 1
" Mappings
" Escape terminal buffer via <ESC>
" tnoremap <silent> <Esc> <C-\><C-n>
" Spawn/Toggle Terminal
noremap <silent> <leader>` :Ttoggle<CR>
tnoremap <silent> <leader>` <C-\><C-n>:Ttoggle<CR>
noremap <silent> <F12> :Ttoggle<CR>
tnoremap <silent> <F12> <C-\><C-n>:Ttoggle<CR>
" Allow Ctrl+W to switch window in terminal
tnoremap <silent> <C-w> <C-\><C-n><C-w>
" Press enter for insert mode in terminal
" nnoremap <Enter> :if &buftype = 'terminal' | startinsert | endif
" Automatic insert mode on terminal buf/win enter
" Prevent terminal buffer for holding <Esc> hostage
" Provides compatibility with fzf terminal window
augroup TerminalBuffers
autocmd!
if has("nvim")
" Hide terminal from buffer list
autocmd TermOpen,TermEnter * setlocal nobuflisted
" Auto enter insert mode for terminal buffers
" autocmd BufWinEnter,WinEnter term://* startinsert
autocmd BufEnter term://* startinsert
autocmd BufLeave term://* stopinsert
" Allow escape from terminal and fzfterm
autocmd TermOpen * tnoremap <buffer> <Esc> <c-\><c-n>
autocmd FileType fzf tunmap <buffer> <Esc>
endif
augroup END
Additional context For clarity sake: I have a preference for PowerShell Core and have slightly modified the shell replacement command. However, I do not believe this is important to the issue seeing as: both result the same errors already presented.
Original: Windows PowerShell
Provided by :h shell-powershell
let &shell = has('win32') ? 'powershell' : 'pwsh'
Modified: PowerShell Core
Wrapped within an if has('win32') for safety
let &shell = executable('pwsh') ? 'pwsh' : 'powershell'
I tried, and it works for me (windows 10, nvim 6.0) . I didn't know neoterm_shell var... nice.
function! TermOV(use_file_dir)
let t=&shell
let g:neoterm_shell = executable('pwsh') ? 'pwsh' : 'powershell'
set shell=cmd.exe
set splitright
let k=g:neoterm.last_id+1
vertical Tnew "~/"
"exe k."T . /etc/bashrc"
"exe k."T . ~/.bash_profile"
if a:use_file_dir
exe k."T cd " . expand('%:p:h')
"else
"exe k."T hookvim"
endif
"exe k."T set -o emacs"
"if g:on_ek_computer
"exe k."T bind '\"\\C-r\": \"\\C-ahstr -- \\C-j\"'"
"endif
exe k."Tclear"
set shell=t
endfunction
It is important that shell would be cmd.exe
Just stumbeled upon a similar error using MSYS bash instead of cmd. Found out, that neoterm uses an heuristic to find the opened terminal. Essentially it goes like this:
- When you open a terminal in neovim, the buffer is named according to the shell and the command you have provided while opening the terminal.
- neoterm uses a comment instead of a command and therefore, you can, e.g. do
:b neoterm-3to jump to the third terminal
Now to the actual error you are getting: on Windows, this marker is set to &::neoterm which I believe is a comment string in cmd.exe. You will have to change it to a proper PowerShell comment string with
let g:neoterm_marker = ';#neoterm'
And just as a reference, this is my working config to use MSYS bash with neoterm on windows:
if vim.loop.os_uname().sysname == "Windows_NT" then
vim.o.shell=vim.env.HOME:gsub('\\', '/') .. [[/AppData/Local/Programs/msys64/usr/bin/bash.exe]]
vim.o.shellpipe="| tee"
vim.o.shellslash=true
vim.o.shellredir=">"
vim.o.shellquote=""
vim.o.shellxquote=""
vim.o.shellcmdflag="-c"
vim.g.neoterm_marker=";#neoterm"
end