How can I open a Shell inside a Vim Window?

VimShellWindow

Vim Problem Overview


I can open a shell by using the :shell command in Vim, however I can't edit a file and at the same time use the shell.

Is there any way to split Vim in many Windows (or tabs), and have a shell opened in one of them?

Vim Solutions


Solution 1 - Vim

Neovim and Vim 8.2 support this natively via the :ter[minal] command.

See terminal-window in the docs for details.

Solution 2 - Vim

Well it depends on your OS - actually I did not test it on MS Windows - but Conque is one of the best plugins out there.

Actually, it can be better, but works.

Solution 3 - Vim

:vsp or :sp - splits vim into two instance but you cannot use :shell in only one of them.

Why not display another tab of the terminal not another tab of vim. If you like the idea you can try it: Ctrl-shift-t. and move between them with Ctrl - pageup and Ctrl - pagedown

If you want just a few shell commands you can make any shell command in vim using !

For example :!./a.out.

Solution 4 - Vim

You can use tmux or screen (second is able to do only horizontal splits without a patch) to split your terminal. But I do not know the way to have one instance of Vim in both panes.

Solution 5 - Vim

If you haven't found out yet, you can use the amazing screen plugin.

Conque is also exceptional but I find screen much more practical (it wont "litter" your buffer for example and you can just send the commands that you really want after editing them in your buffer)

Solution 6 - Vim

I guess this is a fairly old question, but now in 2017. We have neovim, which is a fork of vim which adds terminal support.

So invoking :term would open a terminal window. The beauty of this solution as opposed to using tmux (a terminal multiplexer) is that you'll have the same window bindings as your vim setup. neovim is compatible with vim, so you can basically copy and paste your .vimrc and it will just work.

More advantages are you can switch to normal mode on the opened terminal and you can do basic copy and editing. It is also pretty useful for git commits too I guess, since everything in your buffer you can use in auto-complete.

I'll update this answer since vim is also planning to release terminal support, probably in vim 8.1. You can follow the progress here: https://groups.google.com/forum/#!topic/vim_dev/Q9gUWGCeTXM

Once it's released, I do believe this is a more superior setup than using tmux.

Solution 7 - Vim

Shougo's VimShell, which can auto-complete file names if used with neocomplcache

Solution 8 - Vim

Not absolutely what you are asking for, but you may be interested by my plugin vim-notebook which allows the user to keep a background process alive and to make it evaluate part of the current document (and to write the output in the document). It is intended to be used on notebook-style documents containing pieces of code to be evaluated.

Solution 9 - Vim

You may want to open a "screen" program, split screen, open shell on one and vim on another. Works for me.

Solution 10 - Vim

I am currently using tmux.

Installation: sudo apt-get install tmux Run it: tmux

Ctrl + b followed by Ctr + % : it splits your terminal window in two vertical halves.

Ctrl + "arrow left | arrow right" : moves between terminals.

Solution 11 - Vim

With Vim 8.0 or later you can run a terminal emulator in a vim window by using the terminal feature. BTW if you want to simulate modern IDE terminal (like VSCode integrated terminal) in gVim or MacVim, you can put the following configuration in you vimrc.

set shell=/path/to/shell

" Make sure to replace `sh.exe` in BufNr("sh.exe") with your shell executable.
nnoremap <expr> <space> BufNr("sh.exe") > 0 ? (&buftype == 'terminal' ? '<c-^>' : ':b '. BufNr("sh.exe") . '<cr>') : ':terminal ++curwin<cr>'

function! BufNr(pattern)
  let bufcount = bufnr("$")
  let currbufnr = 1
  let nummatches = 0
  let firstmatchingbufnr = 0
  while currbufnr <= bufcount
    if(bufexists(currbufnr))
      let currbufname = bufname(currbufnr)
      if(match(currbufname, a:pattern) > -1)
        let nummatches += 1
        let firstmatchingbufnr = currbufnr
      endif
    endif
    let currbufnr = currbufnr + 1
  endwhile
  return firstmatchingbufnr
endf

Now you can use space in normal mode (or whatever mapping you chosen) to:

  1. Open a terminal in current window if terminal doesn't exists yet.
  2. Switch to terminal buffer if current buffer is not a terminal type.
  3. Switch to previous buffer if current buffer is a terminal buffer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMart&#237;n FixmanView Question on Stackoverflow
Solution 1 - VimpraterView Answer on Stackoverflow
Solution 2 - VimZsolt BotykaiView Answer on Stackoverflow
Solution 3 - VimvladvView Answer on Stackoverflow
Solution 4 - VimZyXView Answer on Stackoverflow
Solution 5 - VimEelvexView Answer on Stackoverflow
Solution 6 - VimchrizView Answer on Stackoverflow
Solution 7 - VimkurozView Answer on Stackoverflow
Solution 8 - VimThomas BaruchelView Answer on Stackoverflow
Solution 9 - Vimuser3509535View Answer on Stackoverflow
Solution 10 - VimArturo Ruiz MañasView Answer on Stackoverflow
Solution 11 - VimmapktsView Answer on Stackoverflow