voldikss / vim-floaterm

:computer: Terminal manager for (neo)vim
MIT License
2.47k stars 78 forks source link

feat: Use neovim 0.5 native float borders #343

Closed adigitoleo closed 1 year ago

adigitoleo commented 2 years ago

Retains neovim 0.4 support for now, could be removed later.

342

Problem: how to implement window titles? Neovim float API still doesn't have a title option unlike vim, and I don't know if it is possible to draw on top of the border...

adigitoleo commented 2 years ago

@voldikss Any thoughts on what to do about the window title in this case? I've opened an issue at neovim, but it could take some time to arrive: https://github.com/neovim/neovim/issues/17458

The title is not going to be a feature of the floating window API, so we'll have to come up with something ourselves.

voldikss commented 2 years ago

@adigitoleo Many thanks to you for the attention for this. I'm really busy these days and maybe have no time to dig into the new features added in neovim.

Now that neovim doesn't provider native 'title' support for floating window, I am going to suspend and look into some other implements(e.g. there are some lua floating ui plugin for neovim) and hope to find some inpirations.

registerGen commented 1 year ago

There is a PR for floatwin title now. https://github.com/neovim/neovim/pull/20184

EDIT: merged into master now!

adigitoleo commented 1 year ago

@registerGen Sorry for not acting faster on this. To be honest, I have given away this plugin in favour of a sort of dumber custom solution that works for me (although I haven't implemented window titles there either yet).

I don't think I'll be able to pick this up any time soon, so please feel free (or anyone else) to take the idea and create a new PR.

In case anyone is wondering what I'm using now, it's basically as simple as:

function! Floating(buftag, ...) abort
    " Check for adequate parent window size.
    if &columns < 25 || &lines < 30
        echoerr "failed to open floating window; vim window is too small"
        return v:true
    endif
    " Focus or create a floating window, a:1 sets the buftype.
    if exists("t:floating_buffers") && has_key(t:floating_buffers, a:buftag)
                \ && bufexists(t:floating_buffers[a:buftag])
        let l:buf = t:floating_buffers[a:buftag]
    else
        if exists("t:floating_buffers") && has_key(t:floating_buffers, a:buftag)
                    \ && !bufexists(t:floating_buffers[a:buftag])
            unlet t:floating_buffers[a:buftag]
        endif
        let l:buf = nvim_create_buf(v:false, v:true)
        if a:0 == 1 | call nvim_buf_set_option(l:buf, 'buftype', a:1) | endif
    endif
    let l:winconfig = {
                \   'relative': 'editor',
                \   'border': 'single',
                \   'row': 5,
                \   'col': 5,
                \   'width': &columns - 10,
                \   'height': &lines - 12,
                \}
    if exists("t:floating_window") && win_id2win(t:floating_window) > 0
        call win_gotoid(t:floating_window)
        call nvim_win_set_buf(t:floating_window, l:buf)
    else
        let l:win = nvim_open_win(l:buf, v:true, l:winconfig)
        call nvim_tabpage_set_var(0, 'floating_window', l:win)
    endif
    set nowrap nolist
    if !exists("t:floating_buffers")
        call nvim_tabpage_set_var(0, 'floating_buffers', {a:buftag : l:buf})
    elseif !has_key(t:floating_buffers, a:buftag)
        let t:floating_buffers[a:buftag] = l:buf
    else
        return v:true
    endif
    return v:false
endfunction

Which is a function that can be used either to launch floating terminals with custom jobs (and :quit and restore them at will, by calling the function again with the same arguments):

function! StartTerm(...) abort
    " Create a floating/tabnew terminal and optionally execute a shell command.
    if a:0
        if a:1 ==# "-t"
            exec 'tabnew|terminal ' .. expandcmd(join(a:000[1:])) | return
        elseif executable(a:1)
            let l:cmdstr = a:0 > 1 ? expandcmd(join(a:000)) : a:1
        else
            echoerr "no executable command called " .. a:1 | return
        endif
    else
        let l:cmdstr = &shell
    endif
    let l:has_buf = Floating(l:cmdstr)
    if l:has_buf | return | endif
    call nvim_buf_set_option(0, 'modified', v:false)
    if has('win32')
        call termopen(l:cmdstr, a:0 ? {} : {"on_exit": function("<SID>TermQuit")})
    else
        call termopen(
                    \ 'export TERM=' .. $TERM .. ' && ' .. l:cmdstr,
                    \ a:0 ? {} : {"on_exit": function("<SID>TermQuit")},
                    \)
    endif
endfunction

... or to launch floating :help windows:

command! -complete=help -nargs=? H call Floating("help", "help") | help <args>

If you want, you could also just try to add titles to that.