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 create hg-vim-fzf
or svn-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?