22

I know I can :! or :r! to execute external command and optionally insert its output into text. I can even perform :!sh and I'll spawn a shell that will live until I exit it - but while the shell is active, Vim is 'asleep' and inaccessible. I must quit the shell, and spawn a new one if I want to return to Vim for a moment - not very useful.

I can access shell on the opposite end, by suspending Vim with ^Z and manage the Vim job through bg, fg and jobs. This makes more sense but is very cumbersome in the long run. I can use Screen if it's available (it often isn't), or open several windows of my window manager (and ssh to target host from each of them in sequence, to have both vim and shell on the remote host, cumbersome again.)

It would be neatest if Vim allowed me to open a shell session and keep it, say, in one of its (internal) windows, or allow me to switch to it and back. Is something like this possible?

4
  • 1
    So basically, you want to open a shell in a :split, while retaining the file in the other window? ... This sounds like a job for tmux or screen to me ... Feb 6, 2015 at 12:35
  • 1
    @Carpetsmoker: I often don't have control over what is installed on the remote system, and more often than not neither of the two is, while Vim is always there.
    – SF.
    Feb 6, 2015 at 12:36
  • Consider switching to Neovim. It now has a built in terminal emulator which works quite well and can be open in a vim buffer.
    – Zach
    Jul 5, 2015 at 15:49
  • 1
    as suggested here there appears to be now the :terminal command
    – pseyfert
    May 3, 2020 at 11:06

4 Answers 4

17

There are a couple of vim plugins that allow for this. I use Conque (Github).

After putting it in your plugins directory all you have to do is:

:ConqueTermSplit bash

And you will have an interactive bash shell in vim. You can then use your regular vim gestures to do anything else you may want to do in the window.

Also the other plugin is vimshell.

2
  • 1
    No way to do anything like this without a plugin?
    – SF.
    Feb 6, 2015 at 14:12
  • 3
    @SF See :help shell-window. (Short answer: no.)
    – muru
    Feb 6, 2015 at 14:24
9

Just use :vertical terminal and then just map it to a key or something.

Also, I have this in my vimrc: map <Leader>t :set mouse=a<CR>:vertical terminal<CR> That enables me to switch between split windows with my mouse since you wont be able to use :wincmd (h,j,k,l) to switch back and forth split windows cause youre in the terminal.

enter image description here

You can also use set shellcmdflag=-ic to run shell interactively using bashrc. It enabled me to use my bash_aliases.

For my windows gvim, I set the shell to: set shell=Ubuntu. I have wsl enabled. That is why my gvim can use ubuntu shell.

enter image description here

4
  • 1
    Welcome to Vi and Vim!
    – filbranden
    Jan 12, 2021 at 23:57
  • 2
    But you can use <C-w>
    – D. Ben Knoble
    Jan 13, 2021 at 0:16
  • 1
    While I think your answer is good, please use markups and sentences correctly. It is not a chat.
    – peterh
    Jan 13, 2021 at 11:57
  • @D.BenKnoble I use nnoremap <C-h> :wincmd h<CR> since leader key doesnt let you keep it pressed and switch without having to lift your finger Jan 13, 2021 at 19:33
3

With VIM I believe the plugins that are there to do this aren't all that great, though IMO vimshell comes the closest. However you need to understand that it's a 2 part problem.

  1. VIM wasn't designed to be able to do things like this, especially cumbersome is being able to execute any long running task and talking to it asynchronously without blocking VIM. In this case it's not only the shell itself but also other tasks that you might execute within the shell process.
  2. VIM's modal philosophy doesn't play all that well with the way we interact with a shell. In a shell only the current line is editable, although you can scroll and see the older text of your history with shell you can't edit it. This does not fit into the VIM's philosophy at all, if you were to press ESC and go back to normal mode it would becomes quite hard to disallow a user to go back and edit parts of the history above.

In my opinion there are 2 approaches that work much better in this regards.

  1. Using TMUX / Screen and multiplex terminal windows to have both the vim and the shell. That way the two are neatly separated and yet you can view both with very little effort and the two can work to the best of their potential without conflicting with each other's flow.
  2. Using plugins like tpope/vim-dispatch and the likes you can easily launch one off shell commands and have them run asynchronously in the background in an actual terminal shell and pull back the results into vim once it's complete. This also provides you with the same level of isolation between the two and hence the two can again work to the best of their abilities without stepping on each others' toes.

I should add that there is a good likelihood that NeoVIM may bring about a change in this aspect since one of it's core goals is being able to execute jobs asynchronously. But until then this is the best we can get in my opinion.

0
3

In :help shell-window we can read about executing shell commands in a window:

There have been questions for the possibility to execute a shell in a window inside Vim.

The answer: you can't!

Including this would add a lot of code to Vim, which is a good reason not to do this. After all, Vim is an editor, it is not supposed to do non-editing tasks. However, to get something like this, you might try splitting your terminal screen or display window with the "splitvt" program.

An alternative is the "window" command, found on BSD Unix systems, which supports multiple overlapped windows. Or the "screen" program.

However there are few solutions which you can use:

  • use screen which is specially designed for that kind of things, e.g.:

    • Ctrl+a, S to split the current window horizontally
    • Ctrl+a, Tab to switch between windows
    • Ctrl+a, X to remove current region
    • Ctrl+a, Q to remove all regions but one

    See more at: GNU Screen Survival Guide at stackoverflow SE

    Or: GNU Screen Splitting, screen Quick Reference for more details.

  • VIM-Shell - a third-party patch

    The VIM-shell is a extension for VIM which features split windows, and this patch makes it possible to start shells in those windows. It is only available for POSIX systems

  • vterm - Terminal emulator inside vim.

    The goal of vterm is to provide a clone of unix terminal inside vim that works right out of the box without any dependencies.

  • Vimux - easily interact with tmux from vim.

    Inspired by tslime.vim, a plugin that lets you send input to tmux, vimux is to make interacting with tmux from vim effortless.

  • other already mentioned: Conque

Related: How to run a terminal inside of vim? at stackoverflow

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.