Skip to content

Commit

Permalink
Add :AsyncEmbed
Browse files Browse the repository at this point in the history
  • Loading branch information
prabirshrestha committed Jun 20, 2020
1 parent d15123a commit 6102020
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 24 deletions.
26 changes: 2 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,14 @@ APIs are based on neovim's job control APIs.
## Embedding

Async.vim can be either embedded with other plugins or be used as an external plugin.
If you want to embed all you need is to change these 5 function names async#job# to what ever you want. E.g.:
If you want to embed run the following vim command.

```vim
" public apis {{{
function! yourplugin#job#start(cmd, opts) abort
return s:job_start(a:cmd, a:opts)
endfunction
function! yourplugin#job#stop(jobid) abort
call s:job_stop(a:jobid)
endfunction
function! yourplugin#job#send(jobid, data) abort
call s:job_send(a:jobid, a:data)
endfunction
function! yourplugin#job#wait(jobids, ...) abort
let l:timeout = get(a:000, 0, -1)
return s:job_wait(a:jobids, l:timeout)
endfunction
function! yourplugin#job#pid(jobid) abort
return s:job_pid(a:jobid)
endfunction
" }}}
:AsyncEmbed path=./autoload/myplugin/job.vim namespace=myplugin#job
```

## Todos
* Fallback to sync `system()` calls in vim that doesn't support `job`
* `job_stop` and `job_send` is treated as noop when using `system()`
* `on_stderr` doesn't work when using `system()`
* Fallback to python/ruby threads and vimproc instead of using `system()` for better compatibility (PRs welcome!!!)

48 changes: 48 additions & 0 deletions autoload/async/embedder.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
let s:autoload_root = expand('<sfile>:p:h:h')
let s:git_dir = simplify(expand('<sfile>:p:h:h:h') . '/.git')

function! s:get_git_commit() abort
if !executable('git') || !isdirectory(s:git_dir)
return 'UNKNOWN'
endif

let l:git = 'git --git-dir=' . shellescape(s:git_dir) . ' '
let l:commit = system(l:git . 'rev-parse HEAD')
let l:is_dirty = system(l:git . 'status --porcelain') =~? '\S'

return l:commit . (l:is_dirty ? ' (dirty)' : '')
endfunction

function! async#embedder#embed(...) abort
let l:args = {}

for l:arg in a:000
let l:idx = stridx(l:arg, '=')
let l:key = l:arg[:l:idx - 1]
let l:value = l:arg[l:idx + 1:]
let l:args[l:key] = l:value
endfor

if !has_key(l:args, 'path')
echom 'path required'
return
endif

if !has_key(l:args, 'namespace')
echom 'namespace required'
endif


let l:lines = readfile(s:autoload_root . '/async/job.vim')
let l:lines = map(l:lines, {_, l -> substitute(l, '\V\C\<async#job', l:args['namespace'], 'g')})

let l:content = [
\ printf('" https://github.com/prabirshrestha/async.vim#%s', s:get_git_commit()),
\ '" :AsyncEmbed ' . join(a:000, ' '),
\ '',
\ ]

let l:content += l:lines
call mkdir(fnamemodify(l:args['path'], ':h'), 'p')
call writefile(l:content, l:args['path'])
endfunction
7 changes: 7 additions & 0 deletions plugin/async.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
if exists('g:async_vim')
finish
endif
let g:async_vim = 1

" :AsyncEmbed path=./autoload/myplugin/job.vim namespace=myplugin#job
command! -nargs=+ AsyncEmbed :call async#embedder#embed(<f-args>)

0 comments on commit 6102020

Please sign in to comment.