diff --git a/autoload/SpaceVim/api/notification.vim b/autoload/SpaceVim/api/notification.vim index 495698736..8d9327521 100644 --- a/autoload/SpaceVim/api/notification.vim +++ b/autoload/SpaceVim/api/notification.vim @@ -9,10 +9,12 @@ " Global values, this can be used between different notification -let s:shown = [] +let s:notifications = {} + +" dictionary values and functions let s:self = {} - +let s:self.message = [] let s:self.winid = -1 let s:self.bufnr = -1 let s:self.border = {} @@ -22,6 +24,7 @@ let s:self.borderchars = ['─', '│', '─', '│', '┌', '┐', '┘', '└' let s:self.title = '' let s:self.win_is_open = 0 let s:self.timeout = 3000 +let s:self.hashkey = '' if has('nvim') let s:self.__floating = SpaceVim#api#import('neovim#floating') @@ -29,6 +32,7 @@ else let s:self.__floating = SpaceVim#api#import('vim#floating') endif let s:self.__buffer = SpaceVim#api#import('vim#buffer') +let s:self.__password = SpaceVim#api#import('password') function! s:self.draw_border(title, width, height) abort let top = self.borderchars[4] . @@ -69,44 +73,77 @@ endfunction function! s:self.close(...) dict - if len(s:shown) == 1 + if !empty(self.message) + call remove(self.message, 0) + let self.notification_width = max(map(deepcopy(self.message), 'strwidth(v:val)')) + endif + if len(self.message) == 0 noautocmd call self.__floating.win_close(self.border.winid, v:true) noautocmd call self.__floating.win_close(self.winid, v:true) + call remove(s:notifications, self.hashkey) let self.win_is_open = v:false endif - if !empty(s:shown) - call remove(s:shown, 0) - endif + for hashkey in keys(s:notifications) + call s:notifications[hashkey].redraw_windows() + endfor endfunction function! s:self.notification(msg, color) abort - call add(s:shown, a:msg) + call add(self.message, a:msg) + let self.notification_color = a:color 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 empty(self.hashkey) + let self.hashkey = self.__password.generate_simple(10) + endif + call self.redraw_windows() + 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 extend(s:notifications, {self.hashkey : self}) + call timer_start(self.timeout, self.close, {'repeat' : 1}) +endfunction + +function! s:self.redraw_windows() abort + if empty(self.message) + return + endif + let self.notification_width = max(map(deepcopy(self.message), 'strwidth(v:val)')) + call self.__buffer.buf_set_lines(self.border.bufnr, 0 , -1, 0, self.draw_border(self.title, self.notification_width, len(self.message))) + call self.__buffer.buf_set_lines(self.bufnr, 0 , -1, 0, self.message) + let self.begin_row = 2 + for hashkey in keys(s:notifications) + if hashkey !=# self.hashkey + let self.begin_row += len(s:notifications[hashkey].message) + 2 + else + break + endif + endfor 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, + \ 'width' : self.notification_width, + \ 'height' : len(self.message), + \ 'row': self.begin_row + 1, + \ 'highlight' : self.notification_color, \ 'focusable' : v:false, - \ 'col': &columns - strwidth(a:msg) - 1, + \ 'col': &columns - self.notification_width - 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, + \ 'width' : self.notification_width + 2, + \ 'height' : len(self.message) + 2, + \ 'row': self.begin_row, + \ 'col': &columns - self.notification_width - 2, \ 'highlight' : 'VertSplit', \ 'focusable' : v:false, \ }) @@ -114,32 +151,25 @@ function! s:self.notification(msg, color) abort 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, + \ 'width' : self.notification_width, + \ 'height' : len(self.message), + \ 'row': self.begin_row + 1, + \ 'highlight' : self.notification_color, + \ 'col': &columns - self.notification_width - 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, + \ 'width' : self.notification_width + 2, + \ 'height' : len(self.message) + 2, + \ 'row': self.begin_row, + \ 'col': &columns - self.notification_width - 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