Skip to content

Commit

Permalink
Get search results async in neovim
Browse files Browse the repository at this point in the history
  • Loading branch information
gabesoft committed Oct 24, 2015
1 parent f95a472 commit 00880a6
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 6 deletions.
57 changes: 51 additions & 6 deletions autoload/ags.vim
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ let s:lastCopy = ''
" Search results statistics
let s:stats = {}

" Results accumulated during an async request
let s:lines = []

" Flag that indicates whether to add to the search results
" window after a search
let s:add = 0

" Regex patterns cache
let s:patt = {
\ 'lineNo' : '^[1;30m\(\d\{1,}\)',
Expand Down Expand Up @@ -90,6 +97,7 @@ endfunction
"
function! s:processSearchData(data)
let data = substitute(a:data, '\e', '', 'g')
let data = substitute(data, '["\(\d\{-};\d\{-}\)"m', '[\1m', 'g')
let lines = split(data, '\n')
let lmaxlen = 0

Expand Down Expand Up @@ -248,26 +256,63 @@ endfunction
"
function! ags#search(args, cmd)
let last = a:cmd ==# 'last'
let add = a:cmd ==# 'add'
let s:add = a:cmd ==# 'add'
let args = ''

if last && !ags#run#hasLastCmd()
call ags#log#warn("There is no previous search")
return
elseif last
let data = ags#run#runLastCmd()
let args = ags#run#getLastArgs()
else
let args = empty(a:args) ? expand('<cword>') : a:args
let data = ags#run#ag(args)
endif

let lines = s:processSearchData(data)
if has('nvim')
let s:lines = []
call ags#run#agAsync(args,
\ function('s:onSearchOut'),
\ function('s:onSearchDone'),
\ function('s:onSearchError'))
else
let data = ags#run#ag(args)
call s:showSearchResults(data)
endif
endfunction

function! s:onSearchError(job_id, data, event)
call ags#log#warn('Search failed ' . string(a:data))
endfunction

function! s:onSearchOut(job_id, data, event)
let showInfo = empty(s:lines)
let lines = s:processSearchData(join(a:data, "\n"))
let s:lines = s:lines + lines

call s:show(lines, s:add)

let s:add = 1
if showInfo
call ags#log#info('Search started ...')
endif
endfunction

function! s:onSearchDone()
let s:stats = s:gatherStatistics(s:lines)
call ags#log#info('Search ready')
endfunction

function! s:showSearchResults(data)
let lines = s:processSearchData(a:data)
let s:stats = s:gatherStatistics(lines)
let args = ags#run#getLastArgs()

if empty(lines)
call ags#log#warn("No matches for " . string(a:args))
call ags#log#warn('No matches for ' . string(args))
elseif len(lines) == 1
call ags#log#warn(lines[0])
else
call s:show(lines, add)
call s:show(lines, s:add)
endif
endfunction

Expand Down
26 changes: 26 additions & 0 deletions autoload/ags/run.vim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ let s:last = ''
" Last args
let s:lastArgs = ''

let s:id = ''

function! s:remove(args, name)
return substitute(a:args, '\s\{}' . a:name . '\(=\S\{}\)\?', '', 'g')
endfunction
Expand Down Expand Up @@ -50,6 +52,24 @@ function! ags#run#ag(args)
return system(s:cmd(a:args))
endfunction

" Runs an ag search with the givent {args} async.
" The functions {onOut}, {onExit}, and, {onError} will be used to
" communicate with the async process
"
function! ags#run#agAsync(args, onOut, onExit, onError)
let s:lastArgs = a:args
let cmd = split(s:cmd(a:args), '\s\+')
if s:id
silent! call jobstop(s:id)
endif

let s:id = jobstart(cmd, {
\ 'on_stderr': a:onError,
\ 'on_stdout': a:onOut,
\ 'on_exit': a:onExit
\ })
endfunction

" Runs the last ag search
"
function! ags#run#runLastCmd()
Expand All @@ -62,6 +82,12 @@ function! ags#run#hasLastCmd()
return !empty(s:lastArgs)
endfunction

" Return the arguments of the last command
"
function! ags#run#getLastArgs()
return s:lastArgs
endfunction

" Displays the last ag command executed
"
function! ags#run#getLastCmd()
Expand Down

0 comments on commit 00880a6

Please sign in to comment.