.vim/plugin/cecutil.vim
changeset 0 86954f5fc4d2
equal deleted inserted replaced
-1:000000000000 0:86954f5fc4d2
       
     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