Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- let s:sessionFile = g:sessions_dir . '/session'
- let s:sessionLockFile = g:sessions_dir . '/.session.lock'
- fun! LogOpenFile(file)
- if !isdirectory(g:sessions_dir)
- return
- endif
- " logging routine may get called for non-file buffers (e.g. quickfix buffers), in which case the file string will be empty
- " 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.
- " 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.
- if a:file == '' || !buflisted(a:file) || a:file =~# '\v/dev/fd/.*'
- return
- endif
- while filereadable(s:sessionLockFile)
- sleep 10m
- endwhile
- call writefile([], s:sessionLockFile)
- " if file missing, readfile will return an empty list as a fallback, and the file gets created later
- silent! let lines = readfile(s:sessionFile)
- let found = 0
- for line in lines
- if line == a:file
- let found = 1
- break
- endif
- endfor
- if !found
- call writefile([a:file], s:sessionFile, 'a')
- endif
- call delete(s:sessionLockFile)
- endfun
- fun! UnlogOpenFiles(processAll, file)
- if !isdirectory(g:sessions_dir)
- return
- endif
- if a:processAll
- " 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.
- let files = map(getbufinfo({'buflisted': 1}), {key, val -> val.name})
- else
- let files = [a:file]
- endif
- let files = filter(files, {key, val -> val != ''})
- " this avoids unnecessary writes when we have no unloggable files (e.g. only non-file buffers)
- if len(files) == 0
- return
- endif
- while filereadable(s:sessionLockFile)
- sleep 10m
- endwhile
- call writefile([], s:sessionLockFile)
- silent! let lines = readfile(s:sessionFile)
- " 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
- if len(lines) == 0
- return
- endif
- let i = 0
- while i < len(lines) && len(files) > 0
- let j = 0
- while j < len(files)
- if lines[i] == files[j]
- call remove(lines, i)
- call remove(files, j)
- let i -= 1
- break
- endif
- let j += 1
- endwhile
- let i += 1
- endwhile
- call writefile(lines, s:sessionFile)
- call delete(s:sessionLockFile)
- endfun
- augroup SessionManagement
- au!
- au BufWritePost * call LogOpenFile(expand('<afile>:p'))
- au BufReadPost * call LogOpenFile(expand('<afile>:p'))
- " bufdelete conveniently doesn't get called on leave, so it doesn't cause redundancy with vimleave
- au BufDelete * call UnlogOpenFiles(0, expand('<afile>:p'))
- au VimLeave * call UnlogOpenFiles(1, '')
- " renames
- au BufFilePre * call UnlogOpenFiles(0, expand('<afile>:p'))
- au BufFilePost * call LogOpenFile(expand('<afile>:p'))
- augroup END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement