Neovim plugin for one-click code execution
This plugin makes running code in your current buffer lightning fast and incredibly simple. Many popular languages like C, Java, Python, Go, JS, Perl, Shell, Lua, R, Rmarkdown, etc. are supported.
| Command | Default key mapping | Description |
|---|---|---|
:RunBuf |
<F4> |
Run the code |
:RunBufArgs |
<F16> (SHIFT+<F4> or <S-F4>) |
Run the code with arguments |
Using lazy.nvim
{
'rltyty/runit.nvim',
config = function()
require("runit").setup()
end
},- Default options
-- Default options
M.opts = {
key = true, -- false: disable key mapping
run_key = "<F4>",
run_args_key = "<F16>", -- run with args input. <F-16> instead of <S-F4>
src_prefix = "src",
test_prefix = "src",
}- Disable key mapping,
require("runit").setup({
key = false,
})- Change key mapping,
require("runit").setup({
run_key = "<F2>",
run_args_key = "<F14>",
})- Project specific settings
Create a .nvim.lua (See h: exrc) under the project root directory.
require("runit").setup({
run_key = "<F2>",
src_prefix = "source"
test_prefix = "test"
})- Maven POM support: auto-resolves and caches classpath for running Java classes
Runit runs programs in Neovim's command mode, and sometimes you may find
that the output order is "unexpected". For example,
Suppose you run a C program like this — you expect the date output to come
after the welcome message, but it doesn't.
...
printf("Main process says hi\n");
system("date");
// do some other stuff
...- Running in Neovim
:!./Debug/test/a.out
Fri Aug 15 14:33:00 CST 2025
Main process says hi- Running in a terminal,
> ./Debug/test/a.out
Main process says hi
Fri Aug 15 14:42:55 CST 2025Reason for the Discrepancy: When executed in Neovim, the process's
stdout stream is connected to a pipe, not a terminal (TTY). The C standard
library chooses the buffer mode of the stream based on the file type. TTY ->
line-buffered, otherwise -> fully-buffered. Therefore, in Neovim, the output
is fully-buffered, whereas in a terminal it is line-buffered.
In the program above, although the printf(3) message ends with \n — which
normally triggers fflush(3) in line-buffered mode (i.e. when running in a
terminal), which in turn calls the underlying write(2) syscall — in Neovim,
stdout is fully-buffered, so \n has no special effect. fflush(3) will
not be called until the buffer is full, or unless called explicitly. Calling
exit(3) also flushes and closes all streams at program termination.
Meanwhile, system(3) spawns (fork(2) + exec(3) -> exeve(2)) a child
process to run the date command. The child inherits, during fork(2), a
copy of its parent's open file descriptors, including STDOUT_FILENO, which
still points to the same file table entry and further the same pipe. The child
also inherits the parent's file streams and their buffers (copy-on-write), so
the child's stdout buffer also contains "Main process says hi". However,
when execve(2) loads the date program, the child gets a fresh process
image — user space memory is wiped, giving it fresh file streams and empty
buffers. After date is done, it calls exit(3)s, which fflush(3)es and
close(2)s all its file streams, so we can see the date output right away.
As long as the parent finishes after the child — system(3) guarantees this
via waitpid(2) after the spawn — the output order will appear "unexpected".
In reality, it is exactly what buffering rules dictate. It's also the case when
you redirect the output to a file.
> ./Debug/test/a.out > log
> cat log
Sat Aug 16 12:16:05 CST 2025
Main process says hiIf you do need the "expected" order, either run the program in a terminal or change the code:
- Option 1 : Flush the C library buffer explicitly before
system(3)
printf("Main process says hi\n");
fflush(stdout);
system("date");- Option 2: Disable the C library buffer for
stdout
Must be called before any I/O on stdout, typically at the start of main().
setvbuf(stdout, NULL, _IONBF, 0);