This plugin allows you to execute files in a terminal window or a separate buffer.
Install using your favorite package manager, or use Vim's built-in package support:
mkdir ~/.vim/pack/plugin/start/vim-executioner
git clone https://github.com/EvanQuan/vim-executioner.git ~/.vim/pack/plugin/start/vim-executioner
- Add
Plug 'EvanQuan/vim-executioner'
to yourvimrc
file. - Reload your
vimrc
or restart. - Run
:PlugInstall
- Add
Plugin 'EvanQuan/vim-executioner'
to yourvimrc
file. - Reload your
vimrc
or restart. - Run
:BundleInstall
- Add
NeoBundle 'EvanQuan/vim-executioner'
to yourvimrc
file. - Reload your
vimrc
or restart. - Run
:NeoUpdate
git clone https://github.com/EvanQuan/vim-executioner.git ~/.vim/bundle/vim-executioner
This plugin comes with 5 commands:
Each command takes the name of a file as an optional argument, optionally followed by any command-line arguments. Without any arguments, the current buffer that is executing the command will be ran with no arguments.
The file will be executed in a shell, where any output will be printed there. For example:
:Executioner
will attempt to execute the current buffer with no command-line arguments.
:Executioner test.py
will attempt to execute test.py
in the current working directory with no
command-line arguments.
:Executioner test.py foo bar 4
will attempt to execute test.py
in the current working directory, with the
command-line arguments foo
, bar
and 4
.
If Vim has terminal
window support, then the file will be executed in
a horizontally-split terminal window. Once the program execution is completed,
the output will be saved in a 'readonly' buffer.
Otherwise, the file will be executed in a shell and its output will be saved in a horizontally-split 'readonly' buffer. The difference is that without |terminal| support, no input from the user can be made during the program's runtime.
Same as :ExecutionerHorizontal
with no |terminal| window support, forcing
a shell to execute the file and save the output in a horizontally-split
'readonly' buffer.
If Vim has terminal
window support, then the file will be executed in
a vertically-split terminal window. Once the program execution is completed,
the output will be saved in a 'readonly' buffer.
Otherwise, the file will be executed in a shell and its output will be saved
in a vertically-split 'readonly' buffer. The difference is that without
terminal
support, no input from the user can be made during the program's
runtime.
Same as :ExecutionerVertical
with no terminal
window support, forcing
a shell to execute the file and save the output in a vertically-split
'readonly' buffer.
There are advantages and disadvantages to using either the terminal or buffer for split window execution. Perhaps some day in the future this distinction will no longer exist and there will be a unified solution.
Terminal | Buffer | |
---|---|---|
Pros | - Accepts standard input from user - Prints standard output during program execution |
- Can execute multiple commands directly - Accepts standard input and output redirection |
Cons | - Cannot execute multiple commands directly - Does not accept standard input and output redirection |
- Does not accept standard input from user - Prints standard output after program execution is complete |
If you running a version of Vim that has terminal window support, (i.e. :echo has("terminal")
returns 1
), then the horizontal and vertical commands open
an interactive terminal window which updates live as the program is being
executed. This allows for user input from standard input, and displaying of
standard output as it is being printed.
Without the terminal feature available, the horizontal and vertical commands run the program until completion, and store the standard output of the executed program in a read-only buffer. Due to this reason, it will not work for programs that require user input and will not update the standard output over the course of the program execution.
Certain file types that involve multiple commands to be executed, such as
compiling before executing, do not work with terminal windows. This is because
terminal windows treat every space-separated term after the first argument as
command-line arguments, including ones that end with ;
.
Any terminal window command that involves multiple commands will fall back to the buffer equivalent if multiple commands are found.
For the same reason as multiple commands, terminal windows treat every
space-separated term after the first argument as a command-line argument,
including >
, <
, and |
characters.
Any terminal window command that involves input redirection will fall back to the buffer equivalent if input redirection operators are found.
If any executing command defined in g:executioner#extensions
or
g:executioner#names
starts with ':', a Vim command will be executed instead
of a shell, terminal window, or buffer. For example, if the following is
defined in your vimrc
:
let g:executioner#extensions['md'] = ':InstantMarkdownPreview'
let g:executioner#extensions['markdown'] = ':InstantMarkdownPreview'
then running any markdown files with any of the executioner commands will
execute the Vim command :InstantMarkdownPreview
.
By default, Executioner does not provide any key mappings as to not override
mappings defined in your vimrc
. You can map these commands to however you
like to make them easier to use.
For example, I personally use:
" Run current buffer
"
nnoremap <silent> <leader>rf :Executioner<Return>
nnoremap <silent> <leader>hrf :ExecutionerHorizontal<Return>
nnoremap <silent> <leader>vrf :ExecutionerVertical<Return>
" Run current buffer with input redirected from input.txt
"
nnoremap <silent> <leader>ri :ExecutionerBuffer % < input.txt<Return>
nnoremap <silent> <leader>hri :ExecutionerHorizontalBuffer % < input.txt<Return>
nnoremap <silent> <leader>vri :ExecutionerVerticalBuffer % < input.txt<Return>
" run.sh
"
nnoremap <silent> <leader>rr :Executioner run.sh<Return>
nnoremap <silent> <leader>hrr :ExecutionerHorizontal run.sh<Return>
nnoremap <silent> <leader>vrr :ExecutionerVertical run.sh<Return>
" Makefile
"
nnoremap <silent> <leader>rm :Executioner makefile<Return>
nnoremap <silent> <leader>hrm :ExecutionerHorizontal makefile<Return>
nnoremap <silent> <leader>vrm :ExecutionerVertical makefile<Return>
Due to the complexity of many projects that span a large number of files,
I use makefiles and run.sh
to compile and run code without needing to worry
about what file I'm currently editing.
You may want to refer to the full file name or base name in in your commands.
The full file name, which is the base name with file extension, can be
referred to by g:executioner#full_name
, while the base name can be referred
to by g:executioner#base_name
, both which you can set in your vimrc
. By
default they are defined as:
let g:executioner#full_name = '%'
let g:executioner#base_name = '@'
For example, if you want to run a C file by compiling it first, you can define
its command as 'c' : 'gcc % -o @.out; ./@.out'
in g:executioner#commands
,
which will compile a .out
file with the same base name as the source file,
and then execute it.
There are 2 dictionaries that define what types of files can be executed:
g:executioner#extensions
determines commands by file extension. For example,
if you want to execute files with the py
extension, such as
hello_world.py
, with the python
command, (i.e. executing python hello_world.py
in the terminal), then include:
let g:executioner#extensions['py'] = 'python %'
in your vimrc
.
g:executioner#names
determines commands by file name. For example, if you
want to execute files with the name makefile
with the command make
, then
include:
let g:executioner#names['makefile'] = 'make'
in your vimrc
.
Executioner will prioritize names over extensions when determining what command to use. For example, if
let g:executioner#extensions['py'] = 'python3 %'
dictates that py
files are to be executed with python3
and
let g:executioner#names['foo.py'] = 'python2 foo.py'
dictates that foo.py
is to be executed with python2
, then foo.py
will be
executed with python2
.
Luckily, many of these commands are already defined so you don't need to do so yourself. These are the defaults:
Extension | Command |
---|---|
c | gcc % -o @.out;./@.out |
cpp | g++ % -o @.out;./@.out |
hs | ghci % |
java | javac %;java @ |
js | node % |
m | matlab |
ml | ocaml % -o @.out;./@.out |
ps1 | powershell ./% |
php | php % |
pl | perl % |
prolog | swipl % |
py | python % |
py2 | python2 % |
R | Rscript % |
r | Rscript % |
rb | ruby % |
rc | rustc % -o @.out;./@.out |
sh | bash % |
swift | swiftc % -o @.out;./@.out |
Name | Command |
---|---|
makefile | make |
As expected, if any of these extensions or file names are defined in your
vimrc
, they will take precedence over the defaults.
If you wish to disable these defaults entirely, include:
let g:executioner#load_defaults = 0
in your vimrc
and they will not be defined.
Here are some things I have done to customize executioner in my own Vim configuration:
Depending on the machine I'm on, the python
command either runs Python 2 or
Python 3. Also, I sometimes have Anaconda
installed, which I will want to use if possible. As a result, I customize what
version of Python runs depending on some other settings I have:
let g:executioner#extensions = {}
if g:settings#python3_execution == 0
let g:executioner#extensions['py'] = 'python %'
elseif filereadable(expand('/anaconda3/bin/python'))
let g:executioner#extensions['py'] = '/anaconda3/bin/python %'
else
let g:executioner#extensions['py'] = 'python3 %'
endif
With the help of vim-instant-markdown, I can preview github-flavored markdown files. Since the preview command is ran in Vim itself and not in a shell, I can prepend the command with ":" to signify I want to run a Vim command:
let g:executioner#extensions['markdown'] = ':InstantMarkdownPreview'
let g:executioner#extensions['md'] = ':InstantMarkdownPreview'
Similarly, with vimtex, I can compile and preview LaTeX files with:
let g:executioner#extensions['tex'] = ':VimtexCompile'