JohnBeckett (talk | contribs) (tip is based on a script by Steve Hall) |
JohnBeckett (talk | contribs) (→Comments: another todo item) |
||
Line 214: | Line 214: | ||
:BUG: When more than one instance of Vim is running, the last to exit overwrites the data saved by the previous instances. |
:BUG: When more than one instance of Vim is running, the last to exit overwrites the data saved by the previous instances. |
||
− | Need to investigate and prune the tip. |
+ | Need to investigate and prune the tip. |
+ | |||
+ | In version 2, the <tt>silent! q</tt> probably should be <tt>silent! bwipeout</tt>. With '<tt>q</tt>', the .vimsize file is visible in the buffer list, which is irritating, and which causes trouble if another Vim instance changes the file. --[[User:JohnBeckett|JohnBeckett]] 04:00, 13 February 2009 (UTC) |
Revision as of 04:00, 13 February 2009
created June 4, 2008 · complexity basic · author Dfishburn · version 7.0
I often have more than one Vim (gui on Windows) running. Quite often I will have one per project, each instance editing multiple buffers. When I start Vim, I name it (based on the project or tool I launched it from).
gvim --servername VS_NET filename
When I re-open Vim I like its screen position and size to be the same as they were when Vim was closed.
Version 1 (win32 and only one Vim instance)
Add the following to your vimrc to accomplish this.
" Restore screen size and position " Saves data in viminfo in a global variable based on gvim servername. " BUG: When more than one instance of Vim is running, the last to exit " overwrites the data saved by the previous instances. if has("gui_running") && has('win32') function! Screen_init() " - Remembers and restores winposition, columns and lines stored in " global variables written to viminfo " - Must follow font settings so that columns and lines are accurate " based on font size. if ! has("gui_running") || ! has('win32') return endif if &viminfo !~ '!' echoerr 'Screen_init: The viminfo setting must have a "!". :h viminfo :set viminfo+=!' return endif " initialize if !exists("g:COLS_".v:servername) let g:COLS_{v:servername} = &columns endif if !exists("g:LINES_".v:servername) let g:LINES_{v:servername} = &lines endif if !exists("g:WINPOSX_".v:servername) " don't set to 0, let window manager decide let g:WINPOSX_{v:servername} = "" endif if !exists("g:WINPOSY_".v:servername) " don't set to 0, let window manager decide let g:WINPOSY_{v:servername} = "" endif " set execute "set columns=".g:COLS_{v:servername} execute "set lines=".g:LINES_{v:servername} execute "winpos ".g:WINPOSX_{v:servername}." ".g:WINPOSY_{v:servername} endfunction function! Screen_get() " used on exit to retain window position and size let g:COLS_{v:servername} = &columns let g:LINES_{v:servername} = &lines let g:WINPOSX_{v:servername} = getwinposx() " filter negative error condition if g:WINPOSX_{v:servername} < 0 let g:WINPOSX_{v:servername} = 0 endif let g:WINPOSY_{v:servername} = getwinposy() " filter negative error condition if g:WINPOSY_{v:servername} < 0 let g:WINPOSY_{v:servername} = 0 endif endfunction let g:restore_screen_size_pos = 1 " autocmd VimEnter * breakadd func Screen_init autocmd VimEnter * if g:restore_screen_size_pos == 1 | call Screen_init() | endif autocmd VimLeavePre * if g:restore_screen_size_pos == 1 | call Screen_get() | endif endif
Version 2 (all systems and multiple Vim instances)
Here is an alternative script that is being tried that uses a file (vimsize) instead of viminfo. This version access the file used to save the size/position using a Vim buffer.
" Restore screen size and position " Saves data in a separate file, and so works with multiple instances of Vim. if has("gui_running") function! Screen_filename() if has('amiga') return "s:.vimsize" elseif has('win32') return $HOME."\\_vimsize" else return $HOME."/.vimsize" endif endfunction function! Screen_load() " - Remembers and restores winposition, columns and lines stored in " a .vimsize file " - Must follow font settings so that columns and lines are accurate " based on font size. if !has("gui_running") return endif if !g:restore_screen_size_pos return endif " read any existing variables from .vimsize file silent! execute "sview " . escape(Screen_filename(),'%#\ $') silent! execute "0/^" . v:servername . " /" let sizepos = split(getline('.')) if len(sizepos) != 0 && sizepos[0] == v:servername execute "set columns=".sizepos[1] execute "set lines=".sizepos[2] silent! execute "winpos ".sizepos[3]." ".sizepos[4] endif silent! q endfunction function! Screen_save() " used on exit to retain window position and size if !has("gui_running") return endif if !g:restore_screen_size_pos return endif silent! execute "split " . escape(Screen_filename(),'%#\ $') silent! execute "0/^" . v:servername . " /" let sizepos = split(getline('.')) if len(sizepos) != 0 && sizepos[0] == v:servername delete _ endif $put = v:servername . ' ' . &columns . ' ' . &lines . ' ' . \ (getwinposx()<0?0:getwinposx()) . ' ' . \ (getwinposy()<0?0:getwinposy()) silent! x! endfunction if !exists('g:restore_screen_size_pos') let g:restore_screen_size_pos = 1 endif autocmd VimEnter * call Screen_load() autocmd VimLeavePre * call Screen_save() endif
Version 3 (like Version 2, but uses file read/write)
Here is an alternative script that is being tried that uses a file (vimsize) instead of viminfo. This version uses Vim's readfile/writefile functions to access the file used to save the size/position.
" Restore screen size and position. if has("gui_running") function! ScreenFilename() if has('amiga') return "s:.vimsize" elseif has('win32') return $HOME."\\_vimsize" else return $HOME."/.vimsize" endif endfunction function! ScreenRestore() " Restore window size (columns and lines) and position " from values stored in vimsize file. " Must set font first so columns and lines are based on font size. let f = ScreenFilename() if has("gui_running") && g:restore_screen_size_pos && filereadable(f) for line in readfile(f) let sizepos = split(line) if len(sizepos) == 5 && sizepos[0] == v:servername silent! execute "set columns=".sizepos[1]." lines=".sizepos[2] silent! execute "winpos ".sizepos[3]." ".sizepos[4] return endif endfor endif endfunction function! ScreenSave() " Save window size and position. if has("gui_running") && g:restore_screen_size_pos let data = v:servername . ' ' . &columns . ' ' . &lines . ' ' . \ (getwinposx()<0?0:getwinposx()) . ' ' . \ (getwinposy()<0?0:getwinposy()) let f = ScreenFilename() if filereadable(f) let lines = readfile(f) call filter(lines, "v:val !~ '^" . v:servername . "\\>'") call add(lines, data) else let lines = [data] endif call writefile(lines, f) endif endfunction if !exists('g:restore_screen_size_pos') let g:restore_screen_size_pos = 1 endif autocmd VimEnter * call ScreenRestore() autocmd VimLeavePre * call ScreenSave() endif
Comments
As Sightless said on the June new tips page, version 1 can't work with more than one Vim instance. I just finished writing version 3 which has the advantage that the data file does not get read into a buffer, and so doesn't influence MRU file or buffer lists. Please add any thoughts below. --JohnBeckett 11:51, 9 September 2008 (UTC)
TO DO
I think my above comment, and the following which I added to version 1 are totally wrong. :help viminfo-write
- BUG: When more than one instance of Vim is running, the last to exit overwrites the data saved by the previous instances.
Need to investigate and prune the tip.
In version 2, the silent! q probably should be silent! bwipeout. With 'q', the .vimsize file is visible in the buffer list, which is irritating, and which causes trouble if another Vim instance changes the file. --JohnBeckett 04:00, 13 February 2009 (UTC)