<commit_before>" vimtex - LaTeX plugin for Vim
"
" Maintainer: <NAME>
" Email:      <EMAIL>
"

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
  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

  if localtime() <= self.ftime + 299
    " Too short since last write
    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
  return a:name . '_'
        \ . sha256(exists('b:vimtex.tex') ? b:vimtex.tex : expand('%:p'))
endfunction

" }}}1<commit_msg>chore: use recognizable cache filename<commit_after>" vimtex - LaTeX plugin for Vim
"
" Maintainer: <NAME>
" Email:      <EMAIL>
"

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
  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

  if localtime() <= self.ftime + 299
    " Too short since last write
    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')
  return a:name . l:filename
endfunction

" }}}1
{'fraction_non_alphanumeric': 0.17134081196581197, 'fraction_numerical': 0.010817307692307692, 'mean_word_length': 3.5581253804017043, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '483451', 'n_tokens_mistral': 3075, 'n_tokens_neox': 2950, 'n_words': 694}