If you are a Vim user and are using a shell outside Vim such as bash or zsh, you’ve been wasting your time(*1). Install [VimShell](https://github.com/shougo/vimshell) and use it for everything. It works particularly well on your local computer.
There are three steps to using VimShell effectively. At first you will feel that VimShell isn’t as handy as shells outside Vim, but later you will not be able to remember the era without VimShell.
## 1. Bare VimShell as Shell and Interactive commands
Install VimShell and its depencency [vimproc](https://github.com/shougo/vimproc). You can place these files under `&runtimepath` manually, but personally I recommend you to use plugin managers such as [neobundle.vim](https://github.com/shougo/neobundle.vim).
[cc lang=”vim”]
NeoBundle ‘shougo/vimproc’
NeoBundle ‘shougo/vimshell’
[/cc]
You have to build C files in vimproc if you install it manually. If you use neobundle.vim, it takes care of compiling, so you don’t have to manually run make.
After installing vimproc and vimshell, read vimshell’s docs quickly by `:h vimshell`, and try it.
You may feel the shell is weird and different compared to other shells at first.
This screencast is with the following config. The colorscheme is [neverland](https://github.com/trapd00r/neverland-vim-theme)
[cc lang=”vim”]
let g:vimshell_user_prompt = ‘fnamemodify(getcwd(), “:~”)’
let g:vimshell_prompt = ‘$ ‘
[/cc]
## 2. VimShell with neocomplcache and unite
I’m pretty sure that most Vim programmers are using or at least have heard of
[neocomplcache](https://github.com/shougo/neocomplcache), a Vim plugin for
auto-completion. I don’t talk a lot about `neocomplcache` itself in this article,
but if you haven’t tried `neocomplcache` yet, you should consider installing it, particularly for vimshell.
`neocomplcache` and vimshell work well together without any vimshell specific
configuration; just install neocomplcache and set it up properly to enable its
vimshell integration. Since `neocomplcache` is not just a completion plugin but
an auto-complete plugin, it by nature shows completion candidates such as
commands and filenames with no need to use TAB.
[unite.vim](https://github.com/shougo/unite.vim) is also a vital Vim plugin
that provides an interface for anything. I may write another article about
`unite.vim` in the future, but here in short I will just say that it is an alternative
implementation to select an item from candidates.
VimShell supports `unite` by default for searching history like bash’s “. Type “ in Insert mode in a VimShell buffer to open the `unite` interface of VimShell’s command history, choose a candidate, and type “ to execute it.
You can just insert the selected candidates with TAB as well.
## 3. Integrate VimShell with anything you use
VimShell is not only a shell alternative but also provides an environment for interactive programs, such as `irb` or REPLs in general. You can make a new buffer for something with `iexe {command}` in a VimShell buffer. Note that you can still use `neocomplcache` and `unite` functionality in the buffer.
VimShell has the following commands for control of VimShell buffers (both shell and interactive environments) from outside VimShell.
* `:VimShellSendBuffer {bufname}` to specify the destination VimShell buffer
* `:VimShellSendString {string}` to send {string}
* `:[range]VimShellSendString` to send strings that you chose
The details are in the vimshell docs. Read `:h vimshell` from beginning to end.
The strongest aspect of VimShell is that it’s easily controllable since it’s
written in Vim script to run on Vim. You can use the above commands or other
functions to control VimShell easily, or if it’s necessary, you can extend
VimShell not only with C but also the friendly Vim script language.
Below is an example for Scala with SBT. Scala’s compiler and runtime system are
really slow to start, so Scala programmers commonly run an interactive
SBT console and keep using it, instead of making lots of new Scala processes
every time.
[cc lang=”vim”]
command! -nargs=0 StartSBT execute ‘VimShellInteractive sbt’ | let t:sbt_bufname = bufname(‘%’)
function! s:sbt_run()
let cmds = get(t:, ‘sbt_cmds’, ‘run’)
let sbt_bufname = get(t:, ‘sbt_bufname’)
if sbt_bufname !=# ”
call vimshell#interactive#set_send_buffer(sbt_bufname)
call vimshell#interactive#send(cmds)
else
echoerr ‘try StartSBT’
endif
endfunction
function! s:vimrc_scala()
nnoremap m :write:call sbt_run()
endfunction
augroup vimrc_scala
autocmd!
autocmd FileType scala call s:vimrc_scala()
autocmd FileType scala nnoremap st :StartSBT
augroup END
[/cc]
The above Vim script code is in my [vimrc](https://github.com/ujihisa/config/blob/master/_vimrc). Feel free to use it.
## The future of VimShell itself
VimShell doesn’t work well with ssh. There are some plugins like
[vimshell-ssh](https://github.com/ujihisa/vimshell-ssh) or
[unite-ssh](https://github.com/Shougo/unite-ssh) to integrate more features
that work remotely from your local Vim process, but they aren’t mature enough
yet. It’s a known issue that we are working on.
## Notes
* No VimShell, No Life.
* 50% of programmers on my team are using Vim with VimShell.
* The animated gifs above were created with MacVim. I simply took many
screenshots with Cmd-Shift-3, cropped, converted each to a gif, and converted to
a single gif file using `convert` from ImageMagick.
* (*1) or you’ve been saving your time; living without using some awesome Vim
plugins doesn’t make you tempted to write lots of code in Vim script.
Hey,
This is really awesome, I’ve been looking for something like this for a while, thanks! One question.. how can I get
sbt ~compile
(continuous compilation) to work? I added the script above to my .vimrc file and typed in StartSBT and it gave me an “Exec format error”I also tried to just type in “VimShellInteractive sbt ~compile” (and “VimShellInteractive sbt”) and that gave me the same error, but “VimShellInteract scala” works.
Thoughts?
Thanks!
LikeLike
@adelbertc note that ~compile keeps watching every 500msec (configurable), so it consumes machine power and you still waste 500msec, whereas with using the technique described above, you can do exactly same thing with no such disadvantages 😉
LikeLike
@ujm Hm I think what is more interesting to me is if I’m looking at the gif properly, you are able to call sbt commands like “compile” while still remaining “in focus” on the source code window?
Either way I am interested, though I am not familiar with VimScript (yet). Once I copy that VimScript into my vimrc, what do I do to pass commands into SBT without explicitly switching window focus and typing in commands myself?
LikeLike
@adelbertc vimshell#interactive#send() function does the job that sending a string to the vimshell buffer specified in advance, so I didn’t have to switch Vim bufferes manually.
Once you copy the vimrc lines and installed the dependency plugins, your Vim will do the job just by typing <Space>m on a scala file after you open the sbt buffer by :StartSBT command. To change the key to fire it, just change the following line
nnoremap <buffer> <Space>m :<C-u>write<Cr>:call <SID>sbt_run()<Cr>
LikeLike
@ujm Awesome!
LikeLike
Hi thanks for reading my post.
I tried
:VimShellInteractive sbt ~compile
and it simply worked. I’m using the latest version of vimshell (git a57abc23) and vimproc (84f85eca) on GVim 7.3.762 on Gentoo Linux. Which version of plugins/vim did you use?LikeLike
@ujm I am using the latest version (or whatever version is on GitHub) as well, with Vim 7.2. I figured out what’s wrong, I needed to add “#!/bin/bash” to the top of my SBT bash script and everything works fine. Everything is awesome now, thanks!
LikeLike
@adelbertc @ujm Awesome!
LikeLike
Hi thanks for the nice post..i wanted to execute commands in vim shell with key mappings..eg. if i type <leader>bi it should open VimShellPop and execute bundle install and close once it get completed..is it possible using vimshell….
LikeLike