fzy
fzy copied to clipboard
Visual defects in neovim
I tried the example from the README.md with neovim and found visual flaws. Lines are displayed indented as a ladder. If you enter a few characters, then nothing on the screen can be understood.
Happens to me too. Screenshot:
On the right there's the input for fzy.
On the top left, you can see the Vim integration in .vimrc
On the bottom left, there's the ladder (the bug).
Versions:
NVIM v0.2.2
fzy 0.9 (c) 2014 John Hawthorn
(installed from the fzy_0.9-1_amd64.deb
release here on GitHub)
Same! What program do you use with fzy? ripgrep/find/silversearcher? I thought it was some issue with ripgrep + fzy.
There is no issue in neovim 0.2.0
but starting from 0.2.1
up to nightly (0.2.3-dev
),
this issue occurs.
To reproduce just :exec system('ls | fzy')
Related? https://github.com/neovim/neovim/wiki/FAQ#-and-system-do-weird-things-with-interactive-processes
@PowerInside thank you for attention!
It seems that so. I consider that it is necessary to add the correct instruction in README.md for neovim. Do you have a working example of integration with neovim?
I have tried something with termopen()
instead of system()
, but I don't know enough VimScript to figure it out (right now) and it errors out.
let s:Fzy = {}
function s:Fzy.new(bufid)
let this = copy(self)
let this._chunks = ['']
let this._bufid = a:bufid
return this
endfunction
function s:Fzy.on_exit(job_id, code)
redraw!
if !empty(string(fzy._chunks))
exec ':e ' . string(fzy._chunks)
endif
call feedkeys('\<c-\\><c-n>:bd! ' . self._bufid . '<cr>', 'n')
endfunction
function s:Fzy.on_stdout(job_id, data) "dict
let self._chunks[-1] .= a:data[0]
call extend(self._chunks, a:data[1:])
endfunction
function FzyCommand()
let bufid = bufnr('%')
let fzy = s:Fzy.new(bufid)
let cmd = "rg . -l -g '' | fzy"
sp | enew | call termopen(cmd, fzy) | startinsert
endfunction
nnoremap <leader>e :call FzyCommand()<cr>
Maybe somebody knows more than me and can make this work :)
This problem seems to have been solved in the fzf for a long time. But I can not quickly understand ~800 lines of vimscript :)
Picker by Scott Stevenson might be a good place to look for this. I have copied what I think might be the relevant bit below:
function! s:PickerTermopen(list_command, vim_command, callback) abort
" Open a terminal emulator buffer in a new window, execute
" list_command piping its output to the fuzzy selector, and call
" callback.on_select with the item selected by the user as the first
" argument.
"
" Parameters
" ----------
" list_command : String
" Shell command to generate list user will choose from.
" vim_command : String
" Readable representation of the Vim command which will be
" invoked against the user's selection, for display in the
" statusline.
" callback.on_select : String -> Void
" Function executed with the item selected by the user as the
" first argument.
let l:callback = {
\ 'window_id': win_getid(),
\ 'filename': tempname(),
\ 'callback': a:callback
\ }
function! l:callback.on_exit(job_id, data, event) abort
bdelete!
call win_gotoid(self.window_id)
if filereadable(self.filename)
try
call self.callback.on_select(readfile(self.filename)[0])
catch /E684/
endtry
call delete(self.filename)
endif
endfunction
execute g:picker_split g:picker_height . 'new'
let l:term_command = a:list_command . '|' . g:picker_selector . '>' .
\ l:callback.filename
let s:picker_job_id = termopen(l:term_command, l:callback)
let b:picker_statusline = 'Picker [command: ' . a:vim_command .
\ ', directory: ' . getcwd() . ']'
setlocal nonumber norelativenumber statusline=%{b:picker_statusline}
setfiletype picker
startinsert
endfunction
@casr I hacked on it a bit and this works!
function! FzyCommand(list_command) abort
let l:callback = {
\ 'window_id': win_getid(),
\ 'filename': tempname()
\ }
let l:fzy_command = 'fzy'
function! l:callback.on_exit(job_id, data, event) abort
bdelete!
call win_gotoid(self.window_id)
if filereadable(self.filename)
try
let l:selected_filename = readfile(self.filename)[0]
exec ':e ' . l:selected_filename
catch /E684/
endtry
call delete(self.filename)
endif
endfunction
execute 'botright 10 new'
let l:term_command = a:list_command . '|' . l:fzy_command . '>' .
\ l:callback.filename
let l:term_job_id = termopen(l:term_command, l:callback)
setlocal nonumber norelativenumber
startinsert
endfunction
nnoremap <leader>e :call FzyCommand("rg . -l -g ''")<cr>
Adapted FzyCommand
's signature be closer to the one in the README + hid the statusbar & co so it's visually closer to what we had (still one blank line).
function! FzyCommand(choice_command, vim_command) abort
let l:callback = {
\ 'window_id': win_getid(),
\ 'filename': tempname(),
\ 'vim_command': a:vim_command
\ }
function! l:callback.on_exit(job_id, data, event) abort
bdelete!
call win_gotoid(self.window_id)
if filereadable(self.filename)
try
let l:selected_filename = readfile(self.filename)[0]
exec self.vim_command . l:selected_filename
catch /E684/
endtry
endif
call delete(self.filename)
endfunction
botright 10 new
let l:term_command = a:choice_command . ' | fzy > ' . l:callback.filename
silent call termopen(l:term_command, l:callback)
setlocal nonumber norelativenumber
startinsert
endfunction
nnoremap <silent> <c-o> :call FzyCommand('rg --files .', ':e ')<cr>
Is the above a drop in replacement for the README version?
Yes!
Should be added to the readme imo.
@ruifm Open a PR with the changes to the README and your wish might come true :)
Is it possible to use fzy+ripgrep to search inside files?
Is it possible to use fzy+ripgrep to search inside files?
I use it fine using:
nnoremap <silent><leader>t :call FzyCommand("rg --files --hidden -g '!.git/*' .", ":tabedit")<cr>
One hack would be to rely on --color=always
.
rg --column --no-heading --color=always --smart-case -- ""
+
let l:real_filename = matchstr(l:selected_filename, '\f\+\ze\e', 9)
exec self.vim_command . l:real_filename
The issue that I have is fzy does not highlight selection when colors are forced, so impossible to know which one is selected.