Skip to content

Commit

Permalink
Resolve async forerunner job performance issue (#183)
Browse files Browse the repository at this point in the history
* Allow running command via maple

* Use cmd option of maple in vim-clap

* Check if channel can read

* Nits

* .

* .

* Renaming

* .

* Add --output-threshold in vim-clap

* .
  • Loading branch information
liuchengxu authored Dec 28, 2019
1 parent 8871b3b commit 3c81bab
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 24 deletions.
19 changes: 10 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions autoload/clap.vim
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,11 @@ function! s:clear_state() abort
\ 'g:__clap_initial_source_size',
\ ])

if exists('g:__clap_forerunner_tmp_file')
if filereadable(g:__clap_forerunner_tmp_file)
call delete(g:__clap_forerunner_tmp_file)
if exists('g:__clap_forerunner_tempfile')
if filereadable(g:__clap_forerunner_tempfile)
call delete(g:__clap_forerunner_tempfile)
endif
unlet g:__clap_forerunner_tmp_file
unlet g:__clap_forerunner_tempfile
endif
endfunction

Expand Down
4 changes: 2 additions & 2 deletions autoload/clap/api.vim
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ function! s:init_provider() abort
" Pipe the source into the external filter
function! s:wrap_async_cmd(source_cmd) abort
let ext_filter_cmd = clap#filter#get_external_cmd_or_default()
if exists('g:__clap_forerunner_tmp_file')
let cmd = s:read_from_file_or_pipe(ext_filter_cmd, g:__clap_forerunner_tmp_file)
if exists('g:__clap_forerunner_tempfile')
let cmd = s:read_from_file_or_pipe(ext_filter_cmd, g:__clap_forerunner_tempfile)
else
" FIXME Does it work well in Windows?
" Run the source command and pipe into the external filter.
Expand Down
88 changes: 81 additions & 7 deletions autoload/clap/forerunner.vim
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,31 @@ function! s:on_complete() abort
else
let tmp = tempname()
if writefile(s:chunks, tmp) == 0
let g:__clap_forerunner_tmp_file = tmp
let g:__clap_forerunner_tempfile = tmp
endif
unlet s:chunks
endif
endfunction

function! s:on_complete_maple() abort
if !empty(s:chunks)
let decoded = json_decode(s:chunks[0])

if empty(g:clap.input.get())
call g:clap.display.set_lines_lazy(decoded.lines)
endif

let g:clap.display.initial_size = decoded.total
call clap#impl#refresh_matches_count(string(decoded.total))

if has_key(decoded, 'tempfile')
let g:__clap_forerunner_tempfile = decoded.tempfile
else
let g:__clap_forerunner_result = decoded.lines
endif
endif
endfunction

function! s:on_event(job_id, data, event) abort
" We only process the job that was spawned last time.
if a:job_id == s:job_id
Expand All @@ -56,28 +75,83 @@ function! s:on_event(job_id, data, event) abort
endif
endfunction

function! s:on_event_maple(job_id, data, event) abort
" We only process the job that was spawned last time.
if a:job_id == s:job_id
if a:event ==# 'stdout'
if len(a:data) > 1
" Second last is the real last one for neovim.
call extend(s:chunks, a:data[:-2])
endif
elseif a:event ==# 'stderr'
" Ignore the error
else
call s:on_complete_maple()
endif
endif
endfunction

function! s:close_cb(channel) abort
if clap#job#vim8_job_id_of(a:channel) == s:job_id
" https://github.com/vim/vim/issues/5143
let s:chunks = split(ch_readraw(a:channel), "\n")
call s:on_complete()
if ch_canread(a:channel)
let s:chunks = split(ch_readraw(a:channel), "\n")
call s:on_complete()
endif
endif
endfunction

function! s:close_cb_maple(channel) abort
if clap#job#vim8_job_id_of(a:channel) == s:job_id
if ch_canread(a:channel)
let s:chunks = split(ch_readraw(a:channel), "\n")
call s:on_complete_maple()
endif
endif
endfunction

if has('nvim')
function! s:start_maple(cmd) abort
let s:job_id = clap#job#start_buffered(a:cmd, function('s:on_event_maple'))
endfunction

function! s:start_forerunner(cmd) abort
let s:job_id = clap#job#start_buffered(a:cmd, function('s:on_event'))
endfunction
else
function! s:start_maple(cmd) abort
let s:job_id = clap#job#start_buffered(a:cmd, function('s:close_cb_maple'))
endfunction

function! s:start_forerunner(cmd) abort
let s:job_id = clap#job#start_buffered(a:cmd, function('s:close_cb'))
endfunction
endif

function! clap#forerunner#start(cmd) abort
let s:chunks = []
call clap#rooter#run(function('s:start_forerunner'), a:cmd)
endfunction
if clap#maple#is_available()
let s:empty_filter_cmd = printf(clap#maple#filter_cmd_fmt(), '')

function! s:into_maple_cmd(cmd) abort
let cmd_dir = clap#rooter#working_dir()
let cmd = printf('%s --cmd "%s" --cmd-dir "%s" --output-threshold %d',
\ s:empty_filter_cmd,
\ a:cmd,
\ cmd_dir,
\ s:builtin_fuzzy_filter_threshold,
\ )
return cmd
endfunction

function! clap#forerunner#start(cmd) abort
let s:chunks = []
call s:start_maple(s:into_maple_cmd(a:cmd))
endfunction
else
function! clap#forerunner#start(cmd) abort
let s:chunks = []
call clap#rooter#run(function('s:start_forerunner'), a:cmd)
endfunction
endif

function! clap#forerunner#stop() abort
if s:job_id > 0
Expand Down
16 changes: 16 additions & 0 deletions autoload/clap/rooter.vim
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ function! clap#rooter#try_set_cwd() abort
endif
endfunction

function! clap#rooter#working_dir() abort
if exists('g:__clap_provider_cwd')
let dir = g:__clap_provider_cwd
elseif clap#should_use_raw_cwd()
let dir = getcwd()
else
let git_root = clap#util#find_git_root(g:clap.start.bufnr)
if empty(git_root)
let dir = expand('#'.g:clap.start.bufnr.':p:h')
else
let dir = git_root
endif
endif
return dir
endfunction

function! s:run_from_target_dir(target_dir, Run, run_args) abort
let save_cwd = getcwd()
try
Expand Down
10 changes: 8 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,14 @@ impl Maple {
.collect::<Vec<String>>();

let mut cmd = Command::new(args[0].clone());
if let Some(ref cmd_dir) = self.cmd_dir {
cmd.current_dir(cmd_dir);
if let Some(cmd_dir) = self.cmd_dir.clone() {
if cmd_dir.is_dir() {
cmd.current_dir(cmd_dir);
} else {
let mut cmd_dir = cmd_dir;
cmd_dir.pop();
cmd.current_dir(cmd_dir);
}
}
cmd.args(&args[1..]);

Expand Down

0 comments on commit 3c81bab

Please sign in to comment.