diff --git a/.SpaceVim.d/tasks.toml b/.SpaceVim.d/tasks.toml new file mode 100644 index 000000000..5d67cf67f --- /dev/null +++ b/.SpaceVim.d/tasks.toml @@ -0,0 +1,10 @@ +[file-build] + command = 'gcc $(VIM_FILE) -o $(TARGET_DIR)/$(VIM_FILE_NOEXT)' + isBackground = false +[file-build.options] + cmd = '$(workspace)' +[file-run] + command = "echo" + args = ['hello'] + isBackground = false + diff --git a/autoload/SpaceVim/api/cmdlinemenu.vim b/autoload/SpaceVim/api/cmdlinemenu.vim index a41d8de6e..91a09c7a0 100644 --- a/autoload/SpaceVim/api/cmdlinemenu.vim +++ b/autoload/SpaceVim/api/cmdlinemenu.vim @@ -39,7 +39,7 @@ function! s:parseItems(items) abort let items = {} for item in a:items let id = index(a:items, item) + 1 - let items[id] = ['(' . id . ')' . item[0], item[1]] + let items[id] = ['(' . id . ')' . item[0]] + item[1:] endfor return items endfunction @@ -56,6 +56,7 @@ endfunction " should be a funcrc. function! s:menu(items) abort + let cancelled = 0 let saved_more = &more let save_cmdheight = &cmdheight set nomore @@ -78,34 +79,42 @@ function! s:menu(items) abort let menu .= indent . ' ' . items[id][0] . "\n" endif endfor + redraw! echo menu[:-2] let nr = getchar() if s:parseInput(nr) ==# '' || nr == 3 let exit = 1 - redraw + let cancelled = 1 + normal! : elseif index(keys(items), nr2char(nr)) != -1 || nr == 13 if nr != 13 let selected = nr2char(nr) endif let Value = items[selected][1] - redraw + normal! : if type(Value) == 2 - call call(Value, []) + let args = get(items[selected], 2, []) + call call(Value, args) elseif type(Value) == type('') && !empty(Value) execute Value endif let exit = 1 - elseif nr2char(nr) ==# 'j' + elseif nr2char(nr) ==# 'j' || nr ==# 9 let selected = s:nextItem(keys(items), selected) - redraw - elseif nr2char(nr) ==# 'k' + normal! : + elseif nr2char(nr) ==# 'k' || nr ==# "\" let selected = s:previousItem(keys(items), selected) - redraw + normal! : + else + normal! : endif endwhile let &more = saved_more let &cmdheight = save_cmdheight redraw! + if cancelled + echo 'cancelled!' + endif endfunction let s:api['menu'] = function('s:menu') diff --git a/autoload/SpaceVim/layers/core.vim b/autoload/SpaceVim/layers/core.vim index bee7db47e..1b4da6017 100644 --- a/autoload/SpaceVim/layers/core.vim +++ b/autoload/SpaceVim/layers/core.vim @@ -259,7 +259,11 @@ function! SpaceVim#layers#core#config() abort \ ] \ , 1) let g:vimproc#download_windows_dll = 1 - call SpaceVim#mapping#space#def('nnoremap', ['p', 't'], 'call SpaceVim#plugins#projectmanager#current_root()', 'find-project-root', 1) + " 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', '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) call SpaceVim#mapping#space#def('nnoremap', ['p', 'p'], 'call SpaceVim#plugins#projectmanager#list()', 'list-all-projects', 1) call SpaceVim#mapping#space#def('nnoremap', ['p', '/'], 'Grepper', 'fuzzy search for text in current project', 1) diff --git a/autoload/SpaceVim/plugins/runner.vim b/autoload/SpaceVim/plugins/runner.vim index 46f08e5e3..e711afbd3 100644 --- a/autoload/SpaceVim/plugins/runner.vim +++ b/autoload/SpaceVim/plugins/runner.vim @@ -383,3 +383,16 @@ function! SpaceVim#plugins#runner#set_language(lang) abort " the all language is keys(s:runners) let s:selected_language = a:lang endfunction + + +function! SpaceVim#plugins#runner#run_task(task) + let isBackground = get(a:task, 'isBackground', 0) + if !isBackground && !empty(a:task) + let cmd = get(a:task, 'command', '') + let args = get(a:task, 'args', []) + if !empty(args) && !empty(cmd) + let cmd = cmd . ' ' . join(args, ' ') + endif + call SpaceVim#plugins#runner#open(cmd) + endif +endfunction diff --git a/autoload/SpaceVim/plugins/tasks.vim b/autoload/SpaceVim/plugins/tasks.vim new file mode 100644 index 000000000..291940eef --- /dev/null +++ b/autoload/SpaceVim/plugins/tasks.vim @@ -0,0 +1,146 @@ +"============================================================================= +" tasks.vim --- tasks support +" Copyright (c) 2016-2019 Wang Shidong & Contributors +" Author: Wang Shidong < wsdjeg@outlook.com > +" URL: https://spacevim.org +" License: GPLv3 +"============================================================================= + +" this plugin is based on vscode task Scheme +" https://code.visualstudio.com/docs/editor/tasks-appendix + + +let s:TOML = SpaceVim#api#import('data#toml') +let s:JSON = SpaceVim#api#import('data#json') +let s:FILE = SpaceVim#api#import('file') +let s:CMP = SpaceVim#api#import('vim#compatible') +let s:SYS = SpaceVim#api#import('system') +let s:MENU = SpaceVim#api#import('cmdlinemenu') + +" task object + +let s:self = {} +let s:select_task = {} +let s:conf = [] +let s:bufnr = -1 +let s:variables = {} + + +function! s:load() abort + let s:conf = s:TOML.parse_file('.SpaceVim.d/tasks.toml') +endfunction + +function! s:init_variables() abort + " ${workspaceFolder} - /home/your-username/your-project + let s:variables.workspaceFolder = SpaceVim#plugins#projectmanager#current_root() + " ${workspaceFolderBasename} - your-project + let s:variables.workspaceFolderBasename = fnamemodify(s:variables.workspaceFolder, ':t') + " ${file} - /home/your-username/your-project/folder/file.ext + let s:variables.file = s:FILE.unify_path(expand('%:p')) + " ${relativeFile} - folder/file.ext + let s:variables.relativeFile = s:FILE.unify_path(expand('%')) + " ${relativeFileDirname} - folder + let s:variables.relativeFileDirname = s:FILE.unify_path(expand('%:h')) + " ${fileBasename} - file.ext + let s:variables.fileBasename = expand('%:t') + " ${fileBasenameNoExtension} - file + let s:variables.fileBasenameNoExtension = expand('%:t:r') + " ${fileDirname} - /home/your-username/your-project/folder + let s:variables.fileDirname = s:FILE.unify_path(expand('%:p:h')) + " ${fileExtname} - .ext + let s:variables.fileExtname = expand('%:e') + " ${lineNumber} - line number of the cursor + let s:variables.lineNumber = line('.') + " ${selectedText} - text selected in your code editor + let s:variables.selectedText = '' + " ${execPath} - location of Code.exe + let s:variables.execPath = '' +endfunction + +function! s:select_task(taskName) abort + let s:select_task = s:conf[a:taskName] +endfunction + +function! s:pick() abort + let s:select_task = {} + let ques = [] + for key in keys(s:conf) + call add(ques, [key, function('s:select_task'), [key]]) + endfor + call s:MENU.menu(ques) + return s:select_task +endfunction + +function! s:replace_variables(str) abort + let str = a:str + for key in keys(s:variables) + let str = substitute(str, '$(' . key . ')', s:variables[key], 'g') + endfor + return str +endfunction + +function! SpaceVim#plugins#tasks#get() + call s:load() + call s:init_variables() + let task = s:pick() + if has_key(task, 'windows') && s:SYS.isWindows + let task = task.windows + elseif has_key(task, 'osx') && s:SYS.isOSX + let task = task.osx + elseif has_key(task, 'linux') && s:SYS.isLinux + let task = task.linux + endif + if has_key(task, 'command') && type(task.command) ==# 1 + let task.command = s:replace_variables(task.command) + endif + return task +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" list all the tasks +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! SpaceVim#plugins#tasks#list() + call s:load() + call s:init_variables() + call s:open_tasks_list_win() + + +endfunction + + +function! SpaceVim#plugins#tasks#complete(...) + + + +endfunction + + +function! s:open_tasks_list_win() abort + if s:bufnr != 0 && bufexists(s:bufnr) + exe 'bd ' . s:bufnr + endif + botright split __tasks_info__ + let lines = &lines * 30 / 100 + exe 'resize ' . lines + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist nomodifiable + \ noswapfile + \ nowrap + \ cursorline + \ nospell + \ nonu + \ norelativenumber + \ winfixheight + \ nomodifiable + set filetype=SpaceVimTasksInfo + let s:bufnr = bufnr('%') +endfunction + +function! SpaceVim#plugins#tasks#edit(...) + if get(a:000, 0, 0) + exe 'e ~/.SpaceVim.d/tasks.toml' + else + exe 'e .SpaceVim.d/tasks.toml' + endif +endfunction diff --git a/docs/cn/documentation.md b/docs/cn/documentation.md index d1539a5be..f12011b6f 100644 --- a/docs/cn/documentation.md +++ b/docs/cn/documentation.md @@ -78,6 +78,7 @@ lang: zh - [在工程中搜索文件](#在工程中搜索文件) - [自定义跳转文件](#自定义跳转文件) - [标签管理](#标签管理) + - [任务管理](#任务管理) - [Iedit 多光标编辑](#iedit-多光标编辑) - [Iedit 快捷键](#iedit-快捷键) - [异步运行器和交互式编程](#异步运行器和交互式编程) @@ -1691,6 +1692,16 @@ function! myspacevim#before() abort endfunction ``` +### 任务管理 + +构建、打包、测试等任务会涉及到多种外部命令,包括`make`、`mvn`等。 +可以通过任务集成外部工具这些外部命令。 + +| 快捷键 | 功能描述 | +| ----------- | ---------------- | +| `SPC p t e` | 编辑任务配置文件 | +| `SPC p t r` | 选择任务并执行 | + ### Iedit 多光标编辑 SpaceVim 内置了 iedit 多光标模式,可快速进行多光标编辑。这一功能引入了两个新的模式:`iedit-Normal` 模式和 `iedit-Insert`。