vim-makejob

Minimal, asynchronous quickfix commands for Vim 8.0
git clone git://git.danielmoch.com/vim-makejob.git
Log | Files | Refs | README | LICENSE

commit 6325f439850e9e1538770796652b5b30433f5084
parent 01346afbe4623e7483593557b8075488586ec02e
Author: Daniel Moch <daniel@danielmoch.com>
Date:   Fri,  4 Nov 2016 11:55:41 -0400

Complete port to Vim 8. 0.2 release.

Diffstat:
MREADME.md | 36++++++++++++++++--------------------
Mdoc/makejob.txt | 14+++++++-------
Mplugin/makejob.vim | 89+++++++++++++++++++++++++++++++++++++------------------------------------------
3 files changed, 65 insertions(+), 74 deletions(-)

diff --git a/README.md b/README.md @@ -1,20 +1,16 @@ # Vim MakeJob -__NOTE:__ This repository is undergoing conversion from supporting Neovim -to supporting Vim. Please excuse the messiness of the documentation. - -There are plenty of [other](http://github.com/scrooloose/syntastic) [build -solutions](http://github.com/neomake/neomake) for -[Vim](http://github.com/vim/vim) and -[Neovim](http://github.com/neovim/neovim), many of them offering feature -sets that overlap with those the editor already offers. With minimalism -as a goal, _MakeJob_ implements asynchronous `:make` and `:lmake` for -Neovim in just over 100 lines of Vimscript. +There are plenty of [other build +solutions](http://github.com/scrooloose/syntastic) for +[Vim](http://github.com/vim/vim), many of them offering feature sets +that overlap with those the editor already offers. With minimalism as a +goal, _MakeJob_ implements asynchronous `:make` and `:lmake` for Vim in +just over 100 lines of Vimscript. ## Goals 1. Implement a minimal solution for asynchronous `:make` and `:lmake`. No unnecessary features. -2. Let Neovim be Neovim. Use compiler plugins to configure `makeprg` and +2. Let Vim be Vim. Use compiler plugins to configure `makeprg` and `errorformat`. Use the Quickfix or Location List window to view findings. 3. Complete feature parity with `:make` and `:lmake` per the steps @@ -23,22 +19,22 @@ Neovim in just over 100 lines of Vimscript. ## Installation ### Pathogen -`cd ~/.config/nvim/bundle` -`git clone https://github.com/djmoch/nvim-makejob.git` +`cd ~/.vim/bundle` +`git clone https://github.com/djmoch/vim-makejob.git` ### Plug.vim -`Plug 'djmoch/nvim-makejob'` +`Plug 'djmoch/vim-makejob'` Most other plugin managers will resemble one of these two. ## Usage ### The Short Version -Neovim has `:make` and `:lmake`. Replace those calls with `:MakeJob` and +Vim has `:make` and `:lmake`. Replace those calls with `:MakeJob` and `:LmakeJob`. Call it a day. If `:MakeJob` reports findings, use `:copen` to view them, and likewise `:lopen` for `:LmakeJob`. ### The Less Short Version -Users of Syntastic and Neomake may not be aware that Neovim offers many +Users of Syntastic and Neomake may not be aware that Vim offers many of their features out of the box. Here's a brief rundown. With no prior configuration, `:make` will run the `make` program with no @@ -50,7 +46,7 @@ format of the errors to look for. This gets pretty hairy, and so we're all better off trying to avoid this in favor of the easy way: compiler plugins. Using a compiler plugin easy (ex: `:compiler javac`), they abstract away the work of remembering the `errorformat`, they're -extendable, and many are already included in Neovim. _MakeJob_ uses +extendable, and many are already included in Vim. _MakeJob_ uses compilers. Also, it's possible to use `autocmd` to set the compiler of your choice @@ -73,11 +69,11 @@ with something like the following: `autocmd BufWritePost *.py :LmakeJob<CR>` -## Neovim Documentation +## Vim Documentation Part of the goal of _MakeJob_ is to minimize the size of the plugin by -using features Neovim already offers whenever possible. To that end, if +using features Vim already offers whenever possible. To that end, if any of what foregoing discussion doesn't make sense, then take a look at -the help documentation in Neovim. Of particular interest will probably +the help documentation in Vim. Of particular interest will probably be the following: 1. `:h make` diff --git a/doc/makejob.txt b/doc/makejob.txt @@ -1,14 +1,14 @@ -*makejob.txt* Minimal, asynchronous make and lmake for Neovim +*makejob.txt* Minimal, asynchronous make and lmake for Vim Author: Daniel Moch <daniel@danielmoch.com> License: MIT (see LICENSE file for details) -INTRODUCTION *makejob* *nvim-makejob* +INTRODUCTION *makejob* *vim-makejob* -There are plenty of other build solutions for Vim and Neovim, many of them -offering feature sets that overlap with those the editor already offers. With -minimalism as a goal, MakeJob implements asynchronous |:make| and |:lmake| for -Neovim in just over 100 lines of Vimscript. +There are plenty of other build solutions for Vim and Vim, many of them +offering feature sets that overlap with those the editor already offers. +With minimalism as a goal, MakeJob implements asynchronous |:make| and +|:lmake| for Vim in just over 100 lines of Vimscript. Here are your new make commands. @@ -30,4 +30,4 @@ ABOUT *makejob-about* More details can be found in README.md or by navigating to: - https://github.com/djmoch/nvim-makejob + https://github.com/djmoch/vim-makejob diff --git a/plugin/makejob.vim b/plugin/makejob.vim @@ -1,57 +1,57 @@ " -" TITLE: NVIM-MAKEJOB +" TITLE: VIM-MAKEJOB " AUTHOR: Daniel Moch <daniel@danielmoch.com> -" VERSION: 0.1 +" VERSION: 0.2 " -if exists('g:loaded_makejob') || !has('nvim') +if exists('g:loaded_makejob') || version < 800 finish endif let g:loaded_makejob = 1 let s:jobinfo = {} -function! s:JobHandler(job_id, data, event_type) abort - if a:event_type == 'stdout' && type(a:data) == type([]) - let s:jobinfo[a:job_id]['output'] = - \ s:jobinfo[a:job_id]['output'][:-2] + - \ [s:jobinfo[a:job_id]['output'][-1] . get(a:data, - \ 0, '')] + - \ a:data[1:] - elseif a:event_type == 'exit' - let is_lmake = s:jobinfo[a:job_id]['lmake'] - let output = s:jobinfo[a:job_id]['output'] +function! s:Function(name) + return substitute(a:name, '^s:', matchstr(expand('<sfile>'), + \'<SNR>\d\+_\zefunction$'),'') +endfunction - " For reasons I don't understand, copying and re-writing - " errorformat fixes a lot of parsing errors - let tempefm = &errorformat - let &errorformat = tempefm +function! s:JobHandler(channel) abort + let is_lmake = s:jobinfo[split(a:channel)[1]]['lmake'] + let output = [] + while ch_status(a:channel, {'part': 'out'}) == 'buffered' + let output += [ch_read(a:channel)] + endwhile - if is_lmake - lgetexpr output - else - cgetexpr output - endif + " For reasons I don't understand, copying and re-writing + " errorformat fixes a lot of parsing errors + let tempefm = &errorformat + let &errorformat = tempefm - let initqf = is_lmake ? getloclist(winnr()) : getqflist() - let makeoutput = [] - let idx = 0 - while idx < len(initqf) - let qfentry = initqf[idx] - if qfentry['valid'] - let makeoutput += [qfentry] - endif - let idx += 1 - endwhile + if is_lmake + lgetexpr output + else + cgetexpr output + endif - if is_lmake - call setloclist(winnr(), makeoutput, 'r') - else - call setqflist(makeoutput, 'r') + let initqf = is_lmake ? getloclist(winnr()) : getqflist() + let makeoutput = [] + let idx = 0 + while idx < len(initqf) + let qfentry = initqf[idx] + if qfentry['valid'] + let makeoutput += [qfentry] endif + let idx += 1 + endwhile - echo s:jobinfo[a:job_id]['prog']." ended with " - \ .len(makeoutput)." findings" + if is_lmake + call setloclist(winnr(), makeoutput, 'r') + else + call setqflist(makeoutput, 'r') endif + + echo s:jobinfo[split(a:channel)[1]]['prog']." ended with " + \ .len(makeoutput)." findings" endfunction function! s:NumChars(string, char, ...) @@ -101,15 +101,10 @@ function! s:MakeJob(lmake, ...) let joblist += [a:1] endif endif - let opts = { - \ 'on_stdout': function('s:JobHandler'), - \ 'on_stderr': function('s:JobHandler'), - \ 'on_exit': function('s:JobHandler') - \ } - let jobid = jobstart(joblist, opts) - let s:jobinfo[jobid] = {'prog': joblist[0], 'output': [''], - \ 'lmake': a:lmake} - echo s:jobinfo[jobid]['prog'].' started' + let opts = { 'close_cb' : s:Function('s:JobHandler') } + let job = job_start(joblist, opts) + let s:jobinfo[split(job_getchannel(job))[1]] = {'prog': joblist[0],'lmake': a:lmake} + echo s:jobinfo[split(job_getchannel(job))[1]]['prog'].' started' endfunction command! -nargs=? MakeJob call s:MakeJob(0,<f-args>)