Advertisement
Guest User

vim session saving

a guest
Jun 18th, 2019
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VIM 3.28 KB | None | 0 0
  1. let s:sessionFile = g:sessions_dir . '/session'
  2. let s:sessionLockFile = g:sessions_dir . '/.session.lock'
  3. fun! LogOpenFile(file)
  4.     if !isdirectory(g:sessions_dir)
  5.         return
  6.     endif
  7.     " logging routine may get called for non-file buffers (e.g. quickfix buffers), in which case the file string will be empty
  8.     " may also get called for unlisted buffers (e.g. help pages and other kinds of cruft). it makes more sense not to log them at all.
  9.     " the file may also be a temporary file, and some of them may cause issues. on unix-y machines, where shell (bash) process substitution uses the /dev/fd/* path, the file path behaves specially in vim. unlike with other symlinks, vim seems to see the /dev/fd based part on startup (a:file), but later after the file is opened, the file is instead located somewhere under /proc (expand('%')). so, need to take special cautions to avoid logging these files in the first place, otherwise due to this re-locating issue they won't get unlogged when the buffer closes.
  10.     if a:file == '' || !buflisted(a:file) || a:file =~# '\v/dev/fd/.*'
  11.         return
  12.     endif
  13.     while filereadable(s:sessionLockFile)
  14.         sleep 10m
  15.     endwhile
  16.     call writefile([], s:sessionLockFile)
  17.     " if file missing, readfile will return an empty list as a fallback, and the file gets created later
  18.     silent! let lines = readfile(s:sessionFile)
  19.     let found = 0
  20.     for line in lines
  21.         if line == a:file
  22.             let found = 1
  23.             break
  24.         endif
  25.     endfor
  26.     if !found
  27.         call writefile([a:file], s:sessionFile, 'a')
  28.     endif
  29.     call delete(s:sessionLockFile)
  30. endfun
  31. fun! UnlogOpenFiles(processAll, file)
  32.     if !isdirectory(g:sessions_dir)
  33.         return
  34.     endif
  35.     if a:processAll
  36.         " the buffer list may contain unlisted buffers (help pages which we don't log in the first page, and even past buffers that may now be open somewhere else). absolutely avoid taking them into account.
  37.         let files = map(getbufinfo({'buflisted': 1}), {key, val -> val.name})
  38.     else
  39.         let files = [a:file]
  40.     endif
  41.     let files = filter(files, {key, val -> val != ''})
  42.     " this avoids unnecessary writes when we have no unloggable files (e.g. only non-file buffers)
  43.     if len(files) == 0
  44.         return
  45.     endif
  46.     while filereadable(s:sessionLockFile)
  47.         sleep 10m
  48.     endwhile
  49.     call writefile([], s:sessionLockFile)
  50.     silent! let lines = readfile(s:sessionFile)
  51.     " this can avoid a write and may avoid clearing the file in some freak cases where the file somehow couldn't be read even though it existed and contained text
  52.     if len(lines) == 0
  53.         return
  54.     endif
  55.     let i = 0
  56.     while i < len(lines) && len(files) > 0
  57.         let j = 0
  58.         while j < len(files)
  59.             if lines[i] == files[j]
  60.                 call remove(lines, i)
  61.                 call remove(files, j)
  62.                 let i -= 1
  63.                 break
  64.             endif
  65.             let j += 1
  66.         endwhile
  67.         let i += 1
  68.     endwhile
  69.     call writefile(lines, s:sessionFile)
  70.     call delete(s:sessionLockFile)
  71. endfun
  72. augroup SessionManagement
  73.     au!
  74.     au BufWritePost * call LogOpenFile(expand('<afile>:p'))
  75.     au BufReadPost * call LogOpenFile(expand('<afile>:p'))
  76.     " bufdelete conveniently doesn't get called on leave, so it doesn't cause redundancy with vimleave
  77.     au BufDelete * call UnlogOpenFiles(0, expand('<afile>:p'))
  78.     au VimLeave * call UnlogOpenFiles(1, '')
  79.     " renames
  80.     au BufFilePre * call UnlogOpenFiles(0, expand('<afile>:p'))
  81.     au BufFilePost * call LogOpenFile(expand('<afile>:p'))
  82. augroup END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement