diff --git a/autoload/accio.vim b/autoload/accio.vim index 172182c..ff04ddd 100644 --- a/autoload/accio.vim +++ b/autoload/accio.vim @@ -21,51 +21,37 @@ let s:errors_by_line = {} " ====================================================================== " Public API " ====================================================================== -function! accio#accio(args) - let save_makeprg = &l:makeprg - let save_errorformat = &l:errorformat - let [args; rest] = s:parse_accio_args(a:args) - let [compiler, compiler_args] = matchlist(args, '^\(\S*\)\s*\(.*\)')[1:2] - let [compiler_command, compiler_target] = s:parse_makeprg(compiler, compiler_args) - if s:jobs_in_progress - call add(s:accio_queue, [a:args, bufnr("%")]) +function! accio#accio(...) abort + let args = get(a:000, 0, []) + let focus = get(a:000, 1, 0) + let tasks = type(args) == type("") ? [args] : args + + if empty(tasks) + if exists("g:accio_focus") && !empty(g:accio_focus) + let tasks = g:accio_focus + else + let inferred = get(b:, "accio", get(b:, "current_compiler", [])) + let tasks = type(inferred) == type("") ? [inferred] : inferred + endif + elseif focus + let g:accio_focus = tasks + endif + + if empty(tasks) + echohl ErrorMsg | echo "Accio: no task specified" | echohl None + return + endif + + if exists("*jobstart") + call s:accio_do_async(tasks) else - let s:quickfix_cleared = 0 - let s:accio_compiler_task_ids = [] - let compiler_task = s:new_compiler_task(compiler, compiler_target, compiler_command, &l:errorformat) - call s:start_job(compiler_task) - call s:process_arglist(rest) - call s:save_compiler_task(compiler_task) - let s:jobs_in_progress = 1 + len(rest) + call s:accio_do_sync(tasks) endif - let &l:makeprg = save_makeprg - let &l:errorformat = save_errorformat endfunction -function! accio#accio_vim(args) - let save_makeprg = &l:makeprg - let save_errorformat = &l:errorformat - for arg in s:parse_accio_args(a:args) - let [compiler, compiler_args] = matchlist(arg, '^\(\S*\)\s*\(.*\)')[1:2] - execute printf("compiler %s | silent noautocmd make! %s", compiler, compiler_args) - redraw! - let qflist = getqflist() - let compiler_target = s:get_compiler_target(&l:makeprg, compiler_args) - let compiler_task = s:new_compiler_task(compiler, compiler_target, &l:makeprg, &l:errorformat) - let compiler_task.qflist = qflist - call s:update_display(compiler_task) - call s:clear_stale_compiler_errors(compiler_task) - call s:refresh_all_signs(compiler_task) - call s:save_compiler_task(compiler_task) - call extend(s:accio_quickfix_list, qflist) - silent! colder - endfor - let &l:makeprg = save_makeprg - let &l:errorformat = save_errorformat - let force_update = !empty(s:accio_quickfix_list) || g:accio_create_empty_quickfix - call s:set_quickfix_list(s:accio_quickfix_list, force_update) - call s:cwindow() +function! accio#obliviate() abort + unlet! g:accio_focus endfunction @@ -165,15 +151,14 @@ let s:job_control_callbacks = { " ====================================================================== " Parsing Functions " ====================================================================== -function! s:parse_accio_args(args) - if a:args[0] ==# "[" && a:args[-1:] ==# "]" - let args = eval(a:args)[0] - let rest = eval(a:args)[1:] +function! accio#parse_args(args) + if empty(a:args) + return [] + elseif a:args[0] ==# "[" && a:args[-1:] ==# "]" + return eval(a:args) else - let args = a:args - let rest = [] + return [a:args] endif - return [args] + rest endfunction @@ -481,9 +466,56 @@ endfunction " ====================================================================== " Process Queue/Arglist " ====================================================================== +function! s:accio_do_async(tasks) + let save_makeprg = &l:makeprg + let save_errorformat = &l:errorformat + let [compiler, compiler_args] = matchlist(a:tasks[0], '^\(\S*\)\s*\(.*\)')[1:2] + let [compiler_command, compiler_target] = s:parse_makeprg(compiler, compiler_args) + if s:jobs_in_progress + call add(s:accio_queue, [a:tasks, bufnr("%")]) + else + let s:quickfix_cleared = 0 + let s:accio_compiler_task_ids = [] + let compiler_task = s:new_compiler_task(compiler, compiler_target, compiler_command, &l:errorformat) + call s:start_job(compiler_task) + call s:process_arglist(a:tasks[1:]) + call s:save_compiler_task(compiler_task) + let s:jobs_in_progress = 1 + len(a:tasks[1:]) + endif + let &l:makeprg = save_makeprg + let &l:errorformat = save_errorformat +endfunction + + +function! s:accio_do_sync(tasks) + let save_makeprg = &l:makeprg + let save_errorformat = &l:errorformat + for task in a:tasks + let [compiler, compiler_args] = matchlist(task, '^\(\S*\)\s*\(.*\)')[1:2] + execute printf("compiler %s | silent noautocmd make! %s", compiler, compiler_args) + redraw! + let qflist = getqflist() + let compiler_target = s:get_compiler_target(&l:makeprg, compiler_args) + let compiler_task = s:new_compiler_task(compiler, compiler_target, &l:makeprg, &l:errorformat) + let compiler_task.qflist = qflist + call s:update_display(compiler_task) + call s:clear_stale_compiler_errors(compiler_task) + call s:refresh_all_signs(compiler_task) + call s:save_compiler_task(compiler_task) + call extend(s:accio_quickfix_list, qflist) + silent! colder + endfor + let &l:makeprg = save_makeprg + let &l:errorformat = save_errorformat + let force_update = !empty(s:accio_quickfix_list) || g:accio_create_empty_quickfix + call s:set_quickfix_list(s:accio_quickfix_list, force_update) + call s:cwindow() +endfunction + + function! s:process_arglist(rest) - for args in a:rest - call accio#accio(args) + for task in a:rest + call s:accio_do_async([task]) let s:jobs_in_progress = 0 endfor endfunction @@ -493,9 +525,9 @@ function! s:accio_process_queue() if !empty(s:accio_queue) call uniq(sort(s:accio_queue)) let save_buffer = bufnr("%") - let [accio_args, target_buffer] = remove(s:accio_queue, 0) + let [tasks, target_buffer] = remove(s:accio_queue, 0) execute "silent! buffer " . target_buffer - call accio#accio(accio_args) + call s:accio_do_async(tasks) execute "buffer " save_buffer endif endfunction diff --git a/doc/accio.txt b/doc/accio.txt index 928e4ef..eaa5fe7 100644 --- a/doc/accio.txt +++ b/doc/accio.txt @@ -67,7 +67,7 @@ g:accio_update_interval *g:accio_update_interval* ============================================================================== Commands *accio-commands* -:Accio {arguments} *:Accio* +:Accio {tasks} *:Accio* Invokes the 'makeprg' specified by the compiler plugins passed to the command and displays any errors/warnings reported. If |g:accio_auto_copen| is @@ -88,6 +88,18 @@ Commands *accio-commands* a list, otherwise Vim will attempt to resolve them as variable names and throw an error +:Accio *b:accio* + Invokes |:Accio| with the arguments found in b:accio. + If not set, falls back to b:current_compiler. + +:Accio! {tasks} + Focus and execute {tasks}. Same as |:Accio| but + remembers the arguments such that they are reused in + subsequent invocations (globally) without having to + specify the {tasks} again. + +:Accio! + Forget the currently focused task(s). ============================================================================== Mappings *accio-mappings* diff --git a/plugin/accio.vim b/plugin/accio.vim index ac78da7..dfd50ba 100644 --- a/plugin/accio.vim +++ b/plugin/accio.vim @@ -43,11 +43,12 @@ augroup accio autocmd CursorMoved * call accio#echo_message() augroup END -if has("nvim") - command! -nargs=+ -complete=compiler Accio call accio#accio() -else - command! -nargs=+ -complete=compiler Accio call accio#accio_vim() -endif +command! -bang -bar -nargs=? -complete=compiler Accio + \ if empty() && 0 | + \ call accio#obliviate() | + \ else | + \ call accio#accio(accio#parse_args(), 0) | + \ endif let &cpoptions = s:save_cpo unlet s:save_cpo