A wrapper around vim 8's new term_start to make it friendlier and easier to use.
Vim 8 added asynchronous terminal support via term_start
, and it's really neat. Except it's a pain to use. I basically have to do :h term_start
every time I think I might want to use it. But it seems like it wasn't really intended to be used directly, since there's no command for it. You have to invoke it with :call term_start
. I could've made a simple command like :Term cmd { args }
but that's annoying to type every time, so instead, this plugin exposes the determined#command
function, which you should call in your vim config setup (e.g. in vimrc). This function will create commands for you that wrap specific invocations of :call term_start
to make it easy to use. For example, here are the current commands I'm creating in my setup via determined#command
:
" Example:
" :Npm install some-module
call determined#command('Npm', 'npm', { 'vertical': 0, 'rows': '5', 'cols': '40%' })
" Example:
" :Repl
" start an interactive node repl
call determined#command('Repl', 'node', { 'autoclose': 0, 'background': 0 })
" Example:
" :Node -e "[1, 2, 3].map((i) => i * i)"
call determined#command('Node', 'node', { 'vertical': 0, 'rows': '10', 'cols': '40%' })
" Example:
" :Rg blah ./test
call determined#command('Rg', 'rg', { 'background': 0, 'autoclose': 0 })
" Example:
" :Grunt spec:unit
call determined#command('Grunt', 'grunt', { 'autoclose': 0, 'reuse': 1 })
vim-determined
makes it easy to interact with any command line tool directly from node. I'd suggest git
as an obvious candidate except it still wouldn't be as good as vim-fugitive.
This plugin requires vim at or above version 8 compiled with +terminal
(check :echo has('terminal')
).
If you don't have a preferred installation method, I really like vim-plug and recommend it.
Clone this repository and copy the files in plugin/, autoload/, and doc/ to their respective directories in your vimfiles, or copy the text from the github repository into new files in those directories. Make sure to run :helptags
.
Add the following to your vimrc, or something sourced therein:
Plug 'tandrewnichols/vim-determined'
Then install via :PlugInstall
Add the following to your vimrc, or something sourced therein:
Plugin 'tandrewnichols/vim-determined'
Then install via :BundleInstall
NeoBundle (https://github.com/Shougo/neobundle.vim)
Add the following to your vimrc, or something sourced therein:
NeoBundle 'tandrewnichols/vim-determined'
Then install via :BundleInstall
Pathogen (https://github.com/tpope/vim-pathogen)
git clone https://github.com/tandrewnichols/vim-determined.git ~/.vim/bundle/vim-determined
To create term_start
wrappers at vim startup, call the following function:
This creates a command that wraps some command line tool in a call to term_start
. Invoke as follows:
call determined#command(name, cmd, args)
Type: string
The name of the vim command to create. This argument will be capitalized if it is not already because vim requires that custom commands be capitalized.
Type: string
The static part of the command to run when the vim command is invoked. Usually this is the base binary name only, but it could be more if you run very specific things very often. For example:
call determined#command('TermGrep', 'grep -r')
Type: dict
The following options are supported:
vertical
: Whether the terminal window should split vertically or not. Default1
(because I use it this way far more often, even though the default for term_start is not vertical). Regardless of the value passed here, you can invert this behavior by calling the created command with!
. So in theTermGrep
example above, by default,:TermGrep foo
would open in a vertical split, but:TermGrep! foo
would open in a horizontal one.background
: Whether focus should be returned to your current window. Default1
. The nice thing aboutterm_start
is that it is async, so it doesn't interrupt what you're doing in vim. The not so nice thing is that it focuses you on the new terminal window instead of keeping you where you're already working. This flag just runswincmd p
at the end to return you to where you were previously working.autoclose
: This param sets'term_finish': 'close'
in the options passed toterm_start
. Default0
. This is useful if you need to install something or run some other kind of build command of which you don't need to see the final output.reuse
: If the same command has been run previously, reuse the existing window instead of creating a new one. Default0
. Useful for running tests or other recurring commands.singleton
: Likereuse
but for the top level command. If you created:TermGrep
with thesingleton
flag, all greps, regardless of other parameters, will happen in the same window. Default0
.expand
: Treat%
(and#
,<cfile>
, etc.) specially and callexpand()
on it. Default0
.filename-modifiers
work here as well, so something like:TermGrep foo %:h:h
would work as expected.size
: The size of the terminal window. By default,term_start
will use half the vertical or horizontal space, andvim-determined
keeps this default. You can pass a number (or string number) to specify the number of rows or columns, depending on the vertical flag (i.e. this becomesterm_rows
orterm_cols
). But you can also pass a percentage as a string (e.g. '40%') andvim-determined
will figure out the number of rows or columns to use. You can also pass the special flags'small'
(or'sm'
or'quarter'
) to make it 25%,'medium'
(or'med'
or'half'
) to make it 50% (but instead you should probably just let it use the default), or'large'
(or'lg'
) to make it 75%. Finally, there is a special valueauto
which will look at the window height and width ratios to determine for you whether a vertical or horizontal split would be more efficient. Passingauto
is incompatible with passingrows
andcols
(see below). It will also cause!
to be ignored. The one exception to this parameter is that ifcurwin
is set, this option is ignored, as it will use the space of the current window regardless.rows
/cols
: Thesize
parameter is not very granular, since you might want different sizes based on the window orientation. In that case, you can pass the same kinds of identifiers forrows
and/orcols
as you can forsize
(except for'auto'
which would not make sense).complete
: Add custom completion. This maps basically one to one to the-complete
option of commands, so pass it exactly as you would there.tabnew
: Always runcmd
in a new tab. Default0
.curwin
: Always runcmd
in the current window. Default0
.term_args
: Finally, a catch all. This should be a dict, and anything you pass here will be added to theterm_start
options viaextend()
. Have a look at:h term_start
for the various options supported.
Once the command is created, you can call it with additional string parameters to pass to term_start
. For example, if you created a command like this:
call determined#command('Npm', 'npm')
You can invoke it in any of the following ways:
:Npm install foo
:Npm uninstall foo
:Npm test
:Npm run custom-script
:Npm ls
:Npm install -D grunt grunt-contrib-copy grunt-contrib-uglify grunt-contrib-concat
- etc. etc.
For completeness, determined#command
also creates E
and T
versions for opening the command in a new tab or in the current window (even though you can configure this per command via args. So in the case above, the following commands are also created:
:ENpm
- Run the npm command in the current window.:TNpm
- Run the npm command in a new tabpage.
vim-determined
does include a few built in commands.
:TermClose[!]
- Close all open term windows (where the job is not currently running). When<bang>
is included, stop running jobs and close those terms too.:Term[!]
- A generic wrapper for callterm_start
with commands that you haven't created viadetermined#command
. For instance, I don't usefind
very often, so I'm not creating a command for it withdetermined#command
, but if I need to use it in vim, I can run:Term find . -name somefile.ext
. This uses the default arguments toterm_start
, which means it will open in a horizontal split. Use<bang>
to open it in a vertical split.:ETerm
- Like:Term
, but in the current window.:TTerm
- Like:Term
, but in a new tabpage.:VTerm
- Like:Term
, but in a vertical split . . . so this is identical to:Term!
but is included for completeness.:STerm
- Synonymous with:Term
but included for completeness.
Within a terminal window opened by vim-determined
, <C-r>
is mapped to rerun the original command. Hopefully, the symmetry is obvious. <C-r>
is for "redo," but terminals are not modifiable, so I'm repurposing that keybinding to have specialized meaning.
I always try to be open to suggestions, but I do still have opinions about what this should and should not be so . . . it never hurts to ask before investing a lot of time on a patch.
See LICENSE