I am currently new to neovim.

Something that has me a bit stuck is being able to easily run my code. The text editor I used before trying out vim was Sublime Text 3, and, in that text editor, all I had to do was press Cmd-B. It would use a build system that either came with the text editor or one that I made myself.

I haven't found a way to do this within vim. The closest I have gotten to doing something similar to this is by adding this to my init.vim command PYrun :!python3 %, but this only works with python. It is no where near as good as the build systems in Sublime.

Is there some way that neovim can read the file's extension (eg., .py, .asm, .cs) and use a preconfigured build system to run the code?

Default Python Build System:

"cmd": ["/usr/local/bin/python3", "-u", "$file"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"quiet": true

My Customized Assembly Build System:

"shell": true,
"cmd": ["nasm -f macho64 ${file} && ld -macosx_version_min 10.12 -lSystem -o ${file_base_name} ${file_base_name}.o && ./${file_base_name}"],
"file_regex": "^(.+):([0-9]+)()?: error: (.*)$",
"working_dir": "${file_path}",
"selector": "source.assembly"

4 Answers 4


There are, in fact, some predefined build scripts, and it is relatively straightforward to create your own. These are known as compiler plugins or scripts, and live in the compiler directory of runtimepath.

You can switch to a compiler with the :compiler command, or by setting makeprg and errorformat (which is what most of these scripts do).

You then build by typing :make {arguments}. One benefit of this strategy is that build output goes to the quickfix list, which can navigate between lines with errors if the errorformat is set correctly.

You can automatically pick a compiler per language by adding the compiler or setlocal makeprg/setlocal errorformat commands to ~/.vim/after/ftplugin files (add language name, substitute correct vim configuration directory).

For more, see the help topics on those commands and options.

Note that this system is not intended to run interactive programs; for that, using :terminal is probably best.


Yes, there is a way to build the file based on its file types. No, there is no predefined build script to build a script, you need to write it yourself, or look it up on the internet.

Use autocmd

One way is to use autocmd to define a shortcut to run the build command for your current file:

autocmd FileType cpp nnoremap <F9> :!g++ -Wall -Wextra -std=c++11 -O2 expand('%:p:~') expand('%:p:~:r')

Use filetype detection

A better way is to use the builtin file type detection mechanism and create a file name cpp.vim in directory $HOME/.config/nvim/after/ftplugin/ and put the following code inside it:

nnoremap <silent> <buffer> <F9> :call <SID>compile_run_cpp()<CR>

function! s:compile_run_cpp() abort
  let src_path = expand('%:p:~')
  let src_noext = expand('%:p:~:r')
  " The building flags
  let _flag = '-Wall -Wextra -std=c++11 -O2'

  if executable('clang++')
    let prog = 'clang++'
  elseif executable('g++')
    let prog = 'g++'
    echoerr 'No C++ compiler found on the system!'
  call s:create_term_buf('h', 20)
  execute printf('term %s %s %s -o %s && %s', prog, _flag, src_path, src_noext, src_noext)

function s:create_term_buf(_type, size) abort
  set splitbelow
  set splitright
  if a:_type ==# 'v'
  execute 'resize ' . a:size

You can press <F9> to compile and run your cpp program in both cases. You can customize the build process to exactly the way you want with vim script. The possibilities are endless.


After doing a bit research, I found a plugin called "quickrun.vim*" and this plugin (from what I understand) runs a series of commands based on the extension of the current file you are working on. You can use the default "build-systems" that the plugin comes with, however, you create your own build systems by specifying what commands need to be run when ever you use QuickRun on a specific file type. Down below are my current settings and build systems for quickrun.vim.

My C++ Build System:

let g:quickrun_known_file_types = {
    \"cpp": ["!g++ % -o $(basename % .cpp) && eval ./$(basename % .cpp)"],

My Assembly Build System in my init.vim:

let g:quickrun_known_file_types = {
    \"asm": ["!nasm -f macho64 % && ld -macosx_version_min 10.12 -lSystem -o $(basename % .asm) $(echo $(basename % .asm).o) && eval ./$(basename % .asm)"]

My Current Quickrun Settings:

let g:quickrun_known_file_types = {
    \"cpp": ["!g++ % -o $(basename % .cpp) && eval ./$(basename % .cpp)"],
    \"c": ["!gcc % -o $(basename % .c)"],
    \"vim": ["source %"],
    \"py": ["!python3 %"],
    \"asm": ["!nasm -f macho64 % && ld -macosx_version_min 10.12 -lSystem -o $(basename % .asm) $(echo $(basename % .asm).o) && eval ./$(basename % .asm)"]

nnoremap <space>b :QuickRun<CR>

Once you have the plugin installed and you have your quickrun.vim settings in your .vimrc/init.vim, you can just execute "QuickRun" in command mode and the plugin will then do the rest of the work for you.

  • 1
    Any chance you could elaborate on what advantages this technique has over Vim’s built-in systems (described in @D.BenKnoble’s answer)?
    – Rich
    Jun 7, 2021 at 11:05

vim.cmd('call nvim_create_user_command(\'Render\', \'! R -e \"rmarkdown::render(\\"realpath %\\")\" && FILE=\"realpath %\" && tmux neww zathura ${FILE/rmd/pdf} && tmux last-window \', {})')

I use a smal command for my rmd files which I knit with R (rmarkdown).

After the document is knited the pdf file pops up in a new window with zathura (running in a new tmux tab)

Go step by step trough the command. Maybe you can get some inspiration for your work.

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.