2021-03-10 12:15:06 +00:00
|
|
|
local uv, api = vim.loop, vim.api
|
2022-07-30 13:05:27 +00:00
|
|
|
local util = require('go.utils')
|
|
|
|
local log = require('go.utils').log
|
2021-03-10 12:15:06 +00:00
|
|
|
|
2022-06-28 04:36:30 +00:00
|
|
|
-- run command with loop
|
2021-09-03 02:13:15 +00:00
|
|
|
local run = function(cmd, opts)
|
|
|
|
opts = opts or {}
|
|
|
|
log(cmd)
|
2022-07-30 13:05:27 +00:00
|
|
|
if type(cmd) == 'string' then
|
|
|
|
local split_pattern = '%s+'
|
2021-09-03 02:13:15 +00:00
|
|
|
cmd = vim.split(cmd, split_pattern)
|
|
|
|
log(cmd)
|
|
|
|
end
|
2022-02-02 04:49:54 +00:00
|
|
|
local cmd_str = vim.inspect(cmd)
|
2021-09-03 02:13:15 +00:00
|
|
|
local job_options = vim.deepcopy(opts or {})
|
|
|
|
job_options.args = job_options.args or {}
|
|
|
|
local cmdargs = vim.list_slice(cmd, 2, #cmd) or {}
|
2021-11-13 03:29:42 +00:00
|
|
|
|
2022-07-30 13:05:27 +00:00
|
|
|
if cmdargs and cmdargs[1] == 'test' and #cmdargs == 3 then
|
|
|
|
table.insert(cmdargs, '.' .. util.sep() .. '...')
|
2021-11-13 03:29:42 +00:00
|
|
|
log(cmdargs)
|
|
|
|
end
|
2021-09-03 02:13:15 +00:00
|
|
|
vim.list_extend(cmdargs, job_options.args)
|
|
|
|
job_options.args = cmdargs
|
|
|
|
|
|
|
|
cmd = cmd[1]
|
|
|
|
log(cmd, job_options.args)
|
|
|
|
|
2021-03-10 12:15:06 +00:00
|
|
|
local stdin = uv.new_pipe(false)
|
|
|
|
local stdout = uv.new_pipe(false)
|
|
|
|
local stderr = uv.new_pipe(false)
|
2021-09-03 02:13:15 +00:00
|
|
|
-- local file = api.nvim_buf_get_name(0)
|
|
|
|
local handle = nil
|
2021-03-10 12:15:06 +00:00
|
|
|
|
2022-07-30 13:05:27 +00:00
|
|
|
local output_buf = ''
|
2022-08-06 12:00:49 +00:00
|
|
|
local output_stderr = ''
|
2022-06-28 04:36:30 +00:00
|
|
|
local function update_chunk_fn(err, chunk)
|
2022-06-01 11:29:13 +00:00
|
|
|
if err then
|
2022-07-05 22:28:29 +00:00
|
|
|
vim.schedule(function()
|
2023-02-12 20:55:00 +00:00
|
|
|
vim.notify('error ' .. tostring(err) .. vim.inspect(chunk or ''), vim.log.levels.WARN)
|
2022-07-05 22:28:29 +00:00
|
|
|
end)
|
2022-06-01 11:29:13 +00:00
|
|
|
end
|
2022-10-06 04:16:29 +00:00
|
|
|
|
|
|
|
local lines = {}
|
2021-09-03 02:13:15 +00:00
|
|
|
if chunk then
|
2022-09-30 04:34:30 +00:00
|
|
|
for s in chunk:gmatch('[^\r\n]+') do
|
|
|
|
table.insert(lines, s)
|
|
|
|
end
|
2022-12-14 20:11:08 +00:00
|
|
|
output_buf = output_buf .. '\n' .. table.concat(lines, '\n')
|
2022-09-30 04:34:30 +00:00
|
|
|
log(lines)
|
|
|
|
|
|
|
|
local cfixlines = vim.split(output_buf, '\n', true)
|
|
|
|
local locopts = {
|
|
|
|
title = vim.inspect(cmd),
|
|
|
|
lines = cfixlines,
|
|
|
|
}
|
|
|
|
if opts.efm then
|
|
|
|
locopts.efm = opts.efm
|
|
|
|
end
|
|
|
|
log(locopts)
|
|
|
|
vim.schedule(function()
|
|
|
|
vim.fn.setloclist(0, {}, ' ', locopts)
|
2023-02-12 20:55:00 +00:00
|
|
|
vim.notify('run lopen to see output', vim.log.levels.INFO)
|
2022-09-30 04:34:30 +00:00
|
|
|
end)
|
2021-03-10 12:15:06 +00:00
|
|
|
end
|
2022-10-06 04:16:29 +00:00
|
|
|
return lines
|
|
|
|
end
|
|
|
|
local update_chunk = function(err, chunk)
|
|
|
|
local lines
|
|
|
|
if opts.update_chunk then
|
|
|
|
lines = opts.update_chunk(err, chunk)
|
|
|
|
else
|
|
|
|
lines = update_chunk_fn(err, chunk)
|
|
|
|
end
|
|
|
|
if opts.on_chunk and lines then
|
|
|
|
opts.on_chunk(err, lines)
|
|
|
|
end
|
2021-09-03 02:13:15 +00:00
|
|
|
end
|
2022-07-30 13:05:27 +00:00
|
|
|
log('job:', cmd, job_options)
|
2022-12-13 21:39:09 +00:00
|
|
|
|
|
|
|
local Sprite = util.load_plugin('guihua.lua', 'guihua.sprite')
|
|
|
|
local sprite
|
|
|
|
if Sprite then
|
|
|
|
sprite = Sprite:new({
|
|
|
|
loc = 'top_center',
|
|
|
|
syntax = 'lua',
|
|
|
|
rect = { height = 1, width = 30},
|
|
|
|
data = { 'Running '.. vim.inspect(cmd) },
|
|
|
|
timeout = 30000,
|
|
|
|
hl_line = 1,
|
|
|
|
})
|
|
|
|
else
|
|
|
|
sprite = {on_close = function() end}
|
|
|
|
end
|
2022-06-01 11:29:13 +00:00
|
|
|
handle, _ = uv.spawn(
|
2022-02-02 04:49:54 +00:00
|
|
|
cmd,
|
|
|
|
{ stdio = { stdin, stdout, stderr }, args = job_options.args },
|
2022-09-30 04:34:30 +00:00
|
|
|
function(code, signal) -- on exit()
|
2022-02-02 04:49:54 +00:00
|
|
|
stdin:close()
|
2021-09-03 02:13:15 +00:00
|
|
|
|
2022-02-02 04:49:54 +00:00
|
|
|
stdout:read_stop()
|
|
|
|
stdout:close()
|
2022-06-28 04:36:30 +00:00
|
|
|
|
|
|
|
stderr:read_stop()
|
|
|
|
stderr:close()
|
|
|
|
|
2022-02-02 04:49:54 +00:00
|
|
|
handle:close()
|
2022-12-13 21:39:09 +00:00
|
|
|
log("spawn finished", code, signal)
|
|
|
|
sprite.on_close()
|
2022-08-06 12:00:49 +00:00
|
|
|
|
2022-09-30 04:34:30 +00:00
|
|
|
if output_stderr ~= '' then
|
2022-08-06 12:00:49 +00:00
|
|
|
vim.schedule(function()
|
|
|
|
vim.notify(output_stderr)
|
|
|
|
end)
|
|
|
|
end
|
2022-07-05 22:28:29 +00:00
|
|
|
if opts and opts.on_exit then
|
|
|
|
-- if on_exit hook is on the hook output is what we want to show in loc
|
|
|
|
-- this avoid show samething in both on_exit and loc
|
|
|
|
output_buf = opts.on_exit(code, signal, output_buf)
|
|
|
|
if not output_buf then
|
2022-06-28 14:37:20 +00:00
|
|
|
return
|
2022-06-28 05:35:05 +00:00
|
|
|
end
|
2022-07-05 22:28:29 +00:00
|
|
|
end
|
|
|
|
if code ~= 0 then
|
2022-07-30 13:05:27 +00:00
|
|
|
log('failed to run', code, output_buf)
|
2022-07-05 22:28:29 +00:00
|
|
|
|
2022-07-30 13:05:27 +00:00
|
|
|
output_buf = output_buf or ''
|
2022-10-24 03:57:53 +00:00
|
|
|
vim.schedule( function()
|
2023-02-12 20:55:00 +00:00
|
|
|
vim.notify(cmd_str .. ' failed exit code ' .. tostring(code) .. output_buf, vim.log.levels.WARN)
|
2022-10-24 03:57:53 +00:00
|
|
|
end)
|
|
|
|
|
2022-07-05 22:28:29 +00:00
|
|
|
end
|
2022-07-30 13:05:27 +00:00
|
|
|
if output_buf ~= '' then
|
|
|
|
local lines = vim.split(output_buf, '\n', true)
|
2022-07-05 22:28:29 +00:00
|
|
|
lines = util.handle_job_data(lines)
|
|
|
|
local locopts = {
|
|
|
|
title = vim.inspect(cmd),
|
|
|
|
lines = lines,
|
|
|
|
}
|
|
|
|
if opts.efm then
|
|
|
|
locopts.efm = opts.efm
|
|
|
|
end
|
|
|
|
log(locopts)
|
|
|
|
if #lines > 0 then
|
2022-09-30 04:34:30 +00:00
|
|
|
log(lines)
|
2022-07-05 22:28:29 +00:00
|
|
|
vim.schedule(function()
|
2022-07-30 13:05:27 +00:00
|
|
|
vim.fn.setloclist(0, {}, ' ', locopts)
|
|
|
|
util.quickfix('lopen')
|
2022-07-05 22:28:29 +00:00
|
|
|
end)
|
2022-06-28 05:35:05 +00:00
|
|
|
end
|
2022-02-21 22:46:59 +00:00
|
|
|
end
|
2022-02-02 04:49:54 +00:00
|
|
|
end
|
|
|
|
)
|
2021-09-03 02:13:15 +00:00
|
|
|
|
|
|
|
uv.read_start(stderr, function(err, data)
|
2022-08-06 12:00:49 +00:00
|
|
|
if err then
|
2023-02-12 20:55:00 +00:00
|
|
|
vim.notify('error ' .. tostring(err) .. tostring(data or ''), vim.log.levels.WARN)
|
2022-08-06 12:00:49 +00:00
|
|
|
end
|
2022-07-05 22:58:17 +00:00
|
|
|
if data ~= nil then
|
2022-08-06 12:00:49 +00:00
|
|
|
log(data)
|
|
|
|
output_stderr = output_stderr .. tostring(data)
|
2022-07-05 22:58:17 +00:00
|
|
|
end
|
2021-09-03 02:13:15 +00:00
|
|
|
end)
|
|
|
|
stdout:read_start(update_chunk)
|
2022-08-04 13:30:52 +00:00
|
|
|
return stdin, stdout, stderr
|
2021-09-03 02:13:15 +00:00
|
|
|
end
|
2021-03-10 12:15:06 +00:00
|
|
|
|
2021-09-03 02:13:15 +00:00
|
|
|
local function make(...)
|
2022-07-30 13:05:27 +00:00
|
|
|
local makeprg = vim.api.nvim_buf_get_option(0, 'makeprg')
|
2022-02-02 04:49:54 +00:00
|
|
|
local args = { ... }
|
2021-11-13 03:29:42 +00:00
|
|
|
local setup = {}
|
2021-09-03 02:13:15 +00:00
|
|
|
if #args > 0 then
|
2022-06-01 11:29:13 +00:00
|
|
|
for _, v in ipairs(args) do
|
2021-09-03 02:13:15 +00:00
|
|
|
table.insert(setup, v)
|
2021-03-10 12:15:06 +00:00
|
|
|
end
|
2021-09-03 02:13:15 +00:00
|
|
|
end
|
|
|
|
local opts = {}
|
|
|
|
opts.args = setup
|
|
|
|
run(makeprg, opts)
|
2021-03-10 12:15:06 +00:00
|
|
|
end
|
|
|
|
|
2022-02-02 04:49:54 +00:00
|
|
|
return { run = run, make = make }
|