" Vimball Archiver by Charles E. Campbell, Jr., Ph.D. UseVimball finish autoload/stay/integrate/fastfold.vim [[[1 33 " FASTFOLD INTEGRATION MODULE " https://github.com/Konfekt/FastFold " - register integration autocommands function! stay#integrate#fastfold#setup() abort autocmd User BufStaySavePre unsilent call stay#integrate#fastfold#save_pre() autocmd User BufStaySavePost unsilent call stay#integrate#fastfold#save_post() endfunction " - on User event 'BufStaySavePre': restore original 'foldmethod' function! stay#integrate#fastfold#save_pre() abort let [l:fdmlocal, l:fdmorig] = s:foldmethods() if l:fdmorig isnot l:fdmlocal \ && index(split(&viewoptions, ','), 'folds') isnot -1 noautocmd silent let &l:foldmethod = l:fdmorig endif endfunction " - on User event 'BufStaySavePost': restore FastFold 'foldmethod' function! stay#integrate#fastfold#save_post() abort let [l:fdmlocal, l:fdmorig] = s:foldmethods() if l:fdmorig isnot l:fdmlocal noautocmd silent let &l:foldmethod = 'manual' endif endfunction " - return tuple of current local and FastFold stored 'foldmethod' function! s:foldmethods() abort let l:fdmlocal = &l:foldmethod return [l:fdmlocal, get(w:, 'lastfdm', l:fdmlocal)] endfunction " vim:set sw=2 sts=2 ts=2 et fdm=marker fmr={{{,}}}: autoload/stay/shim.vim [[[1 17 " STAY EVAL SHIM MODULE " Are these Vim patch levels, my dear? " globpath: " - no {nosuf} argument before 7.2.051 - :h version7.txt " - no {list} argument before 7.4.279 - http://ftp.vim.org/pub/vim/patches/7.4/README function! stay#shim#globpath(path, glob, nosuf, list) abort if v:version < 702 || (v:version is 702 && !has('patch-051')) return split(globpath(a:path, a:glob), '\n') elseif v:version < 704 || (v:version is 704 && !has('patch-279')) return split(globpath(a:path, a:glob, a:nosuf), '\n') else return globpath(a:path, a:glob, a:nosuf, a:list) endif endfunction " vim:set sw=2 sts=2 ts=2 et fdm=marker fmr={{{,}}}: autoload/stay/view.vim [[[1 78 " AUTOLOAD FUNCTION LIBRARY FOR VIM-STAY " View session handling functions let s:cpo = &cpo set cpo&vim " Make a persistent view for window {winnr}: " @signature: stay#view#make({winnr:Number}) " @returns: Boolean function! stay#view#make(winnr) abort if a:winnr is -1 return 0 endif try let l:lazyredraw = &lazyredraw set lazyredraw if !s:win.goto(a:winnr) return 0 endif unlet! b:stay_atpos silent doautocmd User BufStaySavePre mkview silent doautocmd User BufStaySavePost call s:win.back() return 1 finally let &lazyredraw = l:lazyredraw endtry endfunction " Load a persistent view for window {winnr}: " @signature: stay#view#load({winnr:Number}) " @returns: Boolean function! stay#view#load(winnr) abort if a:winnr is -1 || !s:win.goto(a:winnr) return 0 endif silent doautocmd User BufStayLoadPre noautocmd silent loadview silent doautocmd User BufStayLoadPost if exists('b:stay_atpos') call cursor(b:stay_atpos[0], b:stay_atpos[1]) silent! normal! zOzz endif call s:win.back() return 1 endfunction " Private helper functions: " - window navigation stack let s:win = {'stack': []} function! s:win.activate(winnr) abort if winnr() isnot a:winnr execute 'noautocmd keepjumps keepalt silent' a:winnr.'wincmd w' endif endfunction function! s:win.goto(winnr) abort let l:oldwinnr = winnr() call self.activate(a:winnr) call add(self.stack, l:oldwinnr) return winnr() is a:winnr endfunction function! s:win.back() abort if len(self.stack) > 0 let l:towinnr = remove(self.stack, -1) call self.activate(l:towinnr) endif return exists('l:towinnr') && winnr() is l:towinnr endfunction let &cpo = s:cpo unlet! s:cpo " vim:set sw=2 sts=2 ts=2 et fdm=marker fmr={{{,}}}: autoload/stay.vim [[[1 32 " AUTOLOAD FUNCTION LIBRARY FOR VIM-STAY " Core functions (will be loaded when first autocommand is triggered) let s:cpo = &cpo set cpo&vim " Check if buffer {bufnr} is persistent: " @signature: stay#ispersistent({bufnr:Number}, {volatile_ftypes:List}) " @returns: Boolean " @notes: the persistence heuristics are " - buffer must be listed " - buffer must be of ordinary or "acwrite" 'buftype' " - not a preview window " - not a diff window " - buffer's 'bufhidden' must be empty or "hide" " - buffer must not be of a volatile file type " - buffer must map to a readable file function! stay#ispersistent(bufnr, volatile_ftypes) abort return bufexists(a:bufnr) \ && getbufvar(a:bufnr, 'stay_ignore', 0) isnot 1 \ && getbufvar(a:bufnr, '&buflisted') is 1 \ && index(['', 'acwrite'], getbufvar(a:bufnr, '&buftype')) isnot -1 \ && getbufvar(a:bufnr, '&previewwindow') isnot 1 \ && getbufvar(a:bufnr, '&diff') isnot 1 \ && index(['', 'hide'], getbufvar(a:bufnr, '&bufhidden')) isnot -1 \ && index(a:volatile_ftypes, getbufvar(a:bufnr, '&filetype')) is -1 \ && filereadable(fnamemodify(bufname(a:bufnr), ':p')) endfunction let &cpo = s:cpo unlet! s:cpo " vim:set sw=2 sts=2 ts=2 et fdm=marker fmr={{{,}}}: doc/vim-stay.txt [[[1 195 *vim-stay.txt* For Vim version 7.0 or better version 1.1.1 VIM REFERENCE for the Stay plug-in Never lose your place in a buffer again *vim-stay* 1. Introduction |vim-stay-introduction| 2. Usage |vim-stay-configuration| 3. Position specifications |vim-stay-integration| 4. Troubleshooting |vim-stay-troubleshooting| 5. Credits and license |vim-stay-credits-license| {not available when |'compatible'| is set} ============================================================================== 1. Introduction *vim-stay-introduction* vim-stay adds automated |View| creation and restoration whenever editing a buffer, across Vim sessions and window life cycles. It also alleviates Vim's tendency to lose view state when cycling through buffers (via |argdo|, |bufdo| et al.). It is smart about which buffers should be persisted and which should not, making the procedure painless and invisible. ============================================================================== 2. Configuration *vim-stay-configuration* VIEW SESSION CONFIGURATION: *vim-stay-viewoptions* The following, non-standard 'viewoptions' settings are recommended: > set viewoptions=cursor,folds,slash,unix < IGNORED FILE TYPES: *g:volatile_ftypes* vim-stay applies heuristics to detect buffers that should not be persisted, but in some cases non-persistent buffers slip through. Some of them are regular files that are not persistent by their very nature (like git commit messages), a few are buffers created by plug-ins that miss all indication that they are not files. These can be expressly marked as volatile (meaning buffers of this type will never be persisted) by adding their 'filetype' to the `volatile_ftypes` global |List|. Note this list is meant as a safety net for the case heuristics fail; it usually should not be necessary to modify vim-stay's defaults. If you find you need to add file types to it, make sure the plug-in has loaded, then do > let g:volatile_ftypes += ['foo', 'bar'] < ============================================================================== 3. Integration *vim-stay-integration* INTEGRATION WITH 3RD PARTY PLUG-INS: Out of the box, vim-stay integrates with the following plug-ins: 1. vim-fetch http://www.vim.org/scripts/script.php?script_id=5089 2. FastFold https://github.com/Konfekt/FastFold If you'd like vim-stay to integrate with other position-setting or view management plug-ins, open an issue or a PR at https://github.com/kopischke/vim-stay/issues If the plug-in in question is one you own or contribute to, see |vim-stay-plugin-api| instead. INTEGRATION API: 1. Keeping the position set by other scripts *b:stay_atpos* To make vim-stay respect a position set by an unsupported script or plug-in, set the `stay_atpos` buffer-local variable: > let b:stay_atpos = [lnum, colnum] < This position will be restored after loading the session. 2. Ignoring a file on a per-buffer basis *b:stay_ignore* To stop vim-stay making and restoring sessions for a specific buffer, do > let b:stay_ignore = 1 < See the |g:volatile_ftypes| user setting for a way to ignore all buffers of a certain file type. 3. Autocommand API *vim-stay-autocommands* vim-stray triggers two |User| autocommand events each when loading or saving state: *BufStayLoadPre* before loading a view session and *BufStayLoadPost* after loading it, *BufStaySavePre* before saving a view session and *BufStayLoadPost* after. Notes: - The events are triggered with |:silent| to avoid flooding message history with "No matching autocommands" messages. Use |:unsilent| to restore normal message processing, e.g. > autocmd User BufStaySavePre unsilent echomsg 'Gotcha!' < 4. Extended plug-in integration API *vim-stay-plugin-api* The mechanism vim-stay itself uses to integrate with other plug-ins is open to 3rd parties. Add a file > autoload/stay/integrate/yourplugin.vim < containing a `stay#integrate#yourplugin#setup()` |autoload| function to your plug-in. Any function with that signature found in 'runtimepath' when vim-stay loads will be executed. You can set up autocommands in there (which will automatically be added to the `stay` autocommand group), optionally leveraging vim-stay's autocommand API (|vim-stay-autocommands|), or add to the volatile 'filetype' list (|g:volatile_ftypes|). The advantage over hard-wiring support for vim-stay in your plug-in is that - the integration will be set up when your user uses vim-stay regardless of plug-in load order, but - the integration code will only be active if your user actually uses vim-stay. ============================================================================== 4. Troubleshooting *vim-stay-troubleshooting* MY FOLD STATE IS NOT PERSISTED / MY CURSOR ENDS UP IN A CLOSED FOLD You have removed "folds" 'from 'viewoptions'. See the recommended setting above (|vim-stay-viewoptions|). MY STATE IS NOT PERSISTED WHEN SWITCHING BETWEEN WINDOWS AND OTHER OS' With the default settings, 'viewoptions' uses platform specific path separators, which means stored view sessions are not portable. See the recommended setting above (|vim-stay-viewoptions|). MY CURRENT WORKING DIRECTORY / MY ARGLIST CHANGES WHEN OPENING A FILE vim-stay uses |mkview| and |loadview|, which persist the local arglist and local working directory. This can be a bit disorienting at first, but it is by (Vim's) design. If this really irks you, you may be able to work around it using vim-stay's autocommand API (see |vim-stay-autocommands|). VIM-STAY TRIES TO PERSIST STATE FOR TEMPORARY FILES Files in a temporary or cache directory are not recognized as volatile, unless their 'buftype' is set to a non-file type, as there is no way to reliably and portably detect which paths denote temporary state (see |tempfile| just for the platform specific differences in Vim's internal temporary file usage, and this doesn't account for things like OS specific cache directories). You can alleviate the issue by setting |b:stay_ignore| in affected buffers. VIM-STAY TRIES TO PERSIST STATE FOR OTHER VOLATILE FILES Check if the 'filetype' of the affected file is listed in |g:volatile_ftypes| and try adding it if it is not. I'd also be grateful if you reported the file type by opening a support issue (or even better, a PR) at https://github.com/kopischke/vim-stay/issues MY VIEW DIRECTORY IS A FESTERING MESS That is a consequence of Vim's view session design. To quote |loadview|: "You might want to clean up your 'viewdir' directory now and then." MY PROBLEM ISN'T LISTED HERE You might have found a bug. Please open an issue at https://github.com/kopischke/vim-stay/issues Please do not forget to list the steps to reproduce the issue as well as your Vim version and platform. ============================================================================== 5. Credits and License *vim-stay-credits-license* vim-stay is maintained by Martin Kopischke http://martin.kopischke.net and licensed under the terms of the MIT license according to the accompanying license file (LICENSE.md). It is inspired by, but not based on, `restore_view.vim` by Zhou Yi Chao (http://www.vim.org/scripts/script.php?script_id=4021). vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0:fdm=marker: plugin/stay.vim [[[1 62 " A LESS SIMPLISTIC TAKE ON RESTORE_VIEW.VIM " Maintainer: Martin Kopischke " License: MIT (see LICENSE.md) " Version: 1.1.1 if &compatible || !has('autocmd') || !has('mksession') || v:version < 700 finish endif let s:cpo = &cpo set cpo&vim " Set defaults: let s:defaults = {} let s:defaults.volatile_ftypes = ['gitcommit', 'gitrebase', 'gitsendmail'] for [s:key, s:val] in items(s:defaults) execute 'let g:'.s:key. '= get(g:, "'.s:key.'", '.string(s:val).')' unlet! s:key s:val endfor " Set up 3rd party integrations: function! s:integrate() abort let s:integrations = [] for l:file in stay#shim#globpath(&rtp, 'autoload/stay/integrate/*.vim', 1, 1) try let l:name = fnamemodify(l:file, ':t:r') if index(s:integrations, l:name) is -1 call call('stay#integrate#'.l:name.'#setup', []) call add(s:integrations, l:name) endif catch /E117/ " no setup function found continue catch " integration setup execution errors echomsg "Error setting up" l:name "integration:" v:errmsg continue endtry endfor endfunction " Set up autocommands: augroup stay autocmd! " default buffer handling autocmd BufLeave,BufWinLeave ?* \ if stay#ispersistent(str2nr(expand('')), g:volatile_ftypes) | \ call stay#view#make(bufwinnr(str2nr(expand('')))) | \ endif autocmd BufWinEnter ?* \ if stay#ispersistent(str2nr(expand('')), g:volatile_ftypes) | \ call stay#view#load(bufwinnr(str2nr(expand('')))) | \ endif " vim-fetch integration autocmd User BufFetchPosPost let b:stay_atpos = b:fetch_lastpos " generic, extensible 3rd party integration call s:integrate() augroup END let &cpo = s:cpo unlet! s:cpo " vim:set sw=2 sts=2 ts=2 et fdm=marker fmr={{{,}}}: