16

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?

  • 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 ... – Martin Tournoij Feb 6 '15 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 '15 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 '15 at 15:49
16

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.

  • 1
    No way to do anything like this without a plugin? – SF. Feb 6 '15 at 14:12
  • 3
    @SF See :help shell-window. (Short answer: no.) – muru Feb 6 '15 at 14:24
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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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