junegunn / vim-peekaboo

:eyes: " / @ / CTRL-R
1.15k stars 38 forks source link

[Feature Request] Use floating window instead of split #68

Open tuxflo opened 4 years ago

tuxflo commented 4 years ago

I'm a big fan of vim peekaboo. However sometimes the split window destroys my current workspace (when using multiple splits). Therefore I want to ask if it would be possible to use the new vim 8 popup or neovim floating windows for showing the buffer contents.

justrajdeep commented 4 years ago

+1

mxdevmanuel commented 4 years ago

I have something for neovim

Since you can define the command to create the window for peekabo

function! CreateCenteredFloatingWindow()
    let width = float2nr(&columns * 0.6)
    let height = float2nr(&lines * 0.6)
    let top = ((&lines - height) / 2) - 1
    let left = (&columns - width) / 2
    let opts = {'relative': 'editor', 'row': top, 'col': left, 'width': width, 'height': height, 'style': 'minimal'}

    let top = "╭" . repeat("─", width - 2) . "╮"
    let mid = "│" . repeat(" ", width - 2) . "│"
    let bot = "╰" . repeat("─", width - 2) . "╯"
    let lines = [top] + repeat([mid], height - 2) + [bot]
    let s:buf = nvim_create_buf(v:false, v:true)
    call nvim_buf_set_lines(s:buf, 0, -1, v:true, lines)
    call nvim_open_win(s:buf, v:true, opts)
    set winhl=Normal:Floating
    let opts.row += 1
    let opts.height -= 2
    let opts.col += 2
    let opts.width -= 4
    call nvim_open_win(nvim_create_buf(v:false, v:true), v:true, opts)
    au BufWipeout <buffer> exe 'bw '.s:buf
endfunction

That function I just use to create centered windows, found it a while ago in reddit and it works with peekabo

then just let g:peekaboo_window="call CreateCenteredFloatingWindow()" I don't have somethinglike this for vim8 though, hope it helps

krkhan commented 4 years ago

@mxdevmanuel works perfectly, this is awesome. thanks!

weilbith commented 4 years ago

@mxdevmanuel how do you close the outer window with the buffer for the borders? For me it always remains open. I tried to add a WinClosed autocmd to the inner buffer to close the outer window. Fails atm. I'm sure I can fix that, but how does it work for you?

mxdevmanuel commented 4 years ago

@weilbith with peekabo it just works, however when I use this for other purposes I see this behavior you get, but never have gotten around it, sorry, best luck with that

weilbith commented 4 years ago

Funny. How should Peekabo know about the outer window? ^^ Anyways no worries. It works fine without fancy borders for now and does not "destroy" the window partition anymore.

mxdevmanuel commented 4 years ago

@weilbith Funny indeed, in theory the au BufWipeout <buffer> exe 'bw '.s:buf should take care of that but who knows, something people do, as mentioned in here setting a different background color allows to differentiate from the underlying window, maybe that can help

EDIT: I tried it and it works

weilbith commented 4 years ago

Cool, thanks for the reference! :pray:

So this issue could be closed with maybe a hint/example in the doc file? :thinking:

justrajdeep commented 4 years ago

Will this work for vim8?

weilbith commented 4 years ago

Ah no, of course not. This is using the nvim specific API.

kuntau commented 4 years ago

It would be cool if we can use fzf function to display the floating window since it support both neovim & vim8

justrajdeep commented 4 years ago

It would be cool if we can use fzf function to display the floating window since it support both neovim & vim8

+1

mroavi commented 4 years ago

I have something for neovim

Since you can define the command to create the window for peekabo

function! CreateCenteredFloatingWindow()
    let width = float2nr(&columns * 0.6)
    let height = float2nr(&lines * 0.6)
    let top = ((&lines - height) / 2) - 1
    let left = (&columns - width) / 2
    let opts = {'relative': 'editor', 'row': top, 'col': left, 'width': width, 'height': height, 'style': 'minimal'}

    let top = "╭" . repeat("─", width - 2) . "╮"
    let mid = "│" . repeat(" ", width - 2) . "│"
    let bot = "╰" . repeat("─", width - 2) . "╯"
    let lines = [top] + repeat([mid], height - 2) + [bot]
    let s:buf = nvim_create_buf(v:false, v:true)
    call nvim_buf_set_lines(s:buf, 0, -1, v:true, lines)
    call nvim_open_win(s:buf, v:true, opts)
    set winhl=Normal:Floating
    let opts.row += 1
    let opts.height -= 2
    let opts.col += 2
    let opts.width -= 4
    call nvim_open_win(nvim_create_buf(v:false, v:true), v:true, opts)
    au BufWipeout <buffer> exe 'bw '.s:buf
endfunction

That function I just use to create centered windows, found it a while ago in reddit and it works with peekabo

then just let g:peekaboo_window="call CreateCenteredFloatingWindow()" I don't have somethinglike this for vim8 though, hope it helps

Is there a way to adapt this to work in visual mode? I get a blank floating window when I trigger peekaboo in visual mode.

maricn commented 3 years ago

Is there a way to adapt this to work in visual mode? I get a blank floating window when I trigger peekaboo in visual mode.

I'm having this issue for a long time now, and I just kind of learned to live with it.. :(

Linux work-x1c-arch 5.11.2-arch1-1 #1 SMP PREEMPT Fri, 26 Feb 2021 18:26:41 +0000 x86_64 GNU/Linux
NVIM v0.4.4
Build type: Release
LuaJIT 2.0.5
Compilation: /usr/bin/cc -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2 -DNDEBUG -DMIN_LOG_LEVEL=3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -I/build/neovim/src/build/config -I/build/neovim/src/neovim-0.4.4/src -I/usr/include -I/build/neovim/src/build/src/nvim/auto -I/build/neovim/src/build/include
Compiled by builduser

Features: +acl +iconv +tui

Also I see people complaining at https://github.com/junegunn/vim-peekaboo/issues/72. For me, removing the snippet to popup the window fixes the issue, but I kind of wanna have them both :)

juanMarinero commented 3 years ago

Ah no, of course not. This is using the nvim specific API.

Since it's NOT fixed for Vim, please do not close it.

yogeshdhamija commented 2 years ago

Replying to @mroavi's comment: https://github.com/junegunn/vim-peekaboo/issues/68#issuecomment-655431322, quoted:

Is there a way to adapt this to work in visual mode? I get a blank floating window when I trigger peekaboo in visual mode.

Yeah! I've hacked that script you quoted (link: https://github.com/junegunn/vim-peekaboo/issues/68#issuecomment-622601779) so that it works with peekaboo in visual mode, but it loses the borders around the floating window (still very usable for me). Here's the new function:

function! CreateCenteredFloatingWindow() abort
    if(!has('nvim')) 
        split
        new
    else
        let width = float2nr(&columns * 0.6)
        let height = float2nr(&lines * 0.6)
        let top = ((&lines - height) / 2) - 1
        let left = (&columns - width) / 2
        let opts = {'relative': 'editor', 'row': top, 'col': left, 'width': width, 'height': height, 'style': 'minimal'}
        let s:buf = nvim_create_buf(v:false, v:true)
        call nvim_open_win(s:buf, v:true, opts)
    endif
endfunction

As mentioned, you have to add a setting to use it when peekaboo is triggered:

let g:peekaboo_window="call CreateCenteredFloatingWindow()"

Here's what it looks like to me:

Screen Shot 2022-01-15 at 6 33 20 PM
YodaEmbedding commented 1 year ago

A Lua version of the above:

function utils.create_centered_floating_window()
  local width = math.floor(vim.o.columns * 0.8)
  local height = math.floor(vim.o.lines * 0.8)

  local opts = {
    relative = "editor",
    width = width,
    height = height,
    col = math.floor((vim.o.columns - width) / 2),
    row = math.floor((vim.o.lines - height) / 2) - 1,
    style = "minimal",
  }

  local top = "╭" .. string.rep("─", width - 2) .. "╮"
  local mid = "│" .. string.rep(" ", width - 2) .. "│"
  local bot = "╰" .. string.rep("─", width - 2) .. "╯"

  local lines = { top }
  for i = 2, height - 1 do
    lines[i] = mid
  end
  lines[height] = bot

  local buf = api.nvim_create_buf(false, true)
  api.nvim_buf_set_lines(buf, 0, -1, true, lines)
  api.nvim_open_win(buf, true, opts)
  api.nvim_set_option("winhl", "Normal:Floating")

  local opts_new = {
    relative = opts.relative,
    width = opts.width - 4,
    height = opts.height - 2,
    col = opts.col + 2,
    row = opts.row + 1,
    style = opts.style,
  }

  api.nvim_open_win(api.nvim_create_buf(false, true), true, opts_new)
  vim.cmd("au BufWipeout <buffer> execute 'bw " .. tostring(buf) .. "'")
end

That said, there are some alternative plugins for Neovim users: