mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 09:30:04 +08:00
195 lines
4.7 KiB
VimL
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
|