Last active
May 4, 2018 06:26
-
-
Save adscriven/79d6c60bbd01f47432221a405c071f30 to your computer and use it in GitHub Desktop.
Define :SessionRestore and :SessionSave commands for Vim.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" sessions.vim -- Define :SessionSave and :SessionRestore. | |
" SUMMARY | |
" $ mkdir ~/.vim/session | |
" :SessionSave save the current session | |
" :SessionSave {name} save a session as g:sessions_dir/{name} | |
" :SessionRestore restore the current session | |
" :SessionRestore {name} restore the session from g:sessions_dir/{name} | |
" | |
" There is tab completion for {name}. | |
" :mksession! is always used; sessions are overwritten without warning. | |
" The current session is always saved as 'last' by default when | |
" exiting Vim, even if there was no session active at the time. | |
" That way you can always get back to what you were doing when you | |
" last exited Vim by typing :SessionRestore last on startup. | |
" Obviously if you have multiple Vims running, the last one wins. | |
" This is just a convenience; use named sessions otherwise. | |
" REQUIREMENTS | |
" Vim 8 (Probably just because of the map() call.) | |
" INSTALLATION | |
" Chuck this file in ~/.vim/plugin | |
" CONFIGURATION | |
" Use these optional global variables in your vimrc. | |
" To specify the directory for session files (optional trailing slash), | |
" let g:sessions_dir = '~/.vim/jam/' | |
" Default: '~/.vim/session/' | |
" To prompt to save a named session when leaving Vim, e.g. after :qa, | |
" let g:sessions_prompt_on_exit = 1 | |
" Default: 0 | |
" When prompted press 'y' to save. Any other key means 'no'. | |
" To set the default last session name, | |
" let g:sessions_default_name = 'Margaret' | |
" Default: 'last' | |
" To warn if there are modified buffers when restoring a session, even | |
" if you have 'hidden' set, | |
" let g:sessions_warn_modified = 1 | |
" Default: 0 | |
" To define abbreviated command names, :SR and :SS, | |
" let g:sessions_abbreviated_commands = 1 | |
" Default: 0 | |
" Alternatively create some mappings in your vimrc, such as | |
" nnoremap \ss :<c-u>SessionSave | | |
" nnoremap \sr :<c-u>SessionRestore | | |
" To skip autosaving the current session as 'last' for a regexp | |
" matching the current file name, | |
" let g:sessions_dont_autosave_pattern = '\.config\|\.vimrc' | |
" Default: 'COMMIT_EDITMSG\|MERGE_MSG\|TAG_EDITMSG' | |
let s:cpo = &cpo | |
set cpo&vim | |
let s:thisfile = expand('<sfile>:t') | |
fun! s:err(msg) | |
echohl errormsg | |
echomsg '(' . s:thisfile . ') ' . a:msg | |
echohl None | |
endfun | |
if !has('mksession') | |
call s:err('Sessions aren''t supported in this build of Vim.') | |
finish | |
endif | |
let s:dir = get(g:, 'sessions_dir', '~/.vim/session') | |
let s:dir = fnamemodify(expand(s:dir), ':p') | |
if !isdirectory(s:dir) | |
call s:err('Non-existent sessions directory: ' . s:dir) | |
finish | |
endif | |
let s:defaultname = get(g:, 'sessions_default_name', 'last') | |
let s:defaultfile = s:dir . s:defaultname | |
let s:dontautosavepat = get(g:, 'sessions_dont_autosave_pattern', | |
\ 'COMMIT_EDITMSG\|MERGE_MSG\|TAG_EDITMSG') | |
fun! s:savesession(name) | |
if a:name == '' && v:this_session == '' | |
call s:err('Can''t save: no session name.') | |
return | |
endif | |
let file = a:name != '' ? s:dir . a:name : v:this_session | |
execute 'mksession! ' . file | |
redraw! | |
endfun | |
fun! s:aremodifiedbufs() | |
for buf in getbufinfo() | |
if buf.changed | |
return 1 | |
endif | |
endfor | |
return 0 | |
endfun | |
fun! s:restoresession(name) | |
if a:name == '' && v:this_session == '' | |
call s:err('Can''t restore: no session name.') | |
return | |
endif | |
let file = a:name != '' ? s:dir . a:name : v:this_session | |
if !filereadable(file) | |
call s:err('Can''t restore from file: ' . file) | |
return | |
endif | |
if s:aremodifiedbufs() && (!&hidden || get(g:, 'sessions_warn_modified', 0)) | |
call s:err('Write modified buffers before restoring a session.') | |
return | |
endif | |
let v:this_session = "" | |
silent tabnew | |
silent tabonly | |
silent! execute 'source ' . file | |
redraw | |
endfun | |
fun! s:save_on_exit() | |
" If you want a prompt to save the session, and you actually have | |
" a current session, and it isn't the default one, ... | |
if get(g:, 'sessions_prompt_on_exit', 0) && v:this_session != '' && | |
\ v:this_session != s:defaultfile | |
echo 'Save session ''' . fnamemodify(v:this_session, ':t') . '''? (n)' | |
let c = getchar() | |
if nr2char(c) == 'y' | |
call s:savesession('') | |
endif | |
endif | |
" Save the current session as s:default name, if it wasn't saved | |
" above. But skip this if the current filename matches s:dontautosavepat. | |
if expand('%') !~# s:dontautosavepat | |
call s:savesession(s:defaultname) | |
endif | |
endfun | |
augroup sessions_save_on_exit | |
autocmd! | |
autocmd VimLeave * call s:save_on_exit() | |
augroup end | |
fun! s:complete(a, l, p) | |
let files = glob(s:dir . a:a . '*', 0, 1) | |
call map(files, {k, v -> fnamemodify(v, ':t')}) | |
return files | |
endfun | |
command! -nargs=* -complete=customlist,s:complete SessionSave | |
\ call s:savesession(<q-args>) | |
command! -nargs=* -complete=customlist,s:complete SessionRestore | |
\ call s:restoresession(<q-args>) | |
if get(g:, 'sessions_abbreviated_commands', 0) | |
command! -nargs=* -complete=customlist,s:complete SS | |
\ call s:savesession(<q-args>) | |
command! -nargs=* -complete=customlist,s:complete SR | |
\ call s:restoresession(<q-args>) | |
endif | |
let &cpo = s:cpo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment