]>
Commit | Line | Data |
---|---|---|
1 | " ZoomWin: Brief-like ability to zoom into/out-of a window | |
2 | " Author: Charles Campbell | |
3 | " original version by Ron Aaron | |
4 | " Date: Jan 26, 2009 | |
5 | " Version: 23 | |
6 | " History: see :help zoomwin-history {{{1 | |
7 | " GetLatestVimScripts: 508 1 :AutoInstall: ZoomWin.vim | |
8 | ||
9 | " --------------------------------------------------------------------- | |
10 | " Load Once: {{{1 | |
11 | if &cp || exists("g:loaded_ZoomWin") | |
12 | finish | |
13 | endif | |
14 | if v:version < 702 | |
15 | echohl WarningMsg | |
16 | echo "***warning*** this version of ZoomWin needs vim 7.2" | |
17 | echohl Normal | |
18 | finish | |
19 | endif | |
20 | let s:keepcpo = &cpo | |
21 | let g:loaded_ZoomWin = "v23" | |
22 | set cpo&vim | |
23 | "DechoTabOn | |
24 | ||
25 | " ===================================================================== | |
26 | " Functions: {{{1 | |
27 | ||
28 | " --------------------------------------------------------------------- | |
29 | " ZoomWin#ZoomWin: toggles between a single-window and a multi-window layout {{{2 | |
30 | " The original version was by Ron Aaron. | |
31 | fun! ZoomWin#ZoomWin() | |
32 | " let g:decho_hide= 1 "Decho | |
33 | " call Dfunc("ZoomWin#ZoomWin() winbufnr(2)=".winbufnr(2)) | |
34 | ||
35 | " if the vim doesn't have +mksession, only a partial zoom is available {{{3 | |
36 | if !has("mksession") | |
37 | if !exists("s:partialzoom") | |
38 | echomsg "missing the +mksession feature; only a partial zoom is available" | |
39 | let s:partialzoom= 0 | |
40 | endif | |
41 | if v:version < 630 | |
42 | echoerr "***sorry*** you need an updated vim, preferably with +mksession" | |
43 | elseif s:partialzoom | |
44 | " partial zoom out | |
45 | let s:partialzoom= 0 | |
46 | exe s:winrestore | |
47 | else | |
48 | " partial zoom in | |
49 | let s:partialzoom= 1 | |
50 | let s:winrestore = winrestcmd() | |
51 | res | |
52 | endif | |
53 | " call Dret("ZoomWin#ZoomWin : partialzoom=".s:partialzoom) | |
54 | return | |
55 | endif | |
56 | ||
57 | " Close certain windows {{{3 | |
58 | call s:ZoomWinPreserve(0) | |
59 | ||
60 | " save options. Force window minimum height/width to be >= 1 {{{3 | |
61 | let keep_hidden = &hidden | |
62 | let keep_write = &write | |
63 | ||
64 | if v:version < 603 | |
65 | if &wmh == 0 || &wmw == 0 | |
66 | let keep_wmh = &wmh | |
67 | let keep_wmw = &wmw | |
68 | silent! set wmh=1 wmw=1 | |
69 | endif | |
70 | endif | |
71 | set hidden write | |
72 | ||
73 | if winbufnr(2) == -1 | |
74 | " there's only one window - restore to multiple-windows mode {{{3 | |
75 | " call Decho("there's only one window - restore to multiple windows") | |
76 | ||
77 | if exists("s:sessionfile") && filereadable(s:sessionfile) | |
78 | " save position in current one-window-only | |
79 | " call Decho("save position in current one-window-only in sponly") | |
80 | let sponly = s:SavePosn(0) | |
81 | let s:origline = line(".") | |
82 | let s:origcol = virtcol(".") | |
83 | ||
84 | " source session file to restore window layout | |
85 | let ei_keep= &ei | |
86 | set ei=all | |
87 | exe 'silent! so '.fnameescape(s:sessionfile) | |
88 | " Decho("@@<".@@.">") | |
89 | let v:this_session= s:sesskeep | |
90 | ||
91 | if exists("s:savedposn1") | |
92 | " restore windows' positioning and buffers | |
93 | " call Decho("restore windows, positions, buffers") | |
94 | windo call s:RestorePosn(s:savedposn{winnr()})|unlet s:savedposn{winnr()} | |
95 | call s:GotoWinNum(s:winkeep) | |
96 | unlet s:winkeep | |
97 | endif | |
98 | ||
99 | if line(".") != s:origline || virtcol(".") != s:origcol | |
100 | " If the cursor hasn't moved from the original position, | |
101 | " then let the position remain what it was in the original | |
102 | " multi-window layout. | |
103 | " call Decho("restore position using sponly") | |
104 | call s:RestorePosn(sponly) | |
105 | endif | |
106 | ||
107 | " delete session file and variable holding its name | |
108 | " call Decho("delete session file") | |
109 | call delete(s:sessionfile) | |
110 | unlet s:sessionfile | |
111 | let &ei=ei_keep | |
112 | endif | |
113 | ||
114 | else " there's more than one window - go to only-one-window mode {{{3 | |
115 | " call Decho("there's multiple windows - goto one-window-only") | |
116 | ||
117 | let s:winkeep = winnr() | |
118 | let s:sesskeep = v:this_session | |
119 | ||
120 | " doesn't work with the command line window (normal mode q:) | |
121 | if &bt == "nofile" && expand("%") == (v:version < 702 ? 'command-line' : '[Command Line]') | |
122 | echoerr "***error*** ZoomWin#ZoomWin doesn't work with the ".expand("%")." window" | |
123 | " call Dret("ZoomWin#ZoomWin : ".expand('%')." window error") | |
124 | return | |
125 | endif | |
126 | " call Decho("1: @@<".@@.">") | |
127 | ||
128 | " disable all events (autocmds) | |
129 | " call Decho("disable events") | |
130 | let ei_keep= &ei | |
131 | set ei=all | |
132 | " call Decho("2: @@<".@@.">") | |
133 | ||
134 | " save window positioning commands | |
135 | " call Decho("save window positioning commands") | |
136 | windo let s:savedposn{winnr()}= s:SavePosn(1) | |
137 | call s:GotoWinNum(s:winkeep) | |
138 | ||
139 | " set up name of session file | |
140 | " call Decho("3: @@<".@@.">") | |
141 | let s:sessionfile= tempname() | |
142 | " call Decho("4: @@<".@@.">") | |
143 | ||
144 | " save session | |
145 | " call Decho("save session") | |
146 | let ssop_keep = &ssop | |
147 | let &ssop = 'blank,help,winsize,folds,globals,localoptions,options' | |
148 | " call Decho("5: @@<".@@.">") | |
149 | exe 'mksession! '.fnameescape(s:sessionfile) | |
150 | " call Decho("6: @@<".@@.">") | |
151 | let keepyy= @@ | |
152 | let keepy0= @0 | |
153 | let keepy1= @1 | |
154 | let keepy2= @2 | |
155 | let keepy3= @3 | |
156 | let keepy4= @4 | |
157 | let keepy5= @5 | |
158 | let keepy6= @6 | |
159 | let keepy7= @7 | |
160 | let keepy8= @8 | |
161 | let keepy9= @9 | |
162 | set lz ei=all bh= | |
163 | if v:version >= 700 | |
164 | try | |
165 | exe "keepalt keepmarks new! ".fnameescape(s:sessionfile) | |
166 | catch /^Vim\%((\a\+)\)\=:E/ | |
167 | echoerr "Too many windows" | |
168 | silent! call delete(s:sessionfile) | |
169 | unlet s:sessionfile | |
170 | " call Dret("ZoomWin#ZoomWin : too many windows") | |
171 | return | |
172 | endtry | |
173 | silent! keepjumps keepmarks v/wincmd\|split\|resize/d | |
174 | keepalt w! | |
175 | keepalt bw! | |
176 | else | |
177 | exe "new! ".fnameescape(s:sessionfile) | |
178 | v/wincmd\|split\|resize/d | |
179 | w! | |
180 | bw! | |
181 | endif | |
182 | let @@= keepyy | |
183 | let @0= keepy0 | |
184 | let @1= keepy1 | |
185 | let @2= keepy2 | |
186 | let @3= keepy3 | |
187 | let @4= keepy4 | |
188 | let @5= keepy5 | |
189 | let @6= keepy6 | |
190 | let @7= keepy7 | |
191 | let @8= keepy8 | |
192 | let @9= keepy9 | |
193 | call histdel('search', -1) | |
194 | let @/ = histget('search', -1) | |
195 | " call Decho("7: @@<".@@.">") | |
196 | ||
197 | " restore user's session options and restore event handling | |
198 | " call Decho("restore user session options and event handling") | |
199 | set nolz | |
200 | let &ssop = ssop_keep | |
201 | silent! only! | |
202 | " call Decho("8: @@<".@@.">") | |
203 | let &ei = ei_keep | |
204 | echomsg expand("%") | |
205 | " call Decho("9: @@<".@@.">") | |
206 | endif | |
207 | ||
208 | " restore user option settings {{{3 | |
209 | " call Decho("restore user option settings") | |
210 | let &hidden= keep_hidden | |
211 | let &write = keep_write | |
212 | if v:version < 603 | |
213 | if exists("keep_wmw") | |
214 | let &wmh= keep_wmh | |
215 | let &wmw= keep_wmw | |
216 | endif | |
217 | endif | |
218 | ||
219 | " Re-open certain windows {{{3 | |
220 | call s:ZoomWinPreserve(1) | |
221 | ||
222 | " call Dret("ZoomWin#ZoomWin") | |
223 | endfun | |
224 | ||
225 | " --------------------------------------------------------------------- | |
226 | " SavePosn: this function sets up a savedposn variable that {{{2 | |
227 | " has the commands necessary to restore the view | |
228 | " of the current window. | |
229 | fun! s:SavePosn(savewinhoriz) | |
230 | " call Dfunc("SavePosn(savewinhoriz=".a:savewinhoriz.") file<".expand("%").">") | |
231 | let swline = line(".") | |
232 | if swline == 1 && getline(1) == "" | |
233 | " empty buffer | |
234 | let savedposn= "silent b ".winbufnr(0) | |
235 | " call Dret("SavePosn savedposn<".savedposn.">") | |
236 | return savedposn | |
237 | endif | |
238 | let swcol = col(".") | |
239 | let swwline = winline()-1 | |
240 | let swwcol = virtcol(".") - wincol() | |
241 | let savedposn = "silent b ".winbufnr(0)."|".swline."|silent norm! z\<cr>" | |
242 | if swwline > 0 | |
243 | let savedposn= savedposn.":silent norm! ".swwline."\<c-y>\<cr>:silent norm! zs\<cr>" | |
244 | endif | |
245 | let savedposn= savedposn.":silent call cursor(".swline.",".swcol.")\<cr>" | |
246 | ||
247 | if a:savewinhoriz | |
248 | if swwcol > 0 | |
249 | let savedposn= savedposn.":silent norm! ".swwcol."zl\<cr>" | |
250 | endif | |
251 | ||
252 | " handle certain special settings for the multi-window savedposn call | |
253 | " bufhidden buftype buflisted | |
254 | let settings= "" | |
255 | if &bh != "" | |
256 | let settings="bh=".&bh | |
257 | setlocal bh=hide | |
258 | endif | |
259 | if !&bl | |
260 | let settings= settings." nobl" | |
261 | setlocal bl | |
262 | endif | |
263 | if &bt != "" | |
264 | let settings= settings." bt=".&bt | |
265 | setlocal bt= | |
266 | endif | |
267 | if settings != "" | |
268 | let savedposn= savedposn.":setlocal ".settings."\<cr>" | |
269 | endif | |
270 | ||
271 | endif | |
272 | " call Dret("SavePosn savedposn<".savedposn.">") | |
273 | return savedposn | |
274 | endfun | |
275 | ||
276 | " --------------------------------------------------------------------- | |
277 | " s:RestorePosn: this function restores noname and scratch windows {{{2 | |
278 | fun! s:RestorePosn(savedposn) | |
279 | " call Dfunc("RestorePosn(savedposn<".a:savedposn.">) file<".expand("%").">") | |
280 | if &scb | |
281 | setlocal noscb | |
282 | exe a:savedposn | |
283 | setlocal scb | |
284 | else | |
285 | exe a:savedposn | |
286 | endif | |
287 | " call Dret("RestorePosn") | |
288 | endfun | |
289 | ||
290 | " --------------------------------------------------------------------- | |
291 | " CleanupSessionFile: if you exit Vim before cleaning up the {{{2 | |
292 | " supposed-to-be temporary session file | |
293 | fun! ZoomWin#CleanupSessionFile() | |
294 | " call Dfunc("ZoomWin#CleanupSessionFile()") | |
295 | if exists("s:sessionfile") && filereadable(s:sessionfile) | |
296 | " call Decho("sessionfile exists and is readable; deleting it") | |
297 | silent! call delete(s:sessionfile) | |
298 | unlet s:sessionfile | |
299 | endif | |
300 | " call Dret("ZoomWin#CleanupSessionFile") | |
301 | endfun | |
302 | ||
303 | " --------------------------------------------------------------------- | |
304 | " GotoWinNum: this function puts cursor into specified window {{{2 | |
305 | fun! s:GotoWinNum(winnum) | |
306 | " call Dfunc("GotoWinNum(winnum=".a:winnum.") winnr=".winnr()) | |
307 | if a:winnum != winnr() | |
308 | exe a:winnum."wincmd w" | |
309 | endif | |
310 | " call Dret("GotoWinNum") | |
311 | endfun | |
312 | ||
313 | ||
314 | " --------------------------------------------------------------------- | |
315 | " ZoomWinPreserve: This function, largely written by David Fishburn, {{{2 | |
316 | " allows ZoomWin to "preserve" certain windows: | |
317 | " | |
318 | " TagList, by Yegappan Lakshmanan | |
319 | " http://vim.sourceforge.net/scripts/script.php?script_id=273 | |
320 | " | |
321 | " WinManager, by Srinath Avadhanula | |
322 | " http://vim.sourceforge.net/scripts/script.php?script_id=95 | |
323 | " | |
324 | " It does so by closing the associated window upon entry to ZoomWin | |
325 | " and re-opening it upon exit by using commands provided by the | |
326 | " utilities themselves. | |
327 | fun! s:ZoomWinPreserve(open) | |
328 | " call Dfunc("ZoomWinPreserve(open=".a:open.")") | |
329 | ||
330 | if a:open == 0 | |
331 | ||
332 | " Close Taglist | |
333 | if exists('g:zoomwin_preserve_taglist') && exists('g:loaded_taglist') | |
334 | " If taglist window is open then close it. | |
335 | let s:taglist_winnum = bufwinnr(g:TagList_title) | |
336 | if s:taglist_winnum != -1 | |
337 | " Close the window | |
338 | exec "silent! Tlist" | |
339 | endif | |
340 | endif | |
341 | ||
342 | " Close Winmanager | |
343 | if exists('g:zoomwin_preserve_winmanager') && exists('g:loaded_winmanager') | |
344 | " If the winmanager window is open then close it. | |
345 | let s:is_winmgr_vis = IsWinManagerVisible() | |
346 | if s:is_winmgr_vis == 1 | |
347 | exec "WMClose" | |
348 | endif | |
349 | endif | |
350 | ||
351 | else | |
352 | ||
353 | " Re-open Taglist | |
354 | if exists('g:zoomwin_preserve_taglist') && exists('g:loaded_taglist') | |
355 | " If taglist window was open, open it again | |
356 | if s:taglist_winnum != -1 | |
357 | exec "silent! Tlist" | |
358 | endif | |
359 | endif | |
360 | ||
361 | " Re-Open Winmanager | |
362 | if exists('g:zoomwin_preserve_winmanager') && exists('g:loaded_winmanager') | |
363 | " If the winmanager window is open then close it. | |
364 | if s:is_winmgr_vis == 1 | |
365 | exec "WManager" | |
366 | endif | |
367 | endif | |
368 | endif | |
369 | ||
370 | " call Dret("ZoomWinPreserve") | |
371 | endfun | |
372 | ||
373 | " ===================================================================== | |
374 | " Restore: {{{1 | |
375 | let &cpo= s:keepcpo | |
376 | unlet s:keepcpo | |
377 | ||
378 | " --------------------------------------------------------------------- | |
379 | " Modelines: {{{1 | |
380 | " vim: ts=4 fdm=marker |