mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-03-25 03:02:21 +08:00
152 lines
4.7 KiB
VimL
152 lines
4.7 KiB
VimL
"=============================================================================
|
|
" notification.vim --- notification api
|
|
" Copyright (c) 2016-2019 Wang Shidong & Contributors
|
|
" Author: Wang Shidong < wsdjeg@outlook.com >
|
|
" URL: https://spacevim.org
|
|
" License: GPLv3
|
|
"=============================================================================
|
|
|
|
|
|
" Global values, this can be used between different notification
|
|
|
|
let s:shown = []
|
|
|
|
let s:self = {}
|
|
|
|
let s:self.winid = -1
|
|
let s:self.bufnr = -1
|
|
let s:self.border = {}
|
|
let s:self.border.winid = -1
|
|
let s:self.border.bufnr = -1
|
|
let s:self.borderchars = ['─', '│', '─', '│', '┌', '┐', '┘', '└']
|
|
let s:self.title = ''
|
|
let s:self.win_is_open = 0
|
|
let s:self.timeout = 3000
|
|
|
|
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.draw_border(title, width, height) abort
|
|
let top = self.borderchars[4] .
|
|
\ repeat(self.borderchars[0], a:width) .
|
|
\ self.borderchars[5]
|
|
let mid = self.borderchars[3] .
|
|
\ repeat(' ', a:width) .
|
|
\ self.borderchars[1]
|
|
let bot = self.borderchars[7] .
|
|
\ repeat(self.borderchars[2], a:width) .
|
|
\ self.borderchars[6]
|
|
let top = self.string_compose(top, 1, a:title)
|
|
let lines = [top] + repeat([mid], a:height) + [bot]
|
|
return lines
|
|
endfunction
|
|
|
|
function! s:self.string_compose(target, pos, source)
|
|
if a:source == ''
|
|
return a:target
|
|
endif
|
|
let pos = a:pos
|
|
let source = a:source
|
|
if pos < 0
|
|
let source = strcharpart(a:source, -pos)
|
|
let pos = 0
|
|
endif
|
|
let target = strcharpart(a:target, 0, pos)
|
|
if strchars(target) < pos
|
|
let target .= repeat(' ', pos - strchars(target))
|
|
endif
|
|
let target .= source
|
|
" vim popup will pad the end of title but not begin part
|
|
" so we build the title as ' floaterm idx/cnt'
|
|
" therefore, we need to add a space here
|
|
let target .= ' ' . strcharpart(a:target, pos + strchars(source) + 1)
|
|
return target
|
|
endfunction
|
|
|
|
|
|
function! s:self.close(...) dict
|
|
if len(s:shown) == 1
|
|
noautocmd call self.__floating.win_close(self.border.winid, v:true)
|
|
noautocmd call self.__floating.win_close(self.winid, v:true)
|
|
let self.win_is_open = v:false
|
|
endif
|
|
if !empty(s:shown)
|
|
call remove(s:shown, 0)
|
|
endif
|
|
endfunction
|
|
|
|
function! s:self.notification(msg, color) abort
|
|
call add(s:shown, a:msg)
|
|
if !bufexists(self.border.bufnr)
|
|
let self.border.bufnr = self.__buffer.create_buf(0, 0)
|
|
endif
|
|
if !bufexists(self.bufnr)
|
|
let self.bufnr = self.__buffer.create_buf(0, 0)
|
|
endif
|
|
call self.__buffer.buf_set_lines(self.border.bufnr, 0 , -1, 0, self.draw_border(self.title, strwidth(a:msg), len(s:shown)))
|
|
call self.__buffer.buf_set_lines(self.bufnr, 0 , -1, 0, s:shown)
|
|
if self.win_is_open
|
|
call self.__floating.win_config(self.winid,
|
|
\ {
|
|
\ 'relative': 'editor',
|
|
\ 'width' : strwidth(a:msg),
|
|
\ 'height' : len(s:shown),
|
|
\ 'row': 3,
|
|
\ 'highlight' : a:color,
|
|
\ 'focusable' : v:false,
|
|
\ 'col': &columns - strwidth(a:msg) - 1,
|
|
\ })
|
|
call self.__floating.win_config(self.border.winid,
|
|
\ {
|
|
\ 'relative': 'editor',
|
|
\ 'width' : strwidth(a:msg) + 2,
|
|
\ 'height' : len(s:shown) + 2,
|
|
\ 'row': 2,
|
|
\ 'col': &columns - strwidth(a:msg) - 2,
|
|
\ 'highlight' : 'VertSplit',
|
|
\ 'focusable' : v:false,
|
|
\ })
|
|
else
|
|
let self.winid = self.__floating.open_win(self.bufnr, v:false,
|
|
\ {
|
|
\ 'relative': 'editor',
|
|
\ 'width' : strwidth(a:msg),
|
|
\ 'height' : len(s:shown),
|
|
\ 'row': 3,
|
|
\ 'highlight' : a:color,
|
|
\ 'col': &columns - strwidth(a:msg) - 1,
|
|
\ 'focusable' : v:false,
|
|
\ })
|
|
let self.border.winid = self.__floating.open_win(self.border.bufnr, v:false,
|
|
\ {
|
|
\ 'relative': 'editor',
|
|
\ 'width' : strwidth(a:msg) + 2,
|
|
\ 'height' : len(s:shown) + 2,
|
|
\ 'row': 2,
|
|
\ 'col': &columns - strwidth(a:msg) - 2,
|
|
\ 'highlight' : 'VertSplit',
|
|
\ 'focusable' : v:false,
|
|
\ })
|
|
let self.win_is_open = v:true
|
|
endif
|
|
call setbufvar(self.bufnr, '&number', 0)
|
|
call setbufvar(self.bufnr, '&relativenumber', 0)
|
|
call setbufvar(self.bufnr, '&buftype', 'nofile')
|
|
call setbufvar(self.border.bufnr, '&number', 0)
|
|
call setbufvar(self.border.bufnr, '&relativenumber', 0)
|
|
call setbufvar(self.border.bufnr, '&buftype', 'nofile')
|
|
call timer_start(self.timeout, self.close, {'repeat' : 1})
|
|
endfunction
|
|
|
|
|
|
function! SpaceVim#api#notification#get()
|
|
|
|
return deepcopy(s:self)
|
|
|
|
endfunction
|
|
|