Skip to content

Commit

Permalink
Experimental support of clap plugin (#950)
Browse files Browse the repository at this point in the history
* Clap plugin

* Introduce PluginSession

* Rename to notify_provider()

* Remove unused other notification variant

* Commit plugin/mod.rs

* Skip matchdelete if win is not valid

* Separate out plugin/highlight_cursor_word.rs

* Return WordHighlights in find_highlight_positions()

* Update last_cword when current cword is empty

* Fix line start 0

* Clean up

* Skip when cursor word is not meaningful

* Use byte positions

* Fix multiple words in a line

* Distinguish the current and others

* Fixes

* I

* Move clap#init#() into clap#()

* Introduce g:clap_start_server_on_startup

* Refactor service

* Minor refactorings

* Clean up

* Fix clippy

* Make session_id in MethodCall optional

* Nits

* Separate out plugin

* Rename clap#client#notify() to clap#client#notify_provider()

* Do not return early for the same word

* Minor refactorings

Rename to request_async()

Nits

* Nits

* Clear highlights on InsertEnter

* Fix col index

* open-config

* Adjust display line width

* Add ignore-comment-line config

* Remove unnecessary clone

* Nits

* Add ignore_files

* Adjust context tag header line width

* getpos()

* Adjust grep sink

* Fix clippy

* Fxi deprecated clap#client#call_on_move()

* markdown_toc plugin

* preview title for recent_files

* Fix clippy

* Refactor note_recent_files

* Add help for g:clap_start_server_on_startup

* update-toc & delete-toc

* Initialize tagfiles provider

Copied from #557

* Make tagfiles compile

* Minor refactorings to tagfiles

* tagfiles provider

* Add [input-history] config

* Add g:clap_plugin_experimental

* Add blines TODO

* Fix tagfiles

* Empty on_move impl for tagfiles

* Add [input-history] config

* Add g:clap_plugin_experimental

* Add blines TODO

* Initialize tagfiles provider

Copied from #557

* Make tagfiles compile

* Minor refactorings to tagfiles

* Introduce tagfiles provider

Use empty on_move impl for tagfiles.

* Fix tagfiles

Fix tagfiles sink

* Tiny refactorings

* extract handle_action()

* Add color-eyre

* Always load ftplugin clap

* Start using markdown_toc plugin in README.md

* Add TODO

* Fix win_is_valid api

* api: append_and_write()

* Fix tests

* Keep plugin undocumented for now
  • Loading branch information
liuchengxu authored Apr 16, 2023
1 parent d7dcadd commit 9560801
Show file tree
Hide file tree
Showing 62 changed files with 1,712 additions and 621 deletions.
631 changes: 416 additions & 215 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ tokio = { version = "1.23", features = ["rt"] }

cli = { path = "crates/cli" }
upgrade = { path = "crates/upgrade" }
color-eyre = "0.6.2"

[build-dependencies]
built = { package = "built", version = "0.6", features = ["git2"] }
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Vim-clap is a modern generic performant finder using the `floating_win` of neovi

## Table of Contents

<!-- TOC GFM -->
<!-- clap-markdown-toc -->

* [Features](#features)
* [Caveats](#caveats)
Expand Down Expand Up @@ -47,7 +47,7 @@ Vim-clap is a modern generic performant finder using the `floating_win` of neovi
* [Credit](#credit)
* [License](#license)

<!-- /TOC -->
<!-- /clap-markdown-toc -->

## Features

Expand Down Expand Up @@ -319,6 +319,13 @@ User config file is loaded from:
tiebreak = "score,-begin,-end,-length"
```

<!-- ### Plugin -->

<!-- Apart from the providers focusing on the general searching/filtering, vim-clap has an experimental support of a varity of vim plugins reimplemented in Rust. I created them in order to shorten my plugin list in vimrc, use at your own risk. -->

<!-- - highlight-cursor-word -->
<!-- - vim-markdown-toc -->

## How to define your own provider

```vim
Expand Down
10 changes: 5 additions & 5 deletions autoload/clap.vim
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function! s:inject_default_impl_is_ok(provider_info) abort
" If sync provider
if has_key(provider_info, 'source')
if !has_key(provider_info, 'on_typed')
let provider_info.on_typed = { -> clap#client#notify('on_typed') }
let provider_info.on_typed = { -> clap#client#notify_provider('on_typed') }
endif
if !has_key(provider_info, 'filter')
let provider_info.filter = function('clap#legacy#filter#sync')
Expand Down Expand Up @@ -297,10 +297,6 @@ function! clap#for(provider_id_or_alias) abort
call clap#indicator#render()
endfunction

if !exists('g:clap')
call clap#init#()
endif

function! s:parse_opts(args) abort
let idx = 0
let g:clap.provider.raw_args = a:args
Expand Down Expand Up @@ -337,6 +333,10 @@ function! s:parse_opts(args) abort
endfunction

function! clap#(bang, ...) abort
if !exists('g:clap')
call clap#init#()
endif

if a:000 == ['install-binary']
call clap#installer#install(v:false)
return
Expand Down
30 changes: 28 additions & 2 deletions autoload/clap/api.vim
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,26 @@ else
endfunction
endif

let s:api = {}

if s:is_nvim
function! clap#api#floating_win_is_valid(winid) abort
return nvim_win_is_valid(a:winid)
endfunction

function! s:api.win_is_valid(winid) abort
return nvim_win_is_valid(a:winid)
endfunction

else
function! clap#api#floating_win_is_valid(winid) abort
return !empty(popup_getpos(a:winid))
endfunction
endif

let s:api = {}
function! s:api.win_is_valid(winid) abort
return win_screenpos(a:winid) != [0, 0]
endfunction
endif

function! s:api.context_query_or_input() abort
return has_key(g:clap.context, 'query') ? g:clap.context.query : g:clap.input.get()
Expand Down Expand Up @@ -105,6 +114,23 @@ function! s:api.set_var(name, value) abort
execute 'let '.a:name.'= a:value'
endfunction

function! s:api.current_buffer_path() abort
return expand('#'.bufnr('%').':p')
endfunction

function! s:api.matchdelete_batch(match_ids, winid) abort
call map(a:match_ids, 'matchdelete(v:val, a:winid)')
endfunction

function! s:api.curbufline(lnum) abort
return get(getbufline(bufnr(''), a:lnum), 0, v:null)
endfunction

function! s:api.append_and_write(lnum, text) abort
call append(a:lnum, a:text)
silent noautocmd write
endfunction

function! clap#api#call(method, args) abort
" Catch all the exceptions
try
Expand Down
64 changes: 38 additions & 26 deletions autoload/clap/client.vim
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ let s:req_id = get(s:, 'req_id', 0)
let s:handlers = get(s:, 'handlers', {})
let s:session_id = get(s:, 'session_id', 0)

let s:last_recent_file = v:null

function! clap#client#handle(msg) abort
let decoded = json_decode(a:msg)

Expand Down Expand Up @@ -42,38 +40,54 @@ function! clap#client#handle(msg) abort
endif
endfunction

function! s:send_notification(method, params) abort
call clap#job#daemon#send_message(json_encode({
\ 'method': a:method,
\ 'params': a:params,
\ 'session_id': s:session_id,
\ }))
function! s:notify_provider(method, params) abort
if clap#job#daemon#is_running()
call clap#job#daemon#send_message(json_encode({
\ 'method': a:method,
\ 'params': a:params,
\ 'session_id': s:session_id,
\ }))
endif
endfunction

function! s:send_method_call(method, params) abort
let s:req_id += 1
call clap#job#daemon#send_message(json_encode({
\ 'id': s:req_id,
\ 'method': a:method,
\ 'params': a:params,
\ 'session_id': s:session_id,
\ }))
function! s:request_async(method, params) abort
if clap#job#daemon#is_running()
let s:req_id += 1
call clap#job#daemon#send_message(json_encode({
\ 'id': s:req_id,
\ 'method': a:method,
\ 'params': a:params,
\ }))
endif
endfunction

" Recommended API
" Optional argument: params: v:null, List, Dict
function! clap#client#notify_provider(method, ...) abort
call s:notify_provider(a:method, get(a:000, 0, v:null))
endfunction

function! clap#client#notify(method, ...) abort
call s:send_notification(a:method, get(a:000, 0, v:null))
if clap#job#daemon#is_running()
call clap#job#daemon#send_message(json_encode({
\ 'method': a:method,
\ 'params': get(a:000, 0, v:null),
\ }))
endif
endfunction

" Optional argument: params: v:null, List, Dict
function! clap#client#call(method, callback, ...) abort
call s:send_method_call(a:method, get(a:000, 0, v:null))
function! clap#client#request_async(method, callback, ...) abort
call s:request_async(a:method, get(a:000, 0, v:null))
if a:callback isnot v:null
let s:handlers[s:req_id] = a:callback
endif
endfunction

function! clap#client#request(method, ...) abort
call s:request_async(a:method, get(a:000, 0, v:null))
endfunction

function! clap#client#notify_on_init(...) abort
if g:clap.display.winid < 0
return
Expand All @@ -94,25 +108,22 @@ function! clap#client#notify_on_init(...) abort
if a:0 > 0
call extend(params, a:1)
endif
call s:send_notification('new_session', params)
call s:notify_provider('new_session', params)
endfunction

function! clap#client#notify_recent_file() abort
if !clap#job#daemon#is_running()
return
endif
if &buftype ==# 'nofile'
return
endif
let file = expand(expand('<afile>:p'))
call s:send_notification('note_recent_files', [file])
call s:notify_provider('note_recent_files', [file])
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"" Deprecated and unused in clap repo, but keep them to not break the users using old version.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! clap#client#call_preview_file(extra) abort
call clap#client#call('preview/file', function('clap#impl#on_move#handler'), clap#preview#maple_opts(a:extra))
call clap#client#request_async('preview/file', function('clap#impl#on_move#handler'), clap#preview#maple_opts(a:extra))
endfunction

" One optional argument: Dict, extra params
Expand All @@ -125,7 +136,8 @@ function! clap#client#call_on_move(method, callback, ...) abort
if a:0 > 0
call extend(params, a:1)
endif
call clap#client#call(a:method, a:callback, params)
" on_move callback is unused as it's already handled by Rust backend.
call s:notify_provider(a:method, params)
endfunction

let &cpoptions = s:save_cpo
Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/impl/on_move.vim
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ if clap#maple#is_available()
endfunction

function! clap#impl#on_move#async() abort
call clap#client#notify('on_move')
call clap#client#notify_provider('on_move')
endfunction
else
function! s:dispatch_on_move_impl() abort
Expand Down
11 changes: 3 additions & 8 deletions autoload/clap/init.vim
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,9 @@ function! clap#init#() abort
call s:init_submatches_hl_group()
call s:init_fuzzy_match_hl_groups()

" Spawn the daemon process eagerly
if clap#maple#is_available()
call clap#job#daemon#start(function('clap#client#handle'))

augroup ClapRecentFiles
autocmd!
autocmd BufAdd,BufEnter * call clap#client#notify_recent_file()
augroup END
" Spawn the daemon process if not running
if !clap#job#daemon#is_running()
call clap#job#daemon#start()
endif
endfunction

Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/installer.vim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function! s:OnExit(status, bufnr, success_info, ErrorCallback) abort
call a:ErrorCallback()
endif
if clap#maple#is_available()
call clap#job#daemon#start(function('clap#client#handle'))
call clap#job#daemon#start()
endif
endfunction

Expand Down
7 changes: 3 additions & 4 deletions autoload/clap/job/daemon.vim
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,10 @@ function! clap#job#daemon#is_running() abort
return s:job_id != -1
endfunction

function! clap#job#daemon#start(MessageHandler) abort
let s:MessageHandler = a:MessageHandler
function! clap#job#daemon#start() abort
let s:MessageHandler = function('clap#client#handle')
call s:start_service_job(clap#maple#build_cmd('rpc'))
call clap#client#notify('initialize_global_env')
return
call clap#client#notify_provider('initialize_global_env')
endfunction

let &cpoptions = s:save_cpo
Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/maple.vim
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ endif

if s:maple_bin isnot v:null
function! clap#maple#clean_up() abort
call clap#client#notify('exit')
call clap#client#notify_provider('exit')
endfunction
else
function! clap#maple#clean_up() abort
Expand Down
6 changes: 5 additions & 1 deletion autoload/clap/navigation.vim
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ endfunction
function! s:trigger_on_move() abort
" try
if g:clap.display.win_is_valid()
call g:clap.provider.on_move()
if has_key(g:clap.provider._(), 'on_move_async')
call g:clap.provider._().on_move_async()
else
call g:clap.provider.on_move()
endif
endif
" catch
" call g:clap.preview.show([v:exception])
Expand Down
29 changes: 29 additions & 0 deletions autoload/clap/plugin/highlight_cursor_word.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
" Author: liuchengxu <xuliuchengxlc@gmail.com>

let s:save_cpo = &cpoptions
set cpoptions&vim

hi ClapUnderline gui=underline cterm=underline

hi default link ClapCurrentWord IncSearch
hi default link ClapCurrentWordTwins ClapUnderline

function! clap#plugin#highlight_cursor_word#add_highlights(word_highlights) abort
let cword_len = a:word_highlights.cword_len
let match_ids = []
let [lnum, col] = a:word_highlights.cword_highlight
let match_id = matchaddpos('ClapCurrentWord', [[lnum, col+1, cword_len]])
if match_id > -1
call add(match_ids, match_id)
endif
for [lnum, col] in a:word_highlights.other_words_highlight
let match_id = matchaddpos('ClapCurrentWordTwins', [[lnum, col+1, cword_len]])
if match_id > -1
call add(match_ids, match_id)
endif
endfor
return match_ids
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo
8 changes: 4 additions & 4 deletions autoload/clap/popup/move_manager.vim
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,19 @@ function! s:move_manager.ctrl_l(_winid) abort
endfunction

function! s:move_manager.ctrl_n(_winwid) abort
call clap#client#notify('ctrl-n')
call clap#client#notify_provider('ctrl-n')
endfunction

function! s:move_manager.ctrl_p(_winwid) abort
call clap#client#notify('ctrl-p')
call clap#client#notify_provider('ctrl-p')
endfunction

function! s:move_manager.shift_up(_winwid) abort
call clap#client#notify('shift-up')
call clap#client#notify_provider('shift-up')
endfunction

function! s:move_manager.shift_down(_winwid) abort
call clap#client#notify('shift-down')
call clap#client#notify_provider('shift-down')
endfunction

function! s:move_manager.ctrl_u(_winid) abort
Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/preview.vim
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ endfunction

function! clap#preview#inject_title_opt(opts, width) abort
let opts = a:opts
let should_enable_title = ['grep', 'live_grep', 'dumb_jump', 'files', 'git_files', 'proj_tags']
let should_enable_title = ['grep', 'live_grep', 'dumb_jump', 'files', 'git_files', 'proj_tags', 'coc_location', 'recent_files']
if index(should_enable_title, g:clap.provider.id) > -1
let working_dir = clap#rooter#working_dir()
let working_dir = fnamemodify(working_dir, ':~')
Expand Down
5 changes: 1 addition & 4 deletions autoload/clap/provider/bcommits.vim
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ function! s:bcommits.on_move() abort
call clap#provider#commits#on_move_common(s:into_git_diff_cmd(cur_line))
endfunction

function! s:bcommits.on_move_async() abort
call clap#client#notify('on_move')
endfunction

function! s:bcommits.sink(line) abort
call clap#provider#commits#sink_inner('!'.s:into_git_diff_cmd(a:line))
endfunction
Expand Down Expand Up @@ -54,6 +50,7 @@ function! s:find_prev(cur_rev) abort
return prev
endfunction

let s:bcommits.on_move_async = { -> clap#client#notify_provider('on_move') }
let s:bcommits.syntax = 'clap_diff'
let g:clap#provider#bcommits# = s:bcommits

Expand Down
Loading

0 comments on commit 9560801

Please sign in to comment.