1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 17:00:05 +08:00
SpaceVim/bundle/calendar.vim/autoload/calendar/cache.vim

237 lines
5.8 KiB
VimL
Raw Normal View History

" =============================================================================
" Filename: autoload/calendar/cache.vim
" Author: itchyny
" License: MIT License
" Last Change: 2020/11/20 00:09:42.
" =============================================================================
let s:save_cpo = &cpo
set cpo&vim
" Cache object.
function! calendar#cache#new(...) abort
let self = copy(s:self)
let self.subpath = a:0 ? a:1 : ''
let self.subpath .= len(self.subpath) && self.subpath[len(self.subpath) - 1] !~ '^[/\\]$' ? '/' : ''
call s:setfperm_dir(self.dir())
return self
endfunction
function! calendar#cache#clear() abort
for path in s:clearpath
call calendar#util#rmdir(path, 'rf')
endfor
endfunction
let s:clearpath = []
augroup CalendarCache
autocmd!
autocmd VimLeavePre * call calendar#cache#clear()
augroup END
let s:self = {}
function! s:self.new(...) dict abort
return calendar#cache#new(self.subpath . (a:0 ? self.escape(a:1) : ''))
endfunction
function! s:self.escape(key) dict abort
return substitute(a:key, '[^a-zA-Z0-9_.-]', '\=printf("%%%02X",char2nr(submatch(0)))', 'g')
endfunction
if has('win32')
function! s:self.dir() dict abort
return substitute(substitute(s:expand_homedir(calendar#setting#get('cache_directory')), '[/\\]$', '', '') . '/' . self.subpath, '/', '\', 'g')
endfunction
else
function! s:self.dir() dict abort
return substitute(s:expand_homedir(calendar#setting#get('cache_directory')), '[/\\]$', '', '') . '/' . self.subpath
endfunction
endif
function! s:expand_homedir(path) abort
if a:path !~# '^[~]/'
return a:path
endif
return expand('~') . a:path[1:]
endfunction
function! s:self.path(key) dict abort
return self.dir() . self.escape(a:key)
endfunction
function! s:self.rmdir_on_exit() dict abort
call add(s:clearpath, self.dir())
endfunction
function! s:self.check_dir(...) dict abort
let dir = self.dir()
if !get(a:000, 0)
return !isdirectory(dir)
endif
if !isdirectory(dir)
try
if exists('*mkdir')
call mkdir(dir, 'p')
else
call calendar#util#system('mkdir -p ' . shellescape(dir))
endif
call s:setfperm(dir)
catch
endtry
endif
if !isdirectory(dir)
call calendar#echo#error(calendar#message#get('mkdir_fail') . ': ' . dir)
return 1
endif
endfunction
function! s:self.save(key, val) dict abort
if self.check_dir(1)
return 1
endif
let path = self.path(a:key)
if filereadable(path) && !filewritable(path)
call calendar#echo#error(calendar#message#get('cache_file_unwritable') . ': ' . path)
return 1
endif
try
call writefile(calendar#cache#string(a:val), path)
call s:setfperm_file(path)
catch
call calendar#echo#error(calendar#message#get('cache_write_fail') . ': ' . path)
return 1
endtry
endfunction
function! s:self.get(key) dict abort
if self.check_dir()
return 1
endif
let path = self.path(a:key)
if filereadable(path)
call s:setfperm_file(path)
let result = readfile(path)
try
if len(result)
if exists('*js_decode') && has('patch-8.0.0216')
return js_decode(len(result) > 1 ? join(result, '') : result[0])
endif
sandbox return eval(join(result, ''))
else
return 1
endif
catch
return 1
endtry
else
return 1
endif
endfunction
function! s:self.get_raw(key) dict abort
if self.check_dir()
return 1
endif
let path = self.path(a:key)
if filereadable(path)
call s:setfperm_file(path)
return readfile(path)
else
return 1
endif
endfunction
function! s:self.delete(key) dict abort
if self.check_dir()
return 1
endif
let path = self.path(a:key)
return delete(path)
endfunction
function! s:self.clear() dict abort
call calendar#util#rmdir(self.dir(), 'rf')
endfunction
if exists('*json_encode')
function! calendar#cache#string(v) abort
return [json_encode(a:v)]
endfunction
else
" string() with making newlines and indents properly.
function! calendar#cache#string(v, ...) abort
let r = []
let f = 1
let s = a:0 ? a:1 : ''
if type(a:v) == type([])
call add(r, '[ ')
let s .= ' '
for i in range(len(a:v))
call add(r, s . string(a:v[i]) . ',')
endfor
if r[-1][len(r[-1]) - 1] ==# ','
let r[-1] = r[-1][:-2]
endif
call add(r, ' ]')
elseif type(a:v) == type({})
call add(r, '{ ')
let s .= ' '
for k in keys(a:v)
if type(a:v[k]) == type({}) || type(a:v[k]) == type([]) && len(a:v[k]) > 2
let result = calendar#cache#string(a:v[k], s . repeat(' ', len(string(k)) + 2))
let result[-1] .= ','
call add(r, s . string(k) . ': ' . result[0])
call remove(result, 0)
call extend(r, result)
else
call add(r, s . string(k) . ': ' . string(a:v[k]) . ',')
endif
endfor
if r[-1][len(r[-1]) - 1] ==# ','
let r[-1] = r[-1][:-2]
endif
call add(r, ' }')
else
call add(r, s . string(a:v))
let f = 0
endif
if f
if len(r[1]) > len(s) + 1
let r[1] = r[1][len(s):]
endif
let r[0] .= r[1]
call remove(r, 1)
if len(r) > 1
let r[-2] .= r[-1]
call remove(r, -1)
endif
endif
return r
endfunction
endif
if exists('*getfperm') && exists('*setfperm')
function! s:setfperm_dir(dir) abort
let expected = 'rwx------'
if getfperm(a:dir) !=# expected
call setfperm(a:dir, expected)
endif
endfunction
function! s:setfperm_file(path) abort
let expected = 'rw-------'
if getfperm(a:path) !=# expected
call setfperm(a:path, expected)
endif
endfunction
else
function! s:setfperm_dir(dir) abort
endfunction
function! s:setfperm_file(path) abort
endfunction
endif
let &cpo = s:save_cpo
unlet s:save_cpo