vim-fz
vim-fz copied to clipboard
allow vim-fz to be extended
Would it be possible to support an api so that we can use vim-fz
for other things rather than just files something similar to fzf https://github.com/junegunn/fzf/wiki/Examples-(vim). I would like to replace Ctrl+P and fzf features with it.
Here is what I'm thinking.
- Make
vim-fz
only expose the core api and allow other plugin author to use it for something else. - Create another repo that is specific to vim. Might be name something like
basic-vim-fz
? This would then support commands like:FzColors
,:FzFiletypes
,:FzLines
,:FzTags
,:FzQuickFix
,:FzBookmarks
and so on. You could also move:FzFiles
and:FzDirs
in this repo. - Create another repo that is specific to source controls. For example,
git-vim-fz
which contains:FzGitFiles
,:FzGitBranch
,:FzGitStashedFiles
. If someone uses mercurial, svn the can go ahead and createhg-vim-fzf
orsvn-vim-fzf
.
Here is what the core api could look like. This is a very simplified version of the api.
fz#run({
\ 'type': 'cmd',
\ 'cmd': ['git', 'ls-files'],
\ 'accept': {files-> exec 'edit files[0]'},
\ })
fz#run({
\ 'type': 'list',
\ 'list': ['Item1', 'Item2'],
\ 'accept': {items -> .. do something with items ...},
\ })
fz#run({
\ 'type': 'file',
\ 'file': expand('~/somefile'),
\ 'accept': {result-> ... do something with the result },
})
It would be also good to have first class async support. This is a place where most of the plugins doesn't support it.
" if type is not specified it could default to manual, then user can use fz#append(id, list) and fz#clear(id)
let l:id= fz#run({
\ 'accept': {result-> ... do something with the result },
\ })
let s:counter = 0
function! s:some_async_function(t) abort
let s:counter = s:counter + 1
call fz#append(l:id, [s:counter])
if s:counter == 100
call fz#clean(l:id)
let s:counter = 0
endif
endfunction
call timer_start(2000, function('s:some_async_function'), { 'repeat': -1 })
If I wanted to create a command I can easily use command! FzGitFiles call fz#run(....)
This is useful when I'm searching for vim-lsp case where I could be opening multiple language servers and would like to append to the same list. Also useful when streaming support for language server protocol is implemented.
There is also another async feature that would make sense but this might be difficult until gof
or fzf
supports it first. Basically as I type the search text I would also like to be notified about the search text. There are cases where the results is too large. For example when implementing a UI for npm install
I would like to search the npmjs.org repository. This means I would most likely want to make a new http request every time the user presses a key.
let l:id= fz#run({
\ 'type': 'manual',
\ 'accept': {result-> ... do something with the result },
\ 'search_changed': function('s:on_search_text_changed'),
\ })
function! s:on_search_text_changed(id, search_text) abort
let l:result = http#get('http://npmjs.org/search?q=' . a:search_text)
call fz#clear(a:id)
call fz#append(a:id, l:result)
endfunction
There are cases when list
can be just string. For example: for files
, filetypes
, colorschemes
. But there are cases when list
needs to be a bit more complicated might be something like how omnifunc works ie. list of completeitem, it would be good to support ['item1', 'item2']
as well as [ { 'text': 'class HelloWorld', 'data': { 'file': 'hello.js', 'line': 1, 'col: 1 } } ]
. This way when I implement get current document symbols, I can show HelloWorld
in results, but when I click enter in the accept
method I can look at the data and edit the file and navigate to that particular line and col.
accept
function might want to return a dictionary instead of just the selected items so that it can be future proof. For example, the user might type Ctrl+t
, Ctrl+v
and Ctrl+s
instead of enter
. This would allow the plugin author to know that the user pressed Ctrl+v
so it will open the file in vertical split but if the user pressed Ctrl+t
it can open in new tab.
function! s:on_accept(option) abort
a:option.id " id of the fz#run
a:options.items " list of items, since sometimes it is ok to select multiple items
a:options.selection_type " Ctrl+t, Ctrl+v and so on
endfunction
Also would be good if the same api could be ported to CtrlP so supporting both UI would be easy.
Thoughts?
Thanks for implementing some of these requests. There is one minor problem I encountered that I think we should improve.
call fz#run({ 'type': 'cmd', 'cmd': 'git ls-files | gof' })
call fz#run({ 'type': 'cmd', 'cmd': 'git ls-files | fzf' })
Here I need to specify explicitly gof
or fzf
. Would it make sense to do this instead?
" for gof
let g:fz_command = 'gof'
let g:fz_command_files = 'files -A'
" for fzf
let g:fz_command = 'fzf'
let g:fz_command_files = ''
So now I could just do this and don't have to worry about whether it is using gof
or fzf
.
call fz#run({ 'type': 'cmd', 'cmd': 'git ls-files' })
If someone want to override it per fz#run
they could use this. But I think almost no one would use this.
call fz#run({ 'type': 'cmd', 'cmd': 'git ls-files', 'fz_command': 'gof' })
call fz#run({ 'type': 'cmd', 'cmd': 'git ls-files | gof', 'fz_command': '' })
@mattn I have decided to implement a picker ui in pure vim script with a good extension points. It is very much work in progress and supports on_change
handler. Plugin is called quickpick.vim and you can find the roadmap at https://github.com/prabirshrestha/quickpick.vim/issues/1. The goal is for me to replace CtrlP
, vim-fz
and fzf
so I only have one plugin to do fuzzy search.