Skip to content

Commit

Permalink
Add preview support for grep provider (#138)
Browse files Browse the repository at this point in the history
* Add preview support for grep provider

* Nits

* Return directly if meeting any expection when on_move

* Rename to g:clap.preview.add_highlight()

* .
  • Loading branch information
liuchengxu authored Nov 29, 2019
1 parent 4c5affe commit dfffb5e
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 66 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,30 @@ CHANGELOG
- New provider `:Clap registers`.
- New provider `:Clap command`.
- Add a brief description for each provider used in `:Clap`.
- Add syntax for `:Clap jumps`.
- Add the option `g:clap_spinner_frames`.
- Add the option `g:clap_prompt_format`.
- Add the option `g:clap_enable_icon` for configuring the icon functionality globally.
- Add the option `g:clap_popup_cursor_shape` for configuring the mocked cursor shape.
- Add the options `g:clap_fuzzy_match_hl_groups` for configuring the color of fuzzy matched items easier.
- Add an utility function `clap#helper#build_maple()` for building maple easily in vim. Use `:call clap#helper#build_maple()` to install maple inside vim.
- Add the preview support for `:Clap grep`.
- Support running from any specified directory by passing it via the last argument for `:Clap files` and `:Clap grep`.

### Changed

- Put `call g:clap.provider.on_exit()` just before `silent doautocmd <nomodeline> User ClapOnExit` in `clap#_exit()`.

### Improved

- Reverse the original order of `jumps` to make the newer jump appear first.

### Fixed

- sink of `:Clap command_history`.([#109](https://github.com/liuchengxu/vim-clap/issues/109))
- Apply `redraw` when navigating and selecting via tab in vim's popup.
- Fix `bg` of icon highlight([#132](https://github.com/liuchengxu/vim-clap/issues/132))
- Use absolute directory for `g:__clap_provider_cwd` ([#137](https://github.com/liuchengxu/vim-clap/issues/137)).

## [0.1] 2019-10-27

Expand Down
31 changes: 31 additions & 0 deletions autoload/clap/api.vim
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ function! s:init_provider() abort

" When you press Ctrl-J/K
function! provider.on_move() abort
if g:__clap_has_no_matches
return
endif
if has_key(self._(), 'on_move')
if s:on_move_timer != -1
call timer_stop(s:on_move_timer)
Expand Down Expand Up @@ -548,6 +551,13 @@ function! s:inject_base_api(dict) abort
let dict.setbufvar_batch = function('s:_setbufvar_batch')
endfunction

function! s:matchaddpos(lnum) abort
if exists('w:clap_preview_hi_id')
call matchdelete(w:clap_preview_hi_id)
endif
let w:clap_preview_hi_id = matchaddpos('Search', [[a:lnum]])
endfunction

function! clap#api#bake() abort
let g:clap = {}
let g:clap.is_busy = 0
Expand All @@ -566,11 +576,32 @@ function! clap#api#bake() abort

if s:is_nvim
let g:clap.preview = g:clap#floating_win#preview

function! g:clap.preview.load_syntax(filetype) abort
call g:clap.preview.setbufvar('&ft', a:filetype)
endfunction

function! g:clap.preview.add_highlight(lnum) abort
noautocmd call win_gotoid(g:clap.preview.winid)
call s:matchaddpos(a:lnum)
noautocmd call win_gotoid(g:clap.input.winid)
endfunction

let g:clap#display_win = g:clap#floating_win#display
let g:clap.open_win = function('clap#floating_win#open')
let g:clap.close_win = function('clap#floating_win#close')
else
let g:clap.preview = g:clap#popup#preview

function! g:clap.preview.load_syntax(filetype) abort
" vim using noautocmd in win_execute, hence we have to load the syntax file manually.
call win_execute(g:clap.preview.winid, 'runtime syntax/'.a:filetype.'.vim')
endfunction

function! g:clap.preview.add_highlight(lnum) abort
call win_execute(g:clap.preview.winid, 'noautocmd call s:matchaddpos(a:lnum)')
endfunction

let g:clap#display_win = g:clap#popup#display
let g:clap.open_win = function('clap#popup#open')
let g:clap.close_win = function('clap#popup#close')
Expand Down
2 changes: 2 additions & 0 deletions autoload/clap/dispatcher.vim
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ endfunction

function! s:has_no_matches() abort
if g:clap.display.is_empty()
let g:__clap_has_no_matches = v:true
return v:true
else
let g:__clap_has_no_matches = v:false
return v:false
endif
endfunction
Expand Down
40 changes: 40 additions & 0 deletions autoload/clap/ext.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
" Author: liuchengxu <xuliuchengxlc@gmail.com>
" Description: Get filetype based on the fname's extension.

let s:save_cpo = &cpoptions
set cpoptions&vim

" This is not complete, but should be enough to cover the most extensions.
" https://vi.stackexchange.com/questions/9962/get-filetype-by-extension-or-filename-in-vimscript
function! s:init_ext2ft() abort
let matched = []
for line in split(execute('autocmd filetypedetect'), "\n")
if line =~? '\*\.\a\+\s*setf'
call add(matched, line)
endif
endfor

let s:ext2ft = {}
for line in matched
let splitted = split(line)
let ext = split(splitted[0], '\.')[-1]
let ft = splitted[-1]
let s:ext2ft[ext] = ft
endfor
endfunction

if !exists('s:ext2ft')
call s:init_ext2ft()
endif

function! clap#ext#into_filetype(fname) abort
let ext = fnamemodify(a:fname, ':e')
if !empty(ext) && has_key(s:ext2ft, ext)
return s:ext2ft[ext]
else
return ''
endif
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo
6 changes: 3 additions & 3 deletions autoload/clap/impl.vim
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function! s:on_typed_sync_impl() abort

call clap#spinner#set_busy()

let l:has_no_matches = v:false
let g:__clap_has_no_matches = v:false

" Do not use get(g:, '__clap_forerunner_result', s:get_source()) as vim
" evaluates the default value of get(...) any how.
Expand All @@ -89,7 +89,7 @@ function! s:on_typed_sync_impl() abort

if empty(l:lines)
let l:lines = [g:clap_no_matches_msg]
let l:has_no_matches = v:true
let g:__clap_has_no_matches = v:true
call clap#impl#refresh_matches_count('0')
else
call clap#impl#refresh_matches_count(string(len(l:lines)))
Expand All @@ -100,7 +100,7 @@ function! s:on_typed_sync_impl() abort
call g:clap#display_win.compact_if_undersize()
call clap#spinner#set_idle()

if !l:has_no_matches
if !g:__clap_has_no_matches
if exists('g:__clap_fuzzy_matched_indices')
call s:add_highlight_for_fuzzy_matched()
else
Expand Down
74 changes: 50 additions & 24 deletions autoload/clap/provider/grep.vim
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ let s:grep_cmd_format = get(g:, 'clap_provider_grep_cmd_format', '%s %s "%s"'.(h

let s:old_query = ''
let s:grep_timer = -1
let s:icon_appended = v:false

if has('nvim')
let s:default_prompt = 'Type anything you want to find'
Expand Down Expand Up @@ -74,7 +75,7 @@ function! s:spawn(query) abort

call s:clear_job_and_matches()

let s:old_pos = getcurpos()
let s:preview_cache = {}
let s:old_query = query

" Clear the previous search result and reset cache.
Expand All @@ -99,50 +100,73 @@ function! s:grep_exit() abort
call clap#dispatcher#jobstop()
endfunction

function! s:matchlist(line, pattern) abort
if s:icon_appended
return matchlist(a:line, '^.* '.a:pattern)
else
return matchlist(a:line, '^'.a:pattern)
endif
endfunction

function! s:grep_on_move() abort
let pattern = '\(.*\):\(\d\+\):\(\d\+\):'
let cur_line = g:clap.display.getcurline()
let matched = s:matchlist(cur_line, pattern)
try
let [fpath, lnum] = [matched[1], str2nr(matched[2])]
catch
return
endtry
if !has_key(s:preview_cache, fpath)
if filereadable(expand(fpath))
let s:preview_cache[fpath] = {
\ 'lines': readfile(expand(fpath), ''),
\ 'filetype': clap#ext#into_filetype(fpath)
\ }
else
echom fpath.' is unreadable'
return
endif
endif
let [start, end, hi_lnum] = clap#util#get_preview_line_range(lnum, 5)
let preview_lines = s:preview_cache[fpath]['lines'][start : end]
call g:clap.preview.show(preview_lines)
call g:clap.preview.load_syntax(s:preview_cache[fpath].filetype)
call g:clap.preview.add_highlight(hi_lnum)
endfunction

function! s:grep_sink(selected) abort
call s:grep_exit()
let line = a:selected

let pos_pattern = '\(.*\):\(\d\+\):\(\d\+\):'
if get(s:, 'icon_appended', v:false)
let matched = matchlist(line, '^.* '.pos_pattern)
else
let matched = matchlist(line, '^'.pos_pattern)
endif

let pattern = '\(.*\):\(\d\+\):\(\d\+\):'
let matched = s:matchlist(line, pattern)
let [fpath, linenr, column] = [matched[1], str2nr(matched[2]), str2nr(matched[3])]
let s:icon_appended = v:false

" NOTE: Important!
call g:clap.start.goto_win()

if has_key(g:clap, 'open_action')
execute g:clap.open_action fpath
else
" Cannot use noautocmd here as it would lose syntax, and ...
execute 'edit' fpath
endif

noautocmd call cursor(linenr, column)
normal! zz
call call('clap#util#blink', s:grep_blink)
endfunction

function! s:into_qf_item(line, pattern) abort
let matched = s:matchlist(a:line, a:pattern)
let [fpath, linenr, column, text] = [matched[1], str2nr(matched[2]), str2nr(matched[3]), matched[4]]
return {'filename': fpath, 'lnum': linenr, 'col': column, 'text': text}
endfunction

function! s:grep_sink_star(lines) abort
call s:grep_exit()
let qflist = []
for line in a:lines
let pos_pattern = '\(.*\):\(\d\+\):\(\d\+\):\(.*\)'
if get(s:, 'icon_appended', v:false)
let matched = matchlist(line, '^.* '.pos_pattern)
else
let matched = matchlist(line, '^'.pos_pattern)
endif
let [fpath, linenr, column, text] = [matched[1], str2nr(matched[2]), str2nr(matched[3]), matched[4]]
call add(qflist, {'filename': fpath, 'lnum': linenr, 'col': column, 'text': text})
endfor
let pattern = '\(.*\):\(\d\+\):\(\d\+\):\(.*\)'
call setqflist(map(a:lines, 's:into_qf_item(v:val, pattern)'))
let s:icon_appended = v:false
call setqflist(qflist)
call g:clap.start.goto_win()
copen
cc
endfunction
Expand Down Expand Up @@ -183,6 +207,8 @@ let s:grep['sink*'] = function('s:grep_sink_star')

let s:grep.on_typed = function('s:grep_with_delay')

let s:grep.on_move = function('s:grep_on_move')

let s:grep.on_enter = { -> g:clap.display.setbufvar('&ft', 'clap_grep') }

if get(g:, 'clap_provider_grep_enable_icon',
Expand Down
41 changes: 3 additions & 38 deletions autoload/clap/provider/marks.vim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ set cpoptions&vim

let s:marks = {}

let s:ext_to_ft = {'rs': 'rust', 'js': 'javascript'}

let s:preview_size = 5

function! s:format_mark(line) abort
Expand All @@ -28,34 +26,6 @@ function! s:marks.sink(line) abort
execute 'normal! `'.matchstr(a:line, '\S').'zz'
endfunction

function! s:matchaddpos(lnum) abort
if exists('w:clap_mark_hi_id')
call matchdelete(w:clap_mark_hi_id)
endif
let w:clap_mark_hi_id = matchaddpos('Search', [[a:lnum]])
endfunction

if has('nvim')
function! s:execute_matchaddpos(lnum) abort
noautocmd call win_gotoid(g:clap.preview.winid)
call s:matchaddpos(a:lnum)
noautocmd call win_gotoid(g:clap.input.winid)
endfunction

function! s:render_syntax(ft) abort
call g:clap.preview.setbufvar('&ft', a:ft)
endfunction
else
function! s:execute_matchaddpos(lnum) abort
call win_execute(g:clap.preview.winid, 'noautocmd call s:matchaddpos(a:lnum)')
endfunction

function! s:render_syntax(ft) abort
" vim using noautocmd in win_execute, hence we have to load the syntax file manually.
call win_execute(g:clap.preview.winid, 'runtime syntax/'.a:ft.'.vim')
endfunction
endif

function! clap#provider#marks#preview_impl(line, col, file_text) abort
let [line, col, file_text] = [a:line, a:col, a:file_text]

Expand Down Expand Up @@ -90,17 +60,12 @@ function! clap#provider#marks#preview_impl(line, col, file_text) abort
let ft = fnamemodify(expand(bufname(origin_bufnr)), ':e')
endif
else
let ext = fnamemodify(file_text, ':e')
if !empty(ext) && has_key(s:ext_to_ft, ext)
let ft = s:ext_to_ft[ext]
else
let ft = ''
endif
let ft = clap#ext#into_filetype(file_text)
endif
if !empty(ft)
call s:render_syntax(ft)
call g:clap.preview.load_syntax(ft)
endif
call s:execute_matchaddpos(hi_lnum)
call g:clap.preview.add_highlight(hi_lnum)
endif
endfunction

Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/util.vim
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ endfunction

if has('nvim')

" 0-based
function! clap#util#add_highlight_at(lnum, col, hl_group) abort
" 0-based
call nvim_buf_add_highlight(g:clap.display.bufnr, -1, a:hl_group, a:lnum, a:col, a:col+1)
endfunction

Expand Down

0 comments on commit dfffb5e

Please sign in to comment.