Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

A way to execute ad-hoc searches similar to fzf #433

Closed
svermeulen opened this issue May 16, 2020 · 7 comments · Fixed by #467
Closed

A way to execute ad-hoc searches similar to fzf #433

svermeulen opened this issue May 16, 2020 · 7 comments · Fixed by #467

Comments

@svermeulen
Copy link

Is your feature request related to a problem? Please describe.
I dislike how with vim clap you need to pre-define each type of clap popup. You cannot very easily dynamically create popups.

Describe the solution you'd like
With fzf.vim, if you want to create a popup dynamically, you can just call fzf#run like this:

function! s:choseValue(value)
    echom "Chose value " . a:value
endfunction

call fzf#run({
    \ 'source': ['a', 'b', 'c'],
    \ 'down': '40%',
    \ 'sink': function('s:choseValue')})

Whereas, with vim-clap, it seems you have to do something like this:

function! s:choseValue(value)
    echom "Chose value " . a:value
endfunction

let g:clap_provider_temp1 = {
      \ 'source': ['a', 'b', 'c'],
      \ 'sink': function('s:choseValue')
      \ }

Clap temp1

This works ok, because you can define a temporary provider like this and re-use it for any adhoc popups you want to trigger, but it would be much nicer if there was an API method for this instead of needing to define a global variable for the temporary provider ahead of time

Describe alternatives you've considered
n/a

Additional context
n/a

@liuchengxu
Copy link
Owner

liuchengxu commented May 16, 2020

Actually you also have to write fzf#run(...) in your vimrc ahead, I can't image people use :call fzf#run(...) dynamically. One benefit for providing provider_id is to use the autoload mechanism and don't pay for the providers you don't use. Even we add such an API method, it's essentially still a temporary provider.

@runiq
Copy link
Contributor

runiq commented May 23, 2020

I have a different use case for this: I'm trying to use vim-clap as a replacement for fzf in LanguageClient-neovim, which uses fzf as a general-purpose selection UI. I've got a working fzf provider and fzf#run and fzf#wrap functions which simply replace the source and sink on every invocation of the provider. Would you be interested in a PR?

@liuchengxu
Copy link
Owner

I would suggest you creating a new repo for the languageclient-neovim like https://github.com/vn-ki/coc-clap for coc.nvim, and I can also take a look if you make a lcn-clap. @runiq

@runiq
Copy link
Contributor

runiq commented Jun 18, 2020

I would suggest you creating a new repo for the languageclient-neovim like https://github.com/vn-ki/coc-clap for coc.nvim, and I can also take a look if you make a lcn-clap.

Turns out this is not so simple. Both vim-clap and LCN adhere to the Hollywood principle of "Don't call us, we'll call you":

I believe the easiest way forward to implement my plan would be for Clap to expose a convenience function for a general purpose 'ad hoc' provider that just takes source and sink arguments, similar to fzf#run(). It could also be hidden from the :Clap output (because it would not serve a useful purpose there).

@liuchengxu
Copy link
Owner

liuchengxu commented Jun 18, 2020

@runiq @svermeulen Try the following patch for now, if it works for you, I'll merge it later.

diff --git a/autoload/clap.vim b/autoload/clap.vim
index f040ec3..1a04655 100644
--- a/autoload/clap.vim
+++ b/autoload/clap.vim
@@ -376,5 +376,20 @@ function! clap#(bang, ...) abort
   call clap#for(provider_id_or_alias)
 endfunction

+function! clap#run(provider) abort
+  if has_key(a:provider, 'id')
+    let id = a:provider['id']
+  else
+    let id = 'run'
+  endif
+  let g:clap_provider_{id} = a:provider
+  if s:inject_default_impl_is_ok(g:clap_provider_{id})
+    let g:clap.registrar[id] = g:clap_provider_{id}
+    execute 'Clap' id
+  else
+    echoerr 'failed to run:'.string(a:provider)
+  endif
+endfunction

Example: :call clap#run({'id': 'quick_run', 'source': getbufline(bufnr(''), 1, '$'), 'sink': { selected -> execute('unsilent echom "selected: '.selected.'"')}}), the argument is a Dict like g:clap_provider_foo,with an optional extra field id specifing the provider id.

@runiq
Copy link
Contributor

runiq commented Jun 18, 2020

Thank you so much! ❤️

Update – it works:

works

This is with the PR I mentioned above and the following config:

function! MySelectionUI(source, sink) abort
	return clap#run({'id': 'LCN', 'source': a:source, 'sink': a:sink})
endfunction

let g:LanguageClient_selectionUI = function('MySelectionUI')

@liuchengxu
Copy link
Owner

@runiq Thanks for the update, I have opened PR #467.

liuchengxu added a commit that referenced this issue Jun 19, 2020
* Add clap#run()

Close #433

* Update doc

* Nits
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants