▲ 14 r/neovim
Tip: Coderunner in 50 lines
With support for project specific b: runner_prg as well as :vertical, :horizonal and :tab command modifier \:)
-- code_runner.lua
local SIZE = '12'
local M = {}
-- see `:h expand()` and `:h filename-modifiers`
-- I have one variable $root which gets replaced by my `get_root()` function,
-- but for simpler config, you can just use `:h vim.fs.root()`, see at the end
local filetype_defaults = {
python = 'python3 %',
c = 'gcc % -o %:r && ./%:r',
sh = 'bash %',
}
local function exec_terminal(cmd, smods)
cmd = cmd:gsub('%$root', vim.fs.root('.git')) --I use my custom U.get_root() here
local expanded = vim.fn.expand(cmd)
if smods.tab >= 0 then
vim.cmd('tab terminal ' .. expanded)
elseif smods.vertical then
vim.cmd('vertical terminal ' .. expanded)
else
vim.cmd('botright split | resize ' .. SIZE)
vim.cmd('term ' .. expanded)
end
-- vim.cmd 'startinsert'
end
M.run_code = function(opts)
if vim.b.runner_cmd and vim.b.runner_cmd ~= '' then
exec_terminal(vim.b.runner_cmd, opts.smods)
return
end
local cmd = filetype_defaults[vim.bo.filetype]
if cmd then
exec_terminal(cmd, opts.smods)
else
vim.notify('No runner configured for filetype: ' .. vim.bo.filetype, vim.log.levels.WARN)
end
end
vim.api.nvim_create_user_command('RunCode', function(opts)
M.run_code(opts)
end, {})
vim.keymap.set({ 'n', 'i' }, '<D-B>', function()
M.run_code()
end)
return M
You can have custom b:runner_cmd per project like :help makeprg with :h exrc . For example,
--.nvim.lua
vim.b.runner_cmd = "cd $root && uv run main.py"
Or set it dynamically with :let b:runner_cmd="ruff format --check % && uv run %"
u/Beginning-Software80 — 7 days ago