121 lines
3.4 KiB
VimL
121 lines
3.4 KiB
VimL
let s:path = get(g:, 'vim_dir', expand('~/.vim')) . '/theme.json'
|
|
let s:defaults = {
|
|
\ 'background': 'dark',
|
|
\ 'dark': {'theme': 'moonfly', 'transparent': v:false},
|
|
\ 'light': {'theme': 'PaperColor', 'transparent': v:false}}
|
|
let s:config = deepcopy(s:defaults)
|
|
let s:applying = v:false
|
|
let s:transparent_groups = [
|
|
\ 'Normal', 'NormalNC', 'EndOfBuffer', 'Folded', 'LineNr', 'SignColumn',
|
|
\ 'StatusLine', 'StatusLineNC', 'VertSplit', 'WinSeparator', 'NormalFloat']
|
|
|
|
function! s:Merge(defaults, override) abort
|
|
let l:result = deepcopy(a:defaults)
|
|
if type(a:override) != v:t_dict
|
|
return l:result
|
|
endif
|
|
for [l:key, l:value] in items(a:override)
|
|
if type(l:value) == v:t_dict && type(get(l:result, l:key)) == v:t_dict
|
|
let l:result[l:key] = s:Merge(l:result[l:key], l:value)
|
|
else
|
|
let l:result[l:key] = l:value
|
|
endif
|
|
endfor
|
|
return l:result
|
|
endfunction
|
|
|
|
function! s:Available(name) abort
|
|
return !empty(globpath(&runtimepath, 'colors/' . a:name . '.vim', 1, 1))
|
|
endfunction
|
|
|
|
function! s:ApplyTransparency() abort
|
|
if !s:config[&background].transparent
|
|
return
|
|
endif
|
|
for l:group in s:transparent_groups
|
|
execute 'highlight ' . l:group . ' guibg=NONE ctermbg=NONE'
|
|
endfor
|
|
endfunction
|
|
|
|
function! s:Load() abort
|
|
if !filereadable(s:path)
|
|
return deepcopy(s:defaults)
|
|
endif
|
|
try
|
|
let l:saved = json_decode(join(readfile(s:path), "\n"))
|
|
return s:Merge(s:defaults, l:saved)
|
|
catch
|
|
return deepcopy(s:defaults)
|
|
endtry
|
|
endfunction
|
|
|
|
function! theme#save() abort
|
|
try
|
|
call mkdir(fnamemodify(s:path, ':h'), 'p')
|
|
call writefile([json_encode(s:config)], s:path)
|
|
catch
|
|
" A read-only home directory should not prevent Vim from exiting cleanly.
|
|
endtry
|
|
endfunction
|
|
|
|
function! theme#apply(name) abort
|
|
let l:background = &background
|
|
let l:name = s:Available(a:name) ? a:name
|
|
\ : (l:background ==# 'dark' ? 'sunbather_dark' : 'sunbather_light')
|
|
let s:applying = v:true
|
|
try
|
|
execute 'colorscheme ' . l:name
|
|
finally
|
|
let s:applying = v:false
|
|
endtry
|
|
let &background = l:background
|
|
let s:config.background = l:background
|
|
let s:config[l:background].theme = l:name
|
|
call s:ApplyTransparency()
|
|
endfunction
|
|
|
|
function! theme#toggleBg() abort
|
|
let l:background = &background ==# 'dark' ? 'light' : 'dark'
|
|
let l:theme = s:config[l:background].theme
|
|
let s:applying = v:true
|
|
try
|
|
let &background = l:background
|
|
finally
|
|
let s:applying = v:false
|
|
endtry
|
|
let s:config.background = l:background
|
|
call theme#apply(l:theme)
|
|
endfunction
|
|
|
|
function! theme#toggleTransparent() abort
|
|
let s:config[&background].transparent = !s:config[&background].transparent
|
|
if s:config[&background].transparent
|
|
call s:ApplyTransparency()
|
|
else
|
|
call theme#apply(s:config[&background].theme)
|
|
endif
|
|
endfunction
|
|
|
|
function! theme#onColorScheme(name) abort
|
|
if s:applying
|
|
return
|
|
endif
|
|
if a:name !~# '^sunbather_' && index(['everforest', 'moonfly', 'PaperColor'], a:name) < 0
|
|
return
|
|
endif
|
|
let s:config.background = &background
|
|
let s:config[&background].theme = a:name
|
|
call s:ApplyTransparency()
|
|
endfunction
|
|
|
|
function! theme#Init() abort
|
|
let s:config = s:Load()
|
|
let &background = get(s:config, 'background', 'dark')
|
|
call theme#apply(s:config[&background].theme)
|
|
augroup DotfilesTheme
|
|
autocmd!
|
|
autocmd ColorScheme * call theme#onColorScheme(expand('<amatch>'))
|
|
autocmd VimLeavePre * call theme#save()
|
|
augroup END
|
|
endfunction
|