|
1 " cecutil.vim : save/restore window position |
|
2 " save/restore mark position |
|
3 " save/restore selected user maps |
|
4 " Author: Charles E. Campbell, Jr. |
|
5 " Version: 15e ASTRO-ONLY |
|
6 " Date: Apr 10, 2006 |
|
7 " |
|
8 " Saving Restoring Destroying Marks: {{{1 |
|
9 " call SaveMark(markname) let savemark= SaveMark(markname) |
|
10 " call RestoreMark(markname) call RestoreMark(savemark) |
|
11 " call DestroyMark(markname) |
|
12 " commands: SM RM DM |
|
13 " |
|
14 " Saving Restoring Destroying Window Position: {{{1 |
|
15 " call SaveWinPosn() let winposn= SaveWinPosn() |
|
16 " call RestoreWinPosn() call RestoreWinPosn(winposn) |
|
17 " \swp : save current window/buffer's position |
|
18 " \rwp : restore current window/buffer's previous position |
|
19 " commands: SWP RWP |
|
20 " |
|
21 " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim |
|
22 " |
|
23 " You believe that God is one. You do well. The demons also {{{1 |
|
24 " believe, and shudder. But do you want to know, vain man, that |
|
25 " faith apart from works is dead? (James 2:19,20 WEB) |
|
26 |
|
27 " Load Once: {{{1 |
|
28 if &cp || exists("g:loaded_cecutil") |
|
29 finish |
|
30 endif |
|
31 let g:loaded_cecutil = "v15e" |
|
32 let s:keepcpo = &cpo |
|
33 set cpo&vim |
|
34 "DechoVarOn |
|
35 |
|
36 " ----------------------- |
|
37 " Public Interface: {{{1 |
|
38 " ----------------------- |
|
39 |
|
40 " Map Interface: {{{2 |
|
41 if !hasmapto('<Plug>SaveWinPosn') |
|
42 map <unique> <Leader>swp <Plug>SaveWinPosn |
|
43 endif |
|
44 if !hasmapto('<Plug>RestoreWinPosn') |
|
45 map <unique> <Leader>rwp <Plug>RestoreWinPosn |
|
46 endif |
|
47 nmap <silent> <Plug>SaveWinPosn :call SaveWinPosn()<CR> |
|
48 nmap <silent> <Plug>RestoreWinPosn :call RestoreWinPosn()<CR> |
|
49 |
|
50 " Command Interface: {{{2 |
|
51 com -bar -nargs=0 SWP call SaveWinPosn() |
|
52 com -bar -nargs=0 RWP call RestoreWinPosn() |
|
53 com -bar -nargs=1 SM call SaveMark(<q-args>) |
|
54 com -bar -nargs=1 RM call RestoreMark(<q-args>) |
|
55 com -bar -nargs=1 DM call DestroyMark(<q-args>) |
|
56 |
|
57 if v:version < 630 |
|
58 let s:modifier= "sil " |
|
59 else |
|
60 let s:modifier= "sil keepj " |
|
61 endif |
|
62 |
|
63 " --------------------------------------------------------------------- |
|
64 " SaveWinPosn: {{{1 |
|
65 " let winposn= SaveWinPosn() will save window position in winposn variable |
|
66 " call SaveWinPosn() will save window position in b:cecutil_winposn{b:cecutil_iwinposn} |
|
67 " let winposn= SaveWinPosn(0) will *only* save window position in winposn variable (no stacking done) |
|
68 fun! SaveWinPosn(...) |
|
69 " call Dfunc("SaveWinPosn() a:0=".a:0) |
|
70 if line(".") == 1 && getline(1) == "" |
|
71 " call Dfunc("SaveWinPosn : empty buffer") |
|
72 return "" |
|
73 endif |
|
74 let so_keep = &so |
|
75 let siso_keep = &siso |
|
76 let ss_keep = &ss |
|
77 set so=0 siso=0 ss=0 |
|
78 |
|
79 let swline = line(".") |
|
80 let swcol = col(".") |
|
81 let swwline = winline() - 1 |
|
82 let swwcol = virtcol(".") - wincol() |
|
83 let savedposn = "call GoWinbufnr(".winbufnr(0).")|silent ".swline |
|
84 let savedposn = savedposn."|".s:modifier."norm! 0z\<cr>" |
|
85 if swwline > 0 |
|
86 let savedposn= savedposn.":".s:modifier."norm! ".swwline."\<c-y>\<cr>" |
|
87 endif |
|
88 if swwcol > 0 |
|
89 let savedposn= savedposn.":".s:modifier."norm! 0".swwcol."zl\<cr>" |
|
90 endif |
|
91 let savedposn = savedposn.":".s:modifier."call cursor(".swline.",".swcol.")\<cr>" |
|
92 |
|
93 " save window position in |
|
94 " b:cecutil_winposn_{iwinposn} (stack) |
|
95 " only when SaveWinPosn() is used |
|
96 if a:0 == 0 |
|
97 if !exists("b:cecutil_iwinposn") |
|
98 let b:cecutil_iwinposn= 1 |
|
99 else |
|
100 let b:cecutil_iwinposn= b:cecutil_iwinposn + 1 |
|
101 endif |
|
102 " call Decho("saving posn to SWP stack") |
|
103 let b:cecutil_winposn{b:cecutil_iwinposn}= savedposn |
|
104 endif |
|
105 |
|
106 let &so = so_keep |
|
107 let &siso = siso_keep |
|
108 let &ss = ss_keep |
|
109 |
|
110 " if exists("b:cecutil_iwinposn") " Decho |
|
111 " call Decho("b:cecutil_winpos{".b:cecutil_iwinposn."}[".b:cecutil_winposn{b:cecutil_iwinposn}."]") |
|
112 " else " Decho |
|
113 " call Decho("b:cecutil_iwinposn doesn't exist") |
|
114 " endif " Decho |
|
115 " call Dret("SaveWinPosn [".savedposn."]") |
|
116 return savedposn |
|
117 endfun |
|
118 |
|
119 " --------------------------------------------------------------------- |
|
120 " RestoreWinPosn: {{{1 |
|
121 fun! RestoreWinPosn(...) |
|
122 " call Dfunc("RestoreWinPosn() a:0=".a:0) |
|
123 " call Decho("getline(1)<".getline(1).">") |
|
124 " call Decho("line(.)=".line(".")) |
|
125 if line(".") == 1 && getline(1) == "" |
|
126 " call Dfunc("RestoreWinPosn : empty buffer") |
|
127 return "" |
|
128 endif |
|
129 let so_keep = &so |
|
130 let siso_keep = &siso |
|
131 let ss_keep = &ss |
|
132 set so=0 siso=0 ss=0 |
|
133 |
|
134 if a:0 == 0 || a:1 == "" |
|
135 " use saved window position in b:cecutil_winposn{b:cecutil_iwinposn} if it exists |
|
136 if exists("b:cecutil_iwinposn") && exists("b:cecutil_winposn{b:cecutil_iwinposn}") |
|
137 " call Decho("using stack b:cecutil_winposn{".b:cecutil_iwinposn."}<".b:cecutil_winposn{b:cecutil_iwinposn}.">") |
|
138 try |
|
139 exe "silent! ".b:cecutil_winposn{b:cecutil_iwinposn} |
|
140 catch /^Vim\%((\a\+)\)\=:E749/ |
|
141 " ignore empty buffer error messages |
|
142 endtry |
|
143 " normally drop top-of-stack by one |
|
144 " but while new top-of-stack doesn't exist |
|
145 " drop top-of-stack index by one again |
|
146 if b:cecutil_iwinposn >= 1 |
|
147 unlet b:cecutil_winposn{b:cecutil_iwinposn} |
|
148 let b:cecutil_iwinposn= b:cecutil_iwinposn - 1 |
|
149 while b:cecutil_iwinposn >= 1 && !exists("b:cecutil_winposn{b:cecutil_iwinposn}") |
|
150 let b:cecutil_iwinposn= b:cecutil_iwinposn - 1 |
|
151 endwhile |
|
152 if b:cecutil_iwinposn < 1 |
|
153 unlet b:cecutil_iwinposn |
|
154 endif |
|
155 endif |
|
156 else |
|
157 echohl WarningMsg |
|
158 echomsg "***warning*** need to SaveWinPosn first!" |
|
159 echohl None |
|
160 endif |
|
161 |
|
162 else " handle input argument |
|
163 " call Decho("using input a:1<".a:1.">") |
|
164 " use window position passed to this function |
|
165 exe "silent ".a:1 |
|
166 " remove a:1 pattern from b:cecutil_winposn{b:cecutil_iwinposn} stack |
|
167 if exists("b:cecutil_iwinposn") |
|
168 let jwinposn= b:cecutil_iwinposn |
|
169 while jwinposn >= 1 " search for a:1 in iwinposn..1 |
|
170 if exists("b:cecutil_winposn{jwinposn}") " if it exists |
|
171 if a:1 == b:cecutil_winposn{jwinposn} " and the pattern matches |
|
172 unlet b:cecutil_winposn{jwinposn} " unlet it |
|
173 if jwinposn == b:cecutil_iwinposn " if at top-of-stack |
|
174 let b:cecutil_iwinposn= b:cecutil_iwinposn - 1 " drop stacktop by one |
|
175 endif |
|
176 endif |
|
177 endif |
|
178 let jwinposn= jwinposn - 1 |
|
179 endwhile |
|
180 endif |
|
181 endif |
|
182 |
|
183 " seems to be something odd: vertical motions after RWP |
|
184 " cause jump to first column. Following fixes that |
|
185 if wincol() > 1 |
|
186 silent norm! hl |
|
187 elseif virtcol(".") < virtcol("$") |
|
188 silent norm! lh |
|
189 endif |
|
190 |
|
191 let &so = so_keep |
|
192 let &siso = siso_keep |
|
193 let &ss = ss_keep |
|
194 |
|
195 " call Dret("RestoreWinPosn") |
|
196 endfun |
|
197 |
|
198 " --------------------------------------------------------------------- |
|
199 " GoWinbufnr: go to window holding given buffer (by number) {{{1 |
|
200 " Prefers current window; if its buffer number doesn't match, |
|
201 " then will try from topleft to bottom right |
|
202 fun! GoWinbufnr(bufnum) |
|
203 " call Dfunc("GoWinbufnr(".a:bufnum.")") |
|
204 if winbufnr(0) == a:bufnum |
|
205 " call Dret("GoWinbufnr : winbufnr(0)==a:bufnum") |
|
206 return |
|
207 endif |
|
208 winc t |
|
209 let first=1 |
|
210 while winbufnr(0) != a:bufnum && (first || winnr() != 1) |
|
211 winc w |
|
212 let first= 0 |
|
213 endwhile |
|
214 " call Dret("GoWinbufnr") |
|
215 endfun |
|
216 |
|
217 " --------------------------------------------------------------------- |
|
218 " SaveMark: sets up a string saving a mark position. {{{1 |
|
219 " For example, SaveMark("a") |
|
220 " Also sets up a global variable, g:savemark_{markname} |
|
221 fun! SaveMark(markname) |
|
222 " call Dfunc("SaveMark(markname<".a:markname.">)") |
|
223 let markname= a:markname |
|
224 if strpart(markname,0,1) !~ '\a' |
|
225 let markname= strpart(markname,1,1) |
|
226 endif |
|
227 " call Decho("markname=".markname) |
|
228 |
|
229 let lzkeep = &lz |
|
230 set lz |
|
231 |
|
232 if 1 <= line("'".markname) && line("'".markname) <= line("$") |
|
233 let winposn = SaveWinPosn(0) |
|
234 exe s:modifier."norm! `".markname |
|
235 let savemark = SaveWinPosn(0) |
|
236 let g:savemark_{markname} = savemark |
|
237 let savemark = markname.savemark |
|
238 call RestoreWinPosn(winposn) |
|
239 else |
|
240 let g:savemark_{markname} = "" |
|
241 let savemark = "" |
|
242 endif |
|
243 |
|
244 let &lz= lzkeep |
|
245 |
|
246 " call Dret("SaveMark : savemark<".savemark.">") |
|
247 return savemark |
|
248 endfun |
|
249 |
|
250 " --------------------------------------------------------------------- |
|
251 " RestoreMark: {{{1 |
|
252 " call RestoreMark("a") -or- call RestoreMark(savemark) |
|
253 fun! RestoreMark(markname) |
|
254 " call Dfunc("RestoreMark(markname<".a:markname.">)") |
|
255 |
|
256 if strlen(a:markname) <= 0 |
|
257 " call Dret("RestoreMark : no such mark") |
|
258 return |
|
259 endif |
|
260 let markname= strpart(a:markname,0,1) |
|
261 if markname !~ '\a' |
|
262 " handles 'a -> a styles |
|
263 let markname= strpart(a:markname,1,1) |
|
264 endif |
|
265 " call Decho("markname=".markname." strlen(a:markname)=".strlen(a:markname)) |
|
266 |
|
267 let lzkeep = &lz |
|
268 set lz |
|
269 let winposn = SaveWinPosn(0) |
|
270 |
|
271 if strlen(a:markname) <= 2 |
|
272 if exists("g:savemark_{markname}") && strlen(g:savemark_{markname}) != 0 |
|
273 " use global variable g:savemark_{markname} |
|
274 " call Decho("use savemark list") |
|
275 call RestoreWinPosn(g:savemark_{markname}) |
|
276 exe "norm! m".markname |
|
277 endif |
|
278 else |
|
279 " markname is a savemark command (string) |
|
280 " call Decho("use savemark command") |
|
281 let markcmd= strpart(a:markname,1) |
|
282 call RestoreWinPosn(markcmd) |
|
283 exe "norm! m".markname |
|
284 endif |
|
285 |
|
286 call RestoreWinPosn(winposn) |
|
287 let &lz = lzkeep |
|
288 |
|
289 " call Dret("RestoreMark") |
|
290 endfun |
|
291 |
|
292 " --------------------------------------------------------------------- |
|
293 " DestroyMark: {{{1 |
|
294 " call DestroyMark("a") -- destroys mark |
|
295 fun! DestroyMark(markname) |
|
296 " call Dfunc("DestroyMark(markname<".a:markname.">)") |
|
297 |
|
298 " save options and set to standard values |
|
299 let reportkeep= &report |
|
300 let lzkeep = &lz |
|
301 set lz report=10000 |
|
302 |
|
303 let markname= strpart(a:markname,0,1) |
|
304 if markname !~ '\a' |
|
305 " handles 'a -> a styles |
|
306 let markname= strpart(a:markname,1,1) |
|
307 endif |
|
308 " call Decho("markname=".markname) |
|
309 |
|
310 let curmod = &mod |
|
311 let winposn = SaveWinPosn(0) |
|
312 1 |
|
313 let lineone = getline(".") |
|
314 exe "k".markname |
|
315 d |
|
316 put! =lineone |
|
317 let &mod = curmod |
|
318 call RestoreWinPosn(winposn) |
|
319 |
|
320 " restore options to user settings |
|
321 let &report = reportkeep |
|
322 let &lz = lzkeep |
|
323 |
|
324 " call Dret("DestroyMark") |
|
325 endfun |
|
326 |
|
327 " --------------------------------------------------------------------- |
|
328 " ListWinPosn: |
|
329 "fun! ListWinPosn() " Decho |
|
330 " if !exists("b:cecutil_iwinposn") || b:cecutil_iwinposn == 0 " Decho |
|
331 " call Decho("nothing on SWP stack") " Decho |
|
332 " else " Decho |
|
333 " let jwinposn= b:cecutil_iwinposn " Decho |
|
334 " while jwinposn >= 1 " Decho |
|
335 " if exists("b:cecutil_winposn{jwinposn}") " Decho |
|
336 " call Decho("winposn{".jwinposn."}<".b:cecutil_winposn{jwinposn}.">") " Decho |
|
337 " else " Decho |
|
338 " call Decho("winposn{".jwinposn."} -- doesn't exist") " Decho |
|
339 " endif " Decho |
|
340 " let jwinposn= jwinposn - 1 " Decho |
|
341 " endwhile " Decho |
|
342 " endif " Decho |
|
343 "endfun " Decho |
|
344 "com! -nargs=0 LWP call ListWinPosn() " Decho |
|
345 |
|
346 " --------------------------------------------------------------------- |
|
347 " SaveUserMaps: this function sets up a script-variable (s:restoremap) {{{1 |
|
348 " which can be used to restore user maps later with |
|
349 " call RestoreUserMaps() |
|
350 " |
|
351 " mapmode - see :help maparg for its list |
|
352 " ex. "n" = Normal |
|
353 " If the first letter is u, then unmapping will be done |
|
354 " ex. "un" = Normal + unmapping |
|
355 " mapchx - "<something>" handled as a single map item. |
|
356 " ex. "<left>" |
|
357 " - "string" a string of single letters which are actually |
|
358 " multiple two-letter maps (using the maplead: |
|
359 " maplead . each_character_in_string) |
|
360 " ex. maplead="\" and mapchx="abc" saves mappings for |
|
361 " \a, \b, and \c |
|
362 " Of course, if maplead is "", then for mapchx="abc", |
|
363 " mappings for a, b, and c are saved. |
|
364 " - :something handled as a single map item, w/o the ":" |
|
365 " ex. mapchx= ":abc" will save a mapping for "abc" |
|
366 " suffix - a string unique to your plugin |
|
367 " ex. suffix= "DrawIt" |
|
368 fun! SaveUserMaps(mapmode,maplead,mapchx,suffix) |
|
369 " call Dfunc("SaveUserMaps(mapmode<".a:mapmode."> maplead<".a:maplead."> mapchx<".a:mapchx."> suffix<".a:suffix.">)") |
|
370 |
|
371 if !exists("s:restoremap_{a:suffix}") |
|
372 " initialize restoremap_suffix to null string |
|
373 let s:restoremap_{a:suffix}= "" |
|
374 endif |
|
375 |
|
376 " set up dounmap: if 1, then save and unmap (a:mapmode leads with a "u") |
|
377 " if 0, save only |
|
378 if a:mapmode =~ '^u' |
|
379 let dounmap= 1 |
|
380 let mapmode= strpart(a:mapmode,1) |
|
381 else |
|
382 let dounmap= 0 |
|
383 let mapmode= a:mapmode |
|
384 endif |
|
385 |
|
386 " save single map :...something... |
|
387 if strpart(a:mapchx,0,1) == ':' |
|
388 let amap= strpart(a:mapchx,1) |
|
389 if amap == "|" || amap == "\<c-v>" |
|
390 let amap= "\<c-v>".amap |
|
391 endif |
|
392 let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|:silent! ".mapmode."unmap ".amap |
|
393 if maparg(amap,mapmode) != "" |
|
394 let maprhs= substitute(maparg(amap,mapmode),'|','<bar>','ge') |
|
395 " let maprhs= substitute(maprhs,'"<CR>',"\<cr>",'ge') |
|
396 let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|:".mapmode."map ".amap." ".maprhs |
|
397 endif |
|
398 if dounmap |
|
399 exe "silent! ".mapmode."unmap ".amap |
|
400 endif |
|
401 |
|
402 " save single map <something> |
|
403 elseif strpart(a:mapchx,0,1) == '<' |
|
404 let amap = a:mapchx |
|
405 if amap == "|" || amap == "\<c-v>" |
|
406 let amap= "\<c-v>".amap |
|
407 endif |
|
408 let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|silent! ".mapmode."unmap ".amap |
|
409 if maparg(a:mapchx,mapmode) != "" |
|
410 let maprhs= substitute(maparg(amap,mapmode),'|','<bar>','ge') |
|
411 " let maprhs= substitute(maprhs,'"<CR>',"\<cr>",'ge') |
|
412 let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|".mapmode."map ".amap." ".maprhs |
|
413 endif |
|
414 if dounmap |
|
415 exe "silent! ".mapmode."unmap ".amap |
|
416 endif |
|
417 |
|
418 " save multiple maps |
|
419 else |
|
420 let i= 1 |
|
421 while i <= strlen(a:mapchx) |
|
422 let amap= a:maplead.strpart(a:mapchx,i-1,1) |
|
423 if amap == "|" || amap == "\<c-v>" |
|
424 let amap= "\<c-v>".amap |
|
425 endif |
|
426 let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|silent! ".mapmode."unmap ".amap |
|
427 if maparg(amap,mapmode) != "" |
|
428 let maprhs= substitute(maparg(amap,mapmode),'|','<bar>','ge') |
|
429 " let maprhs= substitute(maprhs,'"<CR>',"\<cr>",'ge') |
|
430 let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|".mapmode."map ".amap." ".maprhs |
|
431 endif |
|
432 if dounmap |
|
433 exe "silent! ".mapmode."unmap ".amap |
|
434 endif |
|
435 let i= i + 1 |
|
436 endwhile |
|
437 endif |
|
438 " call Dret("SaveUserMaps : restoremap_".a:suffix.": ".s:restoremap_{a:suffix}) |
|
439 endfun |
|
440 |
|
441 " --------------------------------------------------------------------- |
|
442 " RestoreUserMaps: {{{1 |
|
443 " Used to restore user maps saved by SaveUserMaps() |
|
444 fun! RestoreUserMaps(suffix) |
|
445 " call Dfunc("RestoreUserMaps(suffix<".a:suffix.">)") |
|
446 if exists("s:restoremap_{a:suffix}") |
|
447 let s:restoremap_{a:suffix}= substitute(s:restoremap_{a:suffix},'|\s*$','','e') |
|
448 if s:restoremap_{a:suffix} != "" |
|
449 " call Decho("exe ".s:restoremap_{a:suffix}) |
|
450 exe "silent! s:restoremap_{a:suffix}" |
|
451 endif |
|
452 unlet s:restoremap_{a:suffix} |
|
453 endif |
|
454 " call Dret("RestoreUserMaps") |
|
455 endfun |
|
456 |
|
457 " --------------------------------------------------------------------- |
|
458 " Restore: {{{1 |
|
459 let &cpo= s:keepcpo |
|
460 unlet s:keepcpo |
|
461 |
|
462 " --------------------------------------------------------------------- |
|
463 " Modelines: {{{1 |
|
464 " vim: ts=4 fdm=marker |