diff options
Diffstat (limited to 'autoload/vimtex/cache.vim')
-rw-r--r-- | autoload/vimtex/cache.vim | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/autoload/vimtex/cache.vim b/autoload/vimtex/cache.vim new file mode 100644 index 00000000..a9ab8be1 --- /dev/null +++ b/autoload/vimtex/cache.vim @@ -0,0 +1,179 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve LervÄg +" Email: karl.yngve@gmail.com +" + +function! vimtex#cache#open(name, ...) abort " {{{1 + let l:opts = a:0 > 0 ? a:1 : {} + let l:name = get(l:opts, 'local') ? s:local_name(a:name) : a:name + + let s:caches = get(s:, 'caches', {}) + if has_key(s:caches, l:name) + return s:caches[l:name] + endif + + let s:caches[l:name] = s:cache.init(l:name, l:opts) + return s:caches[l:name] +endfunction + +" }}}1 +function! vimtex#cache#close(name) abort " {{{1 + let s:caches = get(s:, 'caches', {}) + + " Try global name first, then local name + let l:name = a:name + if !has_key(s:caches, l:name) + let l:name = s:local_name(l:name) + endif + if !has_key(s:caches, l:name) | return | endif + + let l:cache = s:caches[l:name] + call l:cache.write() + unlet s:caches[l:name] +endfunction + +" }}}1 +function! vimtex#cache#wrap(Func, name, ...) abort " {{{1 + if !has('lambda') + throw 'error: vimtex#cache#wrap requires +lambda' + endif + + let l:opts = a:0 > 0 ? a:1 : {} + let l:cache = vimtex#cache#open(a:name, l:opts) + + function! CachedFunc(key) closure + if l:cache.has(a:key) + return l:cache.get(a:key) + else + return l:cache.set(a:key, a:Func(a:key)) + endif + endfunction + + return function('CachedFunc') +endfunction + +" }}}1 +function! vimtex#cache#clear(name, local) abort " {{{1 + let l:cache = vimtex#cache#open(a:name, {'local': a:local}) + + call l:cache.read() + if !empty(l:cache.data) + let l:cache.data = {} + call l:cache.write() + endif +endfunction + +" }}}1 +function! vimtex#cache#write_all() abort " {{{1 + for l:cache in values(get(s:, 'caches', {})) + call l:cache.write() + endfor +endfunction + +" }}}1 + +let s:cache = {} + +function! s:cache.init(name, opts) dict abort " {{{1 + let new = deepcopy(self) + unlet new.init + + let l:root = get(g:, 'vimtex_cache_root', $HOME . '/.cache/vimtex') + if !isdirectory(l:root) + call mkdir(l:root, 'p') + endif + + let new.name = a:name + let new.path = l:root . '/' . a:name . '.json' + let new.local = get(a:opts, 'local') + let new.persistent = get(a:opts, 'persistent', + \ get(g:, 'vimtex_cache_persistent', 1)) + + if has_key(a:opts, 'default') + let new.default = a:opts.default + endif + + let new.data = {} + let new.ftime = -1 + let new.modified = 0 + + return new +endfunction + +" }}}1 +function! s:cache.get(key) dict abort " {{{1 + call self.read() + + if has_key(self, 'default') && !has_key(self.data, a:key) + let self.data[a:key] = deepcopy(self.default) + endif + + return get(self.data, a:key) +endfunction + +" }}}1 +function! s:cache.has(key) dict abort " {{{1 + call self.read() + + return has_key(self.data, a:key) +endfunction + +" }}}1 +function! s:cache.set(key, value) dict abort " {{{1 + call self.read() + + let self.data[a:key] = a:value + let self.modified = 1 + call self.write() + + return a:value +endfunction + +" }}}1 +function! s:cache.write() dict abort " {{{1 + if !self.persistent + let self.modified = 0 + return + endif + + if !self.modified | return | endif + + call self.read() + call writefile([json_encode(self.data)], self.path) + let self.ftime = getftime(self.path) + let self.modified = 0 +endfunction + +" }}}1 +function! s:cache.read() dict abort " {{{1 + if !self.persistent | return | endif + + if getftime(self.path) > self.ftime + let self.ftime = getftime(self.path) + call extend(self.data, + \ json_decode(join(readfile(self.path))), 'keep') + endif +endfunction + +" }}}1 + +" +" Utility functions +" +function! s:local_name(name) abort " {{{1 + let l:filename = exists('b:vimtex.tex') + \ ? fnamemodify(b:vimtex.tex, ':r') + \ : expand('%:p:r') + let l:filename = substitute(l:filename, '\s\+', '_', 'g') + let l:filename = substitute(l:filename, '\/', '%', 'g') + let l:filename = substitute(l:filename, '\\', '%', 'g') + let l:filename = substitute(l:filename, ':', '%', 'g') + return a:name . l:filename +endfunction + +" }}}1 + +endif |