1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 07:00:04 +08:00

Improve Task manager (#3857)

This commit is contained in:
Wang Shidong 2020-10-01 22:30:29 +08:00 committed by GitHub
parent 5c832c96c0
commit 371370162f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 168 additions and 103 deletions

View File

@ -3,4 +3,3 @@
isBackground = false
[file-run.options]
cwd = '${workspaceFolder}bin/'

View File

@ -264,6 +264,7 @@ function! SpaceVim#layers#core#config() abort
" call SpaceVim#mapping#space#def('nnoremap', ['p', 't'], 'call SpaceVim#plugins#projectmanager#current_root()', 'find-project-root', 1)
let g:_spacevim_mappings_space.p.t = {'name' : '+Tasks'}
call SpaceVim#mapping#space#def('nnoremap', ['p', 't', 'e'], 'call SpaceVim#plugins#tasks#edit()', 'edit-project-task', 1)
call SpaceVim#mapping#space#def('nnoremap', ['p', 't', 'l'], 'call SpaceVim#plugins#tasks#list()', 'list-tasks', 1)
call SpaceVim#mapping#space#def('nnoremap', ['p', 't', 'r'],
\ 'call SpaceVim#plugins#runner#run_task(SpaceVim#plugins#tasks#get())', 'pick-task-to-run', 1)
call SpaceVim#mapping#space#def('nnoremap', ['p', 'k'], 'call SpaceVim#plugins#projectmanager#kill_project()', 'kill-all-project-buffers', 1)

View File

@ -487,6 +487,8 @@ function! SpaceVim#layers#core#statusline#get(...) abort
return '%#SpaceVim_statusline_a# WinDisk %#SpaceVim_statusline_a_SpaceVim_statusline_b#' . s:lsep
elseif &filetype ==# 'SpaceVimTodoManager'
return '%#SpaceVim_statusline_a# TODO manager %#SpaceVim_statusline_a_SpaceVim_statusline_b#' . s:lsep
elseif &filetype ==# 'SpaceVimTasksInfo'
return '%#SpaceVim_statusline_a# Tasks manager %#SpaceVim_statusline_a_SpaceVim_statusline_b#' . s:lsep
elseif &filetype ==# 'SpaceVimGitBranchManager'
return '%#SpaceVim_statusline_a# Branch manager %#SpaceVim_statusline_a_SpaceVim_statusline_b#' . s:lsep
elseif &filetype ==# 'SpaceVimPlugManager'

View File

@ -140,6 +140,14 @@ function! s:close() abort
endif
endfunction
function! s:close_repl() abort
" stop the job if it is running.
if exists('s:job_id') && s:job_id > 0
call s:JOB.stop(s:job_id)
let s:job_id = 0
endif
endfunction
let s:exes = {}
function! SpaceVim#plugins#repl#reg(ft, execute) abort
@ -171,7 +179,7 @@ function! s:open_windows() abort
nnoremap <silent><buffer> q :call <SID>close()<cr>
augroup spacevim_repl
autocmd!
autocmd BufWipeout <buffer> call <SID>close()
autocmd BufWipeout <buffer> call <SID>close_repl()
augroup END
let s:bufnr = bufnr('%')
let s:winid = win_getid(winnr())

View File

@ -19,6 +19,13 @@ let s:runners = {}
let s:bufnr = 0
let s:winid = -1
let s:job_id = 0
let s:status = {
\ 'is_running' : 0,
\ 'is_exit' : 0,
\ 'has_errors' : 0,
\ 'exit_code' : 0
\ }
function! s:open_win() abort
if s:bufnr != 0 && bufexists(s:bufnr)
@ -27,18 +34,14 @@ function! s:open_win() abort
botright split __runner__
let lines = &lines * 30 / 100
exe 'resize ' . lines
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist nomodifiable
\ noswapfile
\ nowrap
\ cursorline
\ nospell
\ nonu
\ norelativenumber
\ winfixheight
\ nomodifiable
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nospell nonu norelativenumber winfixheight nomodifiable
set filetype=SpaceVimRunner
nnoremap <silent><buffer> q :call SpaceVim#plugins#runner#close()<cr>
nnoremap <silent><buffer> q :call <SID>close()<cr>
nnoremap <silent><buffer> i :call <SID>insert()<cr>
augroup spacevim_runner
autocmd!
autocmd BufWipeout <buffer> call <SID>stop_runner()
augroup END
let s:bufnr = bufnr('%')
let s:winid = win_getid(winnr())
wincmd p
@ -57,6 +60,7 @@ endfunction
let s:target = ''
function! s:async_run(runner, ...) abort
call s:stop_runner()
if type(a:runner) == type('')
" the runner is a string, the %s will be replaced as a file name.
try
@ -236,89 +240,50 @@ endfunction
" @vimlint(EVL103, 1, a:job_id)
" @vimlint(EVL103, 1, a:data)
" @vimlint(EVL103, 1, a:event)
if has('nvim') && exists('*chanclose')
" remoet at the end of each
let s:_out_data = ['']
function! s:on_stdout(job_id, data, event) abort
let s:_out_data[-1] .= a:data[0]
call extend(s:_out_data, a:data[1:])
if s:_out_data[-1] ==# ''
call remove(s:_out_data, -1)
let lines = s:_out_data
else
let lines = s:_out_data
endif
" if s:SYS.isWindows
" let lines = map(lines, 's:ICONV.iconv(v:val, "cp936", "utf-8")')
" endif
if !empty(lines)
let lines = map(lines, "substitute(v:val, ' $', '', 'g')")
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, lines)
endif
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
endif
let s:lines += len(lines)
let s:_out_data = ['']
call s:update_statusline()
endfunction
function! s:on_stdout(job_id, data, event) abort
if a:job_id !=# s:job_id
" that means, a new runner has been opennd
" this is previous runner exit_callback
return
endif
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, a:data)
endif
let s:lines += len(a:data)
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
call s:update_statusline()
endfunction
let s:_err_data = ['']
function! s:on_stderr(job_id, data, event) abort
let s:_out_data[-1] .= a:data[0]
call extend(s:_out_data, a:data[1:])
if s:_out_data[-1] ==# ''
call remove(s:_out_data, -1)
let lines = s:_out_data
else
let lines = s:_out_data
endif
if s:SYS.isWindows
let lines = map(lines, 's:ICONV.iconv(v:val, "cp936", "utf-8")')
endif
if !empty(lines)
let lines = map(lines, "substitute(v:val, ' $', '', 'g')")
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, lines)
endif
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
endif
let s:lines += len(lines)
let s:_out_data = ['']
call s:update_statusline()
endfunction
else
function! s:on_stdout(job_id, data, event) abort
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, a:data)
endif
let s:lines += len(a:data)
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
call s:update_statusline()
endfunction
function! s:on_stderr(job_id, data, event) abort
let s:status.has_errors = 1
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, a:data)
endif
let s:lines += len(a:data)
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
call s:update_statusline()
endfunction
endif
function! s:on_stderr(job_id, data, event) abort
if a:job_id !=# s:job_id
" that means, a new runner has been opennd
" this is previous runner exit_callback
return
endif
let s:status.has_errors = 1
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, a:data)
endif
let s:lines += len(a:data)
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
call s:update_statusline()
endfunction
function! s:on_exit(job_id, data, event) abort
if a:job_id !=# s:job_id
" that means, a new runner has been opennd
" this is previous runner exit_callback
return
endif
let s:end_time = reltime(s:start_time)
let s:status.is_exit = 1
let s:status.exit_code = a:data
let done = ['', '[Done] exited with code=' . a:data . ' in ' . s:STRING.trim(reltimestr(s:end_time)) . ' seconds']
if bufexists(s:bufnr)
call s:BUFFER.buf_set_lines(s:bufnr, s:lines , s:lines + 1, 0, done)
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
call s:update_statusline()
endif
call s:VIM.win_set_cursor(s:winid, [s:VIM.buf_line_count(s:bufnr), 1])
call s:update_statusline()
endfunction
" @vimlint(EVL103, 0, a:job_id)
" @vimlint(EVL103, 0, a:data)
@ -339,11 +304,21 @@ function! SpaceVim#plugins#runner#status() abort
return ''
endfunction
function! SpaceVim#plugins#runner#close() abort
function! s:close() abort
if s:status.is_exit == 0 && s:job_id > 0
call s:JOB.stop(s:job_id)
let s:job_id = 0
endif
if s:bufnr != 0 && bufexists(s:bufnr)
exe 'bd ' s:bufnr
endif
endfunction
function! s:stop_runner() abort
if s:status.is_exit == 0 && s:job_id > 0
call s:JOB.stop(s:job_id)
let s:job_id = 0
endif
exe 'bd ' s:bufnr
endfunction
function! SpaceVim#plugins#runner#select_file() abort

View File

@ -21,6 +21,7 @@ let s:CMP = SpaceVim#api#import('vim#compatible')
let s:SYS = SpaceVim#api#import('system')
let s:MENU = SpaceVim#api#import('cmdlinemenu')
let s:VIM = SpaceVim#api#import('vim')
let s:BUF = SpaceVim#api#import('vim#buffer')
" task object
@ -90,13 +91,8 @@ function! s:replace_variables(str) abort
return str
endfunction
function! SpaceVim#plugins#tasks#get()
call s:load()
for Provider in s:providers
call extend(s:conf, call(Provider, []))
endfor
call s:init_variables()
let task = s:pick()
function! s:expand_task(task) abort
let task = a:task
if has_key(task, 'windows') && s:SYS.isWindows
let task = task.windows
elseif has_key(task, 'osx') && s:SYS.isOSX
@ -118,21 +114,33 @@ function! SpaceVim#plugins#tasks#get()
return task
endfunction
function! SpaceVim#plugins#tasks#get() abort
call s:load()
for Provider in s:providers
call extend(s:conf, call(Provider, []))
endfor
call s:init_variables()
let task = s:expand_task(s:pick())
return task
endfunction
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" list all the tasks
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! SpaceVim#plugins#tasks#list()
function! SpaceVim#plugins#tasks#list() abort
call s:load()
for Provider in s:providers
call extend(s:conf, call(Provider, []))
endfor
call s:init_variables()
call s:open_tasks_list_win()
call s:update_tasks_win_context()
endfunction
function! SpaceVim#plugins#tasks#complete(...)
function! SpaceVim#plugins#tasks#complete(...) abort
@ -157,9 +165,44 @@ function! s:open_tasks_list_win() abort
\ nomodifiable
set filetype=SpaceVimTasksInfo
let s:bufnr = bufnr('%')
nnoremap <buffer><silent> <Enter> :call <SID>open_task()<cr>
endfunction
function! SpaceVim#plugins#tasks#edit(...)
function! s:open_task() abort
let line = getline('.')
if line =~# '^\[.*\]'
let task = matchstr(line, '^\[.*\]')[1:-2]
if line =~# '^\[.*\]\s\+detected'
let task = split(task, ':')[1]
endif
let task = s:expand_task(s:conf[task])
call SpaceVim#mapping#SmartClose()
call SpaceVim#plugins#runner#run_task(task)
else
" not on a task
endif
endfunction
function! s:update_tasks_win_context() abort
let lines = ['Task Type Description']
for task in keys(s:conf)
if has_key(s:conf[task], 'isGlobal') && s:conf[task].isGlobal ==# 1
let line = '[' . task . ']' . repeat(' ', 22 - strlen(task))
let line .= 'global '
elseif has_key(s:conf[task], 'isDetected') && s:conf[task].isDetected ==# 1
let line = '[' . s:conf[task].detectedName . task . ']' . repeat(' ', 22 - strlen(task . s:conf[task].detectedName))
let line .= 'detected '
else
let line = '[' . task . ']' . repeat(' ', 22 - strlen(task))
let line .= 'local '
endif
let line .= get(s:conf[task], 'description', s:conf[task].command . ' ' . join(get(s:conf[task], 'args', []), ' '))
call add(lines, line)
endfor
call s:BUF.buf_set_lines(s:bufnr, 0, -1, 0, sort(lines))
endfunction
function! SpaceVim#plugins#tasks#edit(...) abort
if get(a:000, 0, 0)
exe 'e ~/.SpaceVim.d/tasks.toml'
else
@ -183,7 +226,7 @@ function! s:detect_npm_tasks() abort
return detect_task
endfunction
function! SpaceVim#plugins#tasks#reg_provider(provider)
function! SpaceVim#plugins#tasks#reg_provider(provider) abort
call add(s:providers, a:provider)
endfunction

View File

@ -1874,6 +1874,9 @@ endfunction
| ----------- | ---------------- |
| `SPC p t e` | 编辑任务配置文件 |
| `SPC p t r` | 选定任务并执行 |
| `SPC p t l` | 列出所有任务 |
![task_manager](https://user-images.githubusercontent.com/13142418/94822603-69d0c700-0435-11eb-95a7-b0b4fef91be5.png)
#### 自定义任务
@ -1903,6 +1906,10 @@ endfunction
- **options**: 设置命令运行的一些选项,比如 `cwd`,`env` 或者 `shell`
- **isBackground**: 可设定的值为 `true` 或者 `false` 默认是 `false`
设置是否需要后台运行任务
- **description**: 关于该任务的一段简短介绍
当启动一个任务时,默认会关闭前一个任务,如果需要让任务一直保持后台运行,
可以将 `isBackground` 设为 `true`
在编辑任务配置文件时,可以使用一些预设定的变量,以下列出目前已经支持的预设定变量:
@ -1931,7 +1938,6 @@ endfunction
- **\${fileExtname}**: - `.ext`
- **\${lineNumber}**: - `10`
#### 任务自动识别
SpaceVim 目前支持自动识别以下构建系统的任务npm。

View File

@ -1907,7 +1907,7 @@ endfunction
To integrate with external tools, SpaceVim introduce a task manager system,
which is similar to vscode tasks-manager. There are two kinds of task configuration
file:
file:
- `~/.SpaceVim.d/tasks.toml`: global tasks configuration
- `.SpaceVim.d/tasks.toml`: project local tasks configuration
@ -1919,7 +1919,9 @@ tasks configuration.
| ------------ | ----------------------------- |
| `SPC p t e` | edit tasks configuration file |
| `SPC p t r` | select task to run |
| `SPC p t l` | list all available tasks |
![task_manager](https://user-images.githubusercontent.com/13142418/94822603-69d0c700-0435-11eb-95a7-b0b4fef91be5.png)
#### Custom tasks
@ -1950,6 +1952,10 @@ The task's properties have the following semantic:
- **options**: override the defaults for `cwd`,`env` or `shell`.
- **isBackground**: `true` or `false`, specifies whether background running is required,
by default, it is `false`.
- **description**: short description 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`.
SpaceVim supports variable substitution in task, The following predefined variables are supported:
@ -1984,7 +1990,7 @@ So you will have the following values for each variable:
#### Task auto-detection
Currently, SpaceVim can auto-detect tasks for npm.
Currently, SpaceVim can auto-detect tasks for npm.
the tasks manager will paser the `package.json` file for npm systems.
If you have cloned the [eslint-starter](https://github.com/spicydonuts/eslint-starter) example,
then pressing `SPC p t r` shows the following list:

View File

@ -0,0 +1,25 @@
if exists('b:current_syntax') && b:current_syntax ==# 'SpaceVimTasksInfo'
finish
endif
let b:current_syntax = 'SpaceVimTasksInfo'
syntax case ignore
syn match TaskName /^\[.*\]/
syn match TaskTitle /^Task\s\+Type\s\+Command/
" @question Why \zs does not work in syntax file?
" ref:
" https://github.com/vim/vim/issues/598
" https://stackoverflow.com/questions/49323753/vim-syntax-file-not-matching-with-zs
" https://stackoverflow.com/questions/64153655/why-taskinfo-syntax-file-does-not-work-as-expect
" syn match TaskType /^\[.*\]\s*\zs[a-z]*/
" syn match TaskDescription /^\[.*\]\s*[a-z]*\s\+\zs.*/
syn match TaskType /\(^\[.\+\]\s\+\)\@<=[a-z]*/
syn match TaskDescription /\(^\[.*\]\s\+[a-z]\+\s\+\)\@<=.*/
hi def link TaskTitle Title
hi def link TaskName String
hi def link TaskType Todo
hi def link TaskDescription Comment