mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-03-13 02:05:40 +08:00
Add task problem matcher (#4127)
This commit is contained in:
parent
c69e3af7af
commit
1ca32fce79
@ -3,3 +3,20 @@
|
||||
isBackground = false
|
||||
[file-run.options]
|
||||
cwd = '${workspaceFolder}bin/'
|
||||
[test_problemMatcher]
|
||||
command = "echo"
|
||||
args = ['.SpaceVim.d/tasks.toml:6:1 test error message']
|
||||
isBackground = true
|
||||
[test_problemMatcher.problemMatcher]
|
||||
errorformat = '%f:%l:%c\ %m'
|
||||
[test_regexp]
|
||||
command = "echo"
|
||||
args = ['.SpaceVim.d/tasks.toml:12:1 test error message']
|
||||
isBackground = true
|
||||
[test_regexp.problemMatcher.pattern]
|
||||
regexp = '\(.*\):\(\d\+\):\(\d\+\)\s\(\S.*\)'
|
||||
file = 1
|
||||
line = 2
|
||||
column = 3
|
||||
#severity = 4
|
||||
message = 4
|
||||
|
@ -92,7 +92,7 @@ if exists('*nvim_create_buf')
|
||||
else
|
||||
function! s:self.create_buf(listed, scratch) abort
|
||||
let bufnr = self.bufadd('')
|
||||
" in vim, a:listed must be number, what the fuck!
|
||||
" in vim, a:listed must be number
|
||||
" why can not use v:true and v:false
|
||||
call setbufvar(bufnr, '&buflisted', a:listed ? 1 : 0)
|
||||
if a:scratch
|
||||
|
@ -158,7 +158,7 @@ function! s:open_default_shell(open_with_file_cwd) abort
|
||||
if getwinvar(window, '&buftype') ==# 'terminal'
|
||||
exe window . 'wincmd w'
|
||||
if getbufvar(winbufnr(window), '_spacevim_shell_cwd') ==# l:path
|
||||
" fuck gvim bug, startinsert do not work in gvim
|
||||
" startinsert do not work in gvim
|
||||
if has('nvim')
|
||||
startinsert
|
||||
else
|
||||
|
@ -217,7 +217,8 @@ function! SpaceVim#mapping#close_term_buffer(...) abort
|
||||
if bufexists(abuf)
|
||||
exe 'bd!' . abuf
|
||||
endif
|
||||
" fuck the terminal windows
|
||||
" can not close the terminal windows
|
||||
" close again
|
||||
if get(w:, 'shell_layer_win', 0) == 1
|
||||
close
|
||||
endif
|
||||
|
@ -84,7 +84,8 @@ function! SpaceVim#plugins#iedit#start(...) abort
|
||||
let curpos = getcurpos()
|
||||
let argv = get(a:000, 0, '')
|
||||
let save_reg_k = @k
|
||||
" what the fuck, why register " is cleared.
|
||||
" the register " is cleared
|
||||
" save the register context before run following command
|
||||
let save_reg_default = @"
|
||||
let use_expr = 0
|
||||
if !empty(argv) && type(argv) == 4
|
||||
|
@ -34,6 +34,10 @@ let s:status = {
|
||||
\ 'exit_code' : 0
|
||||
\ }
|
||||
|
||||
let s:task_stdout = {}
|
||||
let s:task_stderr = {}
|
||||
let s:task_problem_matcher = {}
|
||||
|
||||
function! s:open_win() abort
|
||||
if s:bufnr !=# 0 && bufexists(s:bufnr) && index(tabpagebuflist(), s:bufnr) !=# -1
|
||||
return
|
||||
@ -78,7 +82,7 @@ function! s:async_run(runner, ...) abort
|
||||
catch
|
||||
let cmd = a:runner
|
||||
endtry
|
||||
call SpaceVim#logger#info(' cmd:' . string(cmd))
|
||||
call s:LOGGER.info(' cmd:' . string(cmd))
|
||||
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , -1, 0, ['[Running] ' . cmd, '', repeat('-', 20)])
|
||||
let s:lines += 3
|
||||
let s:start_time = reltime()
|
||||
@ -156,7 +160,7 @@ function! s:async_run(runner, ...) abort
|
||||
else
|
||||
let cmd = exe + a:runner.opt + [get(s:, 'selected_file', bufname('%'))]
|
||||
endif
|
||||
call SpaceVim#logger#info(' cmd:' . string(cmd))
|
||||
call s:LOGGER.info(' cmd:' . string(cmd))
|
||||
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , -1, 0, ['[Running] ' . join(cmd) . (usestdin ? ' STDIN' : ''), '', repeat('-', 20)])
|
||||
let s:lines += 3
|
||||
let s:start_time = reltime()
|
||||
@ -342,8 +346,8 @@ function! SpaceVim#plugins#runner#select_file() abort
|
||||
let runner = get(a:000, 0, get(s:runners, &filetype, ''))
|
||||
let s:selected_language = &filetype
|
||||
if !empty(runner)
|
||||
call SpaceVim#logger#info('Code runner startting:')
|
||||
call SpaceVim#logger#info('selected file :' . s:selected_file)
|
||||
call s:LOGGER.info('Code runner startting:')
|
||||
call s:LOGGER.info('selected file :' . s:selected_file)
|
||||
call s:open_win()
|
||||
call s:async_run(runner)
|
||||
call s:update_statusline()
|
||||
@ -392,16 +396,76 @@ function! SpaceVim#plugins#runner#run_task(task) abort
|
||||
if !empty(opts) && has_key(opts, 'env') && !empty(opts.env)
|
||||
call extend(opt, {'env' : opts.env})
|
||||
endif
|
||||
let problemMatcher = get(a:task, 'problemMatcher', {})
|
||||
if isBackground
|
||||
call s:run_backgroud(cmd, opt)
|
||||
call s:run_backgroud(cmd, opt, problemMatcher)
|
||||
else
|
||||
call SpaceVim#plugins#runner#open(cmd, opt)
|
||||
call SpaceVim#plugins#runner#open(cmd, opt, problemMatcher)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:match_problems(output, matcher) abort
|
||||
if has_key(a:matcher, 'pattern')
|
||||
let pattern = a:matcher.pattern
|
||||
let items = []
|
||||
for line in a:output
|
||||
let rst = matchlist(line, pattern.regexp)
|
||||
let file = get(rst, get(pattern, 'file', 1), '')
|
||||
let line = get(rst, get(pattern, 'line', 2), 1)
|
||||
let column = get(rst, get(pattern, 'column', 3), 1)
|
||||
let message = get(rst, get(pattern, 'message', 4), '')
|
||||
if !empty(file)
|
||||
call add(items, {
|
||||
\ 'filename' : file,
|
||||
\ 'lnum' : line,
|
||||
\ 'col' : column,
|
||||
\ 'text' : message,
|
||||
\ })
|
||||
endif
|
||||
endfor
|
||||
call setqflist([], 'r', {'title' : ' task output',
|
||||
\ 'items' : items,
|
||||
\ })
|
||||
copen
|
||||
copen
|
||||
else
|
||||
try
|
||||
let olderrformat = &errorformat
|
||||
if has_key(a:matcher, 'errorformat')
|
||||
let &errorformat = a:matcher.errorformat
|
||||
let cmd = 'noautocmd cexpr a:output'
|
||||
exe cmd
|
||||
call setqflist([], 'a', {'title' : ' task output'})
|
||||
copen
|
||||
endif
|
||||
finally
|
||||
let &errorformat = olderrformat
|
||||
endtry
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:on_backgroud_stdout(job_id, data, event) abort
|
||||
let data = get(s:task_stdout, 'task' . a:job_id, []) + a:data
|
||||
let s:task_stdout['task' . a:job_id] = data
|
||||
endfunction
|
||||
|
||||
function! s:on_backgroud_stderr(job_id, data, event) abort
|
||||
let data = get(s:task_stderr, 'task' . a:job_id, []) + a:data
|
||||
let s:task_stderr['task' . a:job_id] = data
|
||||
endfunction
|
||||
|
||||
function! s:on_backgroud_exit(job_id, data, event) abort
|
||||
let s:end_time = reltime(s:start_time)
|
||||
let task_problem_matcher = get(s:task_problem_matcher, 'task' . a:job_id, {})
|
||||
if get(task_problem_matcher, 'useStdout', 0)
|
||||
let output = get(s:task_stdout, 'task' . a:job_id, [])
|
||||
else
|
||||
let output = get(s:task_stderr, 'task' . a:job_id, [])
|
||||
endif
|
||||
if !empty(task_problem_matcher) && !empty(output)
|
||||
call s:match_problems(output, task_problem_matcher)
|
||||
endif
|
||||
let exit_code = a:data
|
||||
echo 'task finished with code=' . a:data . ' in ' . s:STRING.trim(reltimestr(s:end_time)) . ' seconds'
|
||||
endfunction
|
||||
@ -410,7 +474,13 @@ function! s:run_backgroud(cmd, ...) abort
|
||||
echo 'task running'
|
||||
let opts = get(a:000, 0, {})
|
||||
let s:start_time = reltime()
|
||||
call s:JOB.start(a:cmd,extend({
|
||||
let problemMatcher = get(a:000, 1, {})
|
||||
if !has_key(problemMatcher, 'errorformat') && !has_key(problemMatcher, 'regexp')
|
||||
call extend(problemMatcher, {'errorformat' : &errorformat})
|
||||
endif
|
||||
let task_id = s:JOB.start(a:cmd,extend({
|
||||
\ 'on_stdout' : function('s:on_backgroud_stdout'),
|
||||
\ 'on_exit' : function('s:on_backgroud_exit'),
|
||||
\ }, opts))
|
||||
call extend(s:task_problem_matcher, {'task' . task_id : problemMatcher})
|
||||
endfunction
|
||||
|
@ -98,8 +98,7 @@ endfunction
|
||||
" :w -- BufWriteCmd
|
||||
" <C-w>p -- WinLeave
|
||||
" :wq -- QuitPre -> BufWriteCmd -> WinLeave
|
||||
" fuck when run `:wq` the commit window will not be closed
|
||||
" @fixme what the fuck
|
||||
" when run `:wq` the commit window will not be closed
|
||||
" :q -- QuitPre -> WinLeave
|
||||
function! s:BufWriteCmd() abort
|
||||
let commit_file = '.git\COMMIT_EDITMSG'
|
||||
|
@ -68,8 +68,7 @@ endfunction
|
||||
" :w -- BufWriteCmd
|
||||
" <C-w>p -- WinLeave
|
||||
" :wq -- QuitPre -> BufWriteCmd -> WinLeave
|
||||
" fuck when run `:wq` the commit window will not be closed
|
||||
" @fixme what the fuck
|
||||
" when run `:wq` the commit window will not be closed
|
||||
" :q -- QuitPre -> WinLeave
|
||||
function! s:BufWriteCmd() abort
|
||||
let commit_file = '.git\COMMIT_EDITMSG'
|
||||
|
@ -84,6 +84,7 @@ description: "General documentation about how to using SpaceVim, including the q
|
||||
- [Bookmarks management](#bookmarks-management)
|
||||
- [Tasks](#tasks)
|
||||
- [Custom tasks](#custom-tasks)
|
||||
- [Task Problems Matcher](#task-problems-matcher)
|
||||
- [Task auto-detection](#task-auto-detection)
|
||||
- [Task provider](#task-provider)
|
||||
- [Replace text with iedit](#replace-text-with-iedit)
|
||||
@ -2074,6 +2075,7 @@ The task's properties have the following semantic:
|
||||
- **isBackground**: `true` or `false`, specifies whether background running is required,
|
||||
by default, it is `false`.
|
||||
- **description**: short description of the task
|
||||
- **problemMatcher**: problems matcher of the task
|
||||
|
||||
When start a new task, it will kill the previous task. If you want to keep the task
|
||||
run in background, set `isBackground` to `true`.
|
||||
@ -2109,6 +2111,41 @@ So you will have the following values for each variable:
|
||||
- **\${fileExtname}**: - `.ext`
|
||||
- **\${lineNumber}**: - line number of the cursor
|
||||
|
||||
#### Task Problems Matcher
|
||||
|
||||
Problem matcher is used to capture the message in the task output
|
||||
and show a corresponding problem in quickfix windows.
|
||||
|
||||
`problemMatcher` supports `errorformat` and `pattern` property.
|
||||
|
||||
If `errorformat` property is not defined, `&errorformat` option
|
||||
will be used.
|
||||
|
||||
```toml
|
||||
[tesk_errorformat]
|
||||
command = "echo"
|
||||
args = ['.SpaceVim.d/tasks.toml:6:1 test error message']
|
||||
isBackground = true
|
||||
[tesk_errorformat.problemMatcher]
|
||||
errorformat = '%f:%l:%c\ %m'
|
||||
```
|
||||
|
||||
If `pattern` is defined, the `errorformat` option will be ignored.
|
||||
Here is an example:
|
||||
|
||||
```toml
|
||||
[test_regexp]
|
||||
command = "echo"
|
||||
args = ['.SpaceVim.d/tasks.toml:12:1 test error message']
|
||||
isBackground = true
|
||||
[test_regexp.problemMatcher.pattern]
|
||||
regexp = '\(.*\):\(\d\+\):\(\d\+\)\s\(\S.*\)'
|
||||
file = 1
|
||||
line = 2
|
||||
column = 3
|
||||
message = 4
|
||||
```
|
||||
|
||||
#### Task auto-detection
|
||||
|
||||
Currently, SpaceVim can auto-detect tasks for npm.
|
||||
|
Loading…
x
Reference in New Issue
Block a user