32

Floating Windows Support VIM Popup · Issue #821 · junegunn/fzf.vim · GitHub

 4 years ago
source link: https://github.com/junegunn/fzf.vim/issues/821#issuecomment-581273191
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Join GitHub today

GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.

Sign up

Floating Windows Support VIM Popup #821

Closed

blayz3r opened this issue on Jun 7, 2019 · 41 comments

Closed

Floating Windows Support VIM Popup #821

blayz3r opened this issue on Jun 7, 2019 · 41 comments

Comments

  • Category
    • Question
    • Suggestion
  • OS
    • Linux
    • macOS
    • Windows
  • Vim
    • Neovim

Does the new VIM popup feature enable FZF to float in VIM

Owner

junegunn commented on Jun 8, 2019

the new VIM popup feature

If floating windows of Neovim is what you meant, see #664.

Author

blayz3r commented on Jun 8, 2019

I meant Vim proper. Can the same be achieved with Vim's Popup feature?

Owner

junegunn commented on Jun 8, 2019

edited

I don't know about "the new VIM popup feature". Can you explain what it is? Any reference?

Author

blayz3r commented on Jun 9, 2019

There was discussion here vim/vim#4063 and possible with use with FZF like plugins here vim/vim#4063 (comment)

@junegunn it looks something like this:

58742567-a155ea80-8460-11e9-9925-09082def2c80.gif

screenshot.gif

55285193-400a9000-53b9-11e9-8cff-ffe4983c5947.gif

It is supported in both NeoVim and Vim.

Plugins such as denite.nvim, coc.nvim, vimgon-quest-menu, etc have already implemented it if you are curious to see how it's done.

Author

blayz3r commented on Oct 7, 2019

like liuchengxu/vim-clap

for those of you who are still looking, check out this config from the creator of FZF (@junegunn): junegunn/dotfiles@9545174

@dkarter

    if has('nvim') && exists('&winblend') && &termguicolors

Only for neovim, but we want vim too

Right. Didn't realize that - my bad.

Would love to this setup/feature possible with Vim8! Any news?

I spent a few hours on this today, but ended up with nothing: The results from fzf is printed in the background with the popup (floating window) hovering on top of it. I couldn’t get the result to fill the popup, so it seems I’ll have to leave this to someone more experienced than myself.

@runar can you share your code please? I don’t have so much experience on vim plugin but if I can help :)

@damofthemoon There’s not really any code to share, as all I did was read the Vim documentation on popup windows and try to convert this function to use popup_create().

I don’t understand what the second parameter (call FloatingFZF()) of the below line should be. Is it expecting a window id or buffer number, or a window or buffer instance? What should FloatingFZF() return for this to work?

let g:fzf_layout = { 'window': 'call FloatingFZF()’ }

No better result than you @runar... I can't figure out how it could work for Vim8, I suspect Nvim handles differently pop-up feature thinking

@lightalchemist I'm aware of that, which is why I’m referencing the same commit (where FloatingFZF() is defined) as you do. The problem, as I wrote in my post, is that I’m unable to rewrite the function to make it work for Vim.

What I don't know, is what kind of values g:fzf_layout expects. The first one should be window, but what kind of value is expected where call FloatingFZF() is used? A window id? Buffer number? Or a window or buffer instance? I’ve tried them all without success.

Repository owner

deleted a comment from srijanshetty

on Nov 29, 2019

@junegunn Just what I needed, thank you! I will take a new look at this later.

I can only create a popup with Vim8 but not fill it with FZF output. Another thing disturbing me is the popup needs to be clear with popup_clear() function, it doesn't disappear automatically. Can we access a kind of callback to clean that @junegunn? Any idea why we can't fill the popup with FZF?

Owner

junegunn commented on Dec 2, 2019

I'm a Neovim user, and I have no experience with Vim popups. You might want to read the linked issue above.

vim/vim#4063 (comment)

Bram doesn't seem to understand why we want to open a terminal buffer (running fzf) inside a popup window.

Thanks for pointing this problem @junegunn, now I understand the problem better. I see in the issue tracking a solution could exist but it sounds to me tricky while it's simple to open FZF in a pane (I did try with let g:fzf_layout = { 'window': 'vs' } and it works like a charm). Maybe that's a good opportunity to switch to Neovim nerd_face.

Owner

junegunn commented on Dec 4, 2019

@blayz3r They are native Vim plugins unlike fzf, so they don't have the problem.

lacygoill commented on Feb 3

edited

FWIW, this seems to make fzf display its terminal buffer in a Vim popup window:

fu s:snr() abort
    return matchstr(expand('<sfile>'), '.*\zs<SNR>\d\+_')
endfu
let s:snr = get(s:, 'snr', s:snr())
let g:fzf_layout = {'window': 'call '..s:snr..'fzf_window(0.9, 0.6, "Comment")'}

fu s:fzf_window(width, height, border_highlight) abort
    let width = float2nr(&columns * a:width)
    let height = float2nr(&lines * a:height)
    let row = float2nr((&lines - height) / 2)
    let col = float2nr((&columns - width) / 2)
    let top = '┌' . repeat('─', width - 2) . '┐'
    let mid = '│' . repeat(' ', width - 2) . '│'
    let bot = '└' . repeat('─', width - 2) . '┘'
    let border = [top] + repeat([mid], height - 2) + [bot]
    let frame = s:create_popup_window(a:border_highlight, {
        \ 'line': row,
        \ 'col': col,
        \ 'width': width,
        \ 'height': height,
        \ 'is_frame': 1,
        \ })
    call setbufline(frame, 1, border)
    call s:create_popup_window('Normal', {
        \ 'line': row + 1,
        \ 'col': col + 2,
        \ 'width': width - 4,
        \ 'height': height - 2,
        \ })
endfu

fu s:create_popup_window(hl, opts) abort
    if has_key(a:opts, 'is_frame')
        let id = popup_create('', #{
            \ line: a:opts.line,
            \ col: a:opts.col,
            \ minwidth: a:opts.width,
            \ minheight: a:opts.height,
            \ zindex: 50,
            \ })
        call setwinvar(id, '&wincolor', a:hl)
        exe 'au BufWipeout * ++once call popup_close('..id..')'
        return winbufnr(id)
    else
        let buf = term_start(&shell, #{hidden: 1})
        call popup_create(buf, #{
            \ line: a:opts.line,
            \ col: a:opts.col,
            \ minwidth: a:opts.width,
            \ minheight: a:opts.height,
            \ zindex: 51,
            \ })
        exe 'au BufWipeout * ++once bw! '..buf
    endif
endfu

The code is similar to the one for Nvim documented in the wiki. You can configure the width and the height of the window (as a percentage of the total width/height available), as well as the color of the border, by changing the arguments passed to s:fzf_window():

let g:fzf_layout = {'window': 'call '..s:snr..'fzf_window(0.9, 0.6, "Comment")'}
                                                          │    │     │
                                                          │    │     └ border's highlight group
                                                          │    └ height
                                                          └ width

To support both Vim and Neovim:

fu s:snr() abort
    return matchstr(expand('<sfile>'), '.*\zs<SNR>\d\+_')
endfu
let s:snr = get(s:, 'snr', s:snr())
let g:fzf_layout = {'window': 'call '..s:snr..'fzf_window(0.9, 0.6, "Comment")'}

fu s:fzf_window(width, height, border_highlight) abort
    let width = float2nr(&columns * a:width)
    let height = float2nr(&lines * a:height)
    let row = float2nr((&lines - height) / 2)
    let col = float2nr((&columns - width) / 2)
    let top = '┌' . repeat('─', width - 2) . '┐'
    let mid = '│' . repeat(' ', width - 2) . '│'
    let bot = '└' . repeat('─', width - 2) . '┘'
    let border = [top] + repeat([mid], height - 2) + [bot]
    if has('nvim')
        let frame = s:create_float(a:border_highlight, {
            \ 'row': row,
            \ 'col': col,
            \ 'width': width,
            \ 'height': height,
            \ })
        call nvim_buf_set_lines(frame, 0, -1, v:true, border)
        call s:create_float('Normal', {
            \ 'row': row + 1,
            \ 'col': col + 2,
            \ 'width': width - 4,
            \ 'height': height - 2,
            \ })
        exe 'au BufWipeout <buffer> bw '..frame
    else
        let frame = s:create_popup_window(a:border_highlight, {
            \ 'line': row,
            \ 'col': col,
            \ 'width': width,
            \ 'height': height,
            \ 'is_frame': 1,
            \ })
        call setbufline(frame, 1, border)
        call s:create_popup_window('Normal', {
            \ 'line': row + 1,
            \ 'col': col + 2,
            \ 'width': width - 4,
            \ 'height': height - 2,
            \ })
    endif
endfu

fu s:create_float(hl, opts) abort
    let buf = nvim_create_buf(v:false, v:true)
    let opts = extend({'relative': 'editor', 'style': 'minimal'}, a:opts)
    let win = nvim_open_win(buf, v:true, opts)
    call setwinvar(win, '&winhighlight', 'NormalFloat:'..a:hl)
    return buf
endfu

fu s:create_popup_window(hl, opts) abort
    if has_key(a:opts, 'is_frame')
        let id = popup_create('', #{
            \ line: a:opts.line,
            \ col: a:opts.col,
            \ minwidth: a:opts.width,
            \ minheight: a:opts.height,
            \ zindex: 50,
            \ })
        call setwinvar(id, '&wincolor', a:hl)
        exe 'au BufWipeout * ++once call popup_close('..id..')'
        return winbufnr(id)
    else
        let buf = term_start(&shell, #{hidden: 1})
        call popup_create(buf, #{
            \ line: a:opts.line,
            \ col: a:opts.col,
            \ minwidth: a:opts.width,
            \ minheight: a:opts.height,
            \ zindex: 51,
            \ })
        exe 'au BufWipeout * ++once bw! '..buf
    endif
endfu

If I find issues, I'll try to fix them here and here.

Author

blayz3r commented on Feb 3

@lacygoill Excellent works flawlessly

image

Owner

junegunn commented on Feb 3

edited

@lacygoill Thanks, I'll consider adding that to the main fzf repo so anyone can easily use it.

Owner

junegunn commented on Feb 3

edited

Popup support added in junegunn/fzf@7ceb58b.

let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }

" Border color
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'highlight': 'Todo' } }

" Border style (rounded / sharp / horizontal)
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'highlight': 'Todo', 'border': 'sharp' } }

Works for me fine both on Vim and Neovim. smile

evantravers

added a commit to evantravers/dotfiles that referenced this issue

on Feb 4

Contributor

jesseleite commented on Feb 4

Is it still possible to align the fzf results at the bottom, but still as a popup to prevent fzf from pushing the active buffer upwards off the screen?

mhanberg commented on Feb 4

@junegunn will you be releasing a new version of fzf soon so I can take advantage of this behavior? I use fzf through homebrew.

Thanks!

Owner

junegunn commented on Feb 4

edited

@mhanberg Yes, I will. But there are some nice stuff on the review queue that I'd like to include in the next release, so it will take a few more days. You might already know this, but you can still use the latest vim plugin of fzf even if you installed the binary via Homebrew. Plug 'junegunn/fzf' will make vim-plug clone the main fzf repo on a separate directory and load the vim plugin file from there while using the binary on $PATH. You might want to take a look at the updated installation instruction which hopefully clears up some confusion: https://github.com/junegunn/fzf.vim#installation

@jesseleite While the above dictionary form ({ 'window': { ... } }) currently doesn't support options for positioning the window, you can still write a function that does that and use it as the layout. But yeah, it's a bit of a hassle, do you have any suggestions? Would yoffset suffice?

097115 commented on Feb 4

@junegunn, if you don't mind, I'm not exactly getting why fzf ships with some additional Vim plugin? Why fzf.vim is not enough, is not the only place for al the Vim-related stuff?

Just trying to clarify the structure in my head :)

Thanks.

henrebotha commented on Feb 4

The new feature crashed my machine before I updated my Vim to 8.2. I think a feature guard of some description is in order!

rogchap commented on Feb 4

I have a local fzf#run() is there a way to get this to except the window dictionary for it's layout?
eg:

 fzf#run({'source': l:mysource, 'sink': function("mysink"), 'window': { ... } })

chris-kahn commented on Feb 4

How to make it float relative to the current buffer/window rather than the entire editor?

mhanberg commented on Feb 5

I am able to get this to work in NeoVim, but when using Vim I run into the following error when calling :Files. (I use NeoVim in the terminal, but prefer to use MacVim for normal usage).

The following was produced using the current Vim as installed by Homebrew (MacVim is not updated as of yet).

Screenshot

image

GIF of the error

fzf-popup-error

Any ideas? Thanks!

This is the fzf configuration that I use

" .vimrc
function! RipgrepFzf(query, fullscreen)
  let command_fmt = 'rg --column --line-number --no-heading --color=always --smart-case %s || true'
  let initial_command = printf(command_fmt, shellescape(a:query))
  let reload_command = printf(command_fmt, '{q}')
  let spec = {'options': ['--phony', '--query', a:query, '--bind', 'change:reload:'.reload_command], 'window': { 'width': 0.9, 'height': 0.6 }}
  call fzf#vim#grep(initial_command, 1, fzf#vim#with_preview(spec), a:fullscreen)
endfunction

command! -nargs=* -bang RG call RipgrepFzf(<q-args>, <bang>0)

silent! nnoremap <c-p> :Files<cr>
nnoremap gl :BLines<cr>
nnoremap <leader>a :RG<cr>

let g:fzf_layout = { 'window': { 'width': 0.5, 'height': 0.6 } }
# .zshrc
export FZF_DEFAULT_COMMAND="rg --files --hidden --glob '!.git/'"

Vim Version

⚡︎/usr/local/bin/vim --version
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Feb  3 2020 01:40:55)
macOS version
Included patches: 1-200
Compiled by Homebrew
Huge version without GUI.  Features included (+) or not (-):
+acl               -farsi             -mouse_sysmouse    -tag_old_static
+arabic            +file_in_path      +mouse_urxvt       -tag_any_white
+autocmd           +find_in_path      +mouse_xterm       -tcl
+autochdir         +float             +multi_byte        +termguicolors
-autoservername    +folding           +multi_lang        +terminal
-balloon_eval      -footer            -mzscheme          +terminfo
+balloon_eval_term +fork()            +netbeans_intg     +termresponse
-browse            +gettext           +num64             +textobjects
++builtin_terms    -hangul_input      +packages          +textprop
+byte_offset       +iconv             +path_extra        +timers
+channel           +insert_expand     +perl              +title
+cindent           +job               +persistent_undo   -toolbar
-clientserver      +jumplist          +popupwin          +user_commands
+clipboard         +keymap            +postscript        +vartabs
+cmdline_compl     +lambda            +printer           +vertsplit
+cmdline_hist      +langmap           +profile           +virtualedit
+cmdline_info      +libcall           -python            +visual
+comments          +linebreak         +python3           +visualextra
+conceal           +lispindent        +quickfix          +viminfo
+cryptv            +listcmds          +reltime           +vreplace
+cscope            +localmap          +rightleft         +wildignore
+cursorbind        +lua               +ruby              +wildmenu
+cursorshape       +menu              +scrollbind        +windows
+dialog_con        +mksession         +signs             +writebackup
+diff              +modify_fname      +smartindent       -X11
+digraphs          +mouse             -sound             -xfontset
-dnd               -mouseshape        +spell             -xim
-ebcdic            +mouse_dec         +startuptime       -xpm
+emacs_tags        -mouse_gpm         +statusline        -xsmp
+eval              -mouse_jsbterm     -sun_workshop      -xterm_clipboard
+ex_extra          +mouse_netterm     +syntax            -xterm_save
+extra_search      +mouse_sgr         +tag_binary
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/usr/local/share/vim"
Compilation: clang -c -I. -Iproto -DHAVE_CONFIG_H   -DMACOS_X -DMACOS_X_DARWIN  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: clang   -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/[email protected]/lib -L/usr/local/opt/readline/lib  -L/usr/local/lib -o vim        -lncurses -liconv -lintl -framework AppKit  -L/usr/local/opt/lua/lib -llua5.3 -mmacosx-version-min=10.15 -fstack-protector-strong -L/usr/local/lib  -L/usr/local/Cellar/perl/5.30.1/lib/perl5/5.30.1/darwin-thread-multi-2level/CORE -lperl -lm -lutil -lc  -L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/config-3.7m-darwin -lpython3.7m -framework CoreFoundation  -lruby.2.6

ardenzhan commented on Feb 5

@mhanberg I have the same problem. Workaround for me is to do :set hidden. Which I found by doing :h E948 and then following the link for |abandon|. I haven't read enough of the manual / debugged further to figure out what the actual problem is though.

bluz71 commented on Feb 5

@junegunn,

Your latest commits fix the issue (at least for me). I had the same error as @mhanberg, but now resolved. Many thanks.

mhanberg commented on Feb 5

@junegunn thank you! That solves the problem for me as well.

josefson commented on Feb 12

I have just tried this feature, but under vim 8.2 it's thowing me this error where it's trying to open a shell in the popup window when trying any Fzf command.

image

It actually opens the popup blank and the shells as buffers
image

mhanberg commented on Feb 12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Assignees

No one assigned

Labels
None yet
Projects

None yet

Milestone

No milestone

Linked pull requests

Successfully merging a pull request may close this issue.

None yet

16 participants

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK