mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-23 07:20:04 +08:00
feat(runner): rewrite code runner in lua
This commit is contained in:
parent
69cddda857
commit
8b55955de4
26
.SpaceVim.d/types/vim.fn.lua
Normal file
26
.SpaceVim.d/types/vim.fn.lua
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
-- Return an item that represents a time value. The item is a
|
||||||
|
-- list with items that depend on the system.
|
||||||
|
-- The item can be passed to `reltimestr()` to convert it to a
|
||||||
|
-- string or `reltimefloat()` to convert to a Float.
|
||||||
|
--
|
||||||
|
-- Without an argument it returns the current "relative time", an
|
||||||
|
-- implementation-defined value meaningful only when used as an
|
||||||
|
-- argument to `reltime()`, `reltimestr()` and `reltimefloat()`.
|
||||||
|
--
|
||||||
|
-- With one argument it returns the time passed since the time
|
||||||
|
-- specified in the argument.
|
||||||
|
-- With two arguments it returns the time passed between {start}
|
||||||
|
-- and {end}.
|
||||||
|
--
|
||||||
|
-- The {start} and {end} arguments must be values returned by
|
||||||
|
-- reltime(). Returns zero on error.
|
||||||
|
--
|
||||||
|
-- Can also be used as a `method`:
|
||||||
|
-- ```vim
|
||||||
|
-- GetStart()->reltime()
|
||||||
|
-- ```
|
||||||
|
-- Note: `localtime()` returns the current (non-relative) time.
|
||||||
|
--- @param start? any[]
|
||||||
|
--- @param end_? any[]
|
||||||
|
--- @return any[]
|
||||||
|
function vim.fn.reltime(start, end_) end
|
@ -36,6 +36,62 @@
|
|||||||
" }
|
" }
|
||||||
" <
|
" <
|
||||||
|
|
||||||
|
|
||||||
|
if has('nvim-0.9.0') && $USE_LUA_CODE_RUNEER == 1
|
||||||
|
function! SpaceVim#plugins#runner#get(ft) abort
|
||||||
|
return luaeval('require("spacevim.plugin.runner").get(require("spacevim").eval("a:ft"))')
|
||||||
|
endfunction
|
||||||
|
function! SpaceVim#plugins#runner#open(...) abort
|
||||||
|
lua require("spacevim.plugin.runner").open(
|
||||||
|
\ unpack(require("spacevim").eval("a:000"))
|
||||||
|
\ )
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#reg_runner(ft, runner) abort
|
||||||
|
lua require("spacevim.plugin.runner").reg_runner(
|
||||||
|
\ require("spacevim").eval("a:ft"),
|
||||||
|
\ require("spacevim").eval("a:runner")
|
||||||
|
\ )
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#status() abort
|
||||||
|
return luaeval('require("spacevim.plugin.runner").status()')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#close() abort
|
||||||
|
|
||||||
|
lua require("spacevim.plugin.runner").close()
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#select_file() abort
|
||||||
|
lua require("spacevim.plugin.runner").select_file()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#select_language() abort
|
||||||
|
lua require("spacevim.plugin.runner").select_language()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#set_language(lang) abort
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#run_task(task) abort
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SpaceVim#plugins#runner#clear_tasks() abort
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let s:runners = {}
|
let s:runners = {}
|
||||||
|
|
||||||
let s:JOB = SpaceVim#api#import('job')
|
let s:JOB = SpaceVim#api#import('job')
|
||||||
@ -74,7 +130,8 @@ let s:task_stderr = {}
|
|||||||
let s:task_problem_matcher = {}
|
let s:task_problem_matcher = {}
|
||||||
|
|
||||||
function! s:open_win() abort
|
function! s:open_win() abort
|
||||||
if s:code_runner_bufnr !=# 0 && bufexists(s:code_runner_bufnr) && index(tabpagebuflist(), s:code_runner_bufnr) !=# -1
|
if s:code_runner_bufnr !=# 0 && bufexists(s:code_runner_bufnr)
|
||||||
|
\ && index(tabpagebuflist(), s:code_runner_bufnr) !=# -1
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
botright split __runner__
|
botright split __runner__
|
||||||
@ -281,15 +338,13 @@ function! SpaceVim#plugins#runner#open(...) abort
|
|||||||
\ 'has_errors' : 0,
|
\ 'has_errors' : 0,
|
||||||
\ 'exit_code' : 0
|
\ 'exit_code' : 0
|
||||||
\ }
|
\ }
|
||||||
let s:selected_language = &filetype
|
let selected_language = &filetype
|
||||||
let runner = get(a:000, 0, get(s:runners, s:selected_language, ''))
|
let runner = get(a:000, 0, get(s:runners, selected_language, ''))
|
||||||
let opts = get(a:000, 1, {})
|
let opts = get(a:000, 1, {})
|
||||||
if !empty(runner)
|
if !empty(runner)
|
||||||
call s:open_win()
|
call s:open_win()
|
||||||
call s:async_run(runner, opts)
|
call s:async_run(runner, opts)
|
||||||
call s:update_statusline()
|
call s:update_statusline()
|
||||||
else
|
|
||||||
let s:selected_language = get(s:, 'selected_language', '')
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
snippet func
|
snippet func
|
||||||
abbr function name(args)...end
|
abbr function name(args)...end
|
||||||
options word
|
options word
|
||||||
function ${1:#:function_name}(${2:#:argument}) -- {{{
|
function ${1:#:function_name}(${2:#:argument})
|
||||||
${0:TARGET}
|
${0:TARGET}
|
||||||
end
|
end
|
||||||
-- }}}
|
|
||||||
|
|
||||||
snippet if
|
snippet if
|
||||||
options head
|
options head
|
||||||
|
516
lua/spacevim/plugin/runner.lua
Normal file
516
lua/spacevim/plugin/runner.lua
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
--=============================================================================
|
||||||
|
-- M.lua
|
||||||
|
-- Copyright (c) 2016-2022 Wang Shidong & Contributors
|
||||||
|
-- Author: Wang Shidong < wsdjeg@outlook.com >
|
||||||
|
-- URL: https://spacevim.org
|
||||||
|
-- License: GPLv3
|
||||||
|
--=============================================================================
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local runners = {}
|
||||||
|
|
||||||
|
local logger = require('spacevim.logger').derive('runner')
|
||||||
|
local job = require('spacevim.api').import('job')
|
||||||
|
local file = require('spacevim.api').import('file')
|
||||||
|
local str = require('spacevim.api').import('data.string')
|
||||||
|
|
||||||
|
local code_runner_bufnr = 0
|
||||||
|
|
||||||
|
local winid = -1
|
||||||
|
|
||||||
|
local target = ''
|
||||||
|
|
||||||
|
local runner_lines = 0
|
||||||
|
|
||||||
|
local runner_jobid = 0
|
||||||
|
|
||||||
|
local runner_status = {
|
||||||
|
is_running = false,
|
||||||
|
has_errors = false,
|
||||||
|
exit_code = 0,
|
||||||
|
exit_single = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
local selected_file = ''
|
||||||
|
--- @type any[]
|
||||||
|
local start_time
|
||||||
|
--- @type any[]
|
||||||
|
local end_time
|
||||||
|
|
||||||
|
local task_status = {}
|
||||||
|
|
||||||
|
local task_stdout = {}
|
||||||
|
|
||||||
|
local task_stderr = {}
|
||||||
|
|
||||||
|
local task_problem_matcher = {}
|
||||||
|
|
||||||
|
local selected_language = ''
|
||||||
|
|
||||||
|
local function stop_runner()
|
||||||
|
if runner_status.is_running then
|
||||||
|
logger.debug('stop runner:' .. runner_jobid)
|
||||||
|
job.stop(runner_jobid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function close_win()
|
||||||
|
stop_runner()
|
||||||
|
if code_runner_bufnr ~= 0 and vim.api.nvim_buf_is_valid(code_runner_bufnr) then
|
||||||
|
vim.cmd('bd ' .. code_runner_bufnr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function insert()
|
||||||
|
vim.fn.inputsave()
|
||||||
|
local input = vim.fn.input('input >')
|
||||||
|
if vim.fn.empty(input) == 0 and runner_status.is_running then
|
||||||
|
job.send(runner_jobid, input)
|
||||||
|
end
|
||||||
|
vim.cmd('normal! :')
|
||||||
|
vim.fn.inputrestore()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function open_win()
|
||||||
|
if
|
||||||
|
code_runner_bufnr ~= 0
|
||||||
|
and vim.api.nvim_buf_is_valid(code_runner_bufnr)
|
||||||
|
and vim.fn.index(vim.fn.tabpagebuflist(), code_runner_bufnr) ~= -1
|
||||||
|
then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
logger.debug('open code runner windows')
|
||||||
|
local previous_wind = vim.api.nvim_get_current_win()
|
||||||
|
vim.cmd('botright split __runner__')
|
||||||
|
code_runner_bufnr = vim.fn.bufnr('%')
|
||||||
|
local lines = vim.o.lines * 30 / 100
|
||||||
|
vim.cmd('resize ' .. lines)
|
||||||
|
vim.cmd([[
|
||||||
|
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nospell nonu norelativenumber winfixheight nomodifiable
|
||||||
|
set filetype=SpaceVimRunner
|
||||||
|
]])
|
||||||
|
vim.api.nvim_buf_set_keymap(code_runner_bufnr, 'n', 'q', '', {
|
||||||
|
callback = close_win,
|
||||||
|
})
|
||||||
|
vim.api.nvim_buf_set_keymap(code_runner_bufnr, 'n', 'i', '', {
|
||||||
|
callback = insert,
|
||||||
|
})
|
||||||
|
vim.api.nvim_buf_set_keymap(code_runner_bufnr, 'n', '<C-c>', '', {
|
||||||
|
callback = stop_runner,
|
||||||
|
})
|
||||||
|
local id = vim.api.nvim_create_augroup('spacevim_runner', {
|
||||||
|
clear = true,
|
||||||
|
})
|
||||||
|
vim.api.nvim_create_autocmd({ 'BufWipeout' }, {
|
||||||
|
group = id,
|
||||||
|
buffer = code_runner_bufnr,
|
||||||
|
callback = stop_runner,
|
||||||
|
})
|
||||||
|
winid = vim.api.nvim_get_current_win()
|
||||||
|
if vim.g.spacevim_code_runner_focus == 0 then
|
||||||
|
vim.api.nvim_set_current_win(previous_wind)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function extend(t1, t2)
|
||||||
|
for k, v in pairs(t2) do
|
||||||
|
t1[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function update_statusline()
|
||||||
|
vim.cmd('redrawstatus!')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function on_stdout(id, data, event)
|
||||||
|
if id ~= runner_jobid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if vim.api.nvim_buf_is_valid(code_runner_bufnr) then
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(code_runner_bufnr, runner_lines, runner_lines + 1, false, data)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
runner_lines = runner_lines + #data
|
||||||
|
if winid >= 0 then
|
||||||
|
vim.api.nvim_win_set_cursor(winid, { vim.api.nvim_buf_line_count(code_runner_bufnr), 1 })
|
||||||
|
end
|
||||||
|
update_statusline()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function on_stderr(id, data, event)
|
||||||
|
if id ~= runner_jobid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
runner_status.has_errors = true
|
||||||
|
if vim.api.nvim_buf_is_valid(code_runner_bufnr) then
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(code_runner_bufnr, runner_lines, runner_lines + 1, false, data)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
runner_lines = runner_lines + #data
|
||||||
|
if winid >= 0 then
|
||||||
|
vim.api.nvim_win_set_cursor(winid, { vim.api.nvim_buf_line_count(code_runner_bufnr), 1 })
|
||||||
|
end
|
||||||
|
update_statusline()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function on_exit(id, code, single)
|
||||||
|
if id ~= runner_jobid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end_time = vim.fn.reltime(start_time)
|
||||||
|
runner_status.is_running = false
|
||||||
|
runner_status.exit_single = single
|
||||||
|
runner_status.exit_code = code
|
||||||
|
local done = {
|
||||||
|
'',
|
||||||
|
'[Done] exited with code=' .. code .. ', single=' .. single .. ' in ' .. str.trim(
|
||||||
|
vim.fn.reltimestr(end_time)
|
||||||
|
) .. ' seconds',
|
||||||
|
}
|
||||||
|
if vim.api.nvim_buf_is_valid(code_runner_bufnr) then
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(code_runner_bufnr, runner_lines, runner_lines + 1, false, done)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
if winid >= 0 then
|
||||||
|
vim.api.nvim_win_set_cursor(winid, { vim.api.nvim_buf_line_count(code_runner_bufnr), 1 })
|
||||||
|
end
|
||||||
|
update_statusline()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function merge_list(...)
|
||||||
|
local t = {}
|
||||||
|
|
||||||
|
for _, tb in ipairs({ ... }) do
|
||||||
|
for _, v in ipairs(tb) do
|
||||||
|
table.insert(t, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function on_compile_exit(id, code, single)
|
||||||
|
if id ~= runner_jobid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if code == 0 and single == 0 then
|
||||||
|
runner_jobid = job.start(target, {
|
||||||
|
on_stdout = on_stdout,
|
||||||
|
on_stderr = on_stderr,
|
||||||
|
on_exit = on_exit,
|
||||||
|
})
|
||||||
|
if runner_jobid > 0 then
|
||||||
|
runner_status = {
|
||||||
|
is_running = true,
|
||||||
|
has_errors = false,
|
||||||
|
exit_code = 0,
|
||||||
|
exit_single = 0,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
end_time = vim.fn.reltime(start_time)
|
||||||
|
runner_status.is_running = false
|
||||||
|
runner_status.exit_code = code
|
||||||
|
runner_status.exit_single = single
|
||||||
|
local done = {
|
||||||
|
'',
|
||||||
|
'[Done] exited with code=' .. code .. ', single=' .. single .. ' in ' .. str.trim(
|
||||||
|
vim.fn.reltimestr(end_time)
|
||||||
|
) .. ' seconds',
|
||||||
|
}
|
||||||
|
if vim.api.nvim_buf_is_valid(code_runner_bufnr) then
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(code_runner_bufnr, runner_lines, runner_lines + 1, false, done)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
if winid >= 0 then
|
||||||
|
vim.api.nvim_win_set_cursor(winid, { vim.api.nvim_buf_line_count(code_runner_bufnr), 1 })
|
||||||
|
end
|
||||||
|
update_statusline()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function async_run(runner, ...)
|
||||||
|
if type(runner) == 'string' then
|
||||||
|
local cmd = runner
|
||||||
|
pcall(function()
|
||||||
|
local f
|
||||||
|
if selected_file ~= '' then
|
||||||
|
f = selected_file
|
||||||
|
else
|
||||||
|
f = vim.fn.bufname('%')
|
||||||
|
end
|
||||||
|
cmd = vim.fn.printf(runner, f)
|
||||||
|
end)
|
||||||
|
logger.info(' cmd:' .. cmd)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(
|
||||||
|
code_runner_bufnr,
|
||||||
|
runner_lines,
|
||||||
|
-1,
|
||||||
|
false,
|
||||||
|
{ '[Running] ' .. cmd, '', vim.fn['repeat']('-', 20) }
|
||||||
|
)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
runner_lines = runner_lines + 3
|
||||||
|
start_time = vim.fn.reltime()
|
||||||
|
local opts = select(1, ...) or {}
|
||||||
|
extend(opts, {
|
||||||
|
on_stdout = on_stdout,
|
||||||
|
on_stderr = on_stderr,
|
||||||
|
on_exit = on_exit,
|
||||||
|
})
|
||||||
|
runner_jobid = job.start(cmd, opts)
|
||||||
|
elseif type(runner) == 'table' and #runner == 2 then
|
||||||
|
target = file.unify_path(vim.fn.tempname(), ':p')
|
||||||
|
local dir = vim.fn.fnamemodify(target, ':h')
|
||||||
|
if vim.fn.isdirectory(dir) == 0 then
|
||||||
|
vim.fn.mkdir(dir, 'p')
|
||||||
|
end
|
||||||
|
local compile_cmd
|
||||||
|
local usestdin
|
||||||
|
local compile_cmd_info
|
||||||
|
if type(runner[1]) == 'table' then
|
||||||
|
local exe
|
||||||
|
if type(runner[1].exe) == 'function' then
|
||||||
|
exe = runner[1].exe()
|
||||||
|
elseif type(runner[1].exe) == 'string' then
|
||||||
|
exe = { runner[1].exe }
|
||||||
|
end
|
||||||
|
usestdin = runner[1].usestdin or false
|
||||||
|
compile_cmd = merge_list(exe, { runner[1].targetopt or '' }, { target }, runner[1].opt)
|
||||||
|
if not usestdin then
|
||||||
|
local f
|
||||||
|
if selected_file == '' then
|
||||||
|
f = vim.fn.bufname('%')
|
||||||
|
else
|
||||||
|
f = selected_file
|
||||||
|
end
|
||||||
|
compile_cmd = merge_list(compile_cmd, { f })
|
||||||
|
end
|
||||||
|
elseif type(runner[1]) == 'string' then
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(compile_cmd) == 'table' then
|
||||||
|
if usestdin then
|
||||||
|
compile_cmd_info = vim.inspect(merge_list(compile_cmd, { 'STDIN' }))
|
||||||
|
else
|
||||||
|
compile_cmd_info = vim.inspect(compile_cmd)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if usestdin then
|
||||||
|
compile_cmd_info = compile_cmd .. ' STDIN'
|
||||||
|
else
|
||||||
|
compile_cmd_info = compile_cmd
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(
|
||||||
|
code_runner_bufnr,
|
||||||
|
runner_lines,
|
||||||
|
-1,
|
||||||
|
false,
|
||||||
|
{ '[Compile] ' .. compile_cmd_info, '[Running] ' .. target, '', vim.fn['repeat']('-', 20) }
|
||||||
|
)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
|
||||||
|
runner_lines = runner_lines + 4
|
||||||
|
start_time = vim.fn.reltime()
|
||||||
|
if
|
||||||
|
type(compile_cmd) == 'string'
|
||||||
|
or type(compile_cmd) == 'table' and vim.fn.executable(compile_cmd[1] or '') == 1
|
||||||
|
then
|
||||||
|
runner_jobid = job.start(compile_cmd, {
|
||||||
|
on_stdout = on_stdout,
|
||||||
|
on_stderr = on_stderr,
|
||||||
|
on_exit = on_compile_exit,
|
||||||
|
})
|
||||||
|
if usestdin and runner_jobid > 0 then
|
||||||
|
local range = runner[1].range or { 1, '$' }
|
||||||
|
job.send(runner_jobid, vim.fn.getline(unpack(range)))
|
||||||
|
job.chanclose(runner_jobid, 'stdin')
|
||||||
|
job.stop(runner_jobid)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local exe = compile_cmd[1] or ''
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(
|
||||||
|
code_runner_bufnr,
|
||||||
|
runner_lines,
|
||||||
|
-1,
|
||||||
|
false,
|
||||||
|
{ exe .. ' is not executable, make sure ' .. exe .. ' is in your PATH' }
|
||||||
|
)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
end
|
||||||
|
elseif type(runner) == 'table' then
|
||||||
|
local cmd = {}
|
||||||
|
if type(runner.exe) == 'function' then
|
||||||
|
cmd = merge_list(cmd, runner.exe())
|
||||||
|
elseif type(runner.exe) == 'string' then
|
||||||
|
cmd = { runner.exe }
|
||||||
|
end
|
||||||
|
local usestdin = runner.usestdin or false
|
||||||
|
cmd = merge_list(cmd, runner.opt)
|
||||||
|
if not usestdin then
|
||||||
|
if selected_file == '' then
|
||||||
|
cmd = merge_list(cmd, vim.fn.bufname('%'))
|
||||||
|
else
|
||||||
|
cmd = merge_list(cmd, selected_file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
logger.info(' cmd:' .. vim.inspect(cmd))
|
||||||
|
local running_command = table.concat(cmd, ' ')
|
||||||
|
if usestdin then
|
||||||
|
running_command = running_command .. ' STDIN'
|
||||||
|
end
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(
|
||||||
|
code_runner_bufnr,
|
||||||
|
runner_lines,
|
||||||
|
-1,
|
||||||
|
false,
|
||||||
|
{ '[Running] ' .. running_command, '', vim.fn['repeat']('-', 20) }
|
||||||
|
)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
runner_lines = runner_lines + 3
|
||||||
|
start_time = vim.fn.reltime()
|
||||||
|
if vim.fn.empty(cmd) == 0 and vim.fn.executable(cmd[1]) == 1 then
|
||||||
|
runner_jobid = job.start(cmd, {
|
||||||
|
on_stdout = on_stdout,
|
||||||
|
on_stderr = on_stderr,
|
||||||
|
on_exit = on_exit,
|
||||||
|
})
|
||||||
|
if usestdin and runner_jobid > 0 then
|
||||||
|
local range = runner.range or { 1, '$' }
|
||||||
|
-- if selected file is not empty
|
||||||
|
-- read the context from selected file.
|
||||||
|
local text
|
||||||
|
if selected_file == '' then
|
||||||
|
text = vim.fn.getline(unpack(range))
|
||||||
|
else
|
||||||
|
text = vim.fn.readfile(selected_file, '')
|
||||||
|
end
|
||||||
|
job.send(runner_jobid, text)
|
||||||
|
job.chanclose(runner_jobid, 'stdin')
|
||||||
|
job.stop(runner_jobid)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local exe = cmd[1] or ''
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', true)
|
||||||
|
vim.api.nvim_buf_set_lines(
|
||||||
|
code_runner_bufnr,
|
||||||
|
runner_lines,
|
||||||
|
-1,
|
||||||
|
false,
|
||||||
|
{ exe .. ' is not executable, make sure ' .. exe .. ' is in your PATH' }
|
||||||
|
)
|
||||||
|
vim.api.nvim_buf_set_option(code_runner_bufnr, 'modifiable', false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if runner_jobid > 0 then
|
||||||
|
runner_status = {
|
||||||
|
is_running = true,
|
||||||
|
has_errors = false,
|
||||||
|
exit_code = 0,
|
||||||
|
exit_single = 0,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.open(...)
|
||||||
|
stop_runner()
|
||||||
|
runner_jobid = 0
|
||||||
|
runner_lines = 0
|
||||||
|
runner_status = {
|
||||||
|
is_running = false,
|
||||||
|
has_errors = false,
|
||||||
|
exit_code = 0,
|
||||||
|
exit_single = 0,
|
||||||
|
}
|
||||||
|
local language = vim.o.filetype
|
||||||
|
local runner = select(1, ...) or runners[language] or ''
|
||||||
|
local opts = select(2, ...) or {}
|
||||||
|
logger.debug('runner is:\n' .. vim.inspect(runner))
|
||||||
|
logger.debug('opt is:\n' .. vim.inspect(opts))
|
||||||
|
if vim.fn.empty(runner) == 0 then
|
||||||
|
open_win()
|
||||||
|
async_run(runner, opts)
|
||||||
|
update_statusline()
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.reg_runner(ft, runner)
|
||||||
|
runners[ft] = runner
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.status()
|
||||||
|
local running_nr = 0
|
||||||
|
local running_done = 0
|
||||||
|
for _, v in ipairs(task_status) do
|
||||||
|
if v.is_running then
|
||||||
|
running_nr = running_nr + 1
|
||||||
|
else
|
||||||
|
running_done = running_done + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if runner_status.is_running then
|
||||||
|
running_nr = running_nr + 1
|
||||||
|
end
|
||||||
|
return string.format(' %s running, %s done', running_nr, running_done)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.close()
|
||||||
|
close_win()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.select_file()
|
||||||
|
runner_lines = 0
|
||||||
|
runner_status = {
|
||||||
|
is_running = false,
|
||||||
|
has_errors = false,
|
||||||
|
exit_code = 0,
|
||||||
|
exit_single = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if vim.loop.os_uname().sysname == 'Windows_NT' then
|
||||||
|
-- what the fuck, why need trim?
|
||||||
|
-- because powershell comamnd output has `\n` at the end, and filetype detection failed.
|
||||||
|
selected_file = str.trim(vim.fn.system({'powershell', "Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.OpenFileDialog;$f.Filter='Model Files All files (*.*)|*.*';$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileName"}))
|
||||||
|
end
|
||||||
|
|
||||||
|
if selected_file == '' then
|
||||||
|
logger.debug('file to get selected filename!')
|
||||||
|
return
|
||||||
|
else
|
||||||
|
logger.debug('selected file is:' .. selected_file)
|
||||||
|
local ft = vim.filetype.match({filename = selected_file})
|
||||||
|
if not ft then
|
||||||
|
logger.debug('failed to detect filetype of selected file:' .. selected_file)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local runner = runners[ft]
|
||||||
|
logger.info(vim.inspect(runner))
|
||||||
|
if runner then
|
||||||
|
open_win()
|
||||||
|
async_run(runner)
|
||||||
|
update_statusline()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.select_language()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
@ -7,17 +7,23 @@ syn match KeyBindings /\[Running\]/
|
|||||||
syn match KeyBindings /\[Compile\]/
|
syn match KeyBindings /\[Compile\]/
|
||||||
syn match RunnerCmd /\(\[Running\]\ \)\@<=.*/
|
syn match RunnerCmd /\(\[Running\]\ \)\@<=.*/
|
||||||
syn match RunnerCmd /\(\[Compile\]\ \)\@<=.*/
|
syn match RunnerCmd /\(\[Compile\]\ \)\@<=.*/
|
||||||
syn match DoneSucceeded /\[Done]\(\ exited\ with\ code=0\)\@=/
|
syn match DoneSucceeded /\[Done]\(\ exited\ with\ code=0, single=0\)\@=/
|
||||||
|
syn match DoneSucceeded /\[Done]\(\ exited\ with\ code=0 in\)\@=/
|
||||||
syn match DoneFailed /\[Done]\(\ exited\ with\ code=[^0]\)\@=/
|
syn match DoneFailed /\[Done]\(\ exited\ with\ code=[^0]\)\@=/
|
||||||
|
syn match DoneFailed /\[Done]\(\ exited\ with\ code=0, single=[^0]\)\@=/
|
||||||
syn match ExitCode /\(\[Done\]\ exited\ with \)\@<=code=0/
|
syn match ExitCode /\(\[Done\]\ exited\ with \)\@<=code=0/
|
||||||
syn match ExitCodeFailed /\(\[Done\]\ exited\ with \)\@<=code=[^0]/
|
syn match ExitCodeFailed /\(\[Done\]\ exited\ with \)\@<=code=[1-9]\d*/
|
||||||
|
syn match SingleCode /single=0/
|
||||||
|
syn match SingleCodeFailed /single=[^0]/
|
||||||
|
|
||||||
hi def link RunnerCmd Comment
|
hi def link RunnerCmd Comment
|
||||||
hi def link KeyBindings String
|
hi def link KeyBindings String
|
||||||
hi def link DoneSucceeded String
|
hi def link DoneSucceeded String
|
||||||
hi def link DoneFailed WarningMsg
|
hi def link DoneFailed WarningMsg
|
||||||
hi def link ExitCode MoreMsg
|
hi def link ExitCode MoreMsg
|
||||||
|
hi def link SingleCode MoreMsg
|
||||||
hi def link ExitCodeFailed WarningMsg
|
hi def link ExitCodeFailed WarningMsg
|
||||||
|
hi def link SingleCodeFailed WarningMsg
|
||||||
let s:shellcmd_colors =
|
let s:shellcmd_colors =
|
||||||
\ [
|
\ [
|
||||||
\ '#6c6c6c', '#ff6666', '#66ff66', '#ffd30a',
|
\ '#6c6c6c', '#ff6666', '#66ff66', '#ffd30a',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
local job = require('spacevim.api.job')
|
local job = require('spacevim.api.job')
|
||||||
|
|
||||||
local jobid = job.start('echo 1', {
|
local jobid = job.start({'lua53', '-'}, {
|
||||||
on_stdout = function(id, data, event)
|
on_stdout = function(id, data, event)
|
||||||
vim.print(id)
|
vim.print(id)
|
||||||
vim.print(vim.inspect(data))
|
vim.print(vim.inspect(data))
|
||||||
@ -19,5 +19,9 @@ local jobid = job.start('echo 1', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
-- job.send(jobid, 'hello world')
|
job.send(jobid, 'print(1)\n')
|
||||||
-- job.stop(jobid)
|
job.send(jobid, 'print(1)\n')
|
||||||
|
job.send(jobid, 'print(1)\n')
|
||||||
|
job.send(jobid, 'print(1)\n')
|
||||||
|
job.chanclose(jobid, 'stdin')
|
||||||
|
job.stop(jobid)
|
||||||
|
Loading…
Reference in New Issue
Block a user