1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
--[[ Runner engine: run the current buffer's file with a per-filetype command.
Features register a shell command per filetype; the engine runs the current buffer's file with the
registered command and reports the result. Commands are registered in plugin/50-runner.lua.
API:
register(filetype, cmd) — `cmd` is a command list; `%` in any argument expands to the current file
path. Call once per filetype.
run() — run the current buffer with its filetype's command.
]]
local M = {}
-- Registered run commands, keyed by filetype.
M.runners = {}
-- Expand `%` in each argument of `cmd` to `file`, returning a new command list.
local function _expand(cmd, file)
local out = {}
for i, arg in ipairs(cmd) do
out[i] = arg:gsub("%%", file)
end
return out
end
--- Register the run command `cmd` for `filetype`.
---@param filetype string
---@param cmd string[]
function M.register(filetype, cmd)
assert(type(filetype) == "string", "runner.register: filetype must be a string")
assert(type(cmd) == "table", "runner.register: cmd must be a command list")
M.runners[filetype] = cmd
end
--- Run the current buffer's file, notifying on a missing command or a non-zero exit.
---@return nil
function M.run()
local ft = vim.bo.filetype
local cmd = M.runners[ft]
if cmd == nil then
vim.notify("No runner registered for " .. ft, vim.log.levels.ERROR)
return
end
local file = vim.api.nvim_buf_get_name(0)
-- Spawn the command and wait for it. See <nvim-help://vim.system%28%29>.
local r = vim.system(_expand(cmd, file), { text = true }):wait()
if r.code ~= 0 then
vim.notify(r.stderr, vim.log.levels.WARN)
return
end
vim.notify(r.stdout)
end
return M
|