diff --git a/.VimballRecord b/.VimballRecord index c9f6a358..073f0358 100644 --- a/.VimballRecord +++ b/.VimballRecord @@ -1,4 +1,3 @@ -Align.vba: call delete('/home/lilydjwg/.vim/plugin/AlignPlugin.vim')|call delete('/home/lilydjwg/.vim/plugin/AlignMapsPlugin.vim')|call delete('/home/lilydjwg/.vim/plugin/cecutil.vim')|call delete('/home/lilydjwg/.vim/doc/Align.txt')|call delete('/home/lilydjwg/.vim/autoload/Align.vim')|call delete('/home/lilydjwg/.vim/autoload/AlignMaps.vim') vis.vba: call delete('/home/lilydjwg/.vim/plugin/vis.vim')|call delete('/home/lilydjwg/.vim/plugin/cecutil.vim')|call delete('/home/lilydjwg/.vim/doc/vis.txt') cecutil.vba: call delete('/home/lilydjwg/.vim/plugin/cecutil.vim')|call delete('/home/lilydjwg/.vim/doc/cecutil.txt') vimwiki-1-1-1.vba: call delete('/home/lilydjwg/.vim/autoload/vimwiki.vim')|call delete('/home/lilydjwg/.vim/autoload/vimwiki_diary.vim')|call delete('/home/lilydjwg/.vim/autoload/vimwiki_html.vim')|call delete('/home/lilydjwg/.vim/autoload/vimwiki_lst.vim')|call delete('/home/lilydjwg/.vim/autoload/vimwiki_tbl.vim')|call delete('/home/lilydjwg/.vim/doc/vimwiki.txt')|call delete('/home/lilydjwg/.vim/ftplugin/vimwiki.vim')|call delete('/home/lilydjwg/.vim/plugin/vimwiki.vim')|call delete('/home/lilydjwg/.vim/syntax/vimwiki.vim')|call delete('/home/lilydjwg/.vim/syntax/vimwiki_default.vim')|call delete('/home/lilydjwg/.vim/syntax/vimwiki_media.vim') @@ -14,3 +13,4 @@ tagbar.vmb: call delete('/home/lilydjwg/.vim/autoload/tagbar.vim')|call delete(' manpageview.vba: call delete('/home/lilydjwg/.vim/plugin/manpageviewPlugin.vim')|call delete('/home/lilydjwg/.vim/autoload/manpageview.vim')|call delete('/home/lilydjwg/.vim/syntax/man.vim')|call delete('/home/lilydjwg/.vim/syntax/mangl.vim')|call delete('/home/lilydjwg/.vim/syntax/mankey.vim')|call delete('/home/lilydjwg/.vim/syntax/info.vim')|call delete('/home/lilydjwg/.vim/syntax/manphp.vim')|call delete('/home/lilydjwg/.vim/doc/manpageview.txt')|call delete('/home/lilydjwg/.vim/plugin/cecutil.vim') mark.vba: call delete('/home/lilydjwg/.vim/autoload/mark.vim')|call delete('/home/lilydjwg/.vim/plugin/mark.vim')|call delete('/home/lilydjwg/.vim/doc/mark.txt') NrrwRgn-0.28.vmb: call delete('/home/lilydjwg/.vim/plugin/NrrwRgn.vim')|call delete('/home/lilydjwg/.vim/autoload/nrrwrgn.vim')|call delete('/home/lilydjwg/.vim/doc/NarrowRegion.txt') +Align.vba: call delete('/home/lilydjwg/.vim/plugin/AlignPlugin.vim')|call delete('/home/lilydjwg/.vim/plugin/AlignMapsPlugin.vim')|call delete('/home/lilydjwg/.vim/plugin/cecutil.vim')|call delete('/home/lilydjwg/.vim/doc/Align.txt')|call delete('/home/lilydjwg/.vim/autoload/Align.vim')|call delete('/home/lilydjwg/.vim/autoload/AlignMaps.vim') diff --git a/autoload/Align.vim b/autoload/Align.vim index 31d8f256..e393584e 100644 --- a/autoload/Align.vim +++ b/autoload/Align.vim @@ -1,10 +1,10 @@ " Align: tool to align multiple fields based on one or more separators " Author: Charles E. Campbell, Jr. -" Date: Mar 03, 2009 -" Version: 35 +" Date: Jun 18, 2012 +" Version: 36 " GetLatestVimScripts: 294 1 :AutoInstall: Align.vim " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim -" Copyright: Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1 +" Copyright: Copyright (C) 1999-2012 Charles E. Campbell, Jr. {{{1 " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright " notice is copied with it. Like anything else that's free, @@ -18,13 +18,14 @@ " the power of God for salvation for everyone who believes; for the Jew first, " and also for the Greek. For in it is revealed God's righteousness from " faith to faith. +"redraw!|call DechoSep()|call inputsave()|call input("Press to continue")|call inputrestore() " --------------------------------------------------------------------- " Load Once: {{{1 if exists("g:loaded_Align") || &cp finish endif -let g:loaded_Align = "v35" +let g:loaded_Align = "v36" if v:version < 700 echohl WarningMsg echo "***warning*** this version of Align needs vim 7.0" @@ -84,14 +85,13 @@ endif " | s:AlignSep fun! Align#AlignCtrl(...) -" call Dfunc("AlignCtrl(...) a:0=".a:0) +" call Dfunc("Align#AlignCtrl(...) a:0=".a:0) - " save options that will be changed - let keep_search = @/ - let keep_ic = &ic + " save options that may be changed later + call s:SaveUserOptions() " turn ignorecase off - set noic + setlocal noic " clear visual mode so that old visual-mode selections don't " get applied to new invocations of Align(). @@ -121,19 +121,20 @@ fun! Align#AlignCtrl(...) let ipat= 2 while ipat <= A[0] if "" =~ A[ipat] - echoerr "AlignCtrl: separator<".A[ipat]."> matches zero-length string" - let &ic= keep_ic -" call Dret("AlignCtrl") + echoerr "(AlignCtrl) separator<".A[ipat]."> matches zero-length string" + call s:RestoreUserOptions() +" call Dret("Align#AlignCtrl") return endif let ipat= ipat + 1 endwhile endif endif +" call Decho("(AlignCtrl) passed bad-separator pattern check (no zero-length matches)") -" call Decho("AlignCtrl() A[0]=".A[0]) +" call Decho("(AlignCtrl) A[0]=".A[0]) if !exists("s:AlignStyle") - let s:AlignStyle= "l" + let s:AlignStyle= 'l' endif if !exists("s:AlignPrePad") let s:AlignPrePad= 0 @@ -153,7 +154,7 @@ fun! Align#AlignCtrl(...) let s:AlignPatQty= 0 endif echo "AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep -" call Decho("AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep) +" call Decho("(AlignCtrl) AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep) if exists("s:AlignGPat") && !exists("s:AlignVPat") echo "AlignGPat<".s:AlignGPat.">" elseif !exists("s:AlignGPat") && exists("s:AlignVPat") @@ -164,7 +165,7 @@ fun! Align#AlignCtrl(...) let ipat= 1 while ipat <= s:AlignPatQty echo "Pat".ipat."<".s:AlignPat_{ipat}.">" -" call Decho("Pat".ipat."<".s:AlignPat_{ipat}.">") +" call Decho("(AlignCtrl) Pat".ipat."<".s:AlignPat_{ipat}.">") let ipat= ipat + 1 endwhile @@ -190,9 +191,8 @@ fun! Align#AlignCtrl(...) call Align#AlignCtrl("g") call Align#AlignCtrl("v") let s:dovisclear = 1 - let &ic = keep_ic - let @/ = keep_search -" call Dret("AlignCtrl") + call s:RestoreUserOptions() +" call Dret("Align#AlignCtrl") return endif @@ -205,7 +205,7 @@ fun! Align#AlignCtrl(...) endif " = : record a list of alignment patterns that are equivalent - if style =~# "=" + if style =~# "=" || (A[0] >= 2 && style !~# "C" && s:AlignCtrl =~# '=') " call Decho("style case =: record list of equiv alignment patterns") let s:AlignCtrl = '=' if A[0] >= 2 @@ -221,7 +221,7 @@ fun! Align#AlignCtrl(...) endif "c : cycle through alignment pattern(s) - elseif style =~# 'C' + elseif style =~# 'C' || (A[0] >= 2 && s:AlignCtrl =~# '=') " call Decho("style case C: cycle through alignment pattern(s)") let s:AlignCtrl = 'C' if A[0] >= 2 @@ -239,10 +239,9 @@ fun! Align#AlignCtrl(...) let s:AlignPrePad= substitute(style,'^.*p\(\d\+\).*$','\1','') " call Decho("style case p".s:AlignPrePad.": pre-separator padding") if s:AlignPrePad == "" - echoerr "AlignCtrl: 'p' needs to be followed by a numeric argument' - let @/ = keep_search - let &ic= keep_ic -" call Dret("AlignCtrl") + echoerr "(AlignCtrl) 'p' needs to be followed by a numeric argument'" + call s:RestoreUserOptions() +" call Dret("Align#AlignCtrl") return endif endif @@ -251,10 +250,9 @@ fun! Align#AlignCtrl(...) let s:AlignPostPad= substitute(style,'^.*P\(\d\+\).*$','\1','') " call Decho("style case P".s:AlignPostPad.": post-separator padding") if s:AlignPostPad == "" - echoerr "AlignCtrl: 'P' needs to be followed by a numeric argument' - let @/ = keep_search - let &ic= keep_ic -" call Dret("AlignCtrl") + echoerr "(AlignCtrl) 'P' needs to be followed by a numeric argument'" + call s:RestoreUserOptions() +" call Dret("Align#AlignCtrl") return endif endif @@ -263,10 +261,10 @@ fun! Align#AlignCtrl(...) " call Decho("style case w: ignore leading whitespace") let s:AlignLeadKeep= 'w' elseif style =~# 'W' -" call Decho("style case w: keep leading whitespace") +" call Decho("style case W: keep leading whitespace") let s:AlignLeadKeep= 'W' elseif style =~# 'I' -" call Decho("style case w: retain initial leading whitespace") +" call Decho("style case I: retain initial leading whitespace") let s:AlignLeadKeep= 'I' endif @@ -274,8 +272,8 @@ fun! Align#AlignCtrl(...) " first list item is a "g" selector pattern " call Decho("style case g: global selector pattern") if A[0] < 2 - if exists("s:AlignGPat") - unlet s:AlignGPat + if exists("s:AlignVPat") + unlet s:AlignVPat " call Decho("unlet s:AlignGPat") endif else @@ -286,8 +284,8 @@ fun! Align#AlignCtrl(...) " first list item is a "v" selector pattern " call Decho("style case v: global selector anti-pattern") if A[0] < 2 - if exists("s:AlignVPat") - unlet s:AlignVPat + if exists("s:AlignGPat") + unlet s:AlignGPat " call Decho("unlet s:AlignVPat") endif else @@ -297,9 +295,9 @@ fun! Align#AlignCtrl(...) endif "[-lrc+:] : set up s:AlignStyle - if style =~# '[-lrc+:]' + if style =~# '[-lrc+:*]' " call Decho("style case [-lrc+:]: field justification") - let s:AlignStyle= substitute(style,'[^-lrc:+]','','g') + let s:AlignStyle= substitute(style,'[^-lrc:+*]','','g') " call Decho("AlignStyle<".s:AlignStyle.">") endif @@ -316,11 +314,9 @@ fun! Align#AlignCtrl(...) let s:AlignCtrl= '=' endif - " restore search and options - let @/ = keep_search - let &ic= keep_ic - -" call Dret("AlignCtrl ".s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle) + " restore options and return + call s:RestoreUserOptions() +" call Dret("Align#AlignCtrl ".s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle) return s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle endfun @@ -355,6 +351,9 @@ fun! Align#Align(hasctrl,...) range return endif + " save user options + call s:SaveUserOptions() + " set up a list akin to an argument list if a:0 > 0 let A= s:QArgSplitter(a:1) @@ -384,7 +383,8 @@ fun! Align#Align(hasctrl,...) range let ipat= 1 + hasctrl while ipat <= A[0] if "" =~ A[ipat] - echoerr "Align: separator<".A[ipat]."> matches zero-length string" + echoerr "(Align) separator<".A[ipat]."> matches zero-length string" + call s:RestoreUserOptions() " call Dret("Align#Align") return endif @@ -392,10 +392,8 @@ fun! Align#Align(hasctrl,...) range endwhile " record current search pattern for subsequent restoration - let keep_search= @/ - let keep_ic = &ic - let keep_report= &report - set noic report=10000 + " (these are all global-only options) + set noic report=10000 nohls if A[0] > hasctrl " Align will accept a list of separator regexps @@ -447,17 +445,32 @@ fun! Align#Align(hasctrl,...) range let begline = a:lastline let endline = a:firstline endif + + " Expand range to cover align-able lines when the given range is only the current line. + " Look for the first line above the current line that matches the first separator pattern, and + " look for the last line below the current line that matches the first separator pattern. + if begline == endline +" call Decho("case begline == endline") + if !exists("s:AlignPat_{1}") + echohl Error|echo "(Align) no separators specified!"|echohl None + call s:RestoreUserOptions() +" call Dret("Align#Align") + return + endif + let seppat = s:AlignPat_{1} + let begline= search('^\%(\%('.seppat.'\)\@!.\)*$',"bnW") + if begline == 0|let begline= 1|else|let begline= begline + 1|endif + let endline= search('^\%(\%('.seppat.'\)\@!.\)*$',"nW") + if endline == 0|let endline= line("$")|else|let endline= endline - 1|endif +" call Decho("begline=".begline." endline=".endline." curline#".line(".")) + endif " call Decho("begline=".begline." endline=".endline) let fieldcnt = 0 if (begline == line("'>") && endline == line("'<")) || (begline == line("'<") && endline == line("'>")) let vmode= visualmode() " call Decho("vmode=".vmode) if vmode == "\" - if exists("g:Align_xstrlen") && g:Align_xstrlen - let ragged = ( col("'>") > s:Strlen(getline("'>")) || col("'<") > s:Strlen(getline("'<")) ) - else - let ragged = ( col("'>") > strlen(getline("'>")) || col("'<") > strlen(getline("'<")) ) - endif + let ragged = ( col("'>") > s:Strlen(getline("'>")) || col("'<") > s:Strlen(getline("'<")) ) else let ragged= 1 endif @@ -469,10 +482,14 @@ fun! Align#Align(hasctrl,...) range endif " call Decho("lines[".begline.",".endline."] col[".begcol.",".endcol."] ragged=".ragged." AlignCtrl<".s:AlignCtrl.">") - " Keep user options - let etkeep = &l:et - let pastekeep= &l:paste - setlocal et paste + " record initial whitespace + if s:AlignLeadKeep == 'W' + let wskeep = map(getline(begline,endline),"substitute(v:val,'^\\(\\s*\\).\\{-}$','\\1','')") + endif + + " Align needs these options + setl et + set paste " convert selected range of lines to use spaces instead of tabs " but if first line's initial white spaces are to be retained @@ -480,11 +497,30 @@ fun! Align#Align(hasctrl,...) range if begcol <= 0 && s:AlignLeadKeep == 'I' " retain first leading whitespace for all subsequent lines let bgntxt= substitute(getline(begline),'^\(\s*\).\{-}$','\1','') + + " exception: retain first leading whitespace predicated on g and v patterns + " if such a selected line exists + if exists("s:AlignGPat") + let firstgline= search(s:AlignGPat,"cnW",endline) + if firstgline > 0 + let bgntxt= substitute(getline(firstgline),'^\(\s*\).\{-}$','\1','') + endif + elseif exists("s:AlignVPat") + let firstvline= search(s:AlignVPat,"cnW",endline) + if firstvline > 0 + let bgntxt= substitute('^\%(\%('.getline(firstvline).')\@!\)*$','^\(\s*\).\{-}$','\1','') + endif + endif " call Decho("retaining 1st leading whitespace: bgntxt<".bgntxt.">") - set noet + let &l:et= s:keep_et endif exe begline.",".endline."ret" + " record transformed to spaces leading whitespace + if s:AlignLeadKeep == 'W' + let wsblanks = map(getline(begline,endline),"substitute(v:val,'^\\(\\s*\\).\\{-}$','\\1','')") + endif + " Execute two passes " First pass: collect alignment data (max field sizes) " Second pass: perform alignment @@ -528,11 +564,7 @@ fun! Align#Align(hasctrl,...) range endif " Extract visual-block selected text (init bgntxt, endtxt) - if exists("g:Align_xstrlen") && g:Align_xstrlen let txtlen= s:Strlen(txt) - else - let txtlen= strlen(txt) - endif if begcol > 0 " Record text to left of selected area let bgntxt= strpart(txt,0,begcol) @@ -557,7 +589,8 @@ fun! Align#Align(hasctrl,...) range " call Decho("Pass".pass.": txt<". txt .">") " call Decho("Pass".pass.": endtxt<".endtxt.">") if !exists("s:AlignPat_{1}") - echohl Error|echo "no separators specified!"|echohl None + echohl Error|echo "(Align) no separators specified!"|echohl None + call s:RestoreUserOptions() " call Dret("Align#Align") return endif @@ -575,7 +608,7 @@ fun! Align#Align(hasctrl,...) range let alignpostpad= s:AlignPostPad let alignsep = s:AlignSep let alignophold = " " - let alignop = "l" + let alignop = 'l' " call Decho("Pass".pass.": initial alignstyle<".alignstyle."> seppat<".seppat.">") " Process each field on the line @@ -606,23 +639,41 @@ fun! Align#Align(hasctrl,...) range endif endif - " cylic separator alignment specification handling + " cyclic separator alignment specification handling let alignsepop= strpart(alignsep,0,1) let alignsep = strpart(alignsep,1).alignsepop + " ------------------------------------------------------ " mark end-of-field and the subsequent end-of-separator. - " Extend field if alignop is '-' + " ------------------------------------------------------ let endfield = match(txt,seppat,bgnfield) let sepfield = matchend(txt,seppat,bgnfield) let skipfield= sepfield -" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield) +" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield." alignop=".alignop) + + " Mark eof: Extend field if alignop is '*' and AlignSkip() is true. + if alignop == '*' && exists("g:AlignSkip") && type(g:AlignSkip) == 2 +" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield." alignop=".alignop) + " a '*' acts like a '-' while the g:AlignSkip function reference is true except that alignop doesn't advance + while g:AlignSkip(line,endfield) && endfield != -1 + let endfield = match(txt,seppat,skipfield) + let sepfield = matchend(txt,seppat,skipfield) + let skipfield = sepfield +" call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">") + endwhile + let alignop = strpart(alignstyle,0,1) + let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1) +" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield." alignop=".alignop." (after *)") + endif + + " Mark eof: Extend field if alignop is '-' while alignop == '-' && endfield != -1 let endfield = match(txt,seppat,skipfield) let sepfield = matchend(txt,seppat,skipfield) let skipfield = sepfield let alignop = strpart(alignstyle,0,1) let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1) -" call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">") +" call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">") endwhile let seplen= sepfield - endfield " call Decho("Pass".pass.": seplen=[sepfield=".sepfield."] - [endfield=".endfield."]=".seplen) @@ -637,11 +688,7 @@ fun! Align#Align(hasctrl,...) range let field = bgntxt.field let bgntxt= "" endif - if exists("g:Align_xstrlen") && g:Align_xstrlen - let fieldlen = s:Strlen(field) - else - let fieldlen = strlen(field) - endif + let fieldlen = s:Strlen(field) let sFieldSize = "FieldSize_".ifield if !exists(sFieldSize) let FieldSize_{ifield}= fieldlen @@ -675,11 +722,7 @@ fun! Align#Align(hasctrl,...) range let prepad = 0 let postpad= 0 endif - if exists("g:Align_xstrlen") && g:Align_xstrlen - let fieldlen = s:Strlen(field) - else - let fieldlen = strlen(field) - endif + let fieldlen = s:Strlen(field) let sep = s:MakeSpace(prepad).strpart(txt,endfield,sepfield-endfield).s:MakeSpace(postpad) if seplen < SepSize_{ifield} if alignsepop == "<" @@ -695,7 +738,7 @@ fun! Align#Align(hasctrl,...) range let sep = s:MakeSpace(sepleft).sep.s:MakeSpace(sepright) endif endif - let spaces = FieldSize_{ifield} - fieldlen + let spaces = FieldSize_{ifield} - fieldlen " call Decho("Pass".pass.": Field #".ifield."<".field."> spaces=".spaces." be[".bgnfield.",".endfield."] pad=".prepad.','.postpad." FS_".ifield."<".FieldSize_{ifield}."> sep<".sep."> ragged=".ragged." doend=".doend." alignop<".alignop.">") " Perform alignment according to alignment style justification @@ -746,7 +789,7 @@ fun! Align#Align(hasctrl,...) range " call Decho("Pass".pass.": bgntxt<".bgntxt."> line=".line) " call Decho("Pass".pass.": newtxt<".newtxt.">") " call Decho("Pass".pass.": endtxt<".endtxt.">") - call setline(line,bgntxt.newtxt.endtxt) + keepj call setline(line,bgntxt.newtxt.endtxt) endif let line = line + 1 @@ -756,9 +799,18 @@ fun! Align#Align(hasctrl,...) range endwhile " pass loop " call Decho("end of two pass loop") - " Restore user options - let &l:et = etkeep - let &l:paste = pastekeep + " restore original leading whitespace + if s:AlignLeadKeep == 'W' + let iline= begline + let i = 0 +" call Decho("restore original leading whitespace") + while iline <= endline +" call Decho("exe ".iline."s/^".wsblanks[i]."/".wskeep[i]."/") + exe "keepj ".iline."s/^".wsblanks[i]."/".wskeep[i]."/" + let iline= iline + 1 + let i = i + 1 + endwhile + endif if exists("s:DoAlignPop") " AlignCtrl Map support @@ -766,11 +818,8 @@ fun! Align#Align(hasctrl,...) range unlet s:DoAlignPop endif - " restore current search pattern - let @/ = keep_search - let &ic = keep_ic - let &report = keep_report - + " restore user options and return + call s:RestoreUserOptions() " call Dret("Align#Align") return endfun @@ -778,7 +827,7 @@ endfun " --------------------------------------------------------------------- " Align#AlignPush: this command/function pushes an alignment control string onto a stack {{{1 fun! Align#AlignPush() -" call Dfunc("AlignPush()") +" call Dfunc("Align#AlignPush()") " initialize the stack if !exists("s:AlignCtrlStackQty") @@ -806,7 +855,7 @@ fun! Align#AlignPush() let s:AlignVPat_{s:AlignCtrlStackQty}= "" endif -" call Dret("AlignPush") +" call Dret("Align#AlignPush") endfun " --------------------------------------------------------------------- @@ -817,13 +866,13 @@ fun! Align#AlignPop() " sanity checks if !exists("s:AlignCtrlStackQty") - echoerr "AlignPush needs to be used prior to AlignPop" + echoerr "(AlignPop) AlignPush needs to be used prior to AlignPop" " call Dret("Align#AlignPop <> : AlignPush needs to have been called first") return "" endif if s:AlignCtrlStackQty <= 0 unlet s:AlignCtrlStackQty - echoerr "AlignPush needs to be used prior to AlignPop" + echoerr "(AlignPop) AlignPush needs to be used prior to AlignPop" " call Dret("Align#AlignPop <> : AlignPop needs to have been called first") return "" endif @@ -857,15 +906,11 @@ endfun " --------------------------------------------------------------------- " Align#AlignReplaceQuotedSpaces: {{{1 -fun! Align#AlignReplaceQuotedSpaces() -" call Dfunc("AlignReplaceQuotedSpaces()") +fun! Align#AlignReplaceQuotedSpaces() +" call Dfunc("Align#AlignReplaceQuotedSpaces()") let l:line = getline(line(".")) - if exists("g:Align_xstrlen") && g:Align_xstrlen - let l:linelen = s:Strlen(l:line) - else - let l:linelen = strlen(l:line) - endif + let l:linelen = s:Strlen(l:line) let l:startingPos = 0 let l:startQuotePos = 0 let l:endQuotePos = 0 @@ -875,28 +920,28 @@ fun! Align#AlignReplaceQuotedSpaces() " "call Decho("in replace spaces. line=" . line('.')) while (1) let l:startQuotePos = match(l:line, l:quoteRe, l:startingPos) - if (l:startQuotePos < 0) -" "call Decho("No more quotes to the end of line") - break + if (l:startQuotePos < 0) +" call Decho("No more quotes to the end of line") + break endif let l:endQuotePos = match(l:line, l:quoteRe, l:startQuotePos + 1) if (l:endQuotePos < 0) -" "call Decho("Mismatched quotes") - break +" call Decho("Mismatched quotes") + break endif let l:spaceReplaceRe = '^.\{' . (l:startQuotePos + 1) . '}.\{-}\zs\s\ze.*.\{' . (linelen - l:endQuotePos) . '}$' -" "call Decho('spaceReplaceRe="' . l:spaceReplaceRe . '"') +" call Decho('spaceReplaceRe="' . l:spaceReplaceRe . '"') let l:newStr = substitute(l:line, l:spaceReplaceRe, '%', '') while (l:newStr != l:line) -" "call Decho('newstr="' . l:newStr . '"') +" call Decho('newstr="' . l:newStr . '"') let l:line = l:newStr let l:newStr = substitute(l:line, l:spaceReplaceRe, '%', '') endwhile let l:startingPos = l:endQuotePos + 1 endwhile - call setline(line('.'), l:line) + keepj call setline(line('.'), l:line) -" call Dret("AlignReplaceQuotedSpaces") +" call Dret("Align#AlignReplaceQuotedSpaces") endfun " --------------------------------------------------------------------- @@ -923,19 +968,20 @@ fun! s:QArgSplitter(qarg) while args != "" let iarg = 0 let arglen = strlen(args) -" call Decho("args[".iarg."]<".args[iarg]."> arglen=".arglen) +" call Decho(".args[".iarg."]<".args[iarg]."> arglen=".arglen) " find index to first not-escaped '"' +" call Decho("find index to first not-escaped \"") while args[iarg] != '"' && iarg < arglen if args[iarg] == '\' let args= strpart(args,1) endif let iarg= iarg + 1 endwhile -" call Decho("args<".args."> iarg=".iarg." arglen=".arglen) +" call Decho(".args<".args."> iarg=".iarg." arglen=".arglen) if iarg > 0 " handle left of quote or remaining section -" call Decho("handle left of quote or remaining section") +" call Decho(".handle left of quote or remaining section") if args[iarg] == '"' let qarglist= qarglist + split(strpart(args,0,iarg-1)) else @@ -946,7 +992,7 @@ fun! s:QArgSplitter(qarg) elseif iarg < arglen && args[0] == '"' " handle "quoted" section -" call Decho("handle quoted section") +" call Decho(".handle quoted section") let iarg= 1 while args[iarg] != '"' && iarg < arglen if args[iarg] == '\' @@ -954,7 +1000,7 @@ fun! s:QArgSplitter(qarg) endif let iarg= iarg + 1 endwhile -" call Decho("args<".args."> iarg=".iarg." arglen=".arglen) +" call Decho(".args<".args."> iarg=".iarg." arglen=".arglen) if args[iarg] == '"' call add(qarglist,strpart(args,1,iarg-1)) let args= strpart(args,iarg+1) @@ -963,12 +1009,14 @@ fun! s:QArgSplitter(qarg) let args = "" endif endif -" call Decho("qarglist".string(qarglist)." iarg=".iarg." args<".args.">") +" call Decho(".qarglist".string(qarglist)." iarg=".iarg." args<".args.">") endwhile +" call Decho("end of loop (handling quoted arguments)") else " split at all whitespace - let qarglist= split(a:qarg) +" call Decho("split at all whitespace") + let qarglist= split(a:qarg,"[ \t]") endif let qarglistlen= len(qarglist) @@ -984,26 +1032,26 @@ endfun " nonzero value. Solution from Nicolai Weibull, vim docs " (:help strlen()), Tony Mechelynck, and my own invention. fun! s:Strlen(x) - " lilydjwg: vim7.3 有 strwidth 函数 - if exists('*strwidth') - return strwidth(a:x) - endif +" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen) -" call Dfunc("s:Strlen(x<".a:x.">") - if g:Align_xstrlen == 1 + if type(g:Align_xstrlen) == 1 + " allow user to specify a function to compute the string length + exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')" + + elseif g:Align_xstrlen == 1 " number of codepoints (Latin a + combining circumflex is two codepoints) " (comment from TM, solution from NW) let ret= strlen(substitute(a:x,'.','c','g')) elseif g:Align_xstrlen == 2 - " number of spacing codepoints (Latin a + combining circumflex is one spacing + " number of spacing codepoints (Latin a + combining circumflex is one spacing " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.) " (comment from TM, solution from TM) - let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) + let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) elseif g:Align_xstrlen == 3 - " virtual length (counting, for instance, tabs as anything between 1 and - " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately + " virtual length (counting, for instance, tabs as anything between 1 and + " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately " preceded by lam, one otherwise, etc.) " (comment from TM, solution from me) let modkeep= &l:mod @@ -1011,18 +1059,62 @@ fun! s:Strlen(x) call setline(line("."),a:x) let ret= virtcol("$") - 1 d - " lilydjwg: 这样才不会让光标乱跑 - normal k let &l:mod= modkeep else " at least give a decent default - ret= strlen(a:x) + if v:version >= 703 + let ret= strdisplaywidth(a:x) + else + let ret= strlen(a:x) + endif endif " call Dret("s:Strlen ".ret) return ret endfun +" --------------------------------------------------------------------- +" s:SaveUserOptions: {{{1 +fun! s:SaveUserOptions() +" call Dfunc("s:SaveUserOptions() s:saved_user_options=".(exists("s:saved_user_options")? s:saved_user_options : 'n/a')) + if !exists("s:saved_user_options") + let s:saved_user_options = 1 + let s:keep_search = @/ + let s:keep_et = &l:et + let s:keep_hls = &hls + let s:keep_ic = &ic + let s:keep_paste = &paste + let s:keep_report = &report + else + let s:saved_user_options = s:saved_user_options + 1 + endif +" call Dret("s:SaveUserOptions : s:saved_user_options=".s:saved_user_options) +endfun + +" --------------------------------------------------------------------- +" s:RestoreUserOptions: {{{1 +fun! s:RestoreUserOptions() +" call Dfunc("s:RestoreUserOptions() s:saved_user_options=".(exists("s:saved_user_options")? s:saved_user_options : 'n/a')) + if exists("s:saved_user_options") && s:saved_user_options == 1 + let @/ = s:keep_search + let &l:et = s:keep_et + let &hls = s:keep_hls + let &ic = s:keep_ic + let &paste = s:keep_paste + let &report = s:keep_report + unlet s:keep_search + unlet s:keep_et + unlet s:keep_hls + unlet s:keep_ic + unlet s:keep_paste + unlet s:keep_report + unlet s:saved_user_options + elseif exists("s:saved_user_options") + let s:saved_user_options= s:saved_user_options - 1 + endif +" call Dret("s:RestoreUserOptions : s:saved_user_options=".(exists("s:saved_user_options")? s:saved_user_options : 'n/a')) +endfun + " --------------------------------------------------------------------- " Set up default values: {{{1 "call Decho("-- Begin AlignCtrl Initialization --") diff --git a/autoload/AlignMaps.vim b/autoload/AlignMaps.vim index ace2de8e..9b0f3bc1 100644 --- a/autoload/AlignMaps.vim +++ b/autoload/AlignMaps.vim @@ -1,15 +1,25 @@ " AlignMaps.vim : support functions for AlignMaps " Author: Charles E. Campbell, Jr. -" Date: Mar 03, 2009 -" Version: 41 +" Date: Jun 18, 2012 +" Version: 42 +" Copyright: Copyright (C) 1999-2012 Charles E. Campbell, Jr. {{{1 +" Permission is hereby granted to use and distribute this code, +" with or without modifications, provided that this copyright +" notice is copied with it. Like anything else that's free, +" Align.vim is provided *as is* and comes with no warranty +" of any kind, either expressed or implied. By using this +" plugin, you agree that in no event will the copyright +" holder be liable for any damages resulting from the use +"redraw!|call DechoSep()|call inputsave()|call input("Press to continue")|call inputrestore() " --------------------------------------------------------------------- " Load Once: {{{1 if &cp || exists("g:loaded_AlignMaps") finish endif -let g:loaded_AlignMaps= "v41" +let g:loaded_AlignMaps= "v42" let s:keepcpo = &cpo set cpo&vim +"DechoTabOn " ===================================================================== " Functions: {{{1 @@ -20,7 +30,7 @@ fun! AlignMaps#WrapperStart(vis) range " call Dfunc("AlignMaps#WrapperStart(vis=".a:vis.")") if a:vis - norm! ' + keepj norm! ' endif if line("'y") == 0 || line("'z") == 0 || !exists("s:alignmaps_wrapcnt") || s:alignmaps_wrapcnt <= 0 @@ -34,22 +44,22 @@ fun! AlignMaps#WrapperStart(vis) range let s:alignmaps_posn = SaveWinPosn(0) " set up fencepost blank lines put ='' - norm! mz'a + keepj norm! mz'a put! ='' ky let s:alignmaps_zline = line("'z") - exe "'y,'zs/@/\177/ge" + exe "keepj 'y,'zs/@/\177/ge" else " call Decho("embedded wrapper") let s:alignmaps_wrapcnt = s:alignmaps_wrapcnt + 1 - norm! 'yjma'zk + keepj norm! 'yjma'zk endif " change some settings to align-standard values set nogd set ch=2 AlignPush - norm! 'zk + keepj norm! 'zk " call Dret("AlignMaps#WrapperStart : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z")) endfun @@ -59,7 +69,7 @@ fun! AlignMaps#WrapperEnd() range " call Dfunc("AlignMaps#WrapperEnd() alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z")) " remove trailing white space introduced by whatever in the modification zone - 'y,'zs/ \+$//e + keepj 'y,'zs/ \+$//e " restore AlignCtrl settings AlignPop @@ -67,14 +77,14 @@ fun! AlignMaps#WrapperEnd() range let s:alignmaps_wrapcnt= s:alignmaps_wrapcnt - 1 if s:alignmaps_wrapcnt <= 0 " initial wrapper ending - exe "'y,'zs/\177/@/ge" + exe "keepj 'y,'zs/\177/@/ge" " if the 'z line hasn't moved, then go ahead and restore window position let zstationary= s:alignmaps_zline == line("'z") " remove fencepost blank lines. " restore 'a - norm! 'yjmakdd'zdd + keepj norm! 'yjmakdd'zdd " restore original 'y, 'z, and window positioning call RestoreMark(s:alignmaps_keepmy) @@ -135,10 +145,10 @@ fun! AlignMaps#CharJoiner(chr) let aline = line("'a") let rep = line(".") - aline while rep > 0 - norm! 'a + keepj norm! 'a while match(getline(aline),a:chr . "\s*$") != -1 && rep >= 0 " while = at end-of-line, delete it and join with next - norm! 'a$ + keepj norm! 'a$ j! let rep = rep - 1 endwhile @@ -149,7 +159,7 @@ fun! AlignMaps#CharJoiner(chr) break endif " prepare for next line - norm! jma + keepj norm! jma let aline = line("'a") endwhile " call Dret("AlignMaps#CharJoiner") @@ -159,31 +169,32 @@ endfun " AlignMaps#Equals: supports \t= and \T= {{{2 fun! AlignMaps#Equals() range " call Dfunc("AlignMaps#Equals()") - 'a,'zs/\s\+\([*/+\-%|&\~^]\==\)/ \1/e - 'a,'zs@ \+\([*/+\-%|&\~^]\)=@\1=@ge - 'a,'zs/==/\="\\"/ge - 'a,'zs/\([!<>:]\)=/\=submatch(1)."\"/ge - norm g'zk + keepj 'a,'zs/\s\+\([*/+\-%|&\~^]\==\)/ \1/e + keepj 'a,'zs@ \+\([*/+\-%|&\~^]\)=@\1=@ge + keepj 'a,'zs/==/\="\\"/ge + keepj 'a,'zs/\([!<>:]\)=/\=submatch(1)."\"/ge + keepj norm g'zk AlignCtrl mIp1P1=l = AlignCtrl g = - 'a,'z-1Align - 'a,'z-1s@\([*/+\-%|&\~^!=]\)\( \+\)=@\2\1=@ge - 'a,'z-1s/\( \+\);/;\1/ge + keepj 'a,'z-1Align + keepj 'a,'z-1s@\([*/%|&\~^!=]\)\( \+\)=@\2\1=@ge + keepj 'a,'z-1s@[^+\-]\zs\([+\-]\)\( \+\)=@\2\1=@ge + keepj 'a,'z-1s/\( \+\);/;\1/ge if &ft == "c" || &ft == "cpp" " call Decho("exception for ".&ft) - 'a,'z-1v/^\s*\/[*/]/s/\/[*/]/@&@/e - 'a,'z-1v/^\s*\/[*/]/s/\*\//@&/e + keepj 'a,'z-1v/^\s*\/[*/]/s/\/[*/]/@&@/e + keepj 'a,'z-1v/^\s*\/[*/]/s/\*\//@&/e if exists("g:mapleader") - exe "norm 'zk" + exe "keepj norm 'zk" call AlignMaps#StdAlign(1) else - exe "norm 'zk" + exe "keepj norm 'zk" call AlignMaps#StdAlign(1) endif - 'y,'zs/^\(\s*\) @/\1/e + keepj 'y,'zs/^\(\s*\) @/\1/e endif - 'a,'z-1s/\%x0f/=/ge - 'y,'zs/ @//eg + keepj 'a,'z-1s/\%x0f/=/ge + keepj 'y,'zs/ @//eg " call Dret("AlignMaps#Equals") endfun @@ -194,10 +205,11 @@ fun! AlignMaps#Afnc() " call Dfunc("AlignMaps#Afnc()") " keep display quiet - let chkeep = &ch - let gdkeep = &gd - let vekeep = &ve - set ch=2 nogd ve= + let chkeep = &l:ch + let gdkeep = &l:gd + let wwkeep = &l:ww + let vekeep = &l:ve + setlocal ch=2 nogd ve= ww=b,s,<,>,[,] " will use marks y,z ; save current values let mykeep = SaveMark("'y") @@ -206,7 +218,7 @@ fun! AlignMaps#Afnc() " Find beginning of function -- be careful to skip over comments let cmmntid = synIDtrans(hlID("Comment")) let stringid = synIDtrans(hlID("String")) - exe "norm! ]]" + exe "keepj norm! ]]" while search(")","bW") != 0 " call Decho("line=".line(".")." col=".col(".")) let parenid= synIDtrans(synID(line("."),col("."),1)) @@ -214,23 +226,23 @@ fun! AlignMaps#Afnc() break endif endwhile - norm! %my - s/(\s*\(\S\)/(\r \1/e - exe "norm! `y%" - s/)\s*\(\/[*/]\)/)\r\1/e - exe "norm! `y%mz" - 'y,'zs/\s\+$//e - 'y,'zs/^\s\+//e - 'y+1,'zs/^/ / + keepj norm! %my + keepj s/(\s*\(\S\)/(\r \1/e + exe "keepj norm! `y%" + keepj s/)\s*\(\/[*/]\)/)\r\1/e + exe "keepj norm! `y%mz" + keepj 'y,'zs/\s\+$//e + keepj 'y,'zs/^\s\+//e + keepj 'y+1,'zs/^/ / " insert newline after every comma only one parenthesis deep - sil! exe "norm! `y\h" + exe "sil! keepj norm! `y\h" let parens = 1 let cmmnt = 0 let cmmntline= -1 while parens >= 1 -" call Decho("parens=".parens." @a=".@a) - exe 'norm! ma "ay`a ' + exe 'keepj norm! ma "ay`a ' +" call Decho("parens=".parens." cmmnt=".cmmnt." cmmntline=".cmmntline." line(.)=".line(".")." @a<".@a."> line<".getline(".").">") if @a == "(" let parens= parens + 1 elseif @a == ")" @@ -261,41 +273,42 @@ fun! AlignMaps#Afnc() endif elseif @a == "," && parens == 1 && cmmnt == 0 - exe "norm! i\\" + exe "keepj norm! i\\" endif endwhile - norm! `y%mz% - sil! 'y,'zg/^\s*$/d + sil! keepj norm! `y%mz% + sil! keepj 'y,'zg/^\s*$/d " perform substitutes to mark fields for Align - sil! 'y+1,'zv/^\//s/^\s\+\(\S\)/ \1/e - sil! 'y+1,'zv/^\//s/\(\S\)\s\+/\1 /eg - sil! 'y+1,'zv/^\//s/\* \+/*/ge - sil! 'y+1,'zv/^\//s/\w\zs\s*\*/ */ge + sil! keepj 'y+1,'zv/^\//s/^\s\+\(\S\)/ \1/e + sil! keepj 'y+1,'zv/^\//s/\(\S\)\s\+/\1 /eg + sil! keepj 'y+1,'zv/^\//s/\* \+/*/ge + sil! keepj 'y+1,'zv/^\//s/\w\zs\s*\*/ */ge " func " ws <- declaration -> <-ptr -> <-var-> <-[array][] -> <-glop-> <-end-> - sil! 'y+1,'zv/^\//s/^\s*\(\(\K\k*\s*\)\+\)\s\+\([(*]*\)\s*\(\K\k*\)\s*\(\(\[.\{-}]\)*\)\s*\(.\{-}\)\=\s*\([,)]\)\s*$/ \1@#\3@\4\5@\7\8/e - sil! 'y+1,'z+1g/^\s*\/[*/]/norm! kJ - sil! 'y+1,'z+1s%/[*/]%@&@%ge - sil! 'y+1,'z+1s%*/%@&%ge + sil! keepj 'y+1,'zv/^\//s/^\s*\(\(\K\k*\s*\)\+\)\s\+\([(*]*\)\s*\(\K\k*\)\s*\(\(\[.\{-}]\)*\)\s*\(.\{-}\)\=\s*\([,)]\)\s*$/ \1@#\3@\4\5@\7\8/e + sil! keepj 'y+1,'z+1g/^\s*\/[*/]/norm! kJ + sil! keepj 'y+1,'z+1s%/[*/]%@&@%ge + sil! keepj 'y+1,'z+1s%*/%@&%ge AlignCtrl mIp0P0=l @ - sil! 'y+1,'zAlign - sil! 'y,'zs%@\(/[*/]\)@%\t\1 %e - sil! 'y,'zs%@\*/% */%e - sil! 'y,'zs/@\([,)]\)/\1/ - sil! 'y,'zs/@/ / + sil! keepj 'y+1,'zAlign + sil! keepj 'y,'zs%@\(/[*/]\)@%\t\1 %e + sil! keepj 'y,'zs%@\*/% */%e + sil! keepj 'y,'zs/@\([,)]\)/\1/ + sil! keepj 'y,'zs/@/ / AlignCtrl mIlrp0P0= # @ - sil! 'y+1,'zAlign - sil! 'y+1,'zs/#/ / - sil! 'y+1,'zs/@// - sil! 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e + sil! keepj 'y+1,'zAlign + sil! keepj 'y+1,'zs/#/ / + sil! keepj 'y+1,'zs/@// + sil! keepj 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e " Restore call RestoreMark(mykeep) call RestoreMark(mzkeep) - let &ch= chkeep - let &gd= gdkeep - let &ve= vekeep + let &l:ch= chkeep + let &l:gd= gdkeep + let &l:ww= wwkeep + let &l:ve= vekeep " call Dret("AlignMaps#Afnc") endfun @@ -310,12 +323,42 @@ fun! AlignMaps#FixMultiDec() let curline = getline(".") " call Decho("curline<".curline.">") +" " Attempt to ignore function calls (ie. double x=pow(2.,3.),... +" let leader= substitute(curline,'^\s*\([a-zA-Z_ \t][a-zA-Z0-9<>_ \t]*\)\s\+.*$','\1','') +" let i = strlen(leader) +" let paren = 0 +" let fmd = strpart(curline,i) +" let ifmd = i +" call Decho("fmd<".fmd."> ifmd=".ifmd) +" while i < strlen(curline) +" if strpart(curline,i,1) == '(' +" let paren= paren+1 +" elseif strpart(curline,i,1) == ')' && paren > 0 +" let paren= paren-1 +" elseif strpart(curline,i,1) == '=' +" let eq= 1 +" elseif strpart(curline,i,1) == ';' +" let paren = 0 +" let eq = 0 +" let fmd = fmd.strpart(fmd,ifmd,i-ifmd).";\" +" let ifmd = i + 2 +" let i = i + 1 +" let leader= substitute(curline,'^\s*\([a-zA-Z_ \t][a-zA-Z0-9<>_ \t]*\)\s\+.*$','\1','') +" elseif strpart(curline,i,1) == ',' +" if paren == 0 +" let fmd = fmd.strpart(fmd,ifmd,i-ifmd).";\" +" let ifmd = i + 2 +" let i = i + 1 +" endif +" endif +" let i= i + 1 +" endwhile " Get the type. I'm assuming one type per line (ie. int x; double y; on one line will not be handled properly) - let @x=substitute(curline,'^\(\s*[a-zA-Z_ \t][a-zA-Z0-9_ \t]*\)\s\+[(*]*\h.*$','\1','') + let @x=substitute(curline,'^\(\s*[a-zA-Z_ \t][a-zA-Z0-9<>_ \t]*\)\s\+[(*]*\h.*$','\1','') " call Decho("@x<".@x.">") " transform line - exe 's/,/;\r'.@x.' /ge' + exe 'keepj s/,/;\r'.@x.' /ge' "restore register x let @x= xkeep @@ -323,6 +366,26 @@ fun! AlignMaps#FixMultiDec() " call Dret("AlignMaps#FixMultiDec : my=".line("'y")." mz=".line("'z")) endfun +" --------------------------------------------------------------------- +" AlignMaps#AlignMapsClean: this function removes the AlignMaps plugin {{{2 +fun! AlignMaps#AlignMapsClean() +" call Dfunc("AlignMaps#AlignMapsClean()") + for home in split(&rtp,',') + [''] +" call Decho("considering home<".home.">") + if isdirectory(home) + if filereadable(home."/autoload/AlignMaps.vim") +" call Decho("deleting ".home."/autoload/AlignMaps.vim") + call delete(home."/autoload/AlignMaps.vim") + endif + if filereadable(home."/plugin/AlignMapsPlugin.vim") +" call Decho("deleting ".home."/plugin/AlignMapsPlugin.vim") + call delete(home."/plugin/AlignMapsPlugin.vim") + endif + endif + endfor +" call Dret("AlignMaps#AlignMapsClean") +endfun + " --------------------------------------------------------------------- " Restore: {{{1 let &cpo= s:keepcpo diff --git a/doc/Align.txt b/doc/Align.txt index c4473726..b08eca31 100644 --- a/doc/Align.txt +++ b/doc/Align.txt @@ -1,8 +1,8 @@ -*align.txt* The Alignment Tool Mar 04, 2009 +*align.txt* The Alignment Tool Jun 18, 2012 -Author: Charles E. Campbell, Jr. +Author: Charles E. Campbell (remove NOSPAM from Campbell's email first) -Copyright: (c) 2004-2008 by Charles E. Campbell, Jr. *Align-copyright* +Copyright: (c) 2004-2012 by Charles E. Campbell *Align-copyright* The VIM LICENSE applies to Align.vim, AlignMaps.vim, and Align.txt (see |copyright|) except use "Align and AlignMaps" instead of "Vim" NO WARRANTY, EXPRESS OR IMPLIED. USE AT-YOUR-OWN-RISK. @@ -26,6 +26,7 @@ Copyright: (c) 2004-2008 by Charles E. Campbell, Jr. *Align-copyright* Temporary Settings.....: |alignctrl-m| Padding................: |alignctrl-p| |alignctrl-P| Current Options........: |alignctrl-settings| |alignctrl-| + Alignment Control Init...: |alignctrl-init| Alignment................: |align-align| 4. Alignment Maps...........: |align-maps| \a,....................: |alignmap-a,| @@ -91,6 +92,7 @@ Copyright: (c) 2004-2008 by Charles E. Campbell, Jr. *Align-copyright* || | | - skip this separator || || | | + re-use last justification method || || | | : treat rest of text as a field || +|| | | * use AlignSkip() function (to skip or not) || || | | || || | p1 | p### pad separator on left by # blanks || || | P1 | P### pad separator on right by # blanks || @@ -176,12 +178,14 @@ ALIGNMENT CONCEPTS *align-concept* *align-concepts* {{{2 < Note how each "=" sign is surrounded by a single space; the default padding is p1P1 (p1 means one space before the separator, and P1 means one space after it). If you wish to change the - padding, say to no padding, use (see |alignctrl-p|) > + padding, say, to no padding, use (see |alignctrl-p|) > + :AlignCtrl lp0P0 < Next, note how each field is left justified; that's what the "l" - (a small letter "ell") does. If right-justification of the fields - had been desired, an "r" could've been used: > + in the AlignCtrl parameters (a small letter "ell") does. If + right-justification of the fields had been desired, an "r" + could've been used: > :AlignCtrl r < yielding > x = y = z = 3; @@ -196,10 +200,10 @@ ALIGNMENT CONCEPTS *align-concept* *align-concepts* {{{2 justify, right justify, or center them, too (see |alignctrl-<|). Assume that for some reason a left-right-left-right-... justification - sequence was wished. This wish is simply achieved with > + sequence was desired. This wish is simply achieved with > :AlignCtrl lr :1,4Align = -< because the justification commands are considered to be "cylic"; ie. +< because the justification commands are considered to be "cyclic"; ie. lr is the same as lrlrlrlrlrlrlr... There's a lot more discussed under |alignctrl|; hopefully the examples @@ -261,7 +265,7 @@ ALIGNMENT COMMANDS *align-command* *align-commands* {{{2 < Also see |alignctrl-m| for a way to automatically do an AlignPop after an Align (primarily this is for maps). -ALIGNMENT OPTIONS *align-option* *align-options* {{{2 +ALIGNMENT OPTIONS *align-option* *align-options* *align-xstrlen* {{{2 *align-utf8* *align-utf* *align-codepoint* *align-strlen* *align-multibyte* For those of you who are using 2-byte (or more) characters such as are @@ -279,7 +283,7 @@ ALIGNMENT OPTIONS *align-option* *align-options* {{{2 vim compiled without multi-byte support $LANG is en_US.UTF-8 (assuming USA english) - Number of codepoints (Latin a + combining circumflex is two codepoints)~ + Number of codepoints (Latin a + combining circumflex are two codepoints)~ > let g:Align_xstrlen= 1 (default) < @@ -295,13 +299,20 @@ ALIGNMENT OPTIONS *align-option* *align-options* {{{2 > let g:Align_xstrlen= 3 < + User may specify a function to compute the string length~ +> + let g:Align_xstrlen= "strlen" +< This method will cause Align to call upon the named function returning + string length. it should resemble the |strlen()| function, taking one + argument (the string) for input and returning the string length. + By putting one of these settings into your <.vimrc>, Align will use an internal (interpreted) function to determine a string's length instead - of the Vim's built-in |strlen()| function. Since the function is + of Vim's built-in |strlen()| function. Since the function is interpreted, Align will run a bit slower but will handle such strings - correctly. The last setting (g:Align_xstrlen= 3) probably will run - the slowest but be the most accurate. (thanks to Tony Mechelynck for - these) + correctly. The last settings (g:Align_xstrlen= 3 and + g:Align_xstrlen="userfuncname") probably will run the slowest but be + the most accurate. (thanks to Tony Mechelynck for these) ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 @@ -322,7 +333,7 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 < where "ws" stands for "white space" such as blanks and/or tabs. - + SEPARATORS *alignctrl-separators* {{{3 As a result, separators may not have white space (tabs or blanks) on @@ -337,10 +348,11 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 (ie. @), and then perform a substitute to revert the separators back to their desired condition (ie. s/@/ :: /g). - The Align#Align() function will first convert tabs over the region into - spaces and then apply alignment control. Except for initial white - space, white space surrounding the fields is ignored. One has three - options just for handling initial white space: + The Align#Align() function (which is invoked by the :Align command) + will first convert tabs over the region into spaces and then apply + alignment control. Except for initial white space, white space + surrounding the fields is ignored. One has three options just for + handling initial white space: --- *alignctrl-w* @@ -357,9 +369,9 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 +------------------+---------------+-------------------+-----------------+ | Original | w option | W option | I option | +------------------+---------------+-------------------+-----------------+ - | a := baaa |a := baaa | a : = baaa | a := baaa | - | caaaa := deeee |caaaa := deeee | caaaa : = deeee| caaaa := deeee| - | ee := f |ee := f | ee : = f | ee := f | + | a := baaa |a := baaa | a := baaa | a := baaa | + | caaaa := deeee |caaaa := deeee | caaaa := deeee | caaaa := deeee| + | ee := f |ee := f | ee := f | ee := f | +------------------+---------------+-------------------+-----------------+ < The original has at least one leading white space on every line. @@ -397,17 +409,19 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 cycle only consists of one character (the "l"). Every time left-justification is used for fields. AlignCtrl r : The = separator is repeatedly re-used, as the - cycle only consists of one character (the "l"). + cycle only consists of one character (the "r"). Every time right-justification is used for fields AlignCtrl lr: Again, the "=" separator is repeatedly re-used, but the fields are justified alternately between left and right. - Even more separator control is available. With "-+:": + Even more separator control is available! With "-+:": - - : skip treating the separator as a separator. *alignctrl--* - + : repeat use of the last "lrc" justification *alignctrl-+* - : : treat the rest of the line as a single field *alignctrl-:* + - : skip treating the separator as a separator. *alignctrl--* + + : repeat use of the last "lrc" justification *alignctrl-+* + : : treat the rest of the line as a single field *alignctrl-:* + * : like -, but only if g:AlignSkip() returns true *alignctrl-star* + (see |alignctrl-alignskip|) Example: More justification options: Align = > +------------+---------------+--------------------+---------------+ @@ -452,6 +466,35 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 3rd separator only: AlignCtrl --l: etc. + *g:AlignSkip* + Align Skip Control *alignctrl-alignskip* + + The separator control '*' permits a function to decide whether or + not a character which matches the current separator pattern should + instead be skipped. + + 1. Define a function; example: > + + fun! AlignSkipString(lineno,indx) + let synid = synID(a:lineno,a:indx+1,1) + let synname = synIDattr(synIDtrans(synid),"name") + let ret= (synname == "String")? 1 : 0 + return ret + endfun +< + Input: lineno: current line number + indx : index to character; leftmost character + in the line has an indx of 0 (like |strpart()|) + Output: 0 : if separator is ok + 1 : skip separator like it was a '-' + + 2. Set up |g:AlignSkip| as a function reference (see |Funcref|): > + + let g:AlignSkip= function("AlignSkipString") +< + 3. Use * as a separator control where a separator potentially should + be skipped over. + --- *alignctrl-=* =C CYCLIC VS ALL-ACTIVE SEPARATORS *alignctrl-C* {{{3 @@ -465,8 +508,10 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 constructed: > AlignCtrl ... pat1 pat2 pat3 +< becomes > \(pat1\|pat2\|pat3\) -< +< (ie. pat1 -or- pat2 -or- pat3; see |/bar|) + Each separator pattern is thus equivalent and simultaneously active. The cyclic separator AlignCtrl option stores a list of patterns, only one of which is active for each field at a time. @@ -606,12 +651,12 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 |five= 6; |five = 6; |five = 6; | +----------------+------------------+----------------+ < - The first "Align =" aligned with all "="s, including that one in the - "skip=this" comment. + The first "Align =" aligned with all "="s, including the one in the + "/* skip=this */" comment. The second "Align =" had a AlignCtrl v-pattern which caused it to skip - (ignore) the "skip=this" line when aligning. - + (ignore) the "/* skip=this */" line when aligning. + To remove AlignCtrl's g and v patterns, use (as appropriate) > AlignCtrl g @@ -683,7 +728,7 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 AlignCtrl......|alignctrl| qty............|align-concept| - AlignStyle.....|alignctrl--| |alignctrl-+| |alignctrl-:||alignctrl-c| + AlignStyle.....|alignctrl--| |alignctrl-+| |alignctrl-:| |alignctrl-c| Padding........|alignctrl-p| |alignctrl-P| One may get a string which can be fed back into AlignCtrl: > @@ -697,7 +742,19 @@ ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 however: > :let alignctrl= Align#AlignCtrl("d") -< + + +ALIGNMENT CONTROL INITIALIZATION *alignctrl-init* *alignctrl-initialization* {{{2 + + If you'd like to have your own default AlignCtrl, you'll be wanting to + put it in a file such as: > + + $HOME/.vim/after/plugin/AlignPlugin.vim + +< Anything in that file would be sourced at startup, but after your + .vimrc and after $HOME/.vim/plugin/AlignPlugin.vim; hence, :Align + and :AlignCtrl will then be defined. + ALIGNMENT *align-align* {{{2 @@ -758,23 +815,31 @@ ALIGNMENT *align-align* {{{2 ============================================================================== 4. Alignment Maps *alignmaps* *align-maps* {{{1 - There are a number of maps using Align#AlignCtrl() and Align#Align() - in the file. This file may also be put into the - plugins subdirectory. Since AlignCtrl and Align supercede textab and - its file, the maps either have a leading "t" (for - "textab") or the more complicated ones an "a" (for "alignment") for - backwards compatibility. - - The maps are shown below with a leading backslash (\). Actually, the - construct is used (see |mapleader|), so the maps' leading - kick-off character is easily customized. - - Furthermore, all AlignMapsPlugin.vim maps use the construct (see - ||and |usr_41.txt|). Hence, if one wishes to override the - mapping entirely, one may do that, too. As an example: > + There are a number of maps provided in the AlignMaps plugin which + depend upon the Align plugin. The maps provided by AlignMaps + typically start with a leading "t" (for the older "textab" program + which Align supercedes) or with an "a" for the more complicated + alignment maps. + + The AlignMaps plugin, although provided in the vimball containing + Align.vim, is really a separate plugin (Align doesn't depend on + AlignMaps). Consequently, if you'd rather not have AlignMaps's + mappings, just use the *:AlignMapsClean* command to remove its + components. The :AlignMapsClean command does not remove any maps + generated by AlignMaps in the current instance of vim. + + The maps are shown below with a leading backslash (\). However, the + actual maps use the construct (see |mapleader|), so the maps' + leading kick-off character is easily customized. + + Furthermore, all the maps specified by the AlignMaps plugin use the + construct (see ||and |usr_41.txt|). Hence, if one wishes + to override the mapping(s) entirely, one may do that, too. As an + example: > map ACOM AM_acom -< would have \ACOM do what \acom previously did (assuming that the - mapleader has been left at its default value of a backslash). +< would have \ACOM do + what \acom previously did (assuming that the mapleader has been left + at its default value of a backslash). \a, : useful for breaking up comma-separated declarations prior to \adec |alignmap-a,| @@ -831,9 +896,9 @@ ALIGNMENT *align-align* {{{2 character "x" where "x" is: ,:<=@# |alignmap-T=| \m= : like \t= but aligns with %... style comments - The leading backslash is actually (see |mapleader| for how to - customize the leader to be whatever you like). These maps use the - package and are defined in the file. + The leading backslash is actually (see |mapleader| to learn + how to customize the leader to be whatever you like). These maps use + the package and are defined in the file. Although the maps use AlignCtrl options, they typically use the "m" option which pushes the options (AlignPush). The associated Align call which follows will then AlignPop the user's original options @@ -847,6 +912,18 @@ ALIGNMENT *align-align* {{{2 Alternatively, one may select the text with the "V" visual mode command. + If you want to use visual-block mode (ctrl-v), I suggest using + an AlignMap with the vis.vim plugin, available at either + + stable: http://vim.sourceforge.net/scripts/script.php?script_id=1195 + devel : http://mysite.verizon.net/astronaut/vim/index.html#VIS + + Use it with commands such as > + + ctrl-v (move) + :B norm \alignmap_sequence +< + ALIGNMENT MAP USE WITH MENUS~ One may use the mark-and-move style (ma, move, use the menu) or the visual mode style (use the V visual mode, move, then select @@ -862,7 +939,6 @@ ALIGNMENT *align-align* {{{2 must be included). COMPLEX ALIGNMENT MAP METHOD~ - For those complex alignment maps which do alignment on constructs (e.g. \acom, \adec, etc), a series of substitutes is used to insert "@" symbols in appropriate locations. Align#Align() is then used to @@ -934,7 +1010,7 @@ ALIGNMENT *align-align* {{{2 aa:=bb:=cc:=1; a:=b:=c:=1; aaa:=bbb:=ccc:=1; -< +< Bcomes: select the three assignment lines, then \a:= > aa := bb := cc := 1; a := b := c := 1; @@ -981,6 +1057,17 @@ ALIGNMENT *align-align* {{{2 Alignment Map Examples: \anum *alignmap-anum* {{{3 --------------------------- + First, note that the behavior of the \anum map depends on the existence + of either the vim variable > + g:alignmaps_usanumber +< or > + g:alignmaps_euronumber +< when AlignMaps is loaded. + + Essentially, "usa" numbers use "."s and "euro" numbers use ","s to + separate the integer from the fractional portion of a number. + "Usa" numbers are default. + Original: illustrates how to get numbers lined up > -1.234 .5678 -.901e-4 1.234 5.678 9.01e-4 @@ -1012,7 +1099,8 @@ ALIGNMENT *align-align* {{{2 12,34 56,78 90,1e-4 123,4 567,8 901,e-4 < - Becomes: Go to first line, ma. Go to last line, press \anum > + Becomes: (assuming g:alignmaps_euronumber exists) + Go to first line, ma. Go to last line, press \anum > -1,234 ,5678 -,901e-4 1,234 5,678 9,01e-4 12,34 56,78 90,1e-4 @@ -1022,9 +1110,10 @@ ALIGNMENT *align-align* {{{2 \aenum is provided to support European-style numbers \aunum is provided to support USA-style numbers - One may get \aenum behavior for \anum > + *g:alignmaps_usanumber* *g:alignmaps_euronumber* + One may get \aenum behavior for \anum by putting > let g:alignmaps_euronumber= 1 -< or \aunum behavior for \anum if one puts > +< or \aunum behavior for \anum by putting > let g:alignmaps_usanumber= 1 < in one's <.vimrc>. @@ -1311,21 +1400,48 @@ ALIGNMENT *align-align* {{{2 4. Alignment Tools' History *align-history* {{{1 ALIGN HISTORY {{{2 + 36 : May 20, 2009 * Previously, the "W" AlignCtrl setting, intended + to retain initial white space, did so by convert- + ing any leading tabs into an equivalent quantity + of blanks (using the current tabstop setting). + Align will now retain leading tabs. + Nov 24, 2009 * QArgSplitter() used split(), intending to split + on white space only. However, the \tab map + uses ctrl-o as a separator instead of tabs; the + split() function treated the ctrl-o as a whitespace + character, too. Solution: give split() an explicit + pattern matching blanks and tabs, only. \tab now + works again! + Jun 29, 2010 * included |g:AlignSkip| and |alignctrl-star| support + May 10, 2011 * if the range is only one line, then Align will + automatically grow the range to accommodate all + lines containing the first separator pattern + surrounding the current line. + Aug 05, 2011 * g:Align_xstrlen usage extended to permit users to + specify a function by name which computes string + length. + Oct 27, 2011 * (reported by Fco Javier) reported a problem with + the default s:Strlen() result; there was a missing + "let". Fixed. + Nov 10, 2011 * (Lewis Thompson) Align was doing "set noet" when + it should've been doing "setlocal noet". + Dec 22, 2011 * modifed s:Strlen() to use |strdisplaywidth()| when + g:Align_xstrlen is zero. 35 : Nov 02, 2008 * g:loaded_AlignPlugin testing to prevent re-loading - installed + installed Nov 19, 2008 * new sanity check for an AlignStyle of just ":" Jan 08, 2009 * save&restore of |'mod'| now done with local - variant + variant 34 : Jul 08, 2008 * using :AlignCtrl before entering any alignment - control commands was causing an error. + control commands was causing an error. 33 : Sep 20, 2007 * s:Strlen() introduced to support various ways - used to represent characters and their effects - on string lengths. See |align-strlen|. - * Align now accepts "..." -- so it can accept - whitespace as separators. + used to represent characters and their effects + on string lengths. See |align-strlen|. + * Align now accepts "..." -- so it can accept + whitespace as separators. 32 : Aug 18, 2007 * uses || instead of || plus a custom argument splitter to allow patterns with - backslashes to slide in unaltered. + backslashes to slide in unaltered. 31 : Aug 06, 2007 * :[range]Align! [AlignCtrl settings] pattern(s) implemented. 30 : Feb 12, 2007 * now uses |setline()| @@ -1341,8 +1457,8 @@ ALIGN HISTORY {{{2 25 : Jul 27, 2004 : For debugging, uses Dfunc(), Dret(), and Decho() 24 : Mar 03, 2004 : (should've done this earlier!) visualmode(1) not supported until v6.2, now Align will avoid - calling it for earlier versions. Visualmode - clearing won't take place then, of course. + calling it for earlier versions. Visualmode + clearing won't take place then, of course. 23 : Oct 07, 2003 : Included Leif Wickland's ReplaceQuotedSpaces() function which supports \tsq 22 : Jan 29, 2003 : Now requires 6.1.308 or later to clear visualmode() @@ -1365,7 +1481,7 @@ ALIGN HISTORY {{{2 14 : Aug 20, 2002 : bug fix: AlignCtrl default now keeps &ic unchanged bug fix: Align, on end-field, wasn't using correct alignop bug fix: Align, on end-field, was appending - padding + padding 13 : Aug 19, 2002 : bug fix: zero-length g/v patterns are accepted bug fix: always skip blank lines bug fix: AlignCtrl default now also clears g and v @@ -1382,28 +1498,37 @@ ALIGN HISTORY {{{2 9 : Jun 25, 2002 : implemented cyclic padding ALIGNMENT MAP HISTORY *alignmap-history* {{{2 + v42 Jan 06, 2010 * new maps for \anum, \aenum, \aunum + Feb 16, 2010 * map for \t=, \T= now handles x++ = something; + for c, c++ correctly. + Oct 29, 2010 * added a note on having one's own default + AlignCtrl (see |alignctrl-init|) + Feb 22, 2011 * for menus, &go =~# used to insure correct case + Jun 10, 2011 * |:AlignMapsClean| command provided to make it + easy for those who would prefer not to have + AlignMaps' maps not to have them. v41 Nov 02, 2008 * g:loaded_AlignMapsPlugin testing to prevent - re-loading installed - * AlignMaps now use 0x0f (ctrl-p) for special - character substitutions (instead of 0xff). - Seems to avoid some problems with having to - use Strlen(). - * bug fixed with \ts, - * new maps: \ts; \ts, \ts: \ts< \ts= \a( + re-loading installed + * AlignMaps now use 0x0f (ctrl-p) for special + character substitutions (instead of 0xff). + Seems to avoid some problems with having to + use Strlen(). + * bug fixed with \ts, + * new maps: \ts; \ts, \ts: \ts< \ts= \a( v40 Oct 21, 2008 * Modified AlignMaps so that its maps use s - and