ignore on .netrwhist
[my-vim-dotfolder.git] / PACKAGES / Align.vba
blob5fed3293b869faa3b4b08a1a6af1605cda4b213a
1 " Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
2 UseVimball
3 finish
4 plugin/AlignPlugin.vim  [[[1
5 41
6 " AlignPlugin: tool to align multiple fields based on one or more separators
7 "   Author:      Charles E. Campbell, Jr.
8 "   Date:    Nov 02, 2008
9 " GetLatestVimScripts: 294 1 :AutoInstall: Align.vim
10 " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim
11 " Copyright:    Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1
12 "               Permission is hereby granted to use and distribute this code,
13 "               with or without modifications, provided that this copyright
14 "               notice is copied with it. Like anything else that's free,
15 "               Align.vim is provided *as is* and comes with no warranty
16 "               of any kind, either expressed or implied. By using this
17 "               plugin, you agree that in no event will the copyright
18 "               holder be liable for any damages resulting from the use
19 "               of this software.
21 " Romans 1:16,17a : For I am not ashamed of the gospel of Christ, for it is {{{1
22 " the power of God for salvation for everyone who believes; for the Jew first,
23 " and also for the Greek.  For in it is revealed God's righteousness from
24 " faith to faith.
25 " ---------------------------------------------------------------------
26 " Load Once: {{{1
27 if &cp || exists("g:loaded_AlignPlugin")
28  finish
29 endif
30 let g:loaded_AlignPlugin = "v35"
31 let s:keepcpo            = &cpo
32 set cpo&vim
34 " ---------------------------------------------------------------------
35 " Public Interface: {{{1
36 com! -bang -range -nargs=* Align <line1>,<line2>call Align#Align(<bang>0,<q-args>)
37 com!       -range -nargs=0 AlignReplaceQuotedSpaces <line1>,<line2>call Align#AlignReplaceQuotedSpaces()
38 com!              -nargs=* AlignCtrl call Align#AlignCtrl(<q-args>)
39 com!              -nargs=0 AlignPush call Align#AlignPush()
40 com!              -nargs=0 AlignPop  call Align#AlignPop()
42 " ---------------------------------------------------------------------
43 "  Restore: {{{1
44 let &cpo= s:keepcpo
45 unlet s:keepcpo
46 " vim: ts=4 fdm=marker
47 plugin/AlignMapsPlugin.vim      [[[1
48 242
49 " AlignMapsPlugin:   Alignment maps based upon <Align.vim> and <AlignMaps.vim>
50 " Maintainer:        Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
51 " Date:              Mar 03, 2009
53 " NOTE: the code herein needs vim 6.0 or later
54 "                       needs <Align.vim> v6 or later
55 "                       needs <cecutil.vim> v5 or later
56 " Copyright:    Copyright (C) 1999-2008 Charles E. Campbell, Jr. {{{1
57 "               Permission is hereby granted to use and distribute this code,
58 "               with or without modifications, provided that this copyright
59 "               notice is copied with it. Like anything else that's free,
60 "               AlignMaps.vim is provided *as is* and comes with no warranty
61 "               of any kind, either expressed or implied. By using this
62 "               plugin, you agree that in no event will the copyright
63 "               holder be liable for any damages resulting from the use
64 "               of this software.
66 " Usage: {{{1
67 " Use 'a to mark beginning of to-be-aligned region,   Alternative:  use V
68 " move cursor to end of region, and execute map.      (linewise visual mode) to
69 " The maps also set up marks 'y and 'z, and retain    mark region, execute same
70 " 'a at the beginning of region.                      map.  Uses 'a, 'y, and 'z.
72 " The start/end wrappers save and restore marks 'y and 'z.
74 " Although the comments indicate the maps use a leading backslash,
75 " actually they use <Leader> (:he mapleader), so the user can
76 " specify that the maps start how he or she prefers.
78 " Note: these maps all use <Align.vim>.
80 " Romans 1:20 For the invisible things of Him since the creation of the {{{1
81 " world are clearly seen, being perceived through the things that are
82 " made, even His everlasting power and divinity; that they may be
83 " without excuse.
85 " ---------------------------------------------------------------------
86 " Load Once: {{{1
87 if &cp || exists("g:loaded_AlignMapsPlugin")
88  finish
89 endif
90 let s:keepcpo                = &cpo
91 let g:loaded_AlignMapsPlugin = "v41"
92 set cpo&vim
94 " =====================================================================
95 "  Maps: {{{1
97 " ---------------------------------------------------------------------
98 " WS: wrapper start map (internal)  {{{2
99 " Produces a blank line above and below, marks with 'y and 'z
100 if !hasmapto('<Plug>WrapperStart')
101  map <unique> <SID>WS   <Plug>AlignMapsWrapperStart
102 endif
103 nmap <silent> <script> <Plug>AlignMapsWrapperStart      :set lz<CR>:call AlignMaps#WrapperStart(0)<CR>
104 vmap <silent> <script> <Plug>AlignMapsWrapperStart      :<c-u>set lz<CR>:call AlignMaps#WrapperStart(1)<CR>
106 " ---------------------------------------------------------------------
107 " WE: wrapper end (internal)   {{{2
108 " Removes guard lines, restores marks y and z, and restores search pattern
109 if !hasmapto('<Plug>WrapperEnd')
110  nmap <unique> <SID>WE  <Plug>AlignMapsWrapperEnd
111 endif
112 nmap <silent> <script> <Plug>AlignMapsWrapperEnd        :call AlignMaps#WrapperEnd()<CR>:set nolz<CR>
114 " ---------------------------------------------------------------------
115 " Complex C-code alignment maps: {{{2
116 if !hasmapto('<Plug>AM_a?')   |map <unique> <Leader>a?          <Plug>AM_a?|endif
117 if !hasmapto('<Plug>AM_a,')   |map <unique> <Leader>a,          <Plug>AM_a,|endif
118 if !hasmapto('<Plug>AM_a<')   |map <unique> <Leader>a<          <Plug>AM_a<|endif
119 if !hasmapto('<Plug>AM_a=')   |map <unique> <Leader>a=          <Plug>AM_a=|endif
120 if !hasmapto('<Plug>AM_a(')   |map <unique> <Leader>a(          <Plug>AM_a(|endif
121 if !hasmapto('<Plug>AM_abox') |map <unique> <Leader>abox        <Plug>AM_abox|endif
122 if !hasmapto('<Plug>AM_acom') |map <unique> <Leader>acom        <Plug>AM_acom|endif
123 if !hasmapto('<Plug>AM_adcom')|map <unique> <Leader>adcom       <Plug>AM_adcom|endif
124 if !hasmapto('<Plug>AM_aocom')|map <unique> <Leader>aocom       <Plug>AM_aocom|endif
125 if !hasmapto('<Plug>AM_ascom')|map <unique> <Leader>ascom       <Plug>AM_ascom|endif
126 if !hasmapto('<Plug>AM_adec') |map <unique> <Leader>adec        <Plug>AM_adec|endif
127 if !hasmapto('<Plug>AM_adef') |map <unique> <Leader>adef        <Plug>AM_adef|endif
128 if !hasmapto('<Plug>AM_afnc') |map <unique> <Leader>afnc        <Plug>AM_afnc|endif
129 if !hasmapto('<Plug>AM_afnc') |map <unique> <Leader>afnc        <Plug>AM_afnc|endif
130 if !hasmapto('<Plug>AM_aunum')|map <unique> <Leader>aunum       <Plug>AM_aenum|endif
131 if !hasmapto('<Plug>AM_aenum')|map <unique> <Leader>aenum       <Plug>AM_aunum|endif
132 if exists("g:alignmaps_euronumber") && !exists("g:alignmaps_usanumber")
133  if !hasmapto('<Plug>AM_anum')|map <unique> <Leader>anum        <Plug>AM_aenum|endif
134 else
135  if !hasmapto('<Plug>AM_anum')|map <unique> <Leader>anum        <Plug>AM_aunum|endif
136 endif
138 map <silent> <script> <Plug>AM_a?               <SID>WS:AlignCtrl mIp1P1lC ? : : : : <CR>:'a,.Align<CR>:'a,'z-1s/\(\s\+\)? /?\1/e<CR><SID>WE
139 map <silent> <script> <Plug>AM_a,               <SID>WS:'y,'zs/\(\S\)\s\+/\1 /ge<CR>'yjma'zk:call AlignMaps#CharJoiner(",")<cr>:silent 'y,'zg/,/call AlignMaps#FixMultiDec()<CR>'z:exe "norm \<Plug>AM_adec"<cr><SID>WE
140 map <silent> <script> <Plug>AM_a<               <SID>WS:AlignCtrl mIp1P1=l << >><CR>:'a,.Align<CR><SID>WE
141 map <silent> <script> <Plug>AM_a(       <SID>WS:AlignCtrl mIp0P1=l<CR>:'a,.Align [(,]<CR>:sil 'y+1,'z-1s/\(\s\+\),/,\1/ge<CR><SID>WE
142 map <silent> <script> <Plug>AM_a=               <SID>WS:AlignCtrl mIp1P1=l<CR>:AlignCtrl g :=<CR>:'a,'zAlign :\==<CR><SID>WE
143 map <silent> <script> <Plug>AM_abox             <SID>WS:let g:alignmaps_iws=substitute(getline("'a"),'^\(\s*\).*$','\1','e')<CR>:'a,'z-1s/^\s\+//e<CR>:'a,'z-1s/^.*$/@&@/<CR>:AlignCtrl m=p01P0w @<CR>:'a,.Align<CR>:'a,'z-1s/@/ * /<CR>:'a,'z-1s/@$/*/<CR>'aYP:s/./*/g<CR>0r/'zkYp:s/./*/g<CR>0r A/<Esc>:exe "'a-1,'z-1s/^/".g:alignmaps_iws."/e"<CR><SID>WE
144 map <silent> <script> <Plug>AM_acom             <SID>WS:'a,.s/\/[*/]\/\=/@&@/e<CR>:'a,.s/\*\//@&/e<CR>:'y,'zs/^\( *\) @/\1@/e<CR>'zk:call AlignMaps#StdAlign(2)<CR>:'y,'zs/^\(\s*\) @/\1/e<CR>:'y,'zs/ @//eg<CR><SID>WE
145 map <silent> <script> <Plug>AM_adcom    <SID>WS:'a,.v/^\s*\/[/*]/s/\/[*/]\*\=/@&@/e<CR>:'a,.v/^\s*\/[/*]/s/\*\//@&/e<CR>:'y,'zv/^\s*\/[/*]/s/^\( *\) @/\1@/e<CR>'zk:call AlignMaps#StdAlign(3)<cr>:'y,'zv/^\s*\/[/*]/s/^\(\s*\) @/\1/e<CR>:'y,'zs/ @//eg<CR><SID>WE
146 map <silent> <script> <Plug>AM_aocom    <SID>WS:AlignPush<CR>:AlignCtrl g /[*/]<CR>:exe "norm \<Plug>AM_acom"<cr>:AlignPop<CR><SID>WE
147 map <silent> <script> <Plug>AM_ascom    <SID>WS:'a,.s/\/[*/]/@&@/e<CR>:'a,.s/\*\//@&/e<CR>:silent! 'a,.g/^\s*@\/[*/]/s/@//ge<CR>:AlignCtrl v ^\s*\/[*/]<CR>:AlignCtrl g \/[*/]<CR>'zk:call AlignMaps#StdAlign(2)<cr>:'y,'zs/^\(\s*\) @/\1/e<CR>:'y,'zs/ @//eg<CR><SID>WE
148 map <silent> <script> <Plug>AM_adec             <SID>WS:'a,'zs/\([^ \t/(]\)\([*&]\)/\1 \2/e<CR>:'y,'zv/^\//s/\([^ \t]\)\s\+/\1 /ge<CR>:'y,'zv/^\s*[*/]/s/\([^/][*&]\)\s\+/\1/ge<CR>:'y,'zv/^\s*[*/]/s/^\(\s*\%(\K\k*\s\+\%([a-zA-Z_*(&]\)\@=\)\+\)\([*(&]*\)\s*\([a-zA-Z0-9_()]\+\)\s*\(\(\[.\{-}]\)*\)\s*\(=\)\=\s*\(.\{-}\)\=\s*;/\1@\2#@\3\4@\6@\7;@/e<CR>:'y,'zv/^\s*[*/]/s/\*\/\s*$/@*\//e<CR>:'y,'zv/^\s*[*/]/s/^\s\+\*/@@@@@* /e<CR>:'y,'zv/^\s*[*/]/s/^@@@@@\*\(.*[^*/]\)$/&@*/e<CR>'yjma'zk:AlignCtrl v ^\s*[*/#]<CR>:call AlignMaps#StdAlign(1)<cr>:'y,'zv/^\s*[*/]/s/@ //ge<CR>:'y,'zv/^\s*[*/]/s/\(\s*\);/;\1/e<CR>:'y,'zv/^#/s/# //e<CR>:'y,'zv/^\s\+[*/#]/s/\([^/*]\)\(\*\+\)\( \+\)/\1\3\2/e<CR>:'y,'zv/^\s\+[*/#]/s/\((\+\)\( \+\)\*/\2\1*/e<CR>:'y,'zv/^\s\+[*/#]/s/^\(\s\+\) \*/\1*/e<CR>:'y,'zv/^\s\+[*/#]/s/[ \t@]*$//e<CR>:'y,'zs/^[*]/ */e<CR><SID>WE
149 map <silent> <script> <Plug>AM_adef             <SID>WS:AlignPush<CR>:AlignCtrl v ^\s*\(\/\*\<bar>\/\/\)<CR>:'a,.v/^\s*\(\/\*\<bar>\/\/\)/s/^\(\s*\)#\(\s\)*define\s*\(\I[a-zA-Z_0-9(),]*\)\s*\(.\{-}\)\($\<Bar>\/\*\)/#\1\2define @\3@\4@\5/e<CR>:'a,.v/^\s*\(\/\*\<bar>\/\/\)/s/\($\<Bar>\*\/\)/@&/e<CR>'zk:call AlignMaps#StdAlign(1)<cr>'yjma'zk:'a,.v/^\s*\(\/\*\<bar>\/\/\)/s/ @//g<CR><SID>WE
150 map <silent> <script> <Plug>AM_afnc             :<c-u>set lz<CR>:silent call AlignMaps#Afnc()<CR>:set nolz<CR>
151 map <silent> <script> <Plug>AM_aunum    <SID>WS:'a,'zs/\%([0-9.]\)\s\+\zs\([-+.]\=\d\)/@\1/ge<CR>:'a,'zs/\(\(^\|\s\)\d\+\)\(\s\+\)@/\1@\3@/ge<CR>:'a,'zs/\.@/\.0@/ge<CR>:AlignCtrl wmp0P0r<CR>:'a,'zAlign [.@]<CR>:'a,'zs/@/ /ge<CR>:'a,'zs/\(\.\)\(\s\+\)\([0-9.,eE+]\+\)/\1\3\2/ge<CR>:'a,'zs/\([eE]\)\(\s\+\)\([0-9+\-+]\+\)/\1\3\2/ge<CR><SID>WE
152 map <silent> <script> <Plug>AM_aenum    <SID>WS:'a,'zs/\%([0-9.]\)\s\+\([-+]\=\d\)/\1@\2/ge<CR>:'a,'zs/\.@/\.0@/ge<CR>:AlignCtrl wmp0P0r<CR>:'a,'zAlign [,@]<CR>:'a,'zs/@/ /ge<CR>:'a,'zs/\(,\)\(\s\+\)\([-0-9.,eE+]\+\)/\1\3\2/ge<CR>:'a,'zs/\([eE]\)\(\s\+\)\([0-9+\-+]\+\)/\1\3\2/ge<CR><SID>WE
154 " ---------------------------------------------------------------------
155 " html table alignment  {{{2
156 if !hasmapto('<Plug>AM_Htd')|map <unique> <Leader>Htd   <Plug>AM_Htd|endif
157 map <silent> <script> <Plug>AM_Htd <SID>WS:'y,'zs%<[tT][rR]><[tT][dD][^>]\{-}>\<Bar></[tT][dD]><[tT][dD][^>]\{-}>\<Bar></[tT][dD]></[tT][rR]>%@&@%g<CR>'yjma'zk:AlignCtrl m=Ilp1P0 @<CR>:'a,.Align<CR>:'y,'zs/ @/@/<CR>:'y,'zs/@ <[tT][rR]>/<[tT][rR]>/ge<CR>:'y,'zs/@//ge<CR><SID>WE
159 " ---------------------------------------------------------------------
160 " character-based right-justified alignment maps {{{2
161 if !hasmapto('<Plug>AM_T\x16|')|map <unique> <Leader>T\x16|           <Plug>AM_T\x16||endif
162 if !hasmapto('<Plug>AM_T#')      |map <unique> <Leader>T#               <Plug>AM_T#|endif
163 if !hasmapto('<Plug>AM_T,')      |map <unique> <Leader>T,               <Plug>AM_T,o|endif
164 if !hasmapto('<Plug>AM_Ts,') |map <unique> <Leader>Ts,          <Plug>AM_Ts,|endif
165 if !hasmapto('<Plug>AM_T:')      |map <unique> <Leader>T:               <Plug>AM_T:|endif
166 if !hasmapto('<Plug>AM_T;')      |map <unique> <Leader>T;               <Plug>AM_T;|endif
167 if !hasmapto('<Plug>AM_T<')      |map <unique> <Leader>T<               <Plug>AM_T<|endif
168 if !hasmapto('<Plug>AM_T=')      |map <unique> <Leader>T=               <Plug>AM_T=|endif
169 if !hasmapto('<Plug>AM_T?')      |map <unique> <Leader>T?               <Plug>AM_T?|endif
170 if !hasmapto('<Plug>AM_T@')      |map <unique> <Leader>T@               <Plug>AM_T@|endif
171 if !hasmapto('<Plug>AM_Tab') |map <unique> <Leader>Tab          <Plug>AM_Tab|endif
172 if !hasmapto('<Plug>AM_Tsp') |map <unique> <Leader>Tsp          <Plug>AM_Tsp|endif
173 if !hasmapto('<Plug>AM_T~')      |map <unique> <Leader>T~               <Plug>AM_T~|endif
175 map <silent> <script> <Plug>AM_T\x16| <SID>WS:AlignCtrl mIp0P0=r <Bar><CR>:'a,.Align<CR><SID>WE
176 map <silent> <script> <Plug>AM_T#   <SID>WS:AlignCtrl mIp0P0=r #<CR>:'a,.Align<CR><SID>WE
177 map <silent> <script> <Plug>AM_T,   <SID>WS:AlignCtrl mIp0P1=r ,<CR>:'a,.Align<CR><SID>WE
178 map <silent> <script> <Plug>AM_Ts,  <SID>WS:AlignCtrl mIp0P1=r ,<CR>:'a,.Align<CR>:'a,.s/\(\s*\),/,\1/ge<CR><SID>WE
179 map <silent> <script> <Plug>AM_T:   <SID>WS:AlignCtrl mIp1P1=r :<CR>:'a,.Align<CR><SID>WE
180 map <silent> <script> <Plug>AM_T;   <SID>WS:AlignCtrl mIp0P0=r ;<CR>:'a,.Align<CR><SID>WE
181 map <silent> <script> <Plug>AM_T<   <SID>WS:AlignCtrl mIp0P0=r <<CR>:'a,.Align<CR><SID>WE
182 map <silent> <script> <Plug>AM_T=   <SID>WS:'a,'z-1s/\s\+\([*/+\-%<Bar>&\~^]\==\)/ \1/e<CR>:'a,'z-1s@ \+\([*/+\-%<Bar>&\~^]\)=@\1=@ge<CR>:'a,'z-1s/; */;@/e<CR>:'a,'z-1s/==/\="\<Char-0x0f>\<Char-0x0f>"/ge<CR>:'a,'z-1s/!=/\x="!\<Char-0x0f>"/ge<CR>:AlignCtrl mIp1P1=r = @<CR>:AlignCtrl g =<CR>:'a,'z-1Align<CR>:'a,'z-1s/; *@/;/e<CR>:'a,'z-1s/; *$/;/e<CR>:'a,'z-1s@\([*/+\-%<Bar>&\~^]\)\( \+\)=@\2\1=@ge<CR>:'a,'z-1s/\( \+\);/;\1/ge<CR>:'a,'z-1s/\xff/=/ge<CR><SID>WE:exe "norm <Plug>acom"
183 map <silent> <script> <Plug>AM_T?   <SID>WS:AlignCtrl mIp0P0=r ?<CR>:'a,.Align<CR>:'y,'zs/ \( *\);/;\1/ge<CR><SID>WE
184 map <silent> <script> <Plug>AM_T@   <SID>WS:AlignCtrl mIp0P0=r @<CR>:'a,.Align<CR><SID>WE
185 map <silent> <script> <Plug>AM_Tab  <SID>WS:'a,.s/^\(\t*\)\(.*\)/\=submatch(1).escape(substitute(submatch(2),'\t','@','g'),'\')/<CR>:AlignCtrl mI=r @<CR>:'a,.Align<CR>:'y+1,'z-1s/@/ /g<CR><SID>WE
186 map <silent> <script> <Plug>AM_Tsp  <SID>WS:'a,.s/^\(\s*\)\(.*\)/\=submatch(1).escape(substitute(submatch(2),'\s\+','@','g'),'\')/<CR>:AlignCtrl mI=r @<CR>:'a,.Align<CR>:'y+1,'z-1s/@/ /g<CR><SID>WE
187 map <silent> <script> <Plug>AM_T~   <SID>WS:AlignCtrl mIp0P0=r ~<CR>:'a,.Align<CR>:'y,'zs/ \( *\);/;\1/ge<CR><SID>WE
189 " ---------------------------------------------------------------------
190 " character-based left-justified alignment maps {{{2
191 if !hasmapto('<Plug>AM_t\x16|')    |map <unique> <Leader>t\x16|       <Plug>AM_t\x16||endif
192 if !hasmapto('<Plug>AM_t#')             |map <unique> <Leader>t#        <Plug>AM_t#|endif
193 if !hasmapto('<Plug>AM_t,')             |map <unique> <Leader>t,        <Plug>AM_t,|endif
194 if !hasmapto('<Plug>AM_t:')             |map <unique> <Leader>t:        <Plug>AM_t:|endif
195 if !hasmapto('<Plug>AM_t;')             |map <unique> <Leader>t;        <Plug>AM_t;|endif
196 if !hasmapto('<Plug>AM_t<')             |map <unique> <Leader>t<        <Plug>AM_t<|endif
197 if !hasmapto('<Plug>AM_t=')             |map <unique> <Leader>t=        <Plug>AM_t=|endif
198 if !hasmapto('<Plug>AM_ts,')    |map <unique> <Leader>ts,       <Plug>AM_ts,|endif
199 if !hasmapto('<Plug>AM_ts:')    |map <unique> <Leader>ts:       <Plug>AM_ts:|endif
200 if !hasmapto('<Plug>AM_ts;')    |map <unique> <Leader>ts;       <Plug>AM_ts;|endif
201 if !hasmapto('<Plug>AM_ts<')    |map <unique> <Leader>ts<       <Plug>AM_ts<|endif
202 if !hasmapto('<Plug>AM_ts=')    |map <unique> <Leader>ts=       <Plug>AM_ts=|endif
203 if !hasmapto('<Plug>AM_w=')             |map <unique> <Leader>w=        <Plug>AM_w=|endif
204 if !hasmapto('<Plug>AM_t?')             |map <unique> <Leader>t?        <Plug>AM_t?|endif
205 if !hasmapto('<Plug>AM_t~')             |map <unique> <Leader>t~        <Plug>AM_t~|endif
206 if !hasmapto('<Plug>AM_t@')             |map <unique> <Leader>t@        <Plug>AM_t@|endif
207 if !hasmapto('<Plug>AM_m=')             |map <unique> <Leader>m=        <Plug>AM_m=|endif
208 if !hasmapto('<Plug>AM_tab')    |map <unique> <Leader>tab       <Plug>AM_tab|endif
209 if !hasmapto('<Plug>AM_tml')    |map <unique> <Leader>tml       <Plug>AM_tml|endif
210 if !hasmapto('<Plug>AM_tsp')    |map <unique> <Leader>tsp       <Plug>AM_tsp|endif
211 if !hasmapto('<Plug>AM_tsq')    |map <unique> <Leader>tsq       <Plug>AM_tsq|endif
212 if !hasmapto('<Plug>AM_tt')             |map <unique> <Leader>tt        <Plug>AM_tt|endif
214 map <silent> <script> <Plug>AM_t\x16|              <SID>WS:AlignCtrl mIp0P0=l <Bar><CR>:'a,.Align<CR><SID>WE
215 map <silent> <script> <Plug>AM_t#               <SID>WS:AlignCtrl mIp0P0=l #<CR>:'a,.Align<CR><SID>WE
216 map <silent> <script> <Plug>AM_t,               <SID>WS:AlignCtrl mIp0P1=l ,<CR>:'a,.Align<CR><SID>WE
217 map <silent> <script> <Plug>AM_t:               <SID>WS:AlignCtrl mIp1P1=l :<CR>:'a,.Align<CR><SID>WE
218 map <silent> <script> <Plug>AM_t;               <SID>WS:AlignCtrl mIp0P1=l ;<CR>:'a,.Align<CR>:sil 'y,'zs/\( *\);/;\1/ge<CR><SID>WE
219 map <silent> <script> <Plug>AM_t<               <SID>WS:AlignCtrl mIp0P0=l <<CR>:'a,.Align<CR><SID>WE
220 map <silent> <script> <Plug>AM_t=               <SID>WS:call AlignMaps#Equals()<CR><SID>WE
221 map <silent> <script> <Plug>AM_ts,              <SID>WS:AlignCtrl mIp0P1=l #<CR>:'a,.Align<CR>:sil 'y+1,'z-1s/\(\s*\)#/,\1/ge<CR><SID>WE
222 map <silent> <script> <Plug>AM_ts,              <SID>WS:AlignCtrl mIp0P1=l ,<CR>:'a,.Align<CR>:sil 'y+1,'z-1s/\(\s*\),/,\1/ge<CR><SID>WE
223 map <silent> <script> <Plug>AM_ts:              <SID>WS:AlignCtrl mIp1P1=l :<CR>:'a,.Align<CR>:sil 'y+1,'z-1s/\(\s*\):/:\1/ge<CR><SID>WE
224 map <silent> <script> <Plug>AM_ts;              <SID>WS:AlignCtrl mIp1P1=l ;<CR>:'a,.Align<CR>:sil 'y+1,'z-1s/\(\s*\);/;\1/ge<CR><SID>WE
225 map <silent> <script> <Plug>AM_ts<              <SID>WS:AlignCtrl mIp1P1=l <<CR>:'a,.Align<CR>:sil 'y+1,'z-1s/\(\s*\)</<\1/ge<CR><SID>WE
226 map <silent> <script> <Plug>AM_ts=              <SID>WS:AlignCtrl mIp1P1=l =<CR>:'a,.Align<CR>:sil 'y+1,'z-1s/\(\s*\)=/=\1/ge<CR><SID>WE
227 map <silent> <script> <Plug>AM_w=               <SID>WS:'a,'zg/=/s/\s\+\([*/+\-%<Bar>&\~^]\==\)/ \1/e<CR>:'a,'zg/=/s@ \+\([*/+\-%<Bar>&\~^]\)=@\1=@ge<CR>:'a,'zg/=/s/==/\="\<Char-0x0f>\<Char-0x0f>"/ge<CR>:'a,'zg/=/s/!=/\="!\<Char-0x0f>"/ge<CR>'zk:AlignCtrl mWp1P1=l =<CR>:AlignCtrl g =<CR>:'a,'z-1g/=/Align<CR>:'a,'z-1g/=/s@\([*/+\-%<Bar>&\~^!=]\)\( \+\)=@\2\1=@ge<CR>:'a,'z-1g/=/s/\( \+\);/;\1/ge<CR>:'a,'z-1v/^\s*\/[*/]/s/\/[*/]/@&@/e<CR>:'a,'z-1v/^\s*\/[*/]/s/\*\//@&/e<CR>'zk:call AlignMaps#StdAlign(1)<cr>:'y,'zs/^\(\s*\) @/\1/e<CR>:'a,'z-1g/=/s/\xff/=/ge<CR>:'y,'zg/=/s/ @//eg<CR><SID>WE
228 map <silent> <script> <Plug>AM_t?               <SID>WS:AlignCtrl mIp0P0=l ?<CR>:'a,.Align<CR>:.,'zs/ \( *\);/;\1/ge<CR><SID>WE
229 map <silent> <script> <Plug>AM_t~               <SID>WS:AlignCtrl mIp0P0=l ~<CR>:'a,.Align<CR>:'y,'zs/ \( *\);/;\1/ge<CR><SID>WE
230 map <silent> <script> <Plug>AM_t@               <SID>WS::call AlignMaps#StdAlign(1)<cr>:<SID>WE
231 map <silent> <script> <Plug>AM_m=               <SID>WS:'a,'zs/\s\+\([*/+\-%<Bar>&\~^]\==\)/ \1/e<CR>:'a,'zs@ \+\([*/+\-%<Bar>&\~^]\)=@\1=@ge<CR>:'a,'zs/==/\="\<Char-0x0f>\<Char-0x0f>"/ge<CR>:'a,'zs/!=/\="!\<Char-0x0f>"/ge<CR>'zk:AlignCtrl mIp1P1=l =<CR>:AlignCtrl g =<CR>:'a,'z-1Align<CR>:'a,'z-1s@\([*/+\-%<Bar>&\~^!=]\)\( \+\)=@\2\1=@ge<CR>:'a,'z-1s/\( \+\);/;\1/ge<CR>:'a,'z-s/%\ze[^=]/ @%@ /e<CR>'zk:call AlignMaps#StdAlign(1)<cr>:'y,'zs/^\(\s*\) @/\1/e<CR>:'a,'z-1s/\xff/=/ge<CR>:'y,'zs/ @//eg<CR><SID>WE
232 map <silent> <script> <Plug>AM_tab              <SID>WS:'a,.s/^\(\t*\)\(.*\)$/\=submatch(1).escape(substitute(submatch(2),'\t',"\<Char-0x0f>",'g'),'\')/<CR>:if &ts == 1<bar>exe "AlignCtrl mI=lp0P0 \<Char-0x0f>"<bar>else<bar>exe "AlignCtrl mI=l \<Char-0x0f>"<bar>endif<CR>:'a,.Align<CR>:exe "'y+1,'z-1s/\<Char-0x0f>/".((&ts == 1)? '\t' : ' ')."/g"<CR><SID>WE
233 map <silent> <script> <Plug>AM_tml              <SID>WS:AlignCtrl mWp1P0=l \\\@<!\\\s*$<CR>:'a,.Align<CR><SID>WE
234 map <silent> <script> <Plug>AM_tsp              <SID>WS:'a,.s/^\(\s*\)\(.*\)/\=submatch(1).escape(substitute(submatch(2),'\s\+','@','g'),'\')/<CR>:AlignCtrl mI=lp0P0 @<CR>:'a,.Align<CR>:'y+1,'z-1s/@/ /g<CR><SID>WE
235 map <silent> <script> <Plug>AM_tsq              <SID>WS:'a,.AlignReplaceQuotedSpaces<CR>:'a,.s/^\(\s*\)\(.*\)/\=submatch(1).substitute(submatch(2),'\s\+','@','g')/<CR>:AlignCtrl mIp0P0=l @<CR>:'a,.Align<CR>:'y+1,'z-1s/[%@]/ /g<CR><SID>WE
236 map <silent> <script> <Plug>AM_tt               <SID>WS:AlignCtrl mIp1P1=l \\\@<!& \\\\<CR>:'a,.Align<CR><SID>WE
238 " =====================================================================
239 " Menu Support: {{{1
240 "   ma ..move.. use menu
241 "   v V or ctrl-v ..move.. use menu
242 if has("menu") && has("gui_running") && &go =~ 'm' && !exists("s:firstmenu")
243  let s:firstmenu= 1
244  if !exists("g:DrChipTopLvlMenu")
245   let g:DrChipTopLvlMenu= "DrChip."
246  endif
247  if g:DrChipTopLvlMenu != ""
248   let s:mapleader = exists("g:mapleader")? g:mapleader : '\'
249   let s:emapleader= escape(s:mapleader,'\ ')
250   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.<<\ and\ >><tab>'.s:emapleader.'a<  '.s:mapleader.'a<'
251   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Assignment\ =<tab>'.s:emapleader.'t=        '.s:mapleader.'t='
252   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Assignment\ :=<tab>'.s:emapleader.'a=       '.s:mapleader.'a='
253   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Backslashes<tab>'.s:emapleader.'tml '.s:mapleader.'tml'
254   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Breakup\ Comma\ Declarations<tab>'.s:emapleader.'a, '.s:mapleader.'a,'
255   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.C\ Comment\ Box<tab>'.s:emapleader.'abox    '.s:mapleader.'abox'
256   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Commas<tab>'.s:emapleader.'t,       '.s:mapleader.'t,'
257   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Commas<tab>'.s:emapleader.'ts,      '.s:mapleader.'ts,'
258   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Commas\ With\ Strings<tab>'.s:emapleader.'tsq       '.s:mapleader.'tsq'
259   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Comments<tab>'.s:emapleader.'acom   '.s:mapleader.'acom'
260   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Comments\ Only<tab>'.s:emapleader.'aocom    '.s:mapleader.'aocom'
261   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Declaration\ Comments<tab>'.s:emapleader.'adcom     '.s:mapleader.'adcom'
262   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Declarations<tab>'.s:emapleader.'adec       '.s:mapleader.'adec'
263   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Definitions<tab>'.s:emapleader.'adef        '.s:mapleader.'adef'
264   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Function\ Header<tab>'.s:emapleader.'afnc   '.s:mapleader.'afnc'
265   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Html\ Tables<tab>'.s:emapleader.'Htd        '.s:mapleader.'Htd'
266   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.(\.\.\.)?\.\.\.\ :\ \.\.\.<tab>'.s:emapleader.'a?   '.s:mapleader.'a?'
267   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Numbers<tab>'.s:emapleader.'anum    '.s:mapleader.'anum'
268   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Numbers\ (American-Style)<tab>'.s:emapleader.'aunum <Leader>aunum   '.s:mapleader.'aunum    <Leader>aunum'
269   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Numbers\ (Euro-Style)<tab>'.s:emapleader.'aenum     '.s:mapleader.'aenum'
270   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Spaces\ (Left\ Justified)<tab>'.s:emapleader.'tsp   '.s:mapleader.'tsp'
271   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Spaces\ (Right\ Justified)<tab>'.s:emapleader.'Tsp  '.s:mapleader.'Tsp'
272   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Statements\ With\ Percent\ Style\ Comments<tab>'.s:emapleader.'m=   '.s:mapleader.'m='
273   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Symbol\ <<tab>'.s:emapleader.'t<    '.s:mapleader.'t<'
274   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Symbol\ \|<tab>'.s:emapleader.'t\|  '.s:mapleader.'t|'
275   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Symbol\ @<tab>'.s:emapleader.'t@    '.s:mapleader.'t@'
276   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Symbol\ #<tab>'.s:emapleader.'t#    '.s:mapleader.'t#'
277   exe 'menu '.g:DrChipTopLvlMenu.'AlignMaps.Tabs<tab>'.s:emapleader.'tab        '.s:mapleader.'tab'
278   unlet s:mapleader
279   unlet s:emapleader
280  endif
281 endif
283 " =====================================================================
284 "  Restore: {{{1
285 let &cpo= s:keepcpo
286 unlet s:keepcpo
288 " ==============================================================================
289 "  Modelines: {{{1
290 " vim: ts=4 nowrap fdm=marker
291 plugin/cecutil.vim      [[[1
293 " cecutil.vim : save/restore window position
294 "               save/restore mark position
295 "               save/restore selected user maps
296 "  Author:      Charles E. Campbell, Jr.
297 "  Version:     18b     ASTRO-ONLY
298 "  Date:        Aug 27, 2008
300 "  Saving Restoring Destroying Marks: {{{1
301 "       call SaveMark(markname)       let savemark= SaveMark(markname)
302 "       call RestoreMark(markname)    call RestoreMark(savemark)
303 "       call DestroyMark(markname)
304 "       commands: SM RM DM
306 "  Saving Restoring Destroying Window Position: {{{1
307 "       call SaveWinPosn()        let winposn= SaveWinPosn()
308 "       call RestoreWinPosn()     call RestoreWinPosn(winposn)
309 "               \swp : save current window/buffer's position
310 "               \rwp : restore current window/buffer's previous position
311 "       commands: SWP RWP
313 "  Saving And Restoring User Maps: {{{1
314 "       call SaveUserMaps(mapmode,maplead,mapchx,suffix)
315 "       call RestoreUserMaps(suffix)
317 " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim
319 " You believe that God is one. You do well. The demons also {{{1
320 " believe, and shudder. But do you want to know, vain man, that
321 " faith apart from works is dead?  (James 2:19,20 WEB)
323 " ---------------------------------------------------------------------
324 " Load Once: {{{1
325 if &cp || exists("g:loaded_cecutil")
326  finish
327 endif
328 let g:loaded_cecutil = "v18b"
329 let s:keepcpo        = &cpo
330 set cpo&vim
331 "DechoTabOn
333 " =======================
334 "  Public Interface: {{{1
335 " =======================
337 " ---------------------------------------------------------------------
338 "  Map Interface: {{{2
339 if !hasmapto('<Plug>SaveWinPosn')
340  map <unique> <Leader>swp <Plug>SaveWinPosn
341 endif
342 if !hasmapto('<Plug>RestoreWinPosn')
343  map <unique> <Leader>rwp <Plug>RestoreWinPosn
344 endif
345 nmap <silent> <Plug>SaveWinPosn         :call SaveWinPosn()<CR>
346 nmap <silent> <Plug>RestoreWinPosn      :call RestoreWinPosn()<CR>
348 " ---------------------------------------------------------------------
349 " Command Interface: {{{2
350 com! -bar -nargs=0 SWP  call SaveWinPosn()
351 com! -bar -nargs=0 RWP  call RestoreWinPosn()
352 com! -bar -nargs=1 SM   call SaveMark(<q-args>)
353 com! -bar -nargs=1 RM   call RestoreMark(<q-args>)
354 com! -bar -nargs=1 DM   call DestroyMark(<q-args>)
356 if v:version < 630
357  let s:modifier= "sil "
358 else
359  let s:modifier= "sil keepj "
360 endif
362 " ===============
363 " Functions: {{{1
364 " ===============
366 " ---------------------------------------------------------------------
367 " SaveWinPosn: {{{2
368 "    let winposn= SaveWinPosn()  will save window position in winposn variable
369 "    call SaveWinPosn()          will save window position in b:cecutil_winposn{b:cecutil_iwinposn}
370 "    let winposn= SaveWinPosn(0) will *only* save window position in winposn variable (no stacking done)
371 fun! SaveWinPosn(...)
372 "  call Dfunc("SaveWinPosn() a:0=".a:0)
373   if line(".") == 1 && getline(1) == ""
374 "   call Dfunc("SaveWinPosn : empty buffer")
375    return ""
376   endif
377   let so_keep   = &l:so
378   let siso_keep = &siso
379   let ss_keep   = &l:ss
380   setlocal so=0 siso=0 ss=0
382   let swline    = line(".")
383   let swcol     = col(".")
384   let swwline   = winline() - 1
385   let swwcol    = virtcol(".") - wincol()
386   let savedposn = "call GoWinbufnr(".winbufnr(0).")|silent ".swline
387   let savedposn = savedposn."|".s:modifier."norm! 0z\<cr>"
388   if swwline > 0
389    let savedposn= savedposn.":".s:modifier."norm! ".swwline."\<c-y>\<cr>"
390   endif
391   if swwcol > 0
392    let savedposn= savedposn.":".s:modifier."norm! 0".swwcol."zl\<cr>"
393   endif
394   let savedposn = savedposn.":".s:modifier."call cursor(".swline.",".swcol.")\<cr>"
396   " save window position in
397   " b:cecutil_winposn_{iwinposn} (stack)
398   " only when SaveWinPosn() is used
399   if a:0 == 0
400    if !exists("b:cecutil_iwinposn")
401         let b:cecutil_iwinposn= 1
402    else
403         let b:cecutil_iwinposn= b:cecutil_iwinposn + 1
404    endif
405 "   call Decho("saving posn to SWP stack")
406    let b:cecutil_winposn{b:cecutil_iwinposn}= savedposn
407   endif
409   let &l:so = so_keep
410   let &siso = siso_keep
411   let &l:ss = ss_keep
413 "  if exists("b:cecutil_iwinposn")       " Decho
414 "   call Decho("b:cecutil_winpos{".b:cecutil_iwinposn."}[".b:cecutil_winposn{b:cecutil_iwinposn}."]")
415 "  else                      " Decho
416 "   call Decho("b:cecutil_iwinposn doesn't exist")
417 "  endif                     " Decho
418 "  call Dret("SaveWinPosn [".savedposn."]")
419   return savedposn
420 endfun
422 " ---------------------------------------------------------------------
423 " RestoreWinPosn: {{{2
424 "      call RestoreWinPosn()
425 "      call RestoreWinPosn(winposn)
426 fun! RestoreWinPosn(...)
427 "  call Dfunc("RestoreWinPosn() a:0=".a:0)
428 "  call Decho("getline(1)<".getline(1).">")
429 "  call Decho("line(.)=".line("."))
430   if line(".") == 1 && getline(1) == ""
431 "   call Dfunc("RestoreWinPosn : empty buffer")
432    return ""
433   endif
434   let so_keep   = &l:so
435   let siso_keep = &l:siso
436   let ss_keep   = &l:ss
437   setlocal so=0 siso=0 ss=0
439   if a:0 == 0 || a:1 == ""
440    " use saved window position in b:cecutil_winposn{b:cecutil_iwinposn} if it exists
441    if exists("b:cecutil_iwinposn") && exists("b:cecutil_winposn{b:cecutil_iwinposn}")
442 "       call Decho("using stack b:cecutil_winposn{".b:cecutil_iwinposn."}<".b:cecutil_winposn{b:cecutil_iwinposn}.">")
443         try
444      exe "silent! ".b:cecutil_winposn{b:cecutil_iwinposn}
445         catch /^Vim\%((\a\+)\)\=:E749/
446          " ignore empty buffer error messages
447         endtry
448     " normally drop top-of-stack by one
449     " but while new top-of-stack doesn't exist
450     " drop top-of-stack index by one again
451         if b:cecutil_iwinposn >= 1
452          unlet b:cecutil_winposn{b:cecutil_iwinposn}
453          let b:cecutil_iwinposn= b:cecutil_iwinposn - 1
454          while b:cecutil_iwinposn >= 1 && !exists("b:cecutil_winposn{b:cecutil_iwinposn}")
455           let b:cecutil_iwinposn= b:cecutil_iwinposn - 1
456          endwhile
457          if b:cecutil_iwinposn < 1
458           unlet b:cecutil_iwinposn
459          endif
460         endif
461    else
462         echohl WarningMsg
463         echomsg "***warning*** need to SaveWinPosn first!"
464         echohl None
465    endif
467   else   " handle input argument
468 "   call Decho("using input a:1<".a:1.">")
469    " use window position passed to this function
470    exe "silent ".a:1
471    " remove a:1 pattern from b:cecutil_winposn{b:cecutil_iwinposn} stack
472    if exists("b:cecutil_iwinposn")
473     let jwinposn= b:cecutil_iwinposn
474     while jwinposn >= 1                     " search for a:1 in iwinposn..1
475         if exists("b:cecutil_winposn{jwinposn}")    " if it exists
476          if a:1 == b:cecutil_winposn{jwinposn}      " and the pattern matches
477        unlet b:cecutil_winposn{jwinposn}            " unlet it
478        if jwinposn == b:cecutil_iwinposn            " if at top-of-stack
479         let b:cecutil_iwinposn= b:cecutil_iwinposn - 1      " drop stacktop by one
480        endif
481       endif
482      endif
483      let jwinposn= jwinposn - 1
484     endwhile
485    endif
486   endif
488   " Seems to be something odd: vertical motions after RWP
489   " cause jump to first column.  The following fixes that.
490   " Note: was using wincol()>1, but with signs, a cursor
491   " at column 1 yields wincol()==3.  Beeping ensued.
492   if virtcol('.') > 1
493    silent norm! hl
494   elseif virtcol(".") < virtcol("$")
495    silent norm! lh
496   endif
498   let &l:so   = so_keep
499   let &l:siso = siso_keep
500   let &l:ss   = ss_keep
502 "  call Dret("RestoreWinPosn")
503 endfun
505 " ---------------------------------------------------------------------
506 " GoWinbufnr: go to window holding given buffer (by number) {{{2
507 "   Prefers current window; if its buffer number doesn't match,
508 "   then will try from topleft to bottom right
509 fun! GoWinbufnr(bufnum)
510 "  call Dfunc("GoWinbufnr(".a:bufnum.")")
511   if winbufnr(0) == a:bufnum
512 "   call Dret("GoWinbufnr : winbufnr(0)==a:bufnum")
513    return
514   endif
515   winc t
516   let first=1
517   while winbufnr(0) != a:bufnum && (first || winnr() != 1)
518         winc w
519         let first= 0
520    endwhile
521 "  call Dret("GoWinbufnr")
522 endfun
524 " ---------------------------------------------------------------------
525 " SaveMark: sets up a string saving a mark position. {{{2
526 "           For example, SaveMark("a")
527 "           Also sets up a global variable, g:savemark_{markname}
528 fun! SaveMark(markname)
529 "  call Dfunc("SaveMark(markname<".a:markname.">)")
530   let markname= a:markname
531   if strpart(markname,0,1) !~ '\a'
532    let markname= strpart(markname,1,1)
533   endif
534 "  call Decho("markname=".markname)
536   let lzkeep  = &lz
537   set lz
539   if 1 <= line("'".markname) && line("'".markname) <= line("$")
540    let winposn               = SaveWinPosn(0)
541    exe s:modifier."norm! `".markname
542    let savemark              = SaveWinPosn(0)
543    let g:savemark_{markname} = savemark
544    let savemark              = markname.savemark
545    call RestoreWinPosn(winposn)
546   else
547    let g:savemark_{markname} = ""
548    let savemark              = ""
549   endif
551   let &lz= lzkeep
553 "  call Dret("SaveMark : savemark<".savemark.">")
554   return savemark
555 endfun
557 " ---------------------------------------------------------------------
558 " RestoreMark: {{{2
559 "   call RestoreMark("a")  -or- call RestoreMark(savemark)
560 fun! RestoreMark(markname)
561 "  call Dfunc("RestoreMark(markname<".a:markname.">)")
563   if strlen(a:markname) <= 0
564 "   call Dret("RestoreMark : no such mark")
565    return
566   endif
567   let markname= strpart(a:markname,0,1)
568   if markname !~ '\a'
569    " handles 'a -> a styles
570    let markname= strpart(a:markname,1,1)
571   endif
572 "  call Decho("markname=".markname." strlen(a:markname)=".strlen(a:markname))
574   let lzkeep  = &lz
575   set lz
576   let winposn = SaveWinPosn(0)
578   if strlen(a:markname) <= 2
579    if exists("g:savemark_{markname}") && strlen(g:savemark_{markname}) != 0
580         " use global variable g:savemark_{markname}
581 "       call Decho("use savemark list")
582         call RestoreWinPosn(g:savemark_{markname})
583         exe "norm! m".markname
584    endif
585   else
586    " markname is a savemark command (string)
587 "       call Decho("use savemark command")
588    let markcmd= strpart(a:markname,1)
589    call RestoreWinPosn(markcmd)
590    exe "norm! m".markname
591   endif
593   call RestoreWinPosn(winposn)
594   let &lz       = lzkeep
596 "  call Dret("RestoreMark")
597 endfun
599 " ---------------------------------------------------------------------
600 " DestroyMark: {{{2
601 "   call DestroyMark("a")  -- destroys mark
602 fun! DestroyMark(markname)
603 "  call Dfunc("DestroyMark(markname<".a:markname.">)")
605   " save options and set to standard values
606   let reportkeep= &report
607   let lzkeep    = &lz
608   set lz report=10000
610   let markname= strpart(a:markname,0,1)
611   if markname !~ '\a'
612    " handles 'a -> a styles
613    let markname= strpart(a:markname,1,1)
614   endif
615 "  call Decho("markname=".markname)
617   let curmod  = &mod
618   let winposn = SaveWinPosn(0)
619   1
620   let lineone = getline(".")
621   exe "k".markname
622   d
623   put! =lineone
624   let &mod    = curmod
625   call RestoreWinPosn(winposn)
627   " restore options to user settings
628   let &report = reportkeep
629   let &lz     = lzkeep
631 "  call Dret("DestroyMark")
632 endfun
634 " ---------------------------------------------------------------------
635 " QArgSplitter: to avoid \ processing by <f-args>, <q-args> is needed. {{{2
636 " However, <q-args> doesn't split at all, so this one returns a list
637 " with splits at all whitespace (only!), plus a leading length-of-list.
638 " The resulting list:  qarglist[0] corresponds to a:0
639 "                      qarglist[i] corresponds to a:{i}
640 fun! QArgSplitter(qarg)
641 "  call Dfunc("QArgSplitter(qarg<".a:qarg.">)")
642   let qarglist    = split(a:qarg)
643   let qarglistlen = len(qarglist)
644   let qarglist    = insert(qarglist,qarglistlen)
645 "  call Dret("QArgSplitter ".string(qarglist))
646   return qarglist
647 endfun
649 " ---------------------------------------------------------------------
650 " ListWinPosn: {{{2
651 "fun! ListWinPosn()                                                        " Decho 
652 "  if !exists("b:cecutil_iwinposn") || b:cecutil_iwinposn == 0             " Decho 
653 "   call Decho("nothing on SWP stack")                                     " Decho
654 "  else                                                                    " Decho
655 "   let jwinposn= b:cecutil_iwinposn                                       " Decho 
656 "   while jwinposn >= 1                                                    " Decho 
657 "    if exists("b:cecutil_winposn{jwinposn}")                              " Decho 
658 "     call Decho("winposn{".jwinposn."}<".b:cecutil_winposn{jwinposn}.">") " Decho 
659 "    else                                                                  " Decho 
660 "     call Decho("winposn{".jwinposn."} -- doesn't exist")                 " Decho 
661 "    endif                                                                 " Decho 
662 "    let jwinposn= jwinposn - 1                                            " Decho 
663 "   endwhile                                                               " Decho 
664 "  endif                                                                   " Decho
665 "endfun                                                                    " Decho 
666 "com! -nargs=0 LWP      call ListWinPosn()                                    " Decho 
668 " ---------------------------------------------------------------------
669 " SaveUserMaps: this function sets up a script-variable (s:restoremap) {{{2
670 "          which can be used to restore user maps later with
671 "          call RestoreUserMaps()
673 "          mapmode - see :help maparg for details (n v o i c l "")
674 "                    ex. "n" = Normal
675 "                    The letters "b" and "u" are optional prefixes;
676 "                    The "u" means that the map will also be unmapped
677 "                    The "b" means that the map has a <buffer> qualifier
678 "                    ex. "un"  = Normal + unmapping
679 "                    ex. "bn"  = Normal + <buffer>
680 "                    ex. "bun" = Normal + <buffer> + unmapping
681 "                    ex. "ubn" = Normal + <buffer> + unmapping
682 "          maplead - see mapchx
683 "          mapchx  - "<something>" handled as a single map item.
684 "                    ex. "<left>"
685 "                  - "string" a string of single letters which are actually
686 "                    multiple two-letter maps (using the maplead:
687 "                    maplead . each_character_in_string)
688 "                    ex. maplead="\" and mapchx="abc" saves user mappings for
689 "                        \a, \b, and \c
690 "                    Of course, if maplead is "", then for mapchx="abc",
691 "                    mappings for a, b, and c are saved.
692 "                  - :something  handled as a single map item, w/o the ":"
693 "                    ex.  mapchx= ":abc" will save a mapping for "abc"
694 "          suffix  - a string unique to your plugin
695 "                    ex.  suffix= "DrawIt"
696 fun! SaveUserMaps(mapmode,maplead,mapchx,suffix)
697 "  call Dfunc("SaveUserMaps(mapmode<".a:mapmode."> maplead<".a:maplead."> mapchx<".a:mapchx."> suffix<".a:suffix.">)")
699   if !exists("s:restoremap_{a:suffix}")
700    " initialize restoremap_suffix to null string
701    let s:restoremap_{a:suffix}= ""
702   endif
704   " set up dounmap: if 1, then save and unmap  (a:mapmode leads with a "u")
705   "                 if 0, save only
706   let mapmode  = a:mapmode
707   let dounmap  = 0
708   let dobuffer = ""
709   while mapmode =~ '^[bu]'
710    if     mapmode =~ '^u'
711     let dounmap= 1
712     let mapmode= strpart(a:mapmode,1)
713    elseif mapmode =~ '^b'
714     let dobuffer= "<buffer> "
715     let mapmode= strpart(a:mapmode,1)
716    endif
717   endwhile
718 "  call Decho("dounmap=".dounmap."  dobuffer<".dobuffer.">")
720   " save single map :...something...
721   if strpart(a:mapchx,0,1) == ':'
722 "   call Decho("save single map :...something...")
723    let amap= strpart(a:mapchx,1)
724    if amap == "|" || amap == "\<c-v>"
725     let amap= "\<c-v>".amap
726    endif
727    let amap                    = a:maplead.amap
728    let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|:silent! ".mapmode."unmap ".dobuffer.amap
729    if maparg(amap,mapmode) != ""
730     let maprhs                  = substitute(maparg(amap,mapmode),'|','<bar>','ge')
731         let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|:".mapmode."map ".dobuffer.amap." ".maprhs
732    endif
733    if dounmap
734         exe "silent! ".mapmode."unmap ".dobuffer.amap
735    endif
737   " save single map <something>
738   elseif strpart(a:mapchx,0,1) == '<'
739 "   call Decho("save single map <something>")
740    let amap       = a:mapchx
741    if amap == "|" || amap == "\<c-v>"
742     let amap= "\<c-v>".amap
743 "       call Decho("amap[[".amap."]]")
744    endif
745    let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|silent! ".mapmode."unmap ".dobuffer.amap
746    if maparg(a:mapchx,mapmode) != ""
747     let maprhs                  = substitute(maparg(amap,mapmode),'|','<bar>','ge')
748         let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|".mapmode."map ".amap." ".dobuffer.maprhs
749    endif
750    if dounmap
751         exe "silent! ".mapmode."unmap ".dobuffer.amap
752    endif
754   " save multiple maps
755   else
756 "   call Decho("save multiple maps")
757    let i= 1
758    while i <= strlen(a:mapchx)
759     let amap= a:maplead.strpart(a:mapchx,i-1,1)
760         if amap == "|" || amap == "\<c-v>"
761          let amap= "\<c-v>".amap
762         endif
763         let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|silent! ".mapmode."unmap ".dobuffer.amap
764     if maparg(amap,mapmode) != ""
765      let maprhs                  = substitute(maparg(amap,mapmode),'|','<bar>','ge')
766          let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|".mapmode."map ".amap." ".dobuffer.maprhs
767     endif
768         if dounmap
769          exe "silent! ".mapmode."unmap ".dobuffer.amap
770         endif
771     let i= i + 1
772    endwhile
773   endif
774 "  call Dret("SaveUserMaps : restoremap_".a:suffix.": ".s:restoremap_{a:suffix})
775 endfun
777 " ---------------------------------------------------------------------
778 " RestoreUserMaps: {{{2
779 "   Used to restore user maps saved by SaveUserMaps()
780 fun! RestoreUserMaps(suffix)
781 "  call Dfunc("RestoreUserMaps(suffix<".a:suffix.">)")
782   if exists("s:restoremap_{a:suffix}")
783    let s:restoremap_{a:suffix}= substitute(s:restoremap_{a:suffix},'|\s*$','','e')
784    if s:restoremap_{a:suffix} != ""
785 "       call Decho("exe ".s:restoremap_{a:suffix})
786     exe "silent! ".s:restoremap_{a:suffix}
787    endif
788    unlet s:restoremap_{a:suffix}
789   endif
790 "  call Dret("RestoreUserMaps")
791 endfun
793 " ==============
794 "  Restore: {{{1
795 " ==============
796 let &cpo= s:keepcpo
797 unlet s:keepcpo
799 " ================
800 "  Modelines: {{{1
801 " ================
802 " vim: ts=4 fdm=marker
803 doc/Align.txt   [[[1
804 1469
805 *align.txt*     The Alignment Tool                      Mar 04, 2009
807 Author:    Charles E. Campbell, Jr.  <NdrOchip@ScampbellPfamily.AbizM>
808            (remove NOSPAM from Campbell's email first)
809 Copyright: (c) 2004-2008 by Charles E. Campbell, Jr.    *Align-copyright*
810            The VIM LICENSE applies to Align.vim, AlignMaps.vim, and Align.txt
811            (see |copyright|) except use "Align and AlignMaps" instead of "Vim"
812            NO WARRANTY, EXPRESS OR IMPLIED.  USE AT-YOUR-OWN-RISK.
814 ==============================================================================
815 1. Contents                                     *align* *align-contents* {{{1
817         1. Contents.................: |align-contents|
818         2. Alignment Manual.........: |align-manual|
819         3. Alignment Usage..........: |align-usage|
820            Alignment Concepts.......: |align-concepts|
821            Alignment Commands.......: |align-commands|
822            Alignment Control........: |align-control|
823              Separators.............: |alignctrl-separators|
824              Initial Whitespace.....: |alignctrl-w| |alignctrl-W| |alignctrl-I|
825              Justification..........: |alignctrl-l| |alignctrl-r| |alignctrl-c|
826              Justification Control..: |alignctrl--| |alignctrl-+| |alignctrl-:|
827              Cyclic/Sequential......: |alignctrl-=| |alignctrl-C|
828              Separator Justification: |alignctrl-<| |alignctrl->| |alignctrl-||
829              Line (de)Selection.....: |alignctrl-g| |alignctrl-v|
830              Temporary Settings.....: |alignctrl-m|
831              Padding................: |alignctrl-p| |alignctrl-P|
832              Current Options........: |alignctrl-settings| |alignctrl-|
833            Alignment................: |align-align|
834         4. Alignment Maps...........: |align-maps|
835              \a,....................: |alignmap-a,|
836              \a?....................: |alignmap-a?|
837              \a<....................: |alignmap-a<|
838              \abox..................: |alignmap-abox|
839              \acom..................: |alignmap-acom|
840              \anum..................: |alignmap-anum|
841              \ascom.................: |alignmap-ascom|
842              \adec..................: |alignmap-adec|
843              \adef..................: |alignmap-adef|
844              \afnc..................: |alignmap-afnc|
845              \adcom.................: |alignmap-adcom|
846              \aocom.................: |alignmap-aocom|
847              \tsp...................: |alignmap-tsp|
848              \tsq...................: |alignmap-tsq|
849              \tt....................: |alignmap-tt|
850              \t=....................: |alignmap-t=|
851              \T=....................: |alignmap-T=|
852              \Htd...................: |alignmap-Htd|
853         5. Alignment Tool History...: |align-history|
855 ==============================================================================
856 2. Align Manual                 *alignman* *alignmanual* *align-manual* {{{1
858         Align comes as a vimball; simply typing >
859                 vim Align.vba.gz
860                 :so %
861 <       should put its components where they belong.  The components are: >
862                 .vim/plugin/AlignPlugin.vim
863                 .vim/plugin/AlignMapsPlugin.vim
864                 .vim/plugin/cecutil.vim
865                 .vim/autoload/Align.vim
866                 .vim/autoload/AlignMaps.vim
867                 .vim/doc/Align.txt
868 <       To see a user's guide, see |align-userguide|
869         To see examples, see |alignctrl| and |alignmaps|
871 /=============+=========+=====================================================\
872 ||            \ Default/                                                     ||
873 ||  Commands   \ Value/                Explanation                           ||
874 ||              |    |                                                       ||
875 ++==============+====+=======================================================++
876 ||  AlignCtrl   |    |  =Clrc-+:pPIWw [..list-of-separator-patterns..]       ||
877 ||              |    +-------------------------------------------------------+|
878 ||              |    |  may be called as a command or as a function:         ||
879 ||              |    |  :AlignCtrl =lp0P0W & \\                              ||
880 ||              |    |  :call Align#AlignCtrl('=lp0P0W','&','\\')            ||
881 ||              |    |                                                       ||
882 ||              |    +-------------------------------------------------------++
883 ||   1st arg    |  = | =  all separator patterns are equivalent and are      ||
884 ||              |    |    simultaneously active. Patterns are |regexp|.      ||
885 ||              |    | C  cycle through separator patterns.  Patterns are    ||
886 ||              |    |    |regexp| and are active sequentially.              ||
887 ||              |    |                                                       ||
888 ||              |  < | <  left justify separator   Separators are justified, ||
889 ||              |    | >  right justify separator  too.  Separator styles    ||
890 ||              |    | |  center separator         are cyclic.               ||
891 ||              |    |                                                       ||
892 ||              |  l | l  left justify   Justification styles are always     ||
893 ||              |    | r  right justify  cyclic (ie. lrc would mean left j., ||
894 ||              |    | c  center         then right j., then center, repeat. ||
895 ||              |    | -  skip this separator                                ||
896 ||              |    | +  re-use last justification method                   ||
897 ||              |    | :  treat rest of text as a field                      ||
898 ||              |    |                                                       ||
899 ||              | p1 | p### pad separator on left  by # blanks               ||
900 ||              | P1 | P### pad separator on right by # blanks               ||
901 ||              |    |                                                       ||
902 ||              |  I | I  preserve and apply first line's leading white      ||
903 ||              |    |    space to all lines                                 ||
904 ||              |    | W  preserve leading white space on every line, even   ||
905 ||              |    |    if it varies from line to line                     ||
906 ||              |    | w  don't preserve leading white space                 ||
907 ||              |    |                                                       ||
908 ||              |    | g  second argument is a selection pattern -- only     ||
909 ||              |    |    align on lines that have a match  (inspired by     ||
910 ||              |    |    :g/selection pattern/command)                      ||
911 ||              |    | v  second argument is a selection pattern -- only     ||
912 ||              |    |    align on lines that _don't_ have a match (inspired ||
913 ||              |    |    by :v/selection pattern/command)                   ||
914 ||              |    |                                                       ||
915 ||              |    | m  Map support: AlignCtrl will immediately do an      ||
916 ||              |    |    AlignPush() and the next call to Align() will do   ||
917 ||              |    |    an AlignPop at the end.  This feature allows maps  ||
918 ||              |    |    to preserve user settings.                         ||
919 ||              |    |                                                       ||
920 ||              |    | default                                               ||
921 ||              |    |    AlignCtrl default                                  ||
922 ||              |    |    will clear the AlignCtrl                           ||
923 ||              |    |    stack & set the default:  AlignCtrl "Ilp1P1=" '='  ||
924 ||              |    |                                                       ||
925 ||              +----+-------------------------------------------------------+|
926 ||  More args   |  More arguments are interpreted as describing separators   ||
927 ||              +------------------------------------------------------------+|
928 ||   No args    |  AlignCtrl will display its current settings               ||
929 ||==============+============================================================+|
930 ||[range]Align  |   [..list-of-separators..]                                 ||
931 ||[range]Align! |   [AlignCtrl settings] [..list-of-separators..]            ||
932 ||              +------------------------------------------------------------+|
933 ||              |  Aligns text over the given range.  The range may be       ||
934 ||              |  selected via visual mode (v, V, or ctrl-v) or via         ||
935 ||              |  the command line.  The Align operation may be invoked     ||
936 ||              |  as a command or as a function; as a function, the first   ||
937 ||              |  argument is 0=separators only, 1=AlignCtrl option string  ||
938 ||              |  followed by a list of separators.                         ||
939 ||              |   :[range]Align                                            ||
940 ||              |   :[range]Align [list of separators]                       ||
941 ||              |   :[range]call Align#Align(0)                              ||
942 ||              |   :[range]call Align#Align(0,"list","of","separators",...) ||
943 \=============================================================================/
945 ==============================================================================
946 3. Alignment Usage      *alignusage* *align-usage* *align-userguide* {{{1
949 ALIGNMENT CONCEPTS                      *align-concept* *align-concepts* {{{2
951         The typical text to be aligned is considered to be:
953                 * composed of two or more fields
954                 * separated by one or more separator pattern(s):
955                 * two or more lines
957                 ws field ws separator ws field ws separator ...
958                 ws field ws separator ws field ws separator ...
960         where "ws" stands for "white space" such as blanks and/or tabs,
961         and "fields" are arbitrary text.  For example, consider >
963                 x= y= z= 3;
964                 xx= yy= zz= 4;
965                 zzz= yyy= zzz= 5;
966                 a= b= c= 3;
968         Assume that it is desired to line up all the "=" signs; these,
969         then, are the separators.  The fields are composed of all the
970         alphameric text.  Assuming they lie on lines 1-4, one may align
971         those "=" signs with: >
972                 :AlignCtrl l
973                 :1,4Align =
974 <       The result is: >
975                 x   = y   = z   = 3;
976                 xx  = yy  = zz  = 4;
977                 zzz = yyy = zzz = 5;
978                 a   = b   = c   = 3;
980 <       Note how each "=" sign is surrounded by a single space; the
981         default padding is p1P1 (p1 means one space before the separator,
982         and P1 means one space after it).  If you wish to change the
983         padding, say to no padding, use  (see |alignctrl-p|) >
984                 :AlignCtrl lp0P0
986 <       Next, note how each field is left justified; that's what the "l"
987         (a small letter "ell") does.  If right-justification of the fields
988         had been desired, an "r" could've been used: >
989                 :AlignCtrl r
990 <       yielding >
991                   x =   y =   z = 3;
992                  xx =  yy =  zz = 4;
993                 zzz = yyy = zzz = 5;
994                   a =   b =   c = 3;
995 <       There are many more options available for field justification: see
996         |alignctrl-c| and |alignctrl--|.
998         Separators, although commonly only one character long, are actually
999         specified by regular expressions (see |regexp|), and one may left
1000         justify, right justify, or center them, too (see |alignctrl-<|).
1002         Assume that for some reason a left-right-left-right-... justification
1003         sequence was wished.  This wish is simply achieved with >
1004                 :AlignCtrl lr
1005                 :1,4Align =
1006 <       because the justification commands are considered to be "cylic"; ie.
1007         lr is the same as lrlrlrlrlrlrlr...
1009         There's a lot more discussed under |alignctrl|; hopefully the examples
1010         there will help, too.
1013 ALIGNMENT COMMANDS                      *align-command* *align-commands* {{{2
1015         The <Align.vim> script includes two primary commands and two
1016         minor commands:
1018           AlignCtrl : this command/function sets up alignment options
1019                       which persist until changed for later Align calls.
1020                       It controls such things as: how to specify field
1021                       separators, initial white space, padding about
1022                       separators, left/right/center justification, etc. >
1023                         ex.  AlignCtrl wp0P1
1024                              Interpretation: during subsequent alignment
1025                              operations, preserve each line's initial
1026                              whitespace.  Use no padding before separators
1027                              but provide one padding space after separators.
1029           Align     : this command/function operates on the range given it to
1030                       align text based on one or more separator patterns.  The
1031                       patterns may be provided via AlignCtrl or via Align
1032                       itself. >
1034                         ex. :%Align ,
1035                             Interpretation: align all commas over the entire
1036                             file.
1037 <                     The :Align! format permits alignment control commands
1038                       to precede the alignment patterns. >
1039                         ex. :%Align! p2P2 =
1040 <                     This will align all "=" in the file with two padding
1041                       spaces on both sides of each "=" sign.
1043                       NOTE ON USING PATTERNS WITH ALIGN:~
1044                       Align and AlignCtrl use |<q-args>| to obtain their
1045                       input patterns and they use an internal function to
1046                       split arguments at whitespace unless inside "..."s.
1047                       One may escape characters inside a double-quote string
1048                       by preceding such characters with a backslash.
1050           AlignPush : this command/function pushes the current AlignCtrl
1051                       state onto an internal stack. >
1052                         ex. :AlignPush
1053                             Interpretation: save the current AlignCtrl
1054                             settings, whatever they may be.  They'll
1055                             also remain as the current settings until
1056                             AlignCtrl is used to change them.
1058           AlignPop  : this command/function pops the current AlignCtrl
1059                       state from an internal stack. >
1060                         ex. :AlignPop
1061                             Interpretation: presumably AlignPush was
1062                             used (at least once) previously; this command
1063                             restores the AlignCtrl settings when AlignPush
1064                             was last used.
1065 <                     Also see |alignctrl-m| for a way to automatically do
1066                       an AlignPop after an Align (primarily this is for maps).
1068 ALIGNMENT OPTIONS                       *align-option* *align-options* {{{2
1069     *align-utf8* *align-utf* *align-codepoint* *align-strlen* *align-multibyte*
1071         For those of you who are using 2-byte (or more) characters such as are
1072         available with utf-8, Align now provides a special option which you
1073         may choose based upon your needs:
1075         Use Built-in strlen() ~
1077                         let g:Align_xstrlen= 0
1079 <       This is the fastest method, but it doesn't handle multibyte characters
1080         well.  It is the default for:
1082           enc=latin1
1083           vim compiled without multi-byte support
1084           $LANG is en_US.UTF-8 (assuming USA english)
1086         Number of codepoints (Latin a + combining circumflex is two codepoints)~
1088                         let g:Align_xstrlen= 1              (default)
1090         Number of spacing codepoints (Latin a + combining circumflex is one~
1091         spacing codepoint; a hard tab is one; wide and narrow CJK are one~
1092         each; etc.)~
1094                         let g:Align_xstrlen= 2
1096         Virtual length (counting, for instance, tabs as anything between 1 and~
1097         'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when~
1098         immediately preceded by lam, one otherwise, etc.)~
1100                         let g:Align_xstrlen= 3
1102         By putting one of these settings into your <.vimrc>, Align will use an
1103         internal (interpreted) function to determine a string's length instead
1104         of the Vim's built-in |strlen()| function.  Since the function is
1105         interpreted, Align will run a bit slower but will handle such strings
1106         correctly.  The last setting (g:Align_xstrlen= 3) probably will run
1107         the slowest but be the most accurate.  (thanks to Tony Mechelynck for
1108         these)
1111 ALIGNMENT CONTROL                               *alignctrl* *align-control* {{{2
1113         This command doesn't do the alignment operation itself; instead, it
1114         controls subsequent alignment operation(s).
1116         The first argument to AlignCtrl is a string which may contain one or
1117         more alignment control settings.  Most of the settings are specified
1118         by single letters; the exceptions are the p# and P# commands which
1119         interpret a digit following the p or P as specifying padding about the
1120         separator.
1122         The typical text line is considered to be composed of two or more
1123         fields separated by one or more separator pattern(s): >
1125                 ws field ws separator ws field ws separator ...
1127         where "ws" stands for "white space" such as blanks and/or tabs.
1129         
1130         SEPARATORS                              *alignctrl-separators* {{{3
1132         As a result, separators may not have white space (tabs or blanks) on
1133         their outsides (ie.  ":  :" is fine as a separator, but " :: " is
1134         not).  Usually such separators are not needed, although a map has been
1135         provided which works around this limitation and aligns on whitespace
1136         (see |alignmap-tsp|).
1138         However, if you really need to have separators with leading or
1139         trailing whitespace, consider handling them by performing a substitute
1140         first (ie. s/  ::  /@/g), do the alignment on the temporary pattern
1141         (ie. @), and then perform a substitute to revert the separators back
1142         to their desired condition (ie. s/@/  ::  /g).
1144         The Align#Align() function will first convert tabs over the region into
1145         spaces and then apply alignment control.  Except for initial white
1146         space, white space surrounding the fields is ignored.  One has three
1147         options just for handling initial white space:
1150         ---                                             *alignctrl-w*
1151         wWI     INITIAL WHITE SPACE                     *alignctrl-W* {{{3
1152         ---                                             *alignctrl-I*
1153                 w : ignore all selected lines' initial white space
1154                 W : retain all selected lines' initial white space
1155                 I : retain only the first line's initial white space and
1156                     re-use it for subsequent lines
1158         Example: Leading white space options: >
1159                          +---------------+-------------------+-----------------+
1160                          |AlignCtrl w= :=|  AlignCtrl W= :=  | AlignCtrl I= := |
1161       +------------------+---------------+-------------------+-----------------+
1162       |     Original     |   w option    |     W option      |     I option    |
1163       +------------------+---------------+-------------------+-----------------+
1164       |   a := baaa      |a     := baaa  |   a      : = baaa |   a     := baaa |
1165       | caaaa := deeee   |caaaa := deeee | caaaa    : = deeee|   caaaa := deeee|
1166       |       ee := f    |ee    := f     |       ee : = f    |   ee    := f    |
1167       +------------------+---------------+-------------------+-----------------+
1169         The original has at least one leading white space on every line.
1170         Using Align with w eliminated each line's leading white space.
1171         Using Align with W preserved  each line's leading white space.
1172         Using Align with I applied the first line's leading white space
1173                            (three spaces) to each line.
1176         ------                                          *alignctrl-l*
1177         lrc-+:  FIELD JUSTIFICATION                     *alignctrl-r* {{{3
1178         ------                                          *alignctrl-c*
1180         With "lrc", the fields will be left-justified, right-justified, or
1181         centered as indicated by the justification specifiers (lrc).  The
1182         "lrc" options are re-used by cycling through them as needed:
1184                 l   means llllll....
1185                 r   means rrrrrr....
1186                 lr  means lrlrlr....
1187                 llr means llrllr....
1189      Example: Justification options: Align = >
1190      +------------+-------------------+-------------------+-------------------+
1191      |  Original  |  AlignCtrl l      | AlignCtrl r       | AlignCtrl lr      |
1192      +------------+-------------------+-------------------+-------------------+
1193      | a=bb=ccc=1 |a   = bb  = ccc = 1|  a =  bb = ccc = 1|a   =  bb = ccc = 1|
1194      | ccc=a=bb=2 |ccc = a   = bb  = 2|ccc =   a =  bb = 2|ccc =   a = bb  = 2|
1195      | dd=eee=f=3 |dd  = eee = f   = 3| dd = eee =   f = 3|dd  = eee = f   = 3|
1196      +------------+-------------------+-------------------+-------------------+
1197      | Alignment  |l     l     l     l|  r     r     r   r|l       r   l     r|
1198      +------------+-------------------+-------------------+-------------------+
1200                 AlignCtrl l : The = separator is repeatedly re-used, as the
1201                               cycle only consists of one character (the "l").
1202                               Every time left-justification is used for fields.
1203                 AlignCtrl r : The = separator is repeatedly re-used, as the
1204                               cycle only consists of one character (the "l").
1205                               Every time right-justification is used for fields
1206                 AlignCtrl lr: Again, the "=" separator is repeatedly re-used,
1207                               but the fields are justified alternately between
1208                               left and right.
1210         Even more separator control is available.  With "-+:":
1212             - : skip treating the separator as a separator.   *alignctrl--*
1213             + : repeat use of the last "lrc" justification    *alignctrl-+*
1214             : : treat the rest of the line as a single field  *alignctrl-:*
1216      Example: More justification options:  Align = >
1217      +------------+---------------+--------------------+---------------+
1218      |  Original  |  AlignCtrl -l | AlignCtrl rl+      | AlignCtrl l:  |
1219      +------------+---------------+--------------------+---------------+
1220      | a=bb=ccc=1 |a=bb   = ccc=1 |  a = bb  = ccc = 1 |a   = bb=ccc=1 |
1221      | ccc=a=bb=2 |ccc=a  = bb=2  |ccc = a   = bb  = 2 |ccc = a=bb=2   |
1222      | dd=eee=f=3 |dd=eee = f=3   | dd = eee = f   = 3 |dd  = eee=f=3  |
1223      +------------+---------------+--------------------+---------------+
1224      | Alignment  |l        l     |  r   l     l     l |l     l        |
1225      +------------+---------------+--------------------+---------------+
1227         In the first example in "More justification options":
1229           The first "=" separator is skipped by the "-" specification,
1230           and so "a=bb", "ccc=a", and "dd=eee" are considered as single fields.
1232           The next "=" separator has its (left side) field left-justified.
1233           Due to the cyclic nature of separator patterns, the "-l"
1234           specification is equivalent to "-l-l-l ...".
1236           Hence the next specification is a "skip", so "ccc=1", etc are fields.
1238         In the second example in "More justification options":
1240           The first field is right-justified, the second field is left
1241           justified, and all remaining fields repeat the last justification
1242           command (ie. they are left justified, too).
1244           Hence rl+ is equivalent to         rlllllllll ...
1245           (whereas plain rl is equivalent to rlrlrlrlrl ... ).
1247         In the third example in "More justification options":
1249           The text following the first separator is treated as a single field.
1251         Thus using the - and : operators one can apply justification to a
1252         single separator.
1254         ex. 1st separator only:    AlignCtrl l:
1255             2nd separator only:    AlignCtrl -l:
1256             3rd separator only:    AlignCtrl --l:
1257             etc.
1260         ---                                                  *alignctrl-=*
1261         =C      CYCLIC VS ALL-ACTIVE SEPARATORS              *alignctrl-C* {{{3
1262         ---
1264         The separators themselves may be considered as equivalent and
1265         simultaneously active ("=") or sequentially cycled through ("C").
1266         Separators are regular expressions (|regexp|) and are specified as the
1267         second, third, etc arguments.  When the separator patterns are
1268         equivalent and simultaneously active, there will be one pattern
1269         constructed: >
1271                 AlignCtrl ... pat1 pat2 pat3
1272                 \(pat1\|pat2\|pat3\)
1274         Each separator pattern is thus equivalent and simultaneously active.
1275         The cyclic separator AlignCtrl option stores a list of patterns, only
1276         one of which is active for each field at a time.
1278         Example: Equivalent/Simultaneously-Active vs Cyclic Separators >
1279  +-------------+------------------+---------------------+----------------------+
1280  |   Original  | AlignCtrl = = + -| AlignCtrl = =       | AlignCtrl C = + -    |
1281  +-------------+------------------+---------------------+----------------------+
1282  |a = b + c - d|a = b + c - d     |a = b + c - d        |a = b         + c - d |
1283  |x = y = z + 2|x = y = z + 2     |x = y         = z + 2|x = y = z     + 2     |
1284  |w = s - t = 0|w = s - t = 0     |w = s - t     = 0    |w = s - t = 0         |
1285  +-------------+------------------+---------------------+----------------------+
1287         The original is initially aligned with all operators (=+-) being
1288         considered as equivalent and simultaneously active field separators.
1289         Thus the "AlignCtrl = = + -" example shows no change.
1291         The second example only accepts the '=' as a field separator;
1292         consequently "b + c - d" is now a single field.
1294         The third example illustrates cyclic field separators and is analyzed
1295         in the following illustration: >
1297         field1 separator field2    separator field3 separator field4
1298            a      =      b             +       c        -       d
1299            x      =      y = z         +       2
1300            w      =      s - t = 0
1302         The word "cyclic" is used because the patterns form a cycle of use; in
1303         the above case, its = + - = + - = + - = + -...
1305         Example: Cyclic separators >
1306                 Label : this is some text discussing ":"s | ex. abc:def:ghi
1307                 Label : this is some text with a ":" in it | ex. abc:def
1309           apply AlignCtrl lWC : | |
1310                 (select lines)Align >
1311                 Label : this is some text discussing ":"s  | ex. abc:def:ghi
1312                 Label : this is some text with a ":" in it | ex. abcd:efg
1314         In the current example,
1315           : is the first separator        So the first ":"s are aligned
1316           | is the second separator       but subsequent ":"s are not.
1317           | is the third separator        The "|"s are aligned, too.
1318           : is the fourth separator       Since there aren't two bars,
1319           | is the fifth separator        the subsequent potential cycles
1320           | is the sixth separator        don't appear.
1321          ...
1323         In this case it would probably have been a better idea to have used >
1324                 AlignCtrl WCl: : |
1325 <       as that alignment control would guarantee that no more cycling
1326         would be used after the vertical bar.
1328         Example: Cyclic separators
1330             Original: >
1331                 a| b&c | (d|e) & f-g-h
1332                 aa| bb&cc | (dd|ee) & ff-gg-hh
1333                 aaa| bbb&ccc | (ddd|eee) & fff-ggg-hhh
1335             AlignCtrl C | | & - >
1336                 a   | b&c     | (d|e)     & f   - g-h
1337                 aa  | bb&cc   | (dd|ee)   & ff  - gg-hh
1338                 aaa | bbb&ccc | (ddd|eee) & fff - ggg-hhh
1340         In this example,
1341         the first and second separators are "|",
1342         the third            separator  is  "&", and
1343         the fourth           separator  is  "-",
1345         (cycling)
1346         the fifth and sixth  separators are "|",
1347         the seventh          separator  is  "&", and
1348         the eighth           separator  is  "-", etc.
1350         Thus the first "&"s are (not yet) separators, and hence are treated as
1351         part of the field.  Ignoring white space for the moment, the AlignCtrl
1352         shown here means that Align will work with >
1354         field | field | field & field - field | field | field & field - ...
1357         ---                                             *alignctrl-<*
1358         <>|     SEPARATOR JUSTIFICATION                 *alignctrl->* {{{3
1359         ---                                             *alignctrl-|*
1361         Separators may be of differing lengths as shown in the example below.
1362         Hence they too may be justified left, right, or centered.
1363         Furthermore, separator justification specifications are cyclic:
1365                 <  means <<<<<...    justify separator(s) to the left
1366                 >  means >>>>>...    justify separator(s) to the right
1367                 |  means |||||...    center separator(s)
1369         Example: Separator Justification: Align -\+ >
1370                                 +-----------------+
1371                                 |    Original     |
1372                                 +-----------------+
1373                                 | a - bbb - c     |
1374                                 | aa -- bb -- ccc |
1375                                 | aaa --- b --- cc|
1376         +---------------------+-+-----------------+-+---------------------+
1377         |     AlignCtrl <     |     AlignCtrl >     |     AlignCtrl |     |
1378         +---------------------+---------------------+---------------------+
1379         | a   -   bbb -   c   | a     - bbb   - c   | a    -  bbb  -  c   |
1380         | aa  --  bb  --  ccc | aa   -- bb   -- ccc | aa  --  bb  --  ccc |
1381         | aaa --- b   --- cc  | aaa --- b   --- cc  | aaa --- b   --- cc  |
1382         +---------------------+---------------------+---------------------+
1385         ---                                             *alignctrl-g*
1386         gv      SELECTIVE APPLICATION                   *alignctrl-v* {{{3
1387         ---
1390         These two options provide a way to select (g) or to deselect (v) lines
1391         based on a pattern.  Ideally :g/pat/Align  would work; unfortunately
1392         it results in Align#Align() being called on each line satisfying the
1393         pattern separately. >
1395                 AlignCtrl g pattern
1397         Align will only consider those lines which have the given pattern. >
1399                 AlignCtrl v pattern
1401         Align will only consider those lines without the given pattern.  As an
1402         example of use, consider the following example: >
1404                                            :AlignCtrl v ^\s*/\*
1405           Original          :Align =       :Align =
1406         +----------------+------------------+----------------+
1407         |one= 2;         |one     = 2;      |one   = 2;      |
1408         |three= 4;       |three   = 4;      |three = 4;      |
1409         |/* skip=this */ |/* skip = this */ |/* skip=this */ |
1410         |five= 6;        |five    = 6;      |five  = 6;      |
1411         +----------------+------------------+----------------+
1413         The first "Align =" aligned with all "="s, including that one in the
1414         "skip=this" comment.
1416         The second "Align =" had a AlignCtrl v-pattern which caused it to skip
1417         (ignore) the "skip=this" line when aligning.
1418         
1419         To remove AlignCtrl's g and v patterns, use (as appropriate) >
1421                 AlignCtrl g
1422                 AlignCtrl v
1424         To see what g/v patterns are currently active, just use the reporting
1425         capability of an unadorned call to AlignCtrl: >
1427                 AlignCtrl
1430         ---
1431          m      MAP SUPPORT                             *alignctrl-m* {{{3
1432         ---
1434         This option primarily supports the development of maps.  The
1435         Align#AlignCtrl() call will first do an Align#AlignPush() (ie. retain
1436         current alignment control settings).  The next Align#Align() will, in
1437         addition to its alignment job, finish up with an Align#AlignPop().
1438         Thus the Align#AlignCtrl settings that follow the "m" are only
1439         temporarily in effect for just the next Align#Align().
1442         ---
1443         p###                                            *alignctrl-p*
1444         P###    PADDING                                 *alignctrl-P* {{{3
1445         ---
1447         These two options control pre-padding and post-padding with blanks
1448         about the separator.  One may pad separators with zero to nine spaces;
1449         the padding number(s) is/are treated as a cyclic parameter.  Thus one
1450         may specify padding separately for each field or re-use a padding
1451         pattern. >
1453         Example:          AlignCtrl p102P0
1454         +---------+----------------------------------+
1455         | Original| a=b=c=d=e=f=g=h=1                |
1456         | Align = | a =b=c  =d =e=f  =g =h=1         |
1457         +---------+----------------------------------+
1458         | prepad  |   1 0   2  1 0   2  1 0          |
1459         +---------+----------------------------------+
1461         This example will cause Align to:
1463                 pre-pad the first  "=" with a single blank,
1464                 pre-pad the second "=" with no blanks,
1465                 pre-pad the third  "=" with two blanks,
1466                 pre-pad the fourth "=" with a single blank,
1467                 pre-pad the fifth  "=" with no blanks,
1468                 pre-pad the sixth  "=" with two blanks,
1469                 etc.
1471         ---------------                         *alignctrl-settings*
1472         No option given         DISPLAY STATUS  *alignctrl-*            {{{3
1473         ---------------                         *alignctrl-no-option*
1475         AlignCtrl, when called with no arguments, will display the current
1476         alignment control settings.  A typical display is shown below: >
1478                 AlignCtrl<=> qty=1 AlignStyle<l> Padding<1|1>
1479                 Pat1<\(=\)>
1481         Interpreting, this means that the separator patterns are all
1482         equivalent; in this case, there's only one (qty=1).  Fields will be
1483         padded on the right with spaces (left justification), and separators
1484         will be padded on each side with a single space.
1486         To change one of these items, see:
1488           AlignCtrl......|alignctrl|
1489           qty............|align-concept|
1490           AlignStyle.....|alignctrl--| |alignctrl-+| |alignctrl-:||alignctrl-c|
1491           Padding........|alignctrl-p| |alignctrl-P|
1493         One may get a string which can be fed back into AlignCtrl: >
1495                 :let alignctrl= Align#AlignCtrl()
1497         This form will put a string describing the current AlignCtrl options,
1498         except for the "g" and "v" patterns, into a variable.  The
1499         Align#AlignCtrl() function will still echo its settings, however.  One
1500         can feed any non-supported "option" to AlignCtrl() to prevent this,
1501         however: >
1503                 :let alignctrl= Align#AlignCtrl("d")
1506 ALIGNMENT                                               *align-align* {{{2
1508         Once the alignment control has been determined, the user specifies a
1509         range of lines for the Align command/function to do its thing.
1510         Alignment is often done on a line-range basis, but one may also
1511         restrict alignment to a visual block using ctrl-v.  For any visual
1512         mode, one types the colon (:) and then "Align".  One may, of course,
1513         specify a range of lines: >
1515                 :[range]Align [list-of-separators]
1517         where the |:range| is the usual Vim-powered set of possibilities; the
1518         list of separators is the same as the AlignCtrl capability.  There is
1519         only one list of separators, but either AlignCtrl or Align can be used
1520         to specify that list.
1522         An alternative form of the Align command can handle both alignment
1523         control and the separator list: >
1525                 :[range]Align! [alignment-control-string] [list-of-separators]
1527         The alignment control string will be applied only for this particular
1528         application of Align (it uses |alignctrl-m|).  The "g pattern" and
1529         "v pattern" alignment controls (see |alignctrl-g| and |alignctrl-v|)
1530         are also available via this form of the Align command.
1532         Align makes two passes over the text to be aligned.  The first pass
1533         determines how many fields there are and determines the maximum sizes
1534         of each field; these sizes are then stored in a vector.  The second
1535         pass pads the field (left/right/centered as specified) to bring its
1536         length up to the maximum size of the field.  Then the separator and
1537         its AlignCtrl-specified padding is appended.
1539                 Pseudo-Code:~
1540                  During pass 1
1541                  | For all fields in the current line
1542                  || Determine current separator
1543                  || Examine field specified by current separator
1544                  || Determine length of field and save if largest thus far
1545                  Initialize newline based on initial whitespace option (wWI)
1546                  During pass 2
1547                  | For all fields in current line
1548                  || Determine current separator
1549                  || Extract field specified by current separator
1550                  || Prepend/append padding as specified by AlignCtrl
1551                  || (right/left/center)-justify to fit field into max-size field
1552                  || Append separator with AlignCtrl-specified separator padding
1553                  || Delete current line, install newly aligned line
1555         The g and v AlignCtrl patterns cause the passes not to consider lines
1556         for alignment, either by requiring that the g-pattern be present or
1557         that the v-pattern not be present.
1559         The whitespace on either side of a separator is ignored.
1562 ==============================================================================
1563 4. Alignment Maps                               *alignmaps* *align-maps* {{{1
1565         There are a number of maps using Align#AlignCtrl() and Align#Align()
1566         in the <AlignMapsPlugin.vim> file.  This file may also be put into the
1567         plugins subdirectory.  Since AlignCtrl and Align supercede textab and
1568         its <ttalign.vim> file, the maps either have a leading "t" (for
1569         "textab") or the more complicated ones an "a" (for "alignment") for
1570         backwards compatibility.
1572         The maps are shown below with a leading backslash (\).  Actually, the
1573         <Leader> construct is used (see |mapleader|), so the maps' leading
1574         kick-off character is easily customized.
1576         Furthermore, all AlignMapsPlugin.vim maps use the <Plug> construct (see
1577         |<Plug>|and |usr_41.txt|).  Hence, if one wishes to override the
1578         mapping entirely, one may do that, too.  As an example: >
1579                 map <Leader>ACOM        <Plug>AM_acom
1580 <       would have \ACOM do what \acom previously did (assuming that the
1581         mapleader has been left at its default value of a backslash).
1583           \a,   : useful for breaking up comma-separated
1584                   declarations prior to \adec                   |alignmap-a,|
1585           \a(   : aligns ( and , (useful for prototypes)        *alignmap-a(*
1586           \a?   : aligns (...)? ...:... expressions on ? and :  |alignmap-a?|
1587           \a<   : aligns << and >> for c++                      |alignmap-a<|
1588           \a=   : aligns := assignments                         |alignmap-a=|
1589           \abox : draw a C-style comment box around text lines  |alignmap-abox|
1590           \acom : useful for aligning comments                  |alignmap-acom|
1591           \adcom: useful for aligning comments in declarations  |alignmap-adcom|
1592           \anum : useful for aligning numbers                   |alignmap-anum|
1593                   NOTE: For the visual-mode use of \anum, <vis.vim> is needed!
1594                     See http://mysite.verizon.net/astronaut/vim/index.html#VIS
1595           \aenum: align a European-style number                 |alignmap-anum|
1596           \aunum: align a USA-style number                      |alignmap-anum|
1597           \adec : useful for aligning declarations              |alignmap-adec|
1598           \adef : useful for aligning definitions               |alignmap-adef|
1599           \afnc : useful for aligning ansi-c style functions'
1600                   argument lists                                |alignmap-afnc|
1601           \adcom: a variant of \acom, restricted to comment     |alignmap-adcom|
1602                   containing lines only, but also only for
1603                   those which don't begin with a comment.
1604                   Good for certain declaration styles.
1605           \aocom: a variant of \acom, restricted to comment     |alignmap-aocom|
1606                   containing lines only
1607           \tab  : align a table based on tabs                   *alignmap-tab*
1608                   (converts to spaces)
1609           \tml  : useful for aligning the trailing backslashes  |alignmap-tml|
1610                   used to continue lines (shell programming, etc)
1611           \tsp  : use Align to make a table separated by blanks |alignmap-tsp|
1612                   (left justified)
1613           \ts,  : like \t, but swaps whitespace on the right of *alignmap-ts,*
1614                   the commas to their left
1615           \ts:  : like \t: but swaps whitespace on the right of *alignmap-ts:*
1616                   the colons to their left
1617           \ts<  : like \t< but swaps whitespace on the right of *alignmap-ts<*
1618                   the less-than signs to their left
1619           \ts=  : like \t= but swaps whitespace on the right of *alignmap-ts=*
1620                   the equals signs to their left
1621           \Tsp  : use Align to make a table separated by blanks |alignmap-Tsp|
1622                   (right justified)
1623           \tsq  : use Align to make a table separated by blanks |alignmap-tsq|
1624                   (left justified) -- "strings" are not split up
1625           \tt   : useful for aligning LaTeX tabular tables      |alignmap-tt|
1626           \Htd  : tabularizes html tables:                      |alignmap-Htd|
1627                   <TR><TD> ...field... </TD><TD> ...field... </TD></TR>
1629                   *alignmap-t|* *alignmap-t#* *alignmap-t,* *alignmap-t:*
1630                   *alignmap-t;* *alignmap-t<* *alignmap-t?* *alignmap-t~*
1631                   *alignmap-m=*
1632           \tx   : make a left-justified  alignment on
1633                   character "x" where "x" is: ,:<=@|#           |alignmap-t=|
1634           \Tx   : make a right-justified alignment on
1635                   character "x" where "x" is: ,:<=@#            |alignmap-T=|
1636           \m=   : like \t= but aligns with %... style comments
1638         The leading backslash is actually <leader> (see |mapleader| for how to
1639         customize the leader to be whatever you like).  These maps use the
1640         <Align.vim> package and are defined in the <AlignMaps.vim> file.
1641         Although the maps use AlignCtrl options, they typically use the "m"
1642         option which pushes the options (AlignPush).  The associated Align
1643         call which follows will then AlignPop the user's original options
1644         back.
1646         ALIGNMENT MAP USE WITH MARK AND MOVE~
1647         In the examples below, one may select the text with a "ma" at the
1648         first line, move to the last line, then execute the map.
1650         ALIGNMENT MAP USE WITH VISUAL MODE~
1651         Alternatively, one may select the text with the "V" visual mode
1652         command.
1654         ALIGNMENT MAP USE WITH MENUS~
1655         One may use the mark-and-move style (ma, move, use the menu) or
1656         the visual mode style (use the V visual mode, move, then select
1657         the alignment map with menu selection).  The alignment map menu
1658         items are under DrChip.AlignMaps .
1660         One may even change the top level menu name to whatever is wished; by
1661         default, its >
1662                 let g:DrChipTopLvlMenu= "DrChip."
1663 <       If you set the variable to the empty string (""), then no menu items
1664         will be produced.  Of course, one must have a vim with +menu, the gui
1665         must be running, and |'go'| must have the menu bar suboption (ie. m
1666         must be included).
1668         COMPLEX ALIGNMENT MAP METHOD~
1670         For those complex alignment maps which do alignment on constructs
1671         (e.g. \acom, \adec, etc), a series of substitutes is used to insert
1672         "@" symbols in appropriate locations.  Align#Align() is then used to
1673         do alignment directly on "@"s; then it is followed by further
1674         substitutes to do clean-up.  However, the maps \WS and \WE, used by
1675         every map supported by AlignMaps, protect any original embedded "@"
1676         symbols by first converting them to <DEL> characters, doing the
1677         requested job, and then converting them back. >
1679             \WS  calls AlignMaps#WrapperStart()
1680             \WE  calls AlignMaps#WrapperEnd()
1683         ---------------------------
1684         Alignment Map Examples: \a,                     *alignmap-a,* {{{3
1685         ---------------------------
1687         Original: illustrates comma-separated declaration splitting: >
1688                 int a,b,c;
1689                 struct ABC_str abc,def;
1691         Becomes: >
1692                 int a;
1693                 int b;
1694                 int c;
1695                 struct ABC_str abc;
1696                 struct ABC_str def;
1699         ---------------------------
1700         Alignment Map Examples: \a?                     *alignmap-a?* {{{3
1701         ---------------------------
1703         Original: illustrates ()?: aligning >
1704                 printf("<%s>\n",
1705                   (x == ABC)? "abc" :
1706                   (x == DEFG)? "defg" :
1707                   (x == HIJKL)? "hijkl" : "???");
1709         Becomes:  select "(x == ..." lines, then \a? >
1710                 printf("<%s>\n",
1711                   (x == ABC)?   "abc"   :
1712                   (x == DEFG)?  "defg"  :
1713                   (x == HIJKL)? "hijkl" : "???");
1716         ---------------------------
1717         Alignment Map Examples: \a<                     *alignmap-a<* {{{3
1718         ---------------------------
1720         Original: illustrating aligning of << and >> >
1721                 cin << x;
1722                 cin      << y;
1723                 cout << "this is x=" << x;
1724                 cout << "but y=" << y << "is not";
1726         Becomes:  select "(x == ..." lines, then \a< >
1727                 cin  << x;
1728                 cin  << y;
1729                 cout << "this is x=" << x;
1730                 cout << "but y="     << y  << "is not";
1733         ---------------------------
1734         Alignment Map Examples: \a=                     *alignmap-a=* {{{3
1735         ---------------------------
1737         Original: illustrates how to align := assignments >
1738                 aa:=bb:=cc:=1;
1739                 a:=b:=c:=1;
1740                 aaa:=bbb:=ccc:=1;
1741 <       
1742         Bcomes: select the three assignment lines, then \a:= >
1743                 aa  := bb  := cc  := 1;
1744                 a   := b   := c   := 1;
1745                 aaa := bbb := ccc := 1;
1748         ---------------------------
1749         Alignment Map Examples: \abox                   *alignmap-abox* {{{3
1750         ---------------------------
1752         Original: illustrates how to comment-box some text >
1753                 This is some plain text
1754                 which will
1755                 soon be surrounded by a
1756                 comment box.
1758         Becomes:  Select "This..box." with ctrl-v, press \abox >
1759                 /***************************
1760                  * This is some plain text *
1761                  * which will              *
1762                  * soon be surrounded by a *
1763                  * comment box.            *
1764                  ***************************/
1767         ---------------------------
1768         Alignment Map Examples: \acom                   *alignmap-acom* {{{3
1769         ---------------------------
1771         Original: illustrates aligning C-style comments (works for //, too) >
1772                 if(itworks) { /* this */
1773                         then= dothis; /* is a */
1774                         } /* set of three comments */
1776         Becomes: Select the three lines, press \acom >
1777                 if(itworks) {         /* this                  */
1778                         then= dothis; /* is a                  */
1779                         }             /* set of three comments */
1781         Also see |alignmap-aocom|
1784         ---------------------------
1785         Alignment Map Examples: \anum                   *alignmap-anum* {{{3
1786         ---------------------------
1788         Original: illustrates how to get numbers lined up >
1789                  -1.234 .5678 -.901e-4
1790                  1.234 5.678 9.01e-4
1791                  12.34 56.78 90.1e-4
1792                  123.4 567.8 901.e-4
1794         Becomes: Go to first line, ma.  Go to last line, press \anum >
1795                   -1.234    .5678   -.901e-4
1796                    1.234   5.678    9.01e-4
1797                   12.34   56.78    90.1e-4
1798                  123.4   567.8    901.e-4
1800         Original: >
1801                  | -1.234 .5678 -.901e-4 |
1802                  | 1.234 5.678 9.01e-4   |
1803                  | 12.34 56.78 90.1e-4   |
1804                  | 123.4 567.8 901.e-4   |
1806         Becomes: Select the numbers with ctrl-v (visual-block mode), >
1807                  press \anum
1808                  |  -1.234    .5678   -.901e-4 |
1809                  |   1.234   5.678    9.01e-4  |
1810                  |  12.34   56.78    90.1e-4   |
1811                  | 123.4   567.8    901.e-4    |
1813         Original: >
1814                  -1,234 ,5678 -,901e-4
1815                  1,234 5,678 9,01e-4
1816                  12,34 56,78 90,1e-4
1817                  123,4 567,8 901,e-4
1819         Becomes: Go to first line, ma.  Go to last line, press \anum >
1820                   -1,234    ,5678   -,901e-4
1821                    1,234   5,678    9,01e-4
1822                   12,34   56,78    90,1e-4
1823                  123,4   567,8    901,e-4
1825         In addition:
1826           \aenum is provided to support European-style numbers
1827           \aunum is provided to support USA-style numbers
1829         One may get \aenum behavior for \anum >
1830           let g:alignmaps_euronumber= 1
1831 <       or \aunum behavior for \anum if one puts >
1832           let g:alignmaps_usanumber= 1
1833 <       in one's <.vimrc>.
1836         ---------------------------
1837         Alignment Map Examples: \ascom                  *alignmap-ascom* {{{3
1838         ---------------------------
1840         Original: >
1841                 /* A Title */
1842                 int x; /* this is a comment */
1843                 int yzw; /* this is another comment*/
1845         Becomes: Select the three lines, press \ascom >
1846                 /* A Title */
1847                 int x;   /* this is a comment       */
1848                 int yzw; /* this is another comment */
1851         ---------------------------
1852         Alignment Map Examples: \adec                   *alignmap-adec* {{{3
1853         ---------------------------
1855         Original: illustrates how to clean up C/C++ declarations >
1856                 int     a;
1857                 float   b;
1858                 double *c=NULL;
1859                 char x[5];
1860                 struct  abc_str abc;
1861                 struct  abc_str *pabc;
1862                 int     a;              /* a   */
1863                 float   b;              /* b   */
1864                 double *c=NULL;              /* b   */
1865                 char x[5]; /* x[5] */
1866                 struct  abc_str abc;    /* abc */
1867                 struct  abc_str *pabc;    /* pabc */
1868                 static   int     a;              /* a   */
1869                 static   float   b;              /* b   */
1870                 static   double *c=NULL;              /* b   */
1871                 static   char x[5]; /* x[5] */
1872                 static   struct  abc_str abc;    /* abc */
1873                 static   struct  abc_str *pabc;    /* pabc */
1875         Becomes: Select the declarations text, then \adec >
1876                 int                    a;
1877                 float                  b;
1878                 double                *c    = NULL;
1879                 char                   x[5];
1880                 struct abc_str         abc;
1881                 struct abc_str        *pabc;
1882                 int                    a;           /* a    */
1883                 float                  b;           /* b    */
1884                 double                *c    = NULL; /* b    */
1885                 char                   x[5];        /* x[5] */
1886                 struct abc_str         abc;         /* abc  */
1887                 struct abc_str        *pabc;        /* pabc */
1888                 static int             a;           /* a    */
1889                 static float           b;           /* b    */
1890                 static double         *c    = NULL; /* b    */
1891                 static char            x[5];        /* x[5] */
1892                 static struct abc_str  abc;         /* abc  */
1893                 static struct abc_str *pabc;        /* pabc */
1896         ---------------------------
1897         Alignment Map Examples: \adef                   *alignmap-adef* {{{3
1898         ---------------------------
1900         Original: illustrates how to line up #def'initions >
1901                 #define ONE 1
1902                 #define TWO 22
1903                 #define THREE 333
1904                 #define FOUR 4444
1906         Becomes: Select four definition lines, apply \adef >
1907         #        define ONE   1
1908         #        define TWO   22
1909         #        define THREE 333
1910         #        define FOUR  4444
1913         ---------------------------
1914         Alignment Map Examples: \afnc                   *alignmap-afnc* {{{3
1915         ---------------------------
1917         This map is an exception to the usual selection rules.
1918         It uses "]]" to find the function body's leading "{".
1919         Just put the cursor anywhere in the function arguments and
1920         the entire function declaration should be processed.
1922         Because "]]" looks for that "{" in the first column, the
1923         "original" and "becomes" examples are in the first column,
1924         too.
1926         Original: illustrates lining up ansi-c style function definitions >
1927         int f(
1928           struct abc_str ***a, /* one */
1929           long *b, /* two */
1930           int c) /* three */
1931         {
1932         }
1934         Becomes: put cursor anywhere before the '{', press \afnc >
1935         int f(
1936           struct abc_str ***a,  /* one   */
1937           long             *b,  /* two   */
1938           int               c)  /* three */
1939         {
1940         }
1943         ---------------------------
1944         Alignment Map Examples: \adcom                  *alignmap-adcom* {{{3
1945         ---------------------------
1947         Original: illustrates aligning comments that don't begin
1948                 lines (optionally after some whitespace). >
1949                 struct {
1950                         /* this is a test */
1951                         int x; /* of how */
1952                         double y; /* to use adcom */
1953                         };
1955         Becomes: Select the inside lines of the structure,
1956                 then press \adcom.  The comment-only
1957                 line is ignored but the other two comments
1958                 get aligned. >
1959                 struct {
1960                         /* this is a test */
1961                         int x;    /* of how       */
1962                         double y; /* to use adcom */
1963                         };
1966         ---------------------------
1967         Alignment Map Examples: \aocom                  *alignmap-aocom* {{{3
1968         ---------------------------
1970         Original: illustrates how to align C-style comments (works for //, too)
1971                   but restricted only to aligning with those lines containing
1972                   comments.  See the difference from \acom (|alignmap-acom|). >
1973                 if(itworks) { /* this comment */
1974                         then= dothis;
1975                         } /* only appears on two lines */
1977         Becomes: Select the three lines, press \aocom >
1978                 if(itworks) { /* this comment              */
1979                         then= dothis;
1980                         }     /* only appears on two lines */
1982         Also see |alignmap-acom|
1985         ---------------------------                     *alignmap-Tsp*
1986         Alignment Map Examples: \tsp                    *alignmap-tsp* {{{3
1987         ---------------------------
1989         Normally Align can't use white spaces for field separators as such
1990         characters are ignored surrounding field separators.  The \tsp and
1991         \Tsp maps get around this limitation.
1993         Original: >
1994          one two three four five
1995          six seven eight nine ten
1996          eleven twelve thirteen fourteen fifteen
1998         Becomes: Select the lines, \tsp >
1999          one    two    three    four     five
2000          six    seven  eight    nine     ten
2001          eleven twelve thirteen fourteen fifteen
2003         Becomes: Select the lines, \Tsp >
2004             one    two    three     four    five
2005             six  seven    eight     nine     ten
2006          eleven twelve thirteen fourteen fifteen
2009         ---------------------------
2010         Alignment Map Examples: \tsq                    *alignmap-tsq* {{{3
2011         ---------------------------
2013         The \tsp map is useful for aligning tables based on white space,
2014         but sometimes one wants double-quoted strings to act as a single
2015         object in spite of embedded spaces.  The \tsq map was invented
2016         to support this. (thanks to Leif Wickland)
2018         Original: >
2019          "one two" three
2020          four "five six"
2022         Becomes: Select the lines, \tsq >
2023          "one two" three
2024          four      "five six"
2027         ---------------------------
2028         Alignment Map Examples: \tt                     *alignmap-tt* {{{3
2029         ---------------------------
2031         Original: illustrates aligning a LaTex Table >
2032          \begin{tabular}{||c|l|r||}
2033          \hline\hline
2034            one&two&three\\ \hline
2035            four&five&six\\
2036            seven&eight&nine\\
2037          \hline\hline
2038          \end{tabular}
2040         Becomes: Select the three lines inside the table >
2041         (ie. one..,four..,seven..) and press \tt
2042          \begin{tabular}{||c|l|r||}
2043          \hline\hline
2044            one   & two   & three \\ \hline
2045            four  & five  & six   \\
2046            seven & eight & nine  \\
2047          \hline\hline
2048          \end{tabular}
2051         ----------------------------
2052         Alignment Map Examples: \tml                    *alignmap-tml* {{{3
2053         ----------------------------
2055         Original:  illustrates aligning multi-line continuation marks >
2056         one \
2057         two three \
2058         four five six \
2059         seven \\ \
2060         eight \nine \
2061         ten \
2063         Becomes:  >
2064         one           \
2065         two three     \
2066         four five six \
2067         seven \\      \
2068         eight \nine   \
2069         ten           \
2072         ---------------------------
2073         Alignment Map Examples: \t=                     *alignmap-t=* {{{3
2074         ---------------------------
2076         Original: illustrates left-justified aligning of = >
2077                 aa=bb=cc=1;/*one*/
2078                 a=b=c=1;/*two*/
2079                 aaa=bbb=ccc=1;/*three*/
2081         Becomes: Select the three equations, press \t= >
2082                 aa  = bb  = cc  = 1; /* one   */
2083                 a   = b   = c   = 1; /* two   */
2084                 aaa = bbb = ccc = 1; /* three */
2087         ---------------------------
2088         Alignment Map Examples: \T=                     *alignmap-T=* {{{3
2089         ---------------------------
2091         Original: illustrates right-justified aligning of = >
2092                 aa=bb=cc=1; /* one */
2093                 a=b=c=1; /* two */
2094                 aaa=bbb=ccc=1; /* three */
2096         Becomes: Select the three equations, press \T= >
2097                  aa =  bb =  cc = 1; /* one   */
2098                   a =   b =   c = 1; /* two   */
2099                 aaa = bbb = ccc = 1; /* three */
2102         ---------------------------
2103         Alignment Map Examples: \Htd                    *alignmap-Htd* {{{3
2104         ---------------------------
2106         Original: for aligning tables with html >
2107           <TR><TD>...field one...</TD><TD>...field two...</TD></TR>
2108           <TR><TD>...field three...</TD><TD>...field four...</TD></TR>
2110         Becomes: Select <TR>... lines, press \Htd >
2111           <TR><TD> ...field one...   </TD><TD> ...field two...  </TD></TR>
2112           <TR><TD> ...field three... </TD><TD> ...field four... </TD></TR>
2114 ==============================================================================
2115 4. Alignment Tools' History                             *align-history* {{{1
2117 ALIGN HISTORY                                                           {{{2
2118         35 : Nov 02, 2008 * g:loaded_AlignPlugin testing to prevent re-loading
2119                             installed
2120              Nov 19, 2008 * new sanity check for an AlignStyle of just ":"
2121              Jan 08, 2009 * save&restore of |'mod'| now done with local
2122                             variant
2123         34 : Jul 08, 2008 * using :AlignCtrl before entering any alignment
2124                             control commands was causing an error.
2125         33 : Sep 20, 2007 * s:Strlen() introduced to support various ways
2126                             used to represent characters and their effects
2127                             on string lengths.  See |align-strlen|.
2128                           * Align now accepts "..." -- so it can accept
2129                             whitespace as separators.
2130         32 : Aug 18, 2007 * uses |<q-args>| instead of |<f-args>| plus a
2131                             custom argument splitter to allow patterns with
2132                             backslashes to slide in unaltered.
2133         31 : Aug 06, 2007 * :[range]Align! [AlignCtrl settings] pattern(s)
2134                             implemented.
2135         30 : Feb 12, 2007 * now uses |setline()|
2136         29 : Jan 18, 2006 * cecutil updated to use keepjumps
2137              Feb 23, 2006 * Align now converted to vim 7.0 style using
2138                             auto-loading functions.
2139         28 : Aug 17, 2005 * report option workaround
2140              Oct 24, 2005 * AlignCtrl l:  wasn't behaving as expected; fixed
2141         27 : Apr 15, 2005 : cpo workaround
2142                             ignorecase workaround
2143         26 : Aug 20, 2004 : loaded_align now also indicates version number
2144                             GetLatestVimScripts :AutoInstall: now supported
2145         25 : Jul 27, 2004 : For debugging, uses Dfunc(), Dret(), and Decho()
2146         24 : Mar 03, 2004 : (should've done this earlier!) visualmode(1)
2147                             not supported until v6.2, now Align will avoid
2148                             calling it for earlier versions.  Visualmode
2149                             clearing won't take place then, of course.
2150         23 : Oct 07, 2003 : Included Leif Wickland's ReplaceQuotedSpaces()
2151                             function which supports \tsq
2152         22 : Jan 29, 2003 : Now requires 6.1.308 or later to clear visualmode()
2153         21 : Jan 10, 2003 : BugFix: similar problem to #19; new code
2154                             bypasses "norm! v\<Esc>" until initialization
2155                             is over.
2156         20 : Dec 30, 2002 : BugFix: more on "unable to highlight" fixed
2157         19 : Nov 21, 2002 : BugFix: some terminals gave an "unable to highlight"
2158                             message at startup; Hari Krishna Dara tracked it
2159                             down; a silent! now included to prevent noise.
2160         18 : Nov 04, 2002 : BugFix: re-enabled anti-repeated-loading
2161         17 : Nov 04, 2002 : BugFix: forgot to have AlignPush() push s:AlignSep
2162                             AlignCtrl now clears visual-block mode when used so
2163                             that Align won't try to use old visual-block
2164                             selection marks '< '>
2165         16 : Sep 18, 2002 : AlignCtrl <>| options implemented (separator
2166                             justification)
2167         15 : Aug 22, 2002 : bug fix: AlignCtrl's ":" now acts as a modifier of
2168                                      the preceding alignment operator (lrc)
2169         14 : Aug 20, 2002 : bug fix: AlignCtrl default now keeps &ic unchanged
2170                             bug fix: Align, on end-field, wasn't using correct
2171                             alignop bug fix: Align, on end-field, was appending
2172                             padding
2173         13 : Aug 19, 2002 : bug fix: zero-length g/v patterns are accepted
2174                             bug fix: always skip blank lines
2175                             bug fix: AlignCtrl default now also clears g and v
2176                                      patterns
2177         12 : Aug 16, 2002 : moved keep_ic above zero-length pattern checks
2178                             added "AlignCtrl default"
2179                             fixed bug with last field getting separator spaces
2180                             at end line
2181         11 : Jul 08, 2002 : prevent separator patterns which match zero length
2182                             -+: included as additional alignment/justification
2183                             styles
2184         10 : Jun 26, 2002 : =~# used instead of =~ (for matching case)
2185                             ignorecase option handled
2186          9 : Jun 25, 2002 : implemented cyclic padding
2188 ALIGNMENT MAP HISTORY                                   *alignmap-history* {{{2
2189        v41    Nov 02, 2008   * g:loaded_AlignMapsPlugin testing to prevent
2190                                re-loading installed
2191                              * AlignMaps now use 0x0f (ctrl-p) for special
2192                                character substitutions (instead of 0xff).
2193                                Seems to avoid some problems with having to
2194                                use Strlen().
2195                              * bug fixed with \ts,
2196                              * new maps: \ts; \ts, \ts: \ts< \ts= \a(
2197        v40    Oct 21, 2008   * Modified AlignMaps so that its maps use <Plug>s
2198                                and <script>s.  \t@ and related maps have been
2199                                changed to call StdAlign() instead.  The
2200                                WrapperStart function now takes an argument and
2201                                handles being called via visual mode.  The
2202                                former nmaps and vmaps have thus been replaced
2203                                with a simple map.
2204               Oct 24, 2008   * broke AlignMaps into a plugin and autoload
2205                                pair of scripts.
2206         v39   Mar 06, 2008 : * \t= only does /* ... */ aligning when in *.c
2207                                *.cpp files.
2208         v38   Aug 18, 2007 : * \tt altered so that it works with the new
2209                                use of |<q-args>| plus a custom argument
2210                                splitter
2211         v36   Sep 27, 2006 : * AlignWrapperStart() now has tests that marks
2212                                y and z are not set
2213               May 15, 2007   * \anum and variants improved
2214         v35   Sep 01, 2006 : * \t= and cousins used "`"s.  They now use \xff
2215                                characters.
2216                              * \acom now works with doxygen style /// comments
2217                              * <char-0xff> used in \t= \T= \w= and \m= instead
2218                                of backquotes.
2219         v34   Feb 23, 2006 : * AlignMaps now converted to vim 7.0 style using
2220                                auto-loading functions.
2221         v33   Oct 12, 2005 : * \ts, now uses P1 in its AlignCtrl call
2222         v32   Jun 28, 2005 : * s:WrapperStart() changed to AlignWrapperStart()
2223                                s:WrapperEnd() changed to AlignWrapperEnd()
2224                                These changes let the AlignWrapper...()s to be
2225                                used outside of AlignMaps.vim
2226         v31   Feb 01, 2005 : * \adcom included, with help
2227                              * \a, now works across multiple lines with
2228                                different types
2229                              * AlignMaps now uses <cecutil.vim> for its mark and
2230                                window-position saving and restoration
2231               Mar 04, 2005   * improved \a,
2232               Apr 06, 2005   * included \aenum, \aunum, and provided
2233                       g:alignmaps_{usa|euro]number} options
2234         v30   Aug 20, 2004 : * \a, : handles embedded assignments and does \adec
2235                              * \acom  now can handle Doxygen-style comments
2236                              * g:loaded_alignmaps now also indicates version
2237                              * internal maps \WE and \WS are now re-entrant
2238         v29   Jul 27, 2004 : * \tml aligns trailing multi-line single
2239                               backslashes (thanks to Raul Benavente!)
2240         v28   May 13, 2004 : * \a, had problems with leading blanks; fixed!
2241         v27   Mar 31, 2004 : * \T= was having problems with == and !=
2242                              * Fixed more problems with \adec
2243         v26   Dec 09, 2003 : * \ascom now also ignores lines without comments
2244                              * \tt  \& now not matched
2245                              * \a< handles both << and >>
2246         v25   Nov 14, 2003 : * included \anum (aligns numbers with periods and
2247                                commas).  \anum also supported with ctrl-v mode.
2248                              * \ts, \Ts, : (aligns on commas, then swaps leading
2249                                spaces with commas)
2250                              * \adec ignores preprocessor lines and lines with
2251                                with comments-only
2252         v23   Sep 10, 2003 : * Bugfix for \afnc - no longer overwrites marks y,z
2253                              * fixed bug in \tsp, \tab, \Tsp, and \Tab - lines
2254                                containing backslashes were having their
2255                                backslashes removed.  Included Leif Wickland's
2256                                patch for \tsq.
2257                              * \adef now ignores lines holding comments only
2258         v18   Aug 22, 2003 :   \a< lines up C++'s << operators
2259                                saves/restores gdefault option (sets to nogd)
2260                                all b:..varname.. are now b:alignmaps_..varname..
2261         v17   Nov 04, 2002 :   \afnc now handles // comments correctly and
2262                                commas within comments
2263         v16   Sep 10, 2002 :   changed : to :silent! for \adec
2264         v15   Aug 27, 2002 :   removed some <c-v>s
2265         v14   Aug 20, 2002 :   \WS, \WE mostly moved to functions, marks y and z
2266                                now restored
2267         v11   Jul 08, 2002 :   \abox bug fix
2268          v9   Jun 25, 2002 :   \abox now handles leading initial whitespace
2269                            :   various bugfixes to \afnc, \T=, etc
2271 ==============================================================================
2272 Modelines: {{{1
2273 vim:tw=78:ts=8:ft=help:fdm=marker:
2274 autoload/Align.vim      [[[1
2275 1029
2276 " Align: tool to align multiple fields based on one or more separators
2277 "   Author:             Charles E. Campbell, Jr.
2278 "   Date:               Mar 03, 2009
2279 "   Version:    35
2280 " GetLatestVimScripts: 294 1 :AutoInstall: Align.vim
2281 " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim
2282 " Copyright:    Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1
2283 "               Permission is hereby granted to use and distribute this code,
2284 "               with or without modifications, provided that this copyright
2285 "               notice is copied with it. Like anything else that's free,
2286 "               Align.vim is provided *as is* and comes with no warranty
2287 "               of any kind, either expressed or implied. By using this
2288 "               plugin, you agree that in no event will the copyright
2289 "               holder be liable for any damages resulting from the use
2290 "               of this software.
2292 " Romans 1:16,17a : For I am not ashamed of the gospel of Christ, for it is {{{1
2293 " the power of God for salvation for everyone who believes; for the Jew first,
2294 " and also for the Greek.  For in it is revealed God's righteousness from
2295 " faith to faith.
2297 " ---------------------------------------------------------------------
2298 " Load Once: {{{1
2299 if exists("g:loaded_Align") || &cp
2300  finish
2301 endif
2302 let g:loaded_Align = "v35"
2303 if v:version < 700
2304  echohl WarningMsg
2305  echo "***warning*** this version of Align needs vim 7.0"
2306  echohl Normal
2307  finish
2308 endif
2309 let s:keepcpo= &cpo
2310 set cpo&vim
2311 "DechoTabOn
2313 " ---------------------------------------------------------------------
2314 " Debugging Support: {{{1
2315 "if !exists("g:loaded_Decho") | runtime plugin/Decho.vim | endif
2317 " ---------------------------------------------------------------------
2318 " Options: {{{1
2319 if !exists("g:Align_xstrlen")
2320  if &enc == "latin1" || $LANG == "en_US.UTF-8" || !has("multi_byte")
2321   let g:Align_xstrlen= 0
2322  else
2323   let g:Align_xstrlen= 1
2324  endif
2325 endif
2327 " ---------------------------------------------------------------------
2328 " Align#AlignCtrl: enter alignment patterns here {{{1
2330 "   Styles   =  all alignment-break patterns are equivalent
2331 "            C  cycle through alignment-break pattern(s)
2332 "            l  left-justified alignment
2333 "            r  right-justified alignment
2334 "            c  center alignment
2335 "            -  skip separator, treat as part of field
2336 "            :  treat rest of line as field
2337 "            +  repeat previous [lrc] style
2338 "            <  left justify separators
2339 "            >  right justify separators
2340 "            |  center separators
2342 "   Builds   =  s:AlignPat  s:AlignCtrl  s:AlignPatQty
2343 "            C  s:AlignPat  s:AlignCtrl  s:AlignPatQty
2344 "            p  s:AlignPrePad
2345 "            P  s:AlignPostPad
2346 "            w  s:AlignLeadKeep
2347 "            W  s:AlignLeadKeep
2348 "            I  s:AlignLeadKeep
2349 "            l  s:AlignStyle
2350 "            r  s:AlignStyle
2351 "            -  s:AlignStyle
2352 "            +  s:AlignStyle
2353 "            :  s:AlignStyle
2354 "            c  s:AlignStyle
2355 "            g  s:AlignGPat
2356 "            v  s:AlignVPat
2357 "            <  s:AlignSep
2358 "            >  s:AlignSep
2359 "            |  s:AlignSep
2360 fun! Align#AlignCtrl(...)
2362 "  call Dfunc("AlignCtrl(...) a:0=".a:0)
2364   " save options that will be changed
2365   let keep_search = @/
2366   let keep_ic     = &ic
2368   " turn ignorecase off
2369   set noic
2371   " clear visual mode so that old visual-mode selections don't
2372   " get applied to new invocations of Align().
2373   if v:version < 602
2374    if !exists("s:Align_gavemsg")
2375         let s:Align_gavemsg= 1
2376     echomsg "Align needs at least Vim version 6.2 to clear visual-mode selection"
2377    endif
2378   elseif exists("s:dovisclear")
2379 "   call Decho("clearing visual mode a:0=".a:0." a:1<".a:1.">")
2380    let clearvmode= visualmode(1)
2381   endif
2383   " set up a list akin to an argument list
2384   if a:0 > 0
2385    let A= s:QArgSplitter(a:1)
2386   else
2387    let A=[0]
2388   endif
2390   if A[0] > 0
2391    let style = A[1]
2393    " Check for bad separator patterns (zero-length matches)
2394    " (but zero-length patterns for g/v is ok)
2395    if style !~# '[gv]'
2396     let ipat= 2
2397     while ipat <= A[0]
2398      if "" =~ A[ipat]
2399       echoerr "AlignCtrl: separator<".A[ipat]."> matches zero-length string"
2400           let &ic= keep_ic
2401 "      call Dret("AlignCtrl")
2402       return
2403      endif
2404      let ipat= ipat + 1
2405     endwhile
2406    endif
2407   endif
2409 "  call Decho("AlignCtrl() A[0]=".A[0])
2410   if !exists("s:AlignStyle")
2411    let s:AlignStyle= "l"
2412   endif
2413   if !exists("s:AlignPrePad")
2414    let s:AlignPrePad= 0
2415   endif
2416   if !exists("s:AlignPostPad")
2417    let s:AlignPostPad= 0
2418   endif
2419   if !exists("s:AlignLeadKeep")
2420    let s:AlignLeadKeep= 'w'
2421   endif
2423   if A[0] == 0
2424    " ----------------------
2425    " List current selection
2426    " ----------------------
2427    if !exists("s:AlignPatQty")
2428         let s:AlignPatQty= 0
2429    endif
2430    echo "AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep
2431 "   call Decho("AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep)
2432    if      exists("s:AlignGPat") && !exists("s:AlignVPat")
2433         echo "AlignGPat<".s:AlignGPat.">"
2434    elseif !exists("s:AlignGPat") &&  exists("s:AlignVPat")
2435         echo "AlignVPat<".s:AlignVPat.">"
2436    elseif exists("s:AlignGPat") &&  exists("s:AlignVPat")
2437         echo "AlignGPat<".s:AlignGPat."> AlignVPat<".s:AlignVPat.">"
2438    endif
2439    let ipat= 1
2440    while ipat <= s:AlignPatQty
2441         echo "Pat".ipat."<".s:AlignPat_{ipat}.">"
2442 "       call Decho("Pat".ipat."<".s:AlignPat_{ipat}.">")
2443         let ipat= ipat + 1
2444    endwhile
2446   else
2447    " ----------------------------------
2448    " Process alignment control settings
2449    " ----------------------------------
2450 "   call Decho("process the alignctrl settings")
2451 "   call Decho("style<".style.">")
2453    if style ==? "default"
2454      " Default:  preserve initial leading whitespace, left-justified,
2455      "           alignment on '=', one space padding on both sides
2456          if exists("s:AlignCtrlStackQty")
2457           " clear AlignCtrl stack
2458       while s:AlignCtrlStackQty > 0
2459            call Align#AlignPop()
2460           endwhile
2461           unlet s:AlignCtrlStackQty
2462          endif
2463          " Set AlignCtrl to its default value
2464      call Align#AlignCtrl("Ilp1P1=<",'=')
2465          call Align#AlignCtrl("g")
2466          call Align#AlignCtrl("v")
2467          let s:dovisclear = 1
2468          let &ic          = keep_ic
2469          let @/           = keep_search
2470 "     call Dret("AlignCtrl")
2471          return
2472    endif
2474    if style =~# 'm'
2475         " map support: Do an AlignPush now and the next call to Align()
2476         "              will do an AlignPop at exit
2477 "       call Decho("style case m: do AlignPush")
2478         call Align#AlignPush()
2479         let s:DoAlignPop= 1
2480    endif
2482    " = : record a list of alignment patterns that are equivalent
2483    if style =~# "="
2484 "       call Decho("style case =: record list of equiv alignment patterns")
2485     let s:AlignCtrl  = '='
2486         if A[0] >= 2
2487      let s:AlignPatQty= 1
2488      let s:AlignPat_1 = A[2]
2489      let ipat         = 3
2490      while ipat <= A[0]
2491       let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat]
2492       let ipat         = ipat + 1
2493      endwhile
2494      let s:AlignPat_1= '\('.s:AlignPat_1.'\)'
2495 "     call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">")
2496         endif
2498     "c : cycle through alignment pattern(s)
2499    elseif style =~# 'C'
2500 "       call Decho("style case C: cycle through alignment pattern(s)")
2501     let s:AlignCtrl  = 'C'
2502         if A[0] >= 2
2503      let s:AlignPatQty= A[0] - 1
2504      let ipat         = 1
2505      while ipat < A[0]
2506       let s:AlignPat_{ipat}= A[ipat+1]
2507 "     call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">")
2508       let ipat= ipat + 1
2509      endwhile
2510         endif
2511    endif
2513    if style =~# 'p'
2514     let s:AlignPrePad= substitute(style,'^.*p\(\d\+\).*$','\1','')
2515 "       call Decho("style case p".s:AlignPrePad.": pre-separator padding")
2516     if s:AlignPrePad == ""
2517      echoerr "AlignCtrl: 'p' needs to be followed by a numeric argument'
2518      let @/ = keep_search
2519          let &ic= keep_ic
2520 "     call Dret("AlignCtrl")
2521      return
2522         endif
2523    endif
2525    if style =~# 'P'
2526     let s:AlignPostPad= substitute(style,'^.*P\(\d\+\).*$','\1','')
2527 "       call Decho("style case P".s:AlignPostPad.": post-separator padding")
2528     if s:AlignPostPad == ""
2529      echoerr "AlignCtrl: 'P' needs to be followed by a numeric argument'
2530      let @/ = keep_search
2531          let &ic= keep_ic
2532 "     call Dret("AlignCtrl")
2533      return
2534         endif
2535    endif
2537    if     style =~# 'w'
2538 "       call Decho("style case w: ignore leading whitespace")
2539         let s:AlignLeadKeep= 'w'
2540    elseif style =~# 'W'
2541 "       call Decho("style case w: keep leading whitespace")
2542         let s:AlignLeadKeep= 'W'
2543    elseif style =~# 'I'
2544 "       call Decho("style case w: retain initial leading whitespace")
2545         let s:AlignLeadKeep= 'I'
2546    endif
2548    if style =~# 'g'
2549         " first list item is a "g" selector pattern
2550 "       call Decho("style case g: global selector pattern")
2551         if A[0] < 2
2552          if exists("s:AlignGPat")
2553           unlet s:AlignGPat
2554 "         call Decho("unlet s:AlignGPat")
2555          endif
2556         else
2557          let s:AlignGPat= A[2]
2558 "        call Decho("s:AlignGPat<".s:AlignGPat.">")
2559         endif
2560    elseif style =~# 'v'
2561         " first list item is a "v" selector pattern
2562 "       call Decho("style case v: global selector anti-pattern")
2563         if A[0] < 2
2564          if exists("s:AlignVPat")
2565           unlet s:AlignVPat
2566 "         call Decho("unlet s:AlignVPat")
2567          endif
2568         else
2569          let s:AlignVPat= A[2]
2570 "        call Decho("s:AlignVPat<".s:AlignVPat.">")
2571         endif
2572    endif
2574     "[-lrc+:] : set up s:AlignStyle
2575    if style =~# '[-lrc+:]'
2576 "       call Decho("style case [-lrc+:]: field justification")
2577     let s:AlignStyle= substitute(style,'[^-lrc:+]','','g')
2578 "    call Decho("AlignStyle<".s:AlignStyle.">")
2579    endif
2581    "[<>|] : set up s:AlignSep
2582    if style =~# '[<>|]'
2583 "       call Decho("style case [-lrc+:]: separator justification")
2584         let s:AlignSep= substitute(style,'[^<>|]','','g')
2585 "       call Decho("AlignSep ".s:AlignSep)
2586    endif
2587   endif
2589   " sanity
2590   if !exists("s:AlignCtrl")
2591    let s:AlignCtrl= '='
2592   endif
2594   " restore search and options
2595   let @/ = keep_search
2596   let &ic= keep_ic
2598 "  call Dret("AlignCtrl ".s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle)
2599   return s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle
2600 endfun
2602 " ---------------------------------------------------------------------
2603 " s:MakeSpace: returns a string with spacecnt blanks {{{1
2604 fun! s:MakeSpace(spacecnt)
2605 "  call Dfunc("MakeSpace(spacecnt=".a:spacecnt.")")
2606   let str      = ""
2607   let spacecnt = a:spacecnt
2608   while spacecnt > 0
2609    let str      = str . " "
2610    let spacecnt = spacecnt - 1
2611   endwhile
2612 "  call Dret("MakeSpace <".str.">")
2613   return str
2614 endfun
2616 " ---------------------------------------------------------------------
2617 " Align#Align: align selected text based on alignment pattern(s) {{{1
2618 fun! Align#Align(hasctrl,...) range
2619 "  call Dfunc("Align#Align(hasctrl=".a:hasctrl.",...) a:0=".a:0)
2621   " sanity checks
2622   if string(a:hasctrl) != "0" && string(a:hasctrl) != "1"
2623    echohl Error|echo 'usage: Align#Align(hasctrl<'.a:hasctrl.'> (should be 0 or 1),"separator(s)"  (you have '.a:0.') )'|echohl None
2624 "   call Dret("Align#Align")
2625    return
2626   endif
2627   if exists("s:AlignStyle") && s:AlignStyle == ":"
2628    echohl Error |echo '(Align#Align) your AlignStyle is ":", which implies "do-no-alignment"!'|echohl None
2629 "   call Dret("Align#Align")
2630    return
2631   endif
2633   " set up a list akin to an argument list
2634   if a:0 > 0
2635    let A= s:QArgSplitter(a:1)
2636   else
2637    let A=[0]
2638   endif
2640   " if :Align! was used, then the first argument is (should be!) an AlignCtrl string
2641   " Note that any alignment control set this way will be temporary.
2642   let hasctrl= a:hasctrl
2643 "  call Decho("hasctrl=".hasctrl)
2644   if a:hasctrl && A[0] >= 1
2645 "   call Decho("Align! : using A[1]<".A[1]."> for AlignCtrl")
2646    if A[1] =~ '[gv]'
2647         let hasctrl= hasctrl + 1
2648         call Align#AlignCtrl('m')
2649     call Align#AlignCtrl(A[1],A[2])
2650 "    call Decho("Align! : also using A[2]<".A[2]."> for AlignCtrl")
2651    elseif A[1] !~ 'm'
2652     call Align#AlignCtrl(A[1]."m")
2653    else
2654     call Align#AlignCtrl(A[1])
2655    endif
2656   endif
2658   " Check for bad separator patterns (zero-length matches)
2659   let ipat= 1 + hasctrl
2660   while ipat <= A[0]
2661    if "" =~ A[ipat]
2662         echoerr "Align: separator<".A[ipat]."> matches zero-length string"
2663 "    call Dret("Align#Align")
2664         return
2665    endif
2666    let ipat= ipat + 1
2667   endwhile
2669   " record current search pattern for subsequent restoration
2670   let keep_search= @/
2671   let keep_ic    = &ic
2672   let keep_report= &report
2673   set noic report=10000
2675   if A[0] > hasctrl
2676   " Align will accept a list of separator regexps
2677 "   call Decho("A[0]=".A[0].": accepting list of separator regexp")
2679    if s:AlignCtrl =~# "="
2680         "= : consider all separators to be equivalent
2681 "    call Decho("AlignCtrl: record list of equivalent alignment patterns")
2682     let s:AlignCtrl  = '='
2683     let s:AlignPat_1 = A[1 + hasctrl]
2684     let s:AlignPatQty= 1
2685     let ipat         = 2 + hasctrl
2686     while ipat <= A[0]
2687      let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat]
2688      let ipat         = ipat + 1
2689     endwhile
2690     let s:AlignPat_1= '\('.s:AlignPat_1.'\)'
2691 "    call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">")
2693    elseif s:AlignCtrl =~# 'C'
2694     "c : cycle through alignment pattern(s)
2695 "    call Decho("AlignCtrl: cycle through alignment pattern(s)")
2696     let s:AlignCtrl  = 'C'
2697     let s:AlignPatQty= A[0] - hasctrl
2698     let ipat         = 1
2699     while ipat <= s:AlignPatQty
2700      let s:AlignPat_{ipat}= A[(ipat + hasctrl)]
2701 "     call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">")
2702      let ipat= ipat + 1
2703     endwhile
2704    endif
2705   endif
2707   " Initialize so that begline<endline and begcol<endcol.
2708   " Ragged right: check if the column associated with '< or '>
2709   "               is greater than the line's string length -> ragged right.
2710   " Have to be careful about visualmode() -- it returns the last visual
2711   " mode used whether or not it was used currently.
2712   let begcol   = virtcol("'<")-1
2713   let endcol   = virtcol("'>")-1
2714   if begcol > endcol
2715    let begcol  = virtcol("'>")-1
2716    let endcol  = virtcol("'<")-1
2717   endif
2718 "  call Decho("begcol=".begcol." endcol=".endcol)
2719   let begline  = a:firstline
2720   let endline  = a:lastline
2721   if begline > endline
2722    let begline = a:lastline
2723    let endline = a:firstline
2724   endif
2725 "  call Decho("begline=".begline." endline=".endline)
2726   let fieldcnt = 0
2727   if (begline == line("'>") && endline == line("'<")) || (begline == line("'<") && endline == line("'>"))
2728    let vmode= visualmode()
2729 "   call Decho("vmode=".vmode)
2730    if vmode == "\<c-v>"
2731         if exists("g:Align_xstrlen") && g:Align_xstrlen
2732      let ragged   = ( col("'>") > s:Strlen(getline("'>")) || col("'<") > s:Strlen(getline("'<")) )
2733         else
2734      let ragged   = ( col("'>") > strlen(getline("'>")) || col("'<") > strlen(getline("'<")) )
2735         endif
2736    else
2737         let ragged= 1
2738    endif
2739   else
2740    let ragged= 1
2741   endif
2742   if ragged
2743    let begcol= 0
2744   endif
2745 "  call Decho("lines[".begline.",".endline."] col[".begcol.",".endcol."] ragged=".ragged." AlignCtrl<".s:AlignCtrl.">")
2747   " Keep user options
2748   let etkeep   = &l:et
2749   let pastekeep= &l:paste
2750   setlocal et paste
2752   " convert selected range of lines to use spaces instead of tabs
2753   " but if first line's initial white spaces are to be retained
2754   " then use 'em
2755   if begcol <= 0 && s:AlignLeadKeep == 'I'
2756    " retain first leading whitespace for all subsequent lines
2757    let bgntxt= substitute(getline(begline),'^\(\s*\).\{-}$','\1','')
2758 "   call Decho("retaining 1st leading whitespace: bgntxt<".bgntxt.">")
2759    set noet
2760   endif
2761   exe begline.",".endline."ret"
2763   " Execute two passes
2764   " First  pass: collect alignment data (max field sizes)
2765   " Second pass: perform alignment
2766   let pass= 1
2767   while pass <= 2
2768 "   call Decho(" ")
2769 "   call Decho("---- Pass ".pass.": ----")
2771    let line= begline
2772    while line <= endline
2773     " Process each line
2774     let txt = getline(line)
2775 "    call Decho(" ")
2776 "    call Decho("Pass".pass.": Line ".line." <".txt.">")
2778     " AlignGPat support: allows a selector pattern (akin to g/selector/cmd )
2779     if exists("s:AlignGPat")
2780 "        call Decho("Pass".pass.": AlignGPat<".s:AlignGPat.">")
2781          if match(txt,s:AlignGPat) == -1
2782 "         call Decho("Pass".pass.": skipping")
2783           let line= line + 1
2784           continue
2785          endif
2786     endif
2788     " AlignVPat support: allows a selector pattern (akin to v/selector/cmd )
2789     if exists("s:AlignVPat")
2790 "        call Decho("Pass".pass.": AlignVPat<".s:AlignVPat.">")
2791          if match(txt,s:AlignVPat) != -1
2792 "         call Decho("Pass".pass.": skipping")
2793           let line= line + 1
2794           continue
2795          endif
2796     endif
2798         " Always skip blank lines
2799         if match(txt,'^\s*$') != -1
2800 "         call Decho("Pass".pass.": skipping")
2801          let line= line + 1
2802          continue
2803         endif
2805     " Extract visual-block selected text (init bgntxt, endtxt)
2806         if exists("g:Align_xstrlen") && g:Align_xstrlen
2807      let txtlen= s:Strlen(txt)
2808         else
2809      let txtlen= strlen(txt)
2810         endif
2811     if begcol > 0
2812          " Record text to left of selected area
2813      let bgntxt= strpart(txt,0,begcol)
2814 "         call Decho("Pass".pass.": record text to left: bgntxt<".bgntxt.">")
2815     elseif s:AlignLeadKeep == 'W'
2816          let bgntxt= substitute(txt,'^\(\s*\).\{-}$','\1','')
2817 "         call Decho("Pass".pass.": retaining all leading ws: bgntxt<".bgntxt.">")
2818     elseif s:AlignLeadKeep == 'w' || !exists("bgntxt")
2819          " No beginning text
2820          let bgntxt= ""
2821 "         call Decho("Pass".pass.": no beginning text")
2822     endif
2823     if ragged
2824          let endtxt= ""
2825     else
2826      " Elide any text lying outside selected columnar region
2827      let endtxt= strpart(txt,endcol+1,txtlen-endcol)
2828      let txt   = strpart(txt,begcol,endcol-begcol+1)
2829     endif
2830 "    call Decho(" ")
2831 "    call Decho("Pass".pass.": bgntxt<".bgntxt.">")
2832 "    call Decho("Pass".pass.":    txt<". txt  .">")
2833 "    call Decho("Pass".pass.": endtxt<".endtxt.">")
2834         if !exists("s:AlignPat_{1}")
2835          echohl Error|echo "no separators specified!"|echohl None
2836 "     call Dret("Align#Align")
2837          return
2838         endif
2840     " Initialize for both passes
2841     let seppat      = s:AlignPat_{1}
2842     let ifield      = 1
2843     let ipat        = 1
2844     let bgnfield    = 0
2845     let endfield    = 0
2846     let alignstyle  = s:AlignStyle
2847     let doend       = 1
2848         let newtxt      = ""
2849     let alignprepad = s:AlignPrePad
2850     let alignpostpad= s:AlignPostPad
2851         let alignsep    = s:AlignSep
2852         let alignophold = " "
2853         let alignop     = "l"
2854 "       call Decho("Pass".pass.": initial alignstyle<".alignstyle."> seppat<".seppat.">")
2856     " Process each field on the line
2857     while doend > 0
2859           " C-style: cycle through pattern(s)
2860      if s:AlignCtrl == 'C' && doend == 1
2861           let seppat   = s:AlignPat_{ipat}
2862 "         call Decho("Pass".pass.": processing field: AlignCtrl=".s:AlignCtrl." ipat=".ipat." seppat<".seppat.">")
2863           let ipat     = ipat + 1
2864           if ipat > s:AlignPatQty
2865            let ipat = 1
2866           endif
2867      endif
2869          " cyclic alignment/justification operator handling
2870          let alignophold  = alignop
2871          let alignop      = strpart(alignstyle,0,1)
2872          if alignop == '+' || doend == 2
2873           let alignop= alignophold
2874          else
2875           let alignstyle   = strpart(alignstyle,1).strpart(alignstyle,0,1)
2876           let alignopnxt   = strpart(alignstyle,0,1)
2877           if alignop == ':'
2878            let seppat  = '$'
2879            let doend   = 2
2880 "          call Decho("Pass".pass.": alignop<:> case: setting seppat<$> doend==2")
2881           endif
2882          endif
2884          " cylic separator alignment specification handling
2885          let alignsepop= strpart(alignsep,0,1)
2886          let alignsep  = strpart(alignsep,1).alignsepop
2888          " mark end-of-field and the subsequent end-of-separator.
2889          " Extend field if alignop is '-'
2890      let endfield = match(txt,seppat,bgnfield)
2891          let sepfield = matchend(txt,seppat,bgnfield)
2892      let skipfield= sepfield
2893 "        call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield)
2894          while alignop == '-' && endfield != -1
2895           let endfield  = match(txt,seppat,skipfield)
2896           let sepfield  = matchend(txt,seppat,skipfield)
2897           let skipfield = sepfield
2898           let alignop   = strpart(alignstyle,0,1)
2899           let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1)
2900 "         call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">")
2901          endwhile
2902          let seplen= sepfield - endfield
2903 "        call Decho("Pass".pass.": seplen=[sepfield=".sepfield."] - [endfield=".endfield."]=".seplen)
2905          if endfield != -1
2906           if pass == 1
2907            " ---------------------------------------------------------------------
2908            " Pass 1: Update FieldSize to max
2909 "          call Decho("Pass".pass.": before lead/trail remove: field<".strpart(txt,bgnfield,endfield-bgnfield).">")
2910            let field      = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','')
2911        if s:AlignLeadKeep == 'W'
2912             let field = bgntxt.field
2913             let bgntxt= ""
2914            endif
2915            if exists("g:Align_xstrlen") && g:Align_xstrlen
2916             let fieldlen   = s:Strlen(field)
2917            else
2918             let fieldlen   = strlen(field)
2919            endif
2920            let sFieldSize = "FieldSize_".ifield
2921            if !exists(sFieldSize)
2922             let FieldSize_{ifield}= fieldlen
2923 "           call Decho("Pass".pass.":  set FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field.">")
2924            elseif fieldlen > FieldSize_{ifield}
2925             let FieldSize_{ifield}= fieldlen
2926 "           call Decho("Pass".pass.": oset FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field.">")
2927            endif
2928            let sSepSize= "SepSize_".ifield
2929            if !exists(sSepSize)
2930                 let SepSize_{ifield}= seplen
2931 "           call Decho(" set SepSize_{".ifield."}=".SepSize_{ifield}." <".field.">")
2932            elseif seplen > SepSize_{ifield}
2933                 let SepSize_{ifield}= seplen
2934 "           call Decho("Pass".pass.": oset SepSize_{".ifield."}=".SepSize_{ifield}." <".field.">")
2935            endif
2937           else
2938            " ---------------------------------------------------------------------
2939            " Pass 2: Perform Alignment
2940            let prepad       = strpart(alignprepad,0,1)
2941            let postpad      = strpart(alignpostpad,0,1)
2942            let alignprepad  = strpart(alignprepad,1).strpart(alignprepad,0,1)
2943            let alignpostpad = strpart(alignpostpad,1).strpart(alignpostpad,0,1)
2944            let field        = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','')
2945        if s:AlignLeadKeep == 'W'
2946             let field = bgntxt.field
2947             let bgntxt= ""
2948            endif
2949            if doend == 2
2950                 let prepad = 0
2951                 let postpad= 0
2952            endif
2953            if exists("g:Align_xstrlen") && g:Align_xstrlen
2954             let fieldlen   = s:Strlen(field)
2955            else
2956             let fieldlen   = strlen(field)
2957            endif
2958            let sep        = s:MakeSpace(prepad).strpart(txt,endfield,sepfield-endfield).s:MakeSpace(postpad)
2959            if seplen < SepSize_{ifield}
2960                 if alignsepop == "<"
2961                  " left-justify separators
2962                  let sep       = sep.s:MakeSpace(SepSize_{ifield}-seplen)
2963                 elseif alignsepop == ">"
2964                  " right-justify separators
2965                  let sep       = s:MakeSpace(SepSize_{ifield}-seplen).sep
2966                 else
2967                  " center-justify separators
2968                  let sepleft   = (SepSize_{ifield} - seplen)/2
2969                  let sepright  = SepSize_{ifield} - seplen - sepleft
2970                  let sep       = s:MakeSpace(sepleft).sep.s:MakeSpace(sepright)
2971                 endif
2972            endif
2973            let spaces     = FieldSize_{ifield} - fieldlen
2974 "          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.">")
2976             " Perform alignment according to alignment style justification
2977            if spaces > 0
2978             if     alignop == 'c'
2979                  " center the field
2980              let spaceleft = spaces/2
2981              let spaceright= FieldSize_{ifield} - spaceleft - fieldlen
2982              let newtxt    = newtxt.s:MakeSpace(spaceleft).field.s:MakeSpace(spaceright).sep
2983             elseif alignop == 'r'
2984                  " right justify the field
2985              let newtxt= newtxt.s:MakeSpace(spaces).field.sep
2986             elseif ragged && doend == 2
2987                  " left justify rightmost field (no trailing blanks needed)
2988              let newtxt= newtxt.field
2989                 else
2990                  " left justfiy the field
2991              let newtxt= newtxt.field.s:MakeSpace(spaces).sep
2992             endif
2993            elseif ragged && doend == 2
2994                 " field at maximum field size and no trailing blanks needed
2995             let newtxt= newtxt.field
2996            else
2997                 " field is at maximum field size already
2998             let newtxt= newtxt.field.sep
2999            endif
3000 "          call Decho("Pass".pass.": newtxt<".newtxt.">")
3001           endif " pass 1/2
3003           " bgnfield indexes to end of separator at right of current field
3004           " Update field counter
3005           let bgnfield= sepfield
3006       let ifield  = ifield + 1
3007           if doend == 2
3008            let doend= 0
3009           endif
3010            " handle end-of-text as end-of-field
3011          elseif doend == 1
3012           let seppat  = '$'
3013           let doend   = 2
3014          else
3015           let doend   = 0
3016          endif          " endfield != -1
3017     endwhile    " doend loop (as well as regularly separated fields)
3019         if pass == 2
3020          " Write altered line to buffer
3021 "     call Decho("Pass".pass.": bgntxt<".bgntxt."> line=".line)
3022 "     call Decho("Pass".pass.": newtxt<".newtxt.">")
3023 "     call Decho("Pass".pass.": endtxt<".endtxt.">")
3024          call setline(line,bgntxt.newtxt.endtxt)
3025         endif
3027     let line = line + 1
3028    endwhile     " line loop
3030    let pass= pass + 1
3031   endwhile      " pass loop
3032 "  call Decho("end of two pass loop")
3034   " Restore user options
3035   let &l:et    = etkeep
3036   let &l:paste = pastekeep
3038   if exists("s:DoAlignPop")
3039    " AlignCtrl Map support
3040    call Align#AlignPop()
3041    unlet s:DoAlignPop
3042   endif
3044   " restore current search pattern
3045   let @/      = keep_search
3046   let &ic     = keep_ic
3047   let &report = keep_report
3049 "  call Dret("Align#Align")
3050   return
3051 endfun
3053 " ---------------------------------------------------------------------
3054 " Align#AlignPush: this command/function pushes an alignment control string onto a stack {{{1
3055 fun! Align#AlignPush()
3056 "  call Dfunc("AlignPush()")
3058   " initialize the stack
3059   if !exists("s:AlignCtrlStackQty")
3060    let s:AlignCtrlStackQty= 1
3061   else
3062    let s:AlignCtrlStackQty= s:AlignCtrlStackQty + 1
3063   endif
3065   " construct an AlignCtrlStack entry
3066   if !exists("s:AlignSep")
3067    let s:AlignSep= ''
3068   endif
3069   let s:AlignCtrlStack_{s:AlignCtrlStackQty}= s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle.s:AlignSep
3070 "  call Decho("AlignPush: AlignCtrlStack_".s:AlignCtrlStackQty."<".s:AlignCtrlStack_{s:AlignCtrlStackQty}.">")
3072   " push [GV] patterns onto their own stack
3073   if exists("s:AlignGPat")
3074    let s:AlignGPat_{s:AlignCtrlStackQty}= s:AlignGPat
3075   else
3076    let s:AlignGPat_{s:AlignCtrlStackQty}=  ""
3077   endif
3078   if exists("s:AlignVPat")
3079    let s:AlignVPat_{s:AlignCtrlStackQty}= s:AlignVPat
3080   else
3081    let s:AlignVPat_{s:AlignCtrlStackQty}=  ""
3082   endif
3084 "  call Dret("AlignPush")
3085 endfun
3087 " ---------------------------------------------------------------------
3088 " Align#AlignPop: this command/function pops an alignment pattern from a stack {{{1
3089 "           and into the AlignCtrl variables.
3090 fun! Align#AlignPop()
3091 "  call Dfunc("Align#AlignPop()")
3093   " sanity checks
3094   if !exists("s:AlignCtrlStackQty")
3095    echoerr "AlignPush needs to be used prior to AlignPop"
3096 "   call Dret("Align#AlignPop <> : AlignPush needs to have been called first")
3097    return ""
3098   endif
3099   if s:AlignCtrlStackQty <= 0
3100    unlet s:AlignCtrlStackQty
3101    echoerr "AlignPush needs to be used prior to AlignPop"
3102 "   call Dret("Align#AlignPop <> : AlignPop needs to have been called first")
3103    return ""
3104   endif
3106   " pop top of AlignCtrlStack and pass value to AlignCtrl
3107   let retval=s:AlignCtrlStack_{s:AlignCtrlStackQty}
3108   unlet s:AlignCtrlStack_{s:AlignCtrlStackQty}
3109   call Align#AlignCtrl(retval)
3111   " pop G pattern stack
3112   if s:AlignGPat_{s:AlignCtrlStackQty} != ""
3113    call Align#AlignCtrl('g',s:AlignGPat_{s:AlignCtrlStackQty})
3114   else
3115    call Align#AlignCtrl('g')
3116   endif
3117   unlet s:AlignGPat_{s:AlignCtrlStackQty}
3119   " pop V pattern stack
3120   if s:AlignVPat_{s:AlignCtrlStackQty} != ""
3121    call Align#AlignCtrl('v',s:AlignVPat_{s:AlignCtrlStackQty})
3122   else
3123    call Align#AlignCtrl('v')
3124   endif
3126   unlet s:AlignVPat_{s:AlignCtrlStackQty}
3127   let s:AlignCtrlStackQty= s:AlignCtrlStackQty - 1
3129 "  call Dret("Align#AlignPop <".retval."> : AlignCtrlStackQty=".s:AlignCtrlStackQty)
3130   return retval
3131 endfun
3133 " ---------------------------------------------------------------------
3134 " Align#AlignReplaceQuotedSpaces: {{{1
3135 fun! Align#AlignReplaceQuotedSpaces() 
3136 "  call Dfunc("AlignReplaceQuotedSpaces()")
3138   let l:line          = getline(line("."))
3139   if exists("g:Align_xstrlen") && g:Align_xstrlen
3140    let l:linelen      = s:Strlen(l:line)
3141   else
3142    let l:linelen      = strlen(l:line)
3143   endif
3144   let l:startingPos   = 0
3145   let l:startQuotePos = 0
3146   let l:endQuotePos   = 0
3147   let l:spacePos      = 0
3148   let l:quoteRe       = '\\\@<!"'
3150 "  "call Decho("in replace spaces.  line=" . line('.'))
3151   while (1)
3152     let l:startQuotePos = match(l:line, l:quoteRe, l:startingPos)
3153     if (l:startQuotePos < 0) 
3154 "      "call Decho("No more quotes to the end of line")
3155       break
3156     endif
3157     let l:endQuotePos = match(l:line, l:quoteRe, l:startQuotePos + 1)
3158     if (l:endQuotePos < 0)
3159 "      "call Decho("Mismatched quotes")
3160       break
3161     endif
3162     let l:spaceReplaceRe = '^.\{' . (l:startQuotePos + 1) . '}.\{-}\zs\s\ze.*.\{' . (linelen - l:endQuotePos) . '}$'
3163 "    "call Decho('spaceReplaceRe="' . l:spaceReplaceRe . '"')
3164     let l:newStr = substitute(l:line, l:spaceReplaceRe, '%', '')
3165     while (l:newStr != l:line)
3166 "      "call Decho('newstr="' . l:newStr . '"')
3167       let l:line = l:newStr
3168       let l:newStr = substitute(l:line, l:spaceReplaceRe, '%', '')
3169     endwhile
3170     let l:startingPos = l:endQuotePos + 1
3171   endwhile
3172   call setline(line('.'), l:line)
3174 "  call Dret("AlignReplaceQuotedSpaces")
3175 endfun
3177 " ---------------------------------------------------------------------
3178 " s:QArgSplitter: to avoid \ processing by <f-args>, <q-args> is needed. {{{1
3179 " However, <q-args> doesn't split at all, so this function returns a list
3180 " of arguments which has been:
3181 "   * split at whitespace
3182 "   * unless inside "..."s.  One may escape characters with a backslash inside double quotes.
3183 " along with a leading length-of-list.
3185 "   Examples:   %Align "\""   will align on "s
3186 "               %Align " "    will align on spaces
3188 " The resulting list:  qarglist[0] corresponds to a:0
3189 "                      qarglist[i] corresponds to a:{i}
3190 fun! s:QArgSplitter(qarg)
3191 "  call Dfunc("s:QArgSplitter(qarg<".a:qarg.">)")
3193   if a:qarg =~ '".*"'
3194    " handle "..." args, which may include whitespace
3195    let qarglist = []
3196    let args     = a:qarg
3197 "   call Decho("handle quoted arguments: args<".args.">")
3198    while args != ""
3199         let iarg   = 0
3200         let arglen = strlen(args)
3201 "       call Decho("args[".iarg."]<".args[iarg]."> arglen=".arglen)
3202         " find index to first not-escaped '"'
3203         while args[iarg] != '"' && iarg < arglen
3204          if args[iarg] == '\'
3205           let args= strpart(args,1)
3206          endif
3207          let iarg= iarg + 1
3208         endwhile
3209 "       call Decho("args<".args."> iarg=".iarg." arglen=".arglen)
3211         if iarg > 0
3212          " handle left of quote or remaining section
3213 "        call Decho("handle left of quote or remaining section")
3214          if args[iarg] == '"'
3215           let qarglist= qarglist + split(strpart(args,0,iarg-1))
3216          else
3217           let qarglist= qarglist + split(strpart(args,0,iarg))
3218          endif
3219          let args    = strpart(args,iarg)
3220          let arglen  = strlen(args)
3222         elseif iarg < arglen && args[0] == '"'
3223          " handle "quoted" section
3224 "        call Decho("handle quoted section")
3225          let iarg= 1
3226          while args[iarg] != '"' && iarg < arglen
3227           if args[iarg] == '\'
3228            let args= strpart(args,1)
3229           endif
3230           let iarg= iarg + 1
3231          endwhile
3232 "        call Decho("args<".args."> iarg=".iarg." arglen=".arglen)
3233          if args[iarg] == '"'
3234           call add(qarglist,strpart(args,1,iarg-1))
3235           let args= strpart(args,iarg+1)
3236          else
3237           let qarglist = qarglist + split(args)
3238           let args     = ""
3239          endif
3240         endif
3241 "       call Decho("qarglist".string(qarglist)." iarg=".iarg." args<".args.">")
3242    endwhile
3244   else
3245    " split at all whitespace
3246    let qarglist= split(a:qarg)
3247   endif
3249   let qarglistlen= len(qarglist)
3250   let qarglist   = insert(qarglist,qarglistlen)
3251 "  call Dret("s:QArgSplitter ".string(qarglist))
3252   return qarglist
3253 endfun
3255 " ---------------------------------------------------------------------
3256 " s:Strlen: this function returns the length of a string, even if its {{{1
3257 "           using two-byte etc characters.
3258 "           Currently, its only used if g:Align_xstrlen is set to a
3259 "           nonzero value.  Solution from Nicolai Weibull, vim docs
3260 "           (:help strlen()), Tony Mechelynck, and my own invention.
3261 fun! s:Strlen(x)
3262 "  call Dfunc("s:Strlen(x<".a:x.">")
3263   if g:Align_xstrlen == 1
3264    " number of codepoints (Latin a + combining circumflex is two codepoints)
3265    " (comment from TM, solution from NW)
3266    let ret= strlen(substitute(a:x,'.','c','g'))
3268   elseif g:Align_xstrlen == 2
3269    " number of spacing codepoints (Latin a + combining circumflex is one spacing 
3270    " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
3271    " (comment from TM, solution from TM)
3272    let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) 
3274   elseif g:Align_xstrlen == 3
3275    " virtual length (counting, for instance, tabs as anything between 1 and 
3276    " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately 
3277    " preceded by lam, one otherwise, etc.)
3278    " (comment from TM, solution from me)
3279    let modkeep= &l:mod
3280    exe "norm! o\<esc>"
3281    call setline(line("."),a:x)
3282    let ret= virtcol("$") - 1
3283    d
3284    let &l:mod= modkeep
3286   else
3287    " at least give a decent default
3288    ret= strlen(a:x)
3289   endif
3290 "  call Dret("s:Strlen ".ret)
3291   return ret
3292 endfun
3294 " ---------------------------------------------------------------------
3295 " Set up default values: {{{1
3296 "call Decho("-- Begin AlignCtrl Initialization --")
3297 call Align#AlignCtrl("default")
3298 "call Decho("-- End AlignCtrl Initialization --")
3300 " ---------------------------------------------------------------------
3301 "  Restore: {{{1
3302 let &cpo= s:keepcpo
3303 unlet s:keepcpo
3304 " vim: ts=4 fdm=marker
3305 autoload/AlignMaps.vim  [[[1
3307 " AlignMaps.vim : support functions for AlignMaps
3308 "   Author: Charles E. Campbell, Jr.
3309 "   Date:   Mar 03, 2009
3310 " Version:           41
3311 " ---------------------------------------------------------------------
3312 "  Load Once: {{{1
3313 if &cp || exists("g:loaded_AlignMaps")
3314  finish
3315 endif
3316 let g:loaded_AlignMaps= "v41"
3317 let s:keepcpo         = &cpo
3318 set cpo&vim
3320 " =====================================================================
3321 " Functions: {{{1
3323 " ---------------------------------------------------------------------
3324 " AlignMaps#WrapperStart: {{{2
3325 fun! AlignMaps#WrapperStart(vis) range
3326 "  call Dfunc("AlignMaps#WrapperStart(vis=".a:vis.")")
3328   if a:vis
3329    norm! '<ma'>
3330   endif
3332   if line("'y") == 0 || line("'z") == 0 || !exists("s:alignmaps_wrapcnt") || s:alignmaps_wrapcnt <= 0
3333 "   call Decho("wrapper initialization")
3334    let s:alignmaps_wrapcnt    = 1
3335    let s:alignmaps_keepgd     = &gdefault
3336    let s:alignmaps_keepsearch = @/
3337    let s:alignmaps_keepch     = &ch
3338    let s:alignmaps_keepmy     = SaveMark("'y")
3339    let s:alignmaps_keepmz     = SaveMark("'z")
3340    let s:alignmaps_posn       = SaveWinPosn(0)
3341    " set up fencepost blank lines
3342    put =''
3343    norm! mz'a
3344    put! =''
3345    ky
3346    let s:alignmaps_zline      = line("'z")
3347    exe "'y,'zs/@/\177/ge"
3348   else
3349 "   call Decho("embedded wrapper")
3350    let s:alignmaps_wrapcnt    = s:alignmaps_wrapcnt + 1
3351    norm! 'yjma'zk
3352   endif
3354   " change some settings to align-standard values
3355   set nogd
3356   set ch=2
3357   AlignPush
3358   norm! 'zk
3359 "  call Dret("AlignMaps#WrapperStart : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
3360 endfun
3362 " ---------------------------------------------------------------------
3363 " AlignMaps#WrapperEnd: {{{2
3364 fun! AlignMaps#WrapperEnd() range
3365 "  call Dfunc("AlignMaps#WrapperEnd() alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
3367   " remove trailing white space introduced by whatever in the modification zone
3368   'y,'zs/ \+$//e
3370   " restore AlignCtrl settings
3371   AlignPop
3373   let s:alignmaps_wrapcnt= s:alignmaps_wrapcnt - 1
3374   if s:alignmaps_wrapcnt <= 0
3375    " initial wrapper ending
3376    exe "'y,'zs/\177/@/ge"
3378    " if the 'z line hasn't moved, then go ahead and restore window position
3379    let zstationary= s:alignmaps_zline == line("'z")
3381    " remove fencepost blank lines.
3382    " restore 'a
3383    norm! 'yjmakdd'zdd
3385    " restore original 'y, 'z, and window positioning
3386    call RestoreMark(s:alignmaps_keepmy)
3387    call RestoreMark(s:alignmaps_keepmz)
3388    if zstationary > 0
3389     call RestoreWinPosn(s:alignmaps_posn)
3390 "    call Decho("restored window positioning")
3391    endif
3393    " restoration of options
3394    let &gd= s:alignmaps_keepgd
3395    let &ch= s:alignmaps_keepch
3396    let @/ = s:alignmaps_keepsearch
3398    " remove script variables
3399    unlet s:alignmaps_keepch
3400    unlet s:alignmaps_keepsearch
3401    unlet s:alignmaps_keepmy
3402    unlet s:alignmaps_keepmz
3403    unlet s:alignmaps_keepgd
3404    unlet s:alignmaps_posn
3405   endif
3407 "  call Dret("AlignMaps#WrapperEnd : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
3408 endfun
3410 " ---------------------------------------------------------------------
3411 " AlignMaps#StdAlign: some semi-standard align calls {{{2
3412 fun! AlignMaps#StdAlign(mode) range
3413 "  call Dfunc("AlignMaps#StdAlign(mode=".a:mode.")")
3414   if     a:mode == 1
3415    " align on @
3416 "   call Decho("align on @")
3417    AlignCtrl mIp1P1=l @
3418    'a,.Align
3419   elseif a:mode == 2
3420    " align on @, retaining all initial white space on each line
3421 "   call Decho("align on @, retaining all initial white space on each line")
3422    AlignCtrl mWp1P1=l @
3423    'a,.Align
3424   elseif a:mode == 3
3425    " like mode 2, but ignore /* */-style comments
3426 "   call Decho("like mode 2, but ignore /* */-style comments")
3427    AlignCtrl v ^\s*/[/*]
3428    AlignCtrl mWp1P1=l @
3429    'a,.Align
3430   else
3431    echoerr "(AlignMaps) AlignMaps#StdAlign doesn't support mode#".a:mode
3432   endif
3433 "  call Dret("AlignMaps#StdAlign")
3434 endfun
3436 " ---------------------------------------------------------------------
3437 " AlignMaps#CharJoiner: joins lines which end in the given character (spaces {{{2
3438 "             at end are ignored)
3439 fun! AlignMaps#CharJoiner(chr)
3440 "  call Dfunc("AlignMaps#CharJoiner(chr=".a:chr.")")
3441   let aline = line("'a")
3442   let rep   = line(".") - aline
3443   while rep > 0
3444         norm! 'a
3445         while match(getline(aline),a:chr . "\s*$") != -1 && rep >= 0
3446           " while = at end-of-line, delete it and join with next
3447           norm! 'a$
3448           j!
3449           let rep = rep - 1
3450         endwhile
3451         " update rep(eat) count
3452         let rep = rep - 1
3453         if rep <= 0
3454           " terminate loop if at end-of-block
3455           break
3456         endif
3457         " prepare for next line
3458         norm! jma
3459         let aline = line("'a")
3460   endwhile
3461 "  call Dret("AlignMaps#CharJoiner")
3462 endfun
3464 " ---------------------------------------------------------------------
3465 " AlignMaps#Equals: supports \t= and \T= {{{2
3466 fun! AlignMaps#Equals() range
3467 "  call Dfunc("AlignMaps#Equals()")
3468   'a,'zs/\s\+\([*/+\-%|&\~^]\==\)/ \1/e
3469   'a,'zs@ \+\([*/+\-%|&\~^]\)=@\1=@ge
3470   'a,'zs/==/\="\<Char-0x0f>\<Char-0x0f>"/ge
3471   'a,'zs/\([!<>:]\)=/\=submatch(1)."\<Char-0x0f>"/ge
3472   norm g'zk
3473   AlignCtrl mIp1P1=l =
3474   AlignCtrl g =
3475   'a,'z-1Align
3476   'a,'z-1s@\([*/+\-%|&\~^!=]\)\( \+\)=@\2\1=@ge
3477   'a,'z-1s/\( \+\);/;\1/ge
3478   if &ft == "c" || &ft == "cpp"
3479 "   call Decho("exception for ".&ft)
3480    'a,'z-1v/^\s*\/[*/]/s/\/[*/]/@&@/e
3481    'a,'z-1v/^\s*\/[*/]/s/\*\//@&/e
3482    if exists("g:mapleader")
3483     exe "norm 'zk"
3484     call AlignMaps#StdAlign(1)
3485    else
3486     exe "norm 'zk"
3487     call AlignMaps#StdAlign(1)
3488    endif
3489    'y,'zs/^\(\s*\) @/\1/e
3490   endif
3491   'a,'z-1s/\%x0f/=/ge
3492   'y,'zs/ @//eg
3493 "  call Dret("AlignMaps#Equals")
3494 endfun
3496 " ---------------------------------------------------------------------
3497 " AlignMaps#Afnc: useful for splitting one-line function beginnings {{{2
3498 "            into one line per argument format
3499 fun! AlignMaps#Afnc()
3500 "  call Dfunc("AlignMaps#Afnc()")
3502   " keep display quiet
3503   let chkeep = &ch
3504   let gdkeep = &gd
3505   let vekeep = &ve
3506   set ch=2 nogd ve=
3508   " will use marks y,z ; save current values
3509   let mykeep = SaveMark("'y")
3510   let mzkeep = SaveMark("'z")
3512   " Find beginning of function -- be careful to skip over comments
3513   let cmmntid  = synIDtrans(hlID("Comment"))
3514   let stringid = synIDtrans(hlID("String"))
3515   exe "norm! ]]"
3516   while search(")","bW") != 0
3517 "   call Decho("line=".line(".")." col=".col("."))
3518    let parenid= synIDtrans(synID(line("."),col("."),1))
3519    if parenid != cmmntid && parenid != stringid
3520         break
3521    endif
3522   endwhile
3523   norm! %my
3524   s/(\s*\(\S\)/(\r  \1/e
3525   exe "norm! `y%"
3526   s/)\s*\(\/[*/]\)/)\r\1/e
3527   exe "norm! `y%mz"
3528   'y,'zs/\s\+$//e
3529   'y,'zs/^\s\+//e
3530   'y+1,'zs/^/  /
3532   " insert newline after every comma only one parenthesis deep
3533   sil! exe "norm! `y\<right>h"
3534   let parens   = 1
3535   let cmmnt    = 0
3536   let cmmntline= -1
3537   while parens >= 1
3538 "   call Decho("parens=".parens." @a=".@a)
3539    exe 'norm! ma "ay`a '
3540    if @a == "("
3541     let parens= parens + 1
3542    elseif @a == ")"
3543     let parens= parens - 1
3545    " comment bypass:  /* ... */  or //...
3546    elseif cmmnt == 0 && @a == '/'
3547     let cmmnt= 1
3548    elseif cmmnt == 1
3549         if @a == '/'
3550          let cmmnt    = 2   " //...
3551          let cmmntline= line(".")
3552         elseif @a == '*'
3553          let cmmnt= 3   " /*...
3554         else
3555          let cmmnt= 0
3556         endif
3557    elseif cmmnt == 2 && line(".") != cmmntline
3558         let cmmnt    = 0
3559         let cmmntline= -1
3560    elseif cmmnt == 3 && @a == '*'
3561         let cmmnt= 4
3562    elseif cmmnt == 4
3563         if @a == '/'
3564          let cmmnt= 0   " ...*/
3565         elseif @a != '*'
3566          let cmmnt= 3
3567         endif
3569    elseif @a == "," && parens == 1 && cmmnt == 0
3570         exe "norm! i\<CR>\<Esc>"
3571    endif
3572   endwhile
3573   norm! `y%mz%
3574   sil! 'y,'zg/^\s*$/d
3576   " perform substitutes to mark fields for Align
3577   sil! 'y+1,'zv/^\//s/^\s\+\(\S\)/  \1/e
3578   sil! 'y+1,'zv/^\//s/\(\S\)\s\+/\1 /eg
3579   sil! 'y+1,'zv/^\//s/\* \+/*/ge
3580   sil! 'y+1,'zv/^\//s/\w\zs\s*\*/ */ge
3581   "                                                 func
3582   "                    ws  <- declaration   ->    <-ptr  ->   <-var->    <-[array][]    ->   <-glop->      <-end->
3583   sil! 'y+1,'zv/^\//s/^\s*\(\(\K\k*\s*\)\+\)\s\+\([(*]*\)\s*\(\K\k*\)\s*\(\(\[.\{-}]\)*\)\s*\(.\{-}\)\=\s*\([,)]\)\s*$/  \1@#\3@\4\5@\7\8/e
3584   sil! 'y+1,'z+1g/^\s*\/[*/]/norm! kJ
3585   sil! 'y+1,'z+1s%/[*/]%@&@%ge
3586   sil! 'y+1,'z+1s%*/%@&%ge
3587   AlignCtrl mIp0P0=l @
3588   sil! 'y+1,'zAlign
3589   sil! 'y,'zs%@\(/[*/]\)@%\t\1 %e
3590   sil! 'y,'zs%@\*/% */%e
3591   sil! 'y,'zs/@\([,)]\)/\1/
3592   sil! 'y,'zs/@/ /
3593   AlignCtrl mIlrp0P0= # @
3594   sil! 'y+1,'zAlign
3595   sil! 'y+1,'zs/#/ /
3596   sil! 'y+1,'zs/@//
3597   sil! 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e
3599   " Restore
3600   call RestoreMark(mykeep)
3601   call RestoreMark(mzkeep)
3602   let &ch= chkeep
3603   let &gd= gdkeep
3604   let &ve= vekeep
3606 "  call Dret("AlignMaps#Afnc")
3607 endfun
3609 " ---------------------------------------------------------------------
3610 "  AlignMaps#FixMultiDec: converts a   type arg,arg,arg;   line to multiple lines {{{2
3611 fun! AlignMaps#FixMultiDec()
3612 "  call Dfunc("AlignMaps#FixMultiDec()")
3614   " save register x
3615   let xkeep   = @x
3616   let curline = getline(".")
3617 "  call Decho("curline<".curline.">")
3619   " Get the type.  I'm assuming one type per line (ie.  int x; double y;   on one line will not be handled properly)
3620   let @x=substitute(curline,'^\(\s*[a-zA-Z_ \t][a-zA-Z0-9_ \t]*\)\s\+[(*]*\h.*$','\1','')
3621 "  call Decho("@x<".@x.">")
3623   " transform line
3624   exe 's/,/;\r'.@x.' /ge'
3626   "restore register x
3627   let @x= xkeep
3629 "  call Dret("AlignMaps#FixMultiDec : my=".line("'y")." mz=".line("'z"))
3630 endfun
3632 " ---------------------------------------------------------------------
3633 "  Restore: {{{1
3634 let &cpo= s:keepcpo
3635 unlet s:keepcpo
3636 " vim: ts=4 fdm=marker