1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 09:30:04 +08:00
SpaceVim/bundle/vim-choosewin/autoload/choosewin/hlmanager.vim
2020-06-13 14:06:35 +08:00

195 lines
4.7 KiB
VimL

" Util:
function! s:define_type_checker() "{{{1
" dynamically define s:is_Number(v) etc..
let types = {
\ "Number": 0,
\ "String": 1,
\ "Funcref": 2,
\ "List": 3,
\ "Dictionary": 4,
\ "Float": 5,
\ }
for [type, number] in items(types)
let s = ''
let s .= 'function! s:is_' . type . '(v)' . "\n"
let s .= ' return type(a:v) is ' . number . "\n"
let s .= 'endfunction' . "\n"
execute s
endfor
endfunction
"}}}
call s:define_type_checker()
unlet! s:define_type_checker
" Copied from vim-airline's airline#init#gui_mode function
let s:SCREEN = (has('gui_running') ||
\ (has('termtruecolor') && &guicolors == 1) ||
\ (has('termguicolors') && &termguicolors == 1) ||
\ (has('nvim') && exists('$NVIM_TUI_ENABLE_TRUE_COLOR')
\ && !exists('+termguicolors'))) ? 'gui' : 'cterm'
" Main:
let s:hlmgr = {}
function! s:hlmgr.new(prefix) "{{{1
let R = deepcopy(self)
call R.init(a:prefix)
return R
endfunction
function! s:hlmgr.init(prefix) "{{{1
let self._colors = {}
let self._specs = {}
let self.prefix = a:prefix
return self
endfunction
function! s:hlmgr.register_auto(spec) "{{{1
if s:is_String(a:spec)
return a:spec
endif
if s:is_Dictionary(a:spec)
let spec = string(a:spec[s:SCREEN])
let name = get(self._specs, spec, '')
if !empty(name)
" If color is already defined for spec provided.
" return that color
return name
endif
endif
return self.register(self.color_next(), a:spec)
endfunction
function! s:hlmgr.register(name, spec) "{{{1
call self.define(a:name, a:spec)
let self._colors[a:name] = a:spec
" This might overwrite existing spec but its OK since _specs is simple color
" re-using mechanizm for performance.
let self._specs[string(a:spec[s:SCREEN])] = a:name
return a:name
endfunction
function! s:hlmgr.define(name, color) "{{{1
let command = printf('highlight %s %s', a:name, self.hl_defstr(a:color))
silent execute command
endfunction
function! s:hlmgr.refresh() "{{{1
for [name, color] in items(self._colors)
call self.define(name, color)
endfor
endfunction
function! s:hlmgr.color_next() "{{{1
return printf(self.prefix . '%05d', len(self._colors))
endfunction
function! s:hlmgr.reset() "{{{1
call self.clear()
call self.init(self.prefix)
endfunction
function! s:hlmgr.spec_for(color) "{{{1
return get(self._colors, a:color, '')
endfunction
function! s:hlmgr.parse(spec, ...) "{{{1
" return dictionary from string
" 'guifg=#25292c guibg=#afb0ae' => {'gui': ['#afb0ae', '#25292c']}
let R = {}
if empty(a:spec)
return R
endif
let screens = empty(a:000) ? [s:SCREEN] : ['gui', 'cterm' ]
for screen in screens
let R[screen] = ['','']
for def in split(a:spec)
let [key,val] = split(def, '=')
if key ==# screen . 'bg' | let R[screen][0] = val
elseif key ==# screen . 'fg' | let R[screen][1] = val
elseif key ==# screen | call add(R[screen], val)
endif
endfor
endfor
return R
endfunction
function! s:hlmgr.parse_full(spec) "{{{1
return self.parse(a:spec, 1)
endfunction
function! s:hlmgr.capture(hlname) "{{{1
let hlname = a:hlname
if empty(hlID(hlname))
" if hl not exists, return empty string
return ''
endif
redir => HL_SAVE
execute 'silent! highlight ' . hlname
redir END
if !empty(matchstr(HL_SAVE, 'xxx cleared$'))
return ''
endif
" follow highlight link
let link = matchstr(HL_SAVE, 'xxx links to \zs.*')
if !empty(link)
return self.capture(link)
endif
return matchstr(HL_SAVE, 'xxx \zs.*')
endfunction
function! s:hlmgr.clear() "{{{1
for color in self.colors()
silent execute 'highlight clear' color
endfor
endfunction
function! s:hlmgr.colors() "{{{1
return keys(self._colors)
endfunction
function! s:hlmgr.hl_defstr(color) "{{{1
" return 'guibg=DarkGreen gui=bold' (Type: String)
let color = a:color[s:SCREEN]
let R = []
"[NOTE] empty() is not appropriate, cterm color is specified with number
for [idx, s] in [[ 0, 'bg' ], [ 1, 'fg' ] ,[ 2, ''] ]
let c = get(color, idx, -1)
if (s:is_String(c) && empty(c)) || (s:is_Number(c) && c ==# -1)
continue
endif
call add(R, printf('%s%s=%s', s:SCREEN, s, color[idx]))
endfor
return join(R)
endfunction
function! s:hlmgr.convert(hlname) "{{{1
return self.parse(self.capture(a:hlname))
endfunction
function! s:hlmgr.convert_full(hlname) "{{{1
return self.parse_full(self.capture(a:hlname))
endfunction
function! s:hlmgr.dump() "{{{1
return PP(self)
endfunction
"}}}
" API:
function! choosewin#hlmanager#new(prefix) "{{{1
return s:hlmgr.new(a:prefix)
endfunction
"}}}
" vim: foldmethod=marker