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