mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-02 22:10:06 +08:00
Add floating windows support vim (#3612)
This commit is contained in:
parent
96da1ed022
commit
2c96390ba9
@ -8,6 +8,10 @@
|
||||
|
||||
|
||||
let s:self = {}
|
||||
|
||||
function! s:self.exists() abort
|
||||
return exists('*nvim_open_win')
|
||||
endfunction
|
||||
" in old version nvim_open_win api is:
|
||||
" call nvim_open_win(s:bufnr, v:true, &columns, 12,
|
||||
" \ {
|
||||
@ -64,6 +68,16 @@ function! s:self.win_config(winid, opt) abort
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:self.win_close(id, focuce) abort
|
||||
return nvim_win_close(a:id, a:focuce)
|
||||
" @fixme: nvim_win_close only support one argv in old version
|
||||
try
|
||||
return nvim_win_close(a:id, a:focuce)
|
||||
catch /^Vim\%((\a\+)\)\=:E118/
|
||||
return nvim_win_close(a:id)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! SpaceVim#api#neovim#floating#get() abort
|
||||
return deepcopy(s:self)
|
||||
endfunction
|
||||
|
130
autoload/SpaceVim/api/vim/floating.vim
Normal file
130
autoload/SpaceVim/api/vim/floating.vim
Normal file
@ -0,0 +1,130 @@
|
||||
"=============================================================================
|
||||
" floating.vim --- vim floating api
|
||||
" Copyright (c) 2016-2019 Wang Shidong & Contributors
|
||||
" Author: Wang Shidong < wsdjeg@outlook.com >
|
||||
" URL: https://spacevim.org
|
||||
" License: GPLv3
|
||||
"=============================================================================
|
||||
|
||||
let s:self = {}
|
||||
|
||||
" this api is based on neovim#floating api
|
||||
" options:
|
||||
" 1. col
|
||||
" 2. row
|
||||
" 3. width
|
||||
" 3. height
|
||||
" 4. relative
|
||||
|
||||
" {config} Map defining the window configuration. Keys:
|
||||
" • `relative`: Sets the window layout to "floating", placed
|
||||
" at (row,col) coordinates relative to:
|
||||
" • "editor" The global editor grid
|
||||
" • "win" Window given by the `win` field, or
|
||||
" current window.
|
||||
" • "cursor" Cursor position in current window.
|
||||
"
|
||||
" • `win` : |window-ID| for relative="win".
|
||||
" • `anchor`: Decides which corner of the float to place
|
||||
" at (row,col):
|
||||
" • "NW" northwest (default)
|
||||
" • "NE" northeast
|
||||
" • "SW" southwest
|
||||
" • "SE" southeast
|
||||
"
|
||||
" • `width` : Window width (in character cells).
|
||||
" Minimum of 1.
|
||||
" • `height` : Window height (in character cells).
|
||||
" Minimum of 1.
|
||||
" • `bufpos` : Places float relative to buffer
|
||||
" text (only when relative="win"). Takes a tuple
|
||||
" of zero-indexed [line, column]. `row` and
|
||||
" `col` if given are applied relative to this
|
||||
" position, else they default to `row=1` and
|
||||
" `col=0` (thus like a tooltip near the buffer
|
||||
" text).
|
||||
" • `row` : Row position in units of "screen cell
|
||||
" height", may be fractional.
|
||||
" • `col` : Column position in units of "screen
|
||||
" cell width", may be fractional.
|
||||
" • `focusable` : Enable focus by user actions
|
||||
" (wincmds, mouse events). Defaults to true.
|
||||
" Non-focusable windows can be entered by
|
||||
" |nvim_set_current_win()|.
|
||||
" • `external` : GUI should display the window as
|
||||
" an external top-level window. Currently
|
||||
" accepts no other positioning configuration
|
||||
" together with this.
|
||||
" • `style`: Configure the appearance of the window.
|
||||
" Currently only takes one non-empty value:
|
||||
" • "minimal" Nvim will display the window with
|
||||
" many UI options disabled. This is useful
|
||||
" when displaying a temporary float where the
|
||||
" text should not be edited. Disables
|
||||
" 'number', 'relativenumber', 'cursorline',
|
||||
" 'cursorcolumn', 'foldcolumn', 'spell' and
|
||||
" 'list' options. 'signcolumn' is changed to
|
||||
" `auto` and 'colorcolumn' is cleared. The
|
||||
" end-of-buffer region is hidden by setting
|
||||
" `eob` flag of 'fillchars' to a space char,
|
||||
" and clearing the |EndOfBuffer| region in
|
||||
" 'winhighlight'.
|
||||
"
|
||||
" Return: ~
|
||||
" Window handle, or 0 on error
|
||||
function! s:self.open_win(buffer, focuce, options) abort
|
||||
let col = get(a:options, 'col', 1)
|
||||
let row = get(a:options, 'row', 1)
|
||||
let width = get(a:options, 'width', 1)
|
||||
let height = get(a:options, 'height', 1)
|
||||
let relative = get(a:options, 'relative', 'editor')
|
||||
if relative ==# 'win'
|
||||
elseif relative ==# 'cursor'
|
||||
elseif relative ==# 'editor'
|
||||
let opt = {
|
||||
\ 'line' : row + 1,
|
||||
\ 'col' : col,
|
||||
\ 'maxheight' : height,
|
||||
\ 'minheight' : height,
|
||||
\ 'maxwidth' : width,
|
||||
\ 'minwidth' : width,
|
||||
\ }
|
||||
endif
|
||||
return popup_create(a:buffer, opt)
|
||||
endfunction
|
||||
|
||||
function! s:self.win_config(winid, options) abort
|
||||
let col = get(a:options, 'col', 1)
|
||||
let row = get(a:options, 'row', 1)
|
||||
let width = get(a:options, 'width', 1)
|
||||
let height = get(a:options, 'height', 1)
|
||||
let relative = get(a:options, 'relative', 'editor')
|
||||
if relative ==# 'win'
|
||||
elseif relative ==# 'cursor'
|
||||
elseif relative ==# 'editor'
|
||||
let opt = {
|
||||
\ 'line' : row + 1,
|
||||
\ 'col' : col,
|
||||
\ 'maxheight' : height,
|
||||
\ 'minheight' : height,
|
||||
\ 'maxwidth' : width,
|
||||
\ 'minwidth' : width,
|
||||
\ }
|
||||
endif
|
||||
return popup_setoptions(a:winid, opt)
|
||||
endfunction
|
||||
|
||||
function! s:self.exists() abort
|
||||
return exists('*popup_create')
|
||||
endfunction
|
||||
|
||||
function! s:self.win_close(id, focuce) abort
|
||||
return popup_close(a:id)
|
||||
endfunction
|
||||
|
||||
function! SpaceVim#api#vim#floating#get() abort
|
||||
return deepcopy(s:self)
|
||||
endfunction
|
||||
|
||||
|
||||
|
@ -7,7 +7,12 @@
|
||||
"=============================================================================
|
||||
|
||||
let s:self = {}
|
||||
let s:self.__floating = SpaceVim#api#import('neovim#floating')
|
||||
if has('nvim')
|
||||
let s:self.__floating = SpaceVim#api#import('neovim#floating')
|
||||
else
|
||||
let s:self.__floating = SpaceVim#api#import('vim#floating')
|
||||
endif
|
||||
let s:self.__buffer = SpaceVim#api#import('vim#buffer')
|
||||
|
||||
|
||||
function! s:self.check_width(len, sec, winwidth) abort
|
||||
@ -88,9 +93,13 @@ function! s:self.build(left_sections, right_sections, lsep, rsep, fname, tag, hi
|
||||
return l[:-4]
|
||||
endfunction
|
||||
|
||||
function! s:self.support_float() abort
|
||||
return exists('*nvim_buf_set_virtual_text')
|
||||
endfunction
|
||||
|
||||
function! s:self.open_float(st) abort
|
||||
if !has_key(self, '__bufnr') || !bufexists(self.__bufnr)
|
||||
let self.__bufnr = nvim_create_buf(0,0)
|
||||
let self.__bufnr = self.__buffer.bufadd('')
|
||||
endif
|
||||
if has_key(self, '__winid') && win_id2tabwin(self.__winid)[0] == tabpagenr()
|
||||
else
|
||||
@ -109,7 +118,9 @@ function! s:self.open_float(st) abort
|
||||
call setbufvar(self.__bufnr, '&bufhidden', 'wipe')
|
||||
call setbufvar(self.__bufnr, '&cursorline', 0)
|
||||
call setbufvar(self.__bufnr, '&modifiable', 0)
|
||||
call setwinvar(win_id2win(self.__winid), '&winhighlight', 'Normal:SpaceVim_statusline_a_bold')
|
||||
if exists('&winhighlight')
|
||||
call setwinvar(win_id2win(self.__winid), '&winhighlight', 'Normal:SpaceVim_statusline_a_bold')
|
||||
endif
|
||||
call setwinvar(win_id2win(self.__winid), '&cursorline', 0)
|
||||
call nvim_buf_set_virtual_text(
|
||||
\ self.__bufnr,
|
||||
@ -120,14 +131,9 @@ function! s:self.open_float(st) abort
|
||||
redraw!
|
||||
endfunction
|
||||
|
||||
if exists('*nvim_win_close')
|
||||
if s:self.__floating.exists()
|
||||
function! s:self.close_float() abort
|
||||
" @fixme: nvim_win_close only support one argv in old version
|
||||
try
|
||||
call nvim_win_close(self.__winid, 1)
|
||||
catch /^Vim\%((\a\+)\)\=:E118/
|
||||
call nvim_win_close(self.__winid)
|
||||
endtry
|
||||
call self.__floating.win_close(self.__winid, 1)
|
||||
endfunction
|
||||
else
|
||||
function! s:self.close_float() abort
|
||||
|
@ -15,8 +15,13 @@ scriptencoding utf-8
|
||||
let s:CMP = SpaceVim#api#import('vim#compatible')
|
||||
let s:STR = SpaceVim#api#import('data#string')
|
||||
let s:KEY = SpaceVim#api#import('vim#key')
|
||||
let s:FLOATING = SpaceVim#api#import('neovim#floating')
|
||||
if has('nvim')
|
||||
let s:FLOATING = SpaceVim#api#import('neovim#floating')
|
||||
else
|
||||
let s:FLOATING = SpaceVim#api#import('vim#floating')
|
||||
endif
|
||||
let s:SL = SpaceVim#api#import('vim#statusline')
|
||||
let s:BUFFER = SpaceVim#api#import('vim#buffer')
|
||||
|
||||
" guide specific var
|
||||
|
||||
@ -245,7 +250,6 @@ function! s:escape_keys(inp) abort " {{{
|
||||
return substitute(ret, '|', '<Bar>', '')
|
||||
endfunction " }}}
|
||||
|
||||
|
||||
function! s:calc_layout() abort " {{{
|
||||
let ret = {}
|
||||
let smap = filter(copy(s:lmap), 'v:key !=# "name"')
|
||||
@ -260,8 +264,8 @@ function! s:calc_layout() abort " {{{
|
||||
let ret.col_width = maxlength
|
||||
let ret.win_dim = ret.n_cols * ret.col_width
|
||||
else
|
||||
let ret.n_cols = winwidth(0) >= maxlength ? winwidth(0) / maxlength : 1
|
||||
let ret.col_width = winwidth(0) / ret.n_cols
|
||||
let ret.n_cols = winwidth(s:winid) >= maxlength ? winwidth(s:winid) / maxlength : 1
|
||||
let ret.col_width = winwidth(s:winid) / ret.n_cols
|
||||
let ret.n_rows = ret.n_items / ret.n_cols + (fmod(ret.n_items,ret.n_cols) > 0 ? 1 : 0)
|
||||
let ret.win_dim = ret.n_rows
|
||||
endif
|
||||
@ -340,10 +344,7 @@ function! s:create_string(layout) abort " {{{
|
||||
let mlen = strdisplaywidth(line)
|
||||
endif
|
||||
endfor
|
||||
call insert(r, '')
|
||||
let output = join(r, "\n ")
|
||||
cnoremap <nowait> <buffer> <Space> <Space><CR>
|
||||
cnoremap <nowait> <buffer> <silent> <C-h> <LGCMD>paging_help<CR>
|
||||
let output = join(r, "\n")
|
||||
return output
|
||||
endfunction " }}}
|
||||
|
||||
@ -390,7 +391,7 @@ function! s:start_buffer() abort " {{{
|
||||
let s:winv = winsaveview()
|
||||
let s:winnr = winnr()
|
||||
let s:winres = winrestcmd()
|
||||
call s:winopen()
|
||||
let [s:winid, s:bufnr] = s:winopen()
|
||||
let layout = s:calc_layout()
|
||||
let string = s:create_string(layout)
|
||||
|
||||
@ -398,9 +399,9 @@ function! s:start_buffer() abort " {{{
|
||||
let layout.win_dim = min([g:leaderGuide_max_size, layout.win_dim])
|
||||
endif
|
||||
|
||||
setlocal modifiable
|
||||
if exists('*nvim_open_win')
|
||||
call s:FLOATING.win_config(win_getid(s:winid),
|
||||
call setbufvar(s:bufnr, '&modifiable', 1)
|
||||
if s:FLOATING.exists()
|
||||
let rst = s:FLOATING.win_config(s:winid,
|
||||
\ {
|
||||
\ 'relative': 'editor',
|
||||
\ 'width' : &columns,
|
||||
@ -408,7 +409,6 @@ function! s:start_buffer() abort " {{{
|
||||
\ 'row' : &lines - layout.win_dim - 4,
|
||||
\ 'col' : 0
|
||||
\ })
|
||||
|
||||
else
|
||||
if g:leaderGuide_vertical
|
||||
noautocmd execute 'vert res '.layout.win_dim
|
||||
@ -416,15 +416,14 @@ function! s:start_buffer() abort " {{{
|
||||
noautocmd execute 'res '.layout.win_dim
|
||||
endif
|
||||
endif
|
||||
normal! gg"_dd
|
||||
if exists('*nvim_open_win')
|
||||
if s:FLOATING.exists()
|
||||
" when using floating windows, and the flaating windows do not support
|
||||
" statusline, add extra black line at top and button of the content.
|
||||
call setline(1, [''] + split(string, "\n") + [''])
|
||||
call s:BUFFER.buf_set_lines(s:bufnr, 0, -1, 0, [''] + split(string, "\n") + [''])
|
||||
else
|
||||
call setline(1, split(string, "\n"))
|
||||
call s:BUFFER.buf_set_lines(s:bufnr, 0, -1, 0, split(string, "\n"))
|
||||
endif
|
||||
setlocal nomodifiable
|
||||
call setbufvar(s:bufnr, '&modifiable', 0)
|
||||
redraw!
|
||||
call s:wait_for_input()
|
||||
endfunction " }}}
|
||||
@ -511,12 +510,15 @@ function! s:build_mpt(mpt) abort
|
||||
echohl NONE
|
||||
endfunction
|
||||
|
||||
|
||||
" change this func, do not focus to the new windows, and return winid.
|
||||
|
||||
function! s:winopen() abort " {{{
|
||||
call s:highlight_cursor()
|
||||
let pos = g:leaderGuide_position ==? 'topleft' ? 'topleft' : 'botright'
|
||||
if exists('*nvim_open_win')
|
||||
if s:FLOATING.exists()
|
||||
if !bufexists(s:bufnr)
|
||||
let s:bufnr = nvim_create_buf(v:false,v:false)
|
||||
let s:bufnr = s:BUFFER.bufadd('')
|
||||
endif
|
||||
let s:winid = s:FLOATING.open_win(s:bufnr, v:true,
|
||||
\ {
|
||||
@ -549,21 +551,33 @@ function! s:winopen() abort " {{{
|
||||
let s:winid = winnr()
|
||||
endif
|
||||
let s:guide_help_mode = 0
|
||||
setlocal filetype=leaderGuide
|
||||
call setbufvar(s:bufnr, '&filetype', 'leaderGuide')
|
||||
call setbufvar(s:bufnr, '&number', 0)
|
||||
call setbufvar(s:bufnr, '&relativenumber', 0)
|
||||
call setbufvar(s:bufnr, '&list', 0)
|
||||
call setbufvar(s:bufnr, '&modeline', 0)
|
||||
call setbufvar(s:bufnr, '&wrap', 0)
|
||||
call setbufvar(s:bufnr, '&buflisted', 0)
|
||||
call setbufvar(s:bufnr, '&buftype', 'nofile')
|
||||
call setbufvar(s:bufnr, '&bufhidden', 'unload')
|
||||
call setbufvar(s:bufnr, '&swapfile', 0)
|
||||
call setbufvar(s:bufnr, '&cursorline', 0)
|
||||
call setbufvar(s:bufnr, '&cursorcolumn', 0)
|
||||
call setbufvar(s:bufnr, '&colorcolumn', '')
|
||||
call setbufvar(s:bufnr, '&winfixwidth', 1)
|
||||
call setbufvar(s:bufnr, '&winfixheight', 1)
|
||||
|
||||
if exists('&winhighlight')
|
||||
set winhighlight=Normal:Pmenu
|
||||
endif
|
||||
setlocal nonumber norelativenumber nolist nomodeline nowrap
|
||||
setlocal nobuflisted buftype=nofile bufhidden=unload noswapfile
|
||||
setlocal nocursorline nocursorcolumn colorcolumn=
|
||||
setlocal winfixwidth winfixheight
|
||||
" @fixme not sure if the listchars should be changed!
|
||||
" setlocal listchars=
|
||||
call s:updateStatusline()
|
||||
call s:toggle_hide_cursor()
|
||||
return [s:winid, s:bufnr]
|
||||
endfunction " }}}
|
||||
|
||||
if exists('*nvim_open_win')
|
||||
if s:SL.support_float()
|
||||
function! s:updateStatusline() abort
|
||||
call SpaceVim#mapping#guide#theme#hi()
|
||||
let gname = get(s:guide_group, 'name', '')
|
||||
@ -596,13 +610,13 @@ else
|
||||
endif
|
||||
let keys = get(s:, 'prefix_key_inp', '')
|
||||
let keys = substitute(keys, '\', '\\\', 'g')
|
||||
exe 'setlocal statusline=%#LeaderGuiderPrompt#\ Guide:\ ' .
|
||||
call setbufvar(s:bufnr, '&statusline', '%#LeaderGuiderPrompt#\ Guide:\ ' .
|
||||
\ '%#LeaderGuiderSep1#' . s:lsep .
|
||||
\ '%#LeaderGuiderName#\ ' .
|
||||
\ SpaceVim#mapping#leader#getName(s:prefix_key)
|
||||
\ . keys . gname
|
||||
\ . '\ %#LeaderGuiderSep2#' . s:lsep . '%#LeaderGuiderFill#'
|
||||
\ . s:guide_help_msg(1)
|
||||
\ . s:guide_help_msg(1))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
@ -629,9 +643,11 @@ endfunction
|
||||
|
||||
function! s:winclose() abort " {{{
|
||||
call s:toggle_hide_cursor()
|
||||
if exists('*nvim_win_close')
|
||||
call nvim_win_close(s:winid, 1)
|
||||
call s:close_float_statusline()
|
||||
if s:FLOATING.exists()
|
||||
call s:FLOATING.win_close(s:winid, 1)
|
||||
if s:SL.support_float()
|
||||
call s:close_float_statusline()
|
||||
endif
|
||||
else
|
||||
noautocmd execute s:winid.'wincmd w'
|
||||
if s:winid == winnr()
|
||||
|
@ -245,7 +245,7 @@ function! s:start_replace() abort
|
||||
catch
|
||||
endtr
|
||||
if s:grepid != 0
|
||||
call s:JOB.stop(s:grepid)
|
||||
call s:JOB.stop(s:grepid)
|
||||
endif
|
||||
let replace_text = s:current_grep_pattern
|
||||
if !empty(replace_text)
|
||||
@ -308,7 +308,7 @@ let s:MPT._prompt.mpt = g:spacevim_commandline_prompt . ' '
|
||||
function! s:close_buffer() abort
|
||||
" NOTE: the jobid maybe -1, that is means the cmd is not executable.
|
||||
if s:grepid > 0
|
||||
call s:JOB.stop(s:grepid)
|
||||
call s:JOB.stop(s:grepid)
|
||||
endif
|
||||
call timer_stop(s:grep_timer_id)
|
||||
call timer_stop(s:preview_timer_id)
|
||||
@ -730,7 +730,7 @@ function! SpaceVim#plugins#flygrep#open(argv) abort
|
||||
" set default handle func: s:flygrep
|
||||
let s:MPT._handle_fly = function('s:flygrep')
|
||||
if exists('*nvim_open_win')
|
||||
let s:buffer_id = nvim_create_buf(v:false, v:false)
|
||||
let s:buffer_id = s:BUFFER.bufadd('')
|
||||
let flygrep_win_height = 16
|
||||
let s:flygrep_win_id = s:FLOATING.open_win(s:buffer_id, v:true,
|
||||
\ {
|
||||
@ -798,7 +798,9 @@ function! SpaceVim#plugins#flygrep#open(argv) abort
|
||||
" sometimes user can not see the flygrep windows, redraw only once.
|
||||
redraw
|
||||
call s:MPT.open()
|
||||
call s:close_statusline()
|
||||
if s:SL.support_float()
|
||||
call s:close_statusline()
|
||||
endif
|
||||
call SpaceVim#logger#info('FlyGrep ending ===========================')
|
||||
let &t_ve = save_tve
|
||||
if has('gui_running')
|
||||
|
Loading…
Reference in New Issue
Block a user