"============================================================================= " statusline.vim --- SpaceVim statusline API " Copyright (c) 2016-2023 Wang Shidong & Contributors " Author: Wang Shidong < wsdjeg@outlook.com > " URL: https://spacevim.org " License: GPLv3 "============================================================================= let s:self = {} 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') let s:self.__cmp = SpaceVim#api#import('vim#compatible') function! s:self.check_width(len, sec, winwidth) abort return a:len + self.len(a:sec) < a:winwidth endfunction let s:self.__winid = -1 let s:self.__bufnr = -1 function! s:self.len(sec) abort let str = matchstr(a:sec, '%{.*}') if !empty(str) let pos = match(str, '}') return len(a:sec) - len(str) + len(eval(str[2:pos-1])) + 4 else return len(a:sec) + 4 endif endfunction function! s:self.eval(sec) abort return substitute(a:sec, '%{.*}', '', 'g') endfunction function! s:self.build(left_sections, right_sections, lsep, rsep, fname, tag, hi_a, hi_b, hi_c, hi_z, winwidth) abort let l = '%#' . a:hi_a . '#' . a:left_sections[0] let l .= '%#' . a:hi_a . '_' . a:hi_b . '#' . a:lsep let flag = 1 let len = 0 for sec in filter(a:left_sections[1:], '!empty(v:val)') if self.check_width(len, sec, a:winwidth) let len += self.len(sec) if flag == 1 let l .= '%#' . a:hi_b . '#' . sec let l .= '%#' . a:hi_b . '_' . a:hi_c . '#' . a:lsep else let l .= '%#' . a:hi_c . '#' . sec let l .= '%#' . a:hi_c . '_' . a:hi_b . '#' . a:lsep endif let flag = flag * -1 endif endfor let l = l[:len(a:lsep) * -1 - 1] if empty(a:right_sections) if flag == 1 return l . '%#' . a:hi_c . '#' else return l . '%#' . a:hi_b . '#' endif endif if self.check_width(len, a:fname, a:winwidth) let len += self.len(a:fname) if flag == 1 let l .= '%#' . a:hi_c . '_' . a:hi_z . '#' . a:lsep . '%#' . a:hi_z . '#' . a:fname . '%=' else let l .= '%#' . a:hi_b . '_' . a:hi_z . '#' . a:lsep . '%#' . a:hi_z . '#' . a:fname . '%=' endif else if flag == 1 let l .= '%#' . a:hi_c . '_' . a:hi_z . '#' . a:lsep . '%=' else let l .= '%#' . a:hi_b . '_' . a:hi_z . '#' . a:lsep . '%=' endif endif if self.check_width(len, a:tag, a:winwidth) && g:spacevim_enable_statusline_tag let l .= '%#' . a:hi_z . '#' . a:tag endif let l .= '%#' . a:hi_b . '_' . a:hi_z . '#' . a:rsep let flag = 1 for sec in filter(a:right_sections, '!empty(v:val)') if self.check_width(len, sec, a:winwidth) let len += self.len(sec) if flag == 1 let l .= '%#' . a:hi_b . '#' . sec let l .= '%#' . a:hi_c . '_' . a:hi_b . '#' . a:rsep else let l .= '%#' . a:hi_c . '#' . sec let l .= '%#' . a:hi_b . '_' . a:hi_c . '#' . a:rsep endif let flag = flag * -1 endif endfor return l[:-4] endfunction function! s:self.support_float() abort return self.__floating.exists() endfunction if has('nvim') function! s:self.opened() abort return win_id2tabwin(self.__winid)[0] == tabpagenr() endfunction else function! s:self.opened() abort "tabpage" will be -1 for a global popup, zero for a popup on "the current tabpage and a positive number for a popup on "another tabpage. if exists('*popup_list') return index(popup_list(), self.__winid) != -1 else return index([-1, 0], get(popup_getoptions(self.__winid), 'tabpage', -2)) != -1 endif endfunction endif function! s:self.open_float(st) abort if !has_key(self, '__bufnr') || !bufexists(self.__bufnr) let self.__bufnr = self.__buffer.bufadd('') endif if has_key(self, '__winid') && self.opened() else let self.__winid = self.__floating.open_win(self.__bufnr, \ v:false, \ { \ 'relative': 'editor', \ 'width' : &columns, \ 'height' : 1, \ 'highlight' : 'SpaceVim_statusline_a_bold', \ 'row': &lines - 2 , \ 'col': 0 \ }) endif call setbufvar(self.__bufnr, '&relativenumber', 0) call setbufvar(self.__bufnr, '&number', 0) call setbufvar(self.__bufnr, '&bufhidden', 'wipe') call setbufvar(self.__bufnr, '&cursorline', 0) call setbufvar(self.__bufnr, '&modifiable', 1) if exists('*nvim_buf_set_virtual_text') call setwinvar(win_id2win(self.__winid), '&cursorline', 0) call nvim_buf_set_virtual_text( \ self.__bufnr, \ -1, \ 0, \ a:st, \ {}) else let l = '' for [str, hg] in a:st let l .= str endfor call self.__buffer.buf_set_lines(self.__bufnr, 0, -1, 0, [l]) let begin = 1 let end = 0 for [str, hg] in a:st let end = strlen(str) call win_execute(self.__winid, 'call self.__cmp.matchaddpos(hg, [[1, begin, end]])') let begin += end endfor endif call setbufvar(self.__bufnr, '&modifiable', 0) return self.__winid endfunction if s:self.__floating.exists() function! s:self.close_float() abort if get(self, '__winid', -1) != -1 call self.__floating.win_close(self.__winid, 1) endif endfunction else function! s:self.close_float() abort if get(self, '__winid', -1) != -1 && win_id2tabwin(self.__winid)[0] == tabpagenr() noautocmd execute win_id2win(self.__winid).'wincmd w' noautocmd close endif endfunction endif function! SpaceVim#api#vim#statusline#get() abort return deepcopy(s:self) endfunction " vim:set et sw=2 cc=80 nowrap: