1 " Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
4 plugin/AlignPlugin.vim [[[1
6 " AlignPlugin: tool to align multiple fields based on one or more separators
7 " Author: Charles E. Campbell, Jr.
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
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
25 " ---------------------------------------------------------------------
27 if &cp || exists("g:loaded_AlignPlugin")
30 let g:loaded_AlignPlugin = "v35"
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 " ---------------------------------------------------------------------
46 " vim: ts=4 fdm=marker
47 plugin/AlignMapsPlugin.vim [[[1
49 " AlignMapsPlugin: Alignment maps based upon <Align.vim> and <AlignMaps.vim>
50 " Maintainer: Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
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
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
85 " ---------------------------------------------------------------------
87 if &cp || exists("g:loaded_AlignMapsPlugin")
91 let g:loaded_AlignMapsPlugin = "v41"
94 " =====================================================================
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
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
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
135 if !hasmapto('<Plug>AM_anum')|map <unique> <Leader>anum <Plug>AM_aunum|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 " =====================================================================
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")
244 if !exists("g:DrChipTopLvlMenu")
245 let g:DrChipTopLvlMenu= "DrChip."
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'
283 " =====================================================================
288 " ==============================================================================
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
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)
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
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 " ---------------------------------------------------------------------
325 if &cp || exists("g:loaded_cecutil")
328 let g:loaded_cecutil = "v18b"
333 " =======================
334 " Public Interface: {{{1
335 " =======================
337 " ---------------------------------------------------------------------
338 " Map Interface: {{{2
339 if !hasmapto('<Plug>SaveWinPosn')
340 map <unique> <Leader>swp <Plug>SaveWinPosn
342 if !hasmapto('<Plug>RestoreWinPosn')
343 map <unique> <Leader>rwp <Plug>RestoreWinPosn
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>)
357 let s:modifier= "sil "
359 let s:modifier= "sil keepj "
366 " ---------------------------------------------------------------------
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")
378 let siso_keep = &siso
380 setlocal so=0 siso=0 ss=0
382 let swline = line(".")
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>"
389 let savedposn= savedposn.":".s:modifier."norm! ".swwline."\<c-y>\<cr>"
392 let savedposn= savedposn.":".s:modifier."norm! 0".swwcol."zl\<cr>"
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
400 if !exists("b:cecutil_iwinposn")
401 let b:cecutil_iwinposn= 1
403 let b:cecutil_iwinposn= b:cecutil_iwinposn + 1
405 " call Decho("saving posn to SWP stack")
406 let b:cecutil_winposn{b:cecutil_iwinposn}= savedposn
410 let &siso = siso_keep
413 " if exists("b:cecutil_iwinposn") " Decho
414 " call Decho("b:cecutil_winpos{".b:cecutil_iwinposn."}[".b:cecutil_winposn{b:cecutil_iwinposn}."]")
416 " call Decho("b:cecutil_iwinposn doesn't exist")
418 " call Dret("SaveWinPosn [".savedposn."]")
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")
435 let siso_keep = &l:siso
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}.">")
444 exe "silent! ".b:cecutil_winposn{b:cecutil_iwinposn}
445 catch /^Vim\%((\a\+)\)\=:E749/
446 " ignore empty buffer error messages
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
457 if b:cecutil_iwinposn < 1
458 unlet b:cecutil_iwinposn
463 echomsg "***warning*** need to SaveWinPosn first!"
467 else " handle input argument
468 " call Decho("using input a:1<".a:1.">")
469 " use window position passed to this function
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
483 let jwinposn= jwinposn - 1
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.
494 elseif virtcol(".") < virtcol("$")
499 let &l:siso = siso_keep
502 " call Dret("RestoreWinPosn")
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")
517 while winbufnr(0) != a:bufnum && (first || winnr() != 1)
521 " call Dret("GoWinbufnr")
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)
534 " call Decho("markname=".markname)
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)
547 let g:savemark_{markname} = ""
553 " call Dret("SaveMark : savemark<".savemark.">")
557 " ---------------------------------------------------------------------
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")
567 let markname= strpart(a:markname,0,1)
569 " handles 'a -> a styles
570 let markname= strpart(a:markname,1,1)
572 " call Decho("markname=".markname." strlen(a:markname)=".strlen(a:markname))
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
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
593 call RestoreWinPosn(winposn)
596 " call Dret("RestoreMark")
599 " ---------------------------------------------------------------------
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
610 let markname= strpart(a:markname,0,1)
612 " handles 'a -> a styles
613 let markname= strpart(a:markname,1,1)
615 " call Decho("markname=".markname)
618 let winposn = SaveWinPosn(0)
620 let lineone = getline(".")
625 call RestoreWinPosn(winposn)
627 " restore options to user settings
628 let &report = reportkeep
631 " call Dret("DestroyMark")
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))
649 " ---------------------------------------------------------------------
651 "fun! ListWinPosn() " Decho
652 " if !exists("b:cecutil_iwinposn") || b:cecutil_iwinposn == 0 " Decho
653 " call Decho("nothing on SWP stack") " 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
660 " call Decho("winposn{".jwinposn."} -- doesn't exist") " Decho
662 " let jwinposn= jwinposn - 1 " 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 "")
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.
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
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}= ""
704 " set up dounmap: if 1, then save and unmap (a:mapmode leads with a "u")
706 let mapmode = a:mapmode
709 while mapmode =~ '^[bu]'
712 let mapmode= strpart(a:mapmode,1)
713 elseif mapmode =~ '^b'
714 let dobuffer= "<buffer> "
715 let mapmode= strpart(a:mapmode,1)
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
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
734 exe "silent! ".mapmode."unmap ".dobuffer.amap
737 " save single map <something>
738 elseif strpart(a:mapchx,0,1) == '<'
739 " call Decho("save single map <something>")
741 if amap == "|" || amap == "\<c-v>"
742 let amap= "\<c-v>".amap
743 " call Decho("amap[[".amap."]]")
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
751 exe "silent! ".mapmode."unmap ".dobuffer.amap
756 " call Decho("save multiple maps")
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
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
769 exe "silent! ".mapmode."unmap ".dobuffer.amap
774 " call Dret("SaveUserMaps : restoremap_".a:suffix.": ".s:restoremap_{a:suffix})
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}
788 unlet s:restoremap_{a:suffix}
790 " call Dret("RestoreUserMaps")
802 " vim: ts=4 fdm=marker
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 >
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
868 < To see a user's guide, see |align-userguide|
869 To see examples, see |alignctrl| and |alignmaps|
871 /=============+=========+=====================================================\
873 || Commands \ Value/ Explanation ||
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','&','\\') ||
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. ||
888 || | < | < left justify separator Separators are justified, ||
889 || | | > right justify separator too. Separator styles ||
890 || | | | center separator are cyclic. ||
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 ||
899 || | p1 | p### pad separator on left by # blanks ||
900 || | P1 | P### pad separator on right by # blanks ||
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 ||
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) ||
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. ||
921 || | | AlignCtrl default ||
922 || | | will clear the AlignCtrl ||
923 || | | stack & set the default: AlignCtrl "Ilp1P1=" '=' ||
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):
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 >
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: >
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|) >
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: >
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 >
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
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. >
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
1035 Interpretation: align all commas over the entire
1037 < The :Align! format permits alignment control commands
1038 to precede the alignment patterns. >
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. >
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. >
1061 Interpretation: presumably AlignPush was
1062 used (at least once) previously; this command
1063 restores the AlignCtrl settings when AlignPush
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:
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~
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
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
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.
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:
1151 wWI INITIAL WHITE SPACE *alignctrl-W* {{{3
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:
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
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
1254 ex. 1st separator only: AlignCtrl l:
1255 2nd separator only: AlignCtrl -l:
1256 3rd separator only: AlignCtrl --l:
1261 =C CYCLIC VS ALL-ACTIVE SEPARATORS *alignctrl-C* {{{3
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
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
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.
1323 In this case it would probably have been a better idea to have used >
1325 < as that alignment control would guarantee that no more cycling
1326 would be used after the vertical bar.
1328 Example: Cyclic separators
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
1341 the first and second separators are "|",
1342 the third separator is "&", and
1343 the fourth separator is "-",
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 - ...
1358 <>| SEPARATOR JUSTIFICATION *alignctrl->* {{{3
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 -\+ >
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 +---------------------+---------------------+---------------------+
1386 gv SELECTIVE APPLICATION *alignctrl-v* {{{3
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. >
1397 Align will only consider those lines which have the given 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.
1419 To remove AlignCtrl's g and v patterns, use (as appropriate) >
1424 To see what g/v patterns are currently active, just use the reporting
1425 capability of an unadorned call to AlignCtrl: >
1431 m MAP SUPPORT *alignctrl-m* {{{3
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().
1444 P### PADDING *alignctrl-P* {{{3
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
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,
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>
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,
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.
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)
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|
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|
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~*
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
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
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
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
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: >
1689 struct ABC_str abc,def;
1699 ---------------------------
1700 Alignment Map Examples: \a? *alignmap-a?* {{{3
1701 ---------------------------
1703 Original: illustrates ()?: aligning >
1706 (x == DEFG)? "defg" :
1707 (x == HIJKL)? "hijkl" : "???");
1709 Becomes: select "(x == ..." lines, then \a? >
1712 (x == DEFG)? "defg" :
1713 (x == HIJKL)? "hijkl" : "???");
1716 ---------------------------
1717 Alignment Map Examples: \a< *alignmap-a<* {{{3
1718 ---------------------------
1720 Original: illustrating aligning of << and >> >
1723 cout << "this is x=" << x;
1724 cout << "but y=" << y << "is not";
1726 Becomes: select "(x == ..." lines, then \a< >
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 >
1742 Bcomes: select the three assignment lines, then \a:= >
1743 aa := bb := cc := 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
1755 soon be surrounded by a
1758 Becomes: Select "This..box." with ctrl-v, press \abox >
1759 /***************************
1760 * This is some plain text *
1762 * soon be surrounded by a *
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
1794 Becomes: Go to first line, ma. Go to last line, press \anum >
1795 -1.234 .5678 -.901e-4
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), >
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 |
1814 -1,234 ,5678 -,901e-4
1819 Becomes: Go to first line, ma. Go to last line, press \anum >
1820 -1,234 ,5678 -,901e-4
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 ---------------------------
1842 int x; /* this is a comment */
1843 int yzw; /* this is another comment*/
1845 Becomes: Select the three lines, press \ascom >
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 >
1861 struct abc_str *pabc;
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 >
1881 struct abc_str *pabc;
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 >
1906 Becomes: Select four definition lines, apply \adef >
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,
1926 Original: illustrates lining up ansi-c style function definitions >
1928 struct abc_str ***a, /* one */
1934 Becomes: put cursor anywhere before the '{', press \afnc >
1936 struct abc_str ***a, /* one */
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). >
1950 /* this is a test */
1952 double y; /* to use adcom */
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
1960 /* this is a test */
1962 double y; /* to use adcom */
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 */
1975 } /* only appears on two lines */
1977 Becomes: Select the three lines, press \aocom >
1978 if(itworks) { /* this comment */
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.
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)
2022 Becomes: Select the lines, \tsq >
2027 ---------------------------
2028 Alignment Map Examples: \tt *alignmap-tt* {{{3
2029 ---------------------------
2031 Original: illustrates aligning a LaTex Table >
2032 \begin{tabular}{||c|l|r||}
2034 one&two&three\\ \hline
2040 Becomes: Select the three lines inside the table >
2041 (ie. one..,four..,seven..) and press \tt
2042 \begin{tabular}{||c|l|r||}
2044 one & two & three \\ \hline
2045 four & five & six \\
2046 seven & eight & nine \\
2051 ----------------------------
2052 Alignment Map Examples: \tml *alignmap-tml* {{{3
2053 ----------------------------
2055 Original: illustrates aligning multi-line continuation marks >
2072 ---------------------------
2073 Alignment Map Examples: \t= *alignmap-t=* {{{3
2074 ---------------------------
2076 Original: illustrates left-justified aligning of = >
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 */
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
2118 35 : Nov 02, 2008 * g:loaded_AlignPlugin testing to prevent re-loading
2120 Nov 19, 2008 * new sanity check for an AlignStyle of just ":"
2121 Jan 08, 2009 * save&restore of |'mod'| now done with local
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)
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
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
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
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
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
2181 11 : Jul 08, 2002 : prevent separator patterns which match zero length
2182 -+: included as additional alignment/justification
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
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
2204 Oct 24, 2008 * broke AlignMaps into a plugin and autoload
2206 v39 Mar 06, 2008 : * \t= only does /* ... */ aligning when in *.c
2208 v38 Aug 18, 2007 : * \tt altered so that it works with the new
2209 use of |<q-args>| plus a custom argument
2211 v36 Sep 27, 2006 : * AlignWrapperStart() now has tests that marks
2213 May 15, 2007 * \anum and variants improved
2214 v35 Sep 01, 2006 : * \t= and cousins used "`"s. They now use \xff
2216 * \acom now works with doxygen style /// comments
2217 * <char-0xff> used in \t= \T= \w= and \m= instead
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
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
2250 * \adec ignores preprocessor lines and lines with
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
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
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 ==============================================================================
2273 vim:tw=78:ts=8:ft=help:fdm=marker:
2274 autoload/Align.vim [[[1
2276 " Align: tool to align multiple fields based on one or more separators
2277 " Author: Charles E. Campbell, Jr.
2278 " Date: Mar 03, 2009
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
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
2297 " ---------------------------------------------------------------------
2299 if exists("g:loaded_Align") || &cp
2302 let g:loaded_Align = "v35"
2305 echo "***warning*** this version of Align needs vim 7.0"
2313 " ---------------------------------------------------------------------
2314 " Debugging Support: {{{1
2315 "if !exists("g:loaded_Decho") | runtime plugin/Decho.vim | endif
2317 " ---------------------------------------------------------------------
2319 if !exists("g:Align_xstrlen")
2320 if &enc == "latin1" || $LANG == "en_US.UTF-8" || !has("multi_byte")
2321 let g:Align_xstrlen= 0
2323 let g:Align_xstrlen= 1
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
2360 fun! Align#AlignCtrl(...)
2362 " call Dfunc("AlignCtrl(...) a:0=".a:0)
2364 " save options that will be changed
2365 let keep_search = @/
2368 " turn ignorecase off
2371 " clear visual mode so that old visual-mode selections don't
2372 " get applied to new invocations of Align().
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"
2378 elseif exists("s:dovisclear")
2379 " call Decho("clearing visual mode a:0=".a:0." a:1<".a:1.">")
2380 let clearvmode= visualmode(1)
2383 " set up a list akin to an argument list
2385 let A= s:QArgSplitter(a:1)
2393 " Check for bad separator patterns (zero-length matches)
2394 " (but zero-length patterns for g/v is ok)
2399 echoerr "AlignCtrl: separator<".A[ipat]."> matches zero-length string"
2401 " call Dret("AlignCtrl")
2409 " call Decho("AlignCtrl() A[0]=".A[0])
2410 if !exists("s:AlignStyle")
2411 let s:AlignStyle= "l"
2413 if !exists("s:AlignPrePad")
2414 let s:AlignPrePad= 0
2416 if !exists("s:AlignPostPad")
2417 let s:AlignPostPad= 0
2419 if !exists("s:AlignLeadKeep")
2420 let s:AlignLeadKeep= 'w'
2424 " ----------------------
2425 " List current selection
2426 " ----------------------
2427 if !exists("s:AlignPatQty")
2428 let s:AlignPatQty= 0
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.">"
2440 while ipat <= s:AlignPatQty
2441 echo "Pat".ipat."<".s:AlignPat_{ipat}.">"
2442 " call Decho("Pat".ipat."<".s:AlignPat_{ipat}.">")
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()
2461 unlet s:AlignCtrlStackQty
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
2469 let @/ = keep_search
2470 " call Dret("AlignCtrl")
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()
2482 " = : record a list of alignment patterns that are equivalent
2484 " call Decho("style case =: record list of equiv alignment patterns")
2485 let s:AlignCtrl = '='
2487 let s:AlignPatQty= 1
2488 let s:AlignPat_1 = A[2]
2491 let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat]
2494 let s:AlignPat_1= '\('.s:AlignPat_1.'\)'
2495 " call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">")
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'
2503 let s:AlignPatQty= A[0] - 1
2506 let s:AlignPat_{ipat}= A[ipat+1]
2507 " call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">")
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
2520 " call Dret("AlignCtrl")
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
2532 " call Dret("AlignCtrl")
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'
2549 " first list item is a "g" selector pattern
2550 " call Decho("style case g: global selector pattern")
2552 if exists("s:AlignGPat")
2554 " call Decho("unlet s:AlignGPat")
2557 let s:AlignGPat= A[2]
2558 " call Decho("s:AlignGPat<".s:AlignGPat.">")
2560 elseif style =~# 'v'
2561 " first list item is a "v" selector pattern
2562 " call Decho("style case v: global selector anti-pattern")
2564 if exists("s:AlignVPat")
2566 " call Decho("unlet s:AlignVPat")
2569 let s:AlignVPat= A[2]
2570 " call Decho("s:AlignVPat<".s:AlignVPat.">")
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.">")
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)
2590 if !exists("s:AlignCtrl")
2591 let s:AlignCtrl= '='
2594 " restore search and options
2595 let @/ = keep_search
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
2602 " ---------------------------------------------------------------------
2603 " s:MakeSpace: returns a string with spacecnt blanks {{{1
2604 fun! s:MakeSpace(spacecnt)
2605 " call Dfunc("MakeSpace(spacecnt=".a:spacecnt.")")
2607 let spacecnt = a:spacecnt
2610 let spacecnt = spacecnt - 1
2612 " call Dret("MakeSpace <".str.">")
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)
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")
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")
2633 " set up a list akin to an argument list
2635 let A= s:QArgSplitter(a:1)
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")
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")
2652 call Align#AlignCtrl(A[1]."m")
2654 call Align#AlignCtrl(A[1])
2658 " Check for bad separator patterns (zero-length matches)
2659 let ipat= 1 + hasctrl
2662 echoerr "Align: separator<".A[ipat]."> matches zero-length string"
2663 " call Dret("Align#Align")
2669 " record current search pattern for subsequent restoration
2672 let keep_report= &report
2673 set noic report=10000
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
2687 let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat]
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
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}.">")
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
2715 let begcol = virtcol("'>")-1
2716 let endcol = virtcol("'<")-1
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
2725 " call Decho("begline=".begline." endline=".endline)
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("'<")) )
2734 let ragged = ( col("'>") > strlen(getline("'>")) || col("'<") > strlen(getline("'<")) )
2745 " call Decho("lines[".begline.",".endline."] col[".begcol.",".endcol."] ragged=".ragged." AlignCtrl<".s:AlignCtrl.">")
2749 let pastekeep= &l: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
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.">")
2761 exe begline.",".endline."ret"
2763 " Execute two passes
2764 " First pass: collect alignment data (max field sizes)
2765 " Second pass: perform alignment
2769 " call Decho("---- Pass ".pass.": ----")
2772 while line <= endline
2774 let txt = getline(line)
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")
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")
2798 " Always skip blank lines
2799 if match(txt,'^\s*$') != -1
2800 " call Decho("Pass".pass.": skipping")
2805 " Extract visual-block selected text (init bgntxt, endtxt)
2806 if exists("g:Align_xstrlen") && g:Align_xstrlen
2807 let txtlen= s:Strlen(txt)
2809 let txtlen= strlen(txt)
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")
2821 " call Decho("Pass".pass.": no beginning text")
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)
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")
2840 " Initialize for both passes
2841 let seppat = s:AlignPat_{1}
2846 let alignstyle = s:AlignStyle
2849 let alignprepad = s:AlignPrePad
2850 let alignpostpad= s:AlignPostPad
2851 let alignsep = s:AlignSep
2852 let alignophold = " "
2854 " call Decho("Pass".pass.": initial alignstyle<".alignstyle."> seppat<".seppat.">")
2856 " Process each field on the line
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.">")
2864 if ipat > s:AlignPatQty
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
2875 let alignstyle = strpart(alignstyle,1).strpart(alignstyle,0,1)
2876 let alignopnxt = strpart(alignstyle,0,1)
2880 " call Decho("Pass".pass.": alignop<:> case: setting seppat<$> doend==2")
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.">")
2902 let seplen= sepfield - endfield
2903 " call Decho("Pass".pass.": seplen=[sepfield=".sepfield."] - [endfield=".endfield."]=".seplen)
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
2915 if exists("g:Align_xstrlen") && g:Align_xstrlen
2916 let fieldlen = s:Strlen(field)
2918 let fieldlen = strlen(field)
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.">")
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.">")
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
2953 if exists("g:Align_xstrlen") && g:Align_xstrlen
2954 let fieldlen = s:Strlen(field)
2956 let fieldlen = strlen(field)
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
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)
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
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
2990 " left justfiy the field
2991 let newtxt= newtxt.field.s:MakeSpace(spaces).sep
2993 elseif ragged && doend == 2
2994 " field at maximum field size and no trailing blanks needed
2995 let newtxt= newtxt.field
2997 " field is at maximum field size already
2998 let newtxt= newtxt.field.sep
3000 " call Decho("Pass".pass.": newtxt<".newtxt.">")
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
3010 " handle end-of-text as end-of-field
3016 endif " endfield != -1
3017 endwhile " doend loop (as well as regularly separated fields)
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)
3028 endwhile " line loop
3031 endwhile " pass loop
3032 " call Decho("end of two pass loop")
3034 " Restore user options
3036 let &l:paste = pastekeep
3038 if exists("s:DoAlignPop")
3039 " AlignCtrl Map support
3040 call Align#AlignPop()
3044 " restore current search pattern
3045 let @/ = keep_search
3047 let &report = keep_report
3049 " call Dret("Align#Align")
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
3062 let s:AlignCtrlStackQty= s:AlignCtrlStackQty + 1
3065 " construct an AlignCtrlStack entry
3066 if !exists("s:AlignSep")
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
3076 let s:AlignGPat_{s:AlignCtrlStackQty}= ""
3078 if exists("s:AlignVPat")
3079 let s:AlignVPat_{s:AlignCtrlStackQty}= s:AlignVPat
3081 let s:AlignVPat_{s:AlignCtrlStackQty}= ""
3084 " call Dret("AlignPush")
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()")
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")
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")
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})
3115 call Align#AlignCtrl('g')
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})
3123 call Align#AlignCtrl('v')
3126 unlet s:AlignVPat_{s:AlignCtrlStackQty}
3127 let s:AlignCtrlStackQty= s:AlignCtrlStackQty - 1
3129 " call Dret("Align#AlignPop <".retval."> : AlignCtrlStackQty=".s:AlignCtrlStackQty)
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)
3142 let l:linelen = strlen(l:line)
3144 let l:startingPos = 0
3145 let l:startQuotePos = 0
3146 let l:endQuotePos = 0
3148 let l:quoteRe = '\\\@<!"'
3150 " "call Decho("in replace spaces. line=" . line('.'))
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")
3157 let l:endQuotePos = match(l:line, l:quoteRe, l:startQuotePos + 1)
3158 if (l:endQuotePos < 0)
3159 " "call Decho("Mismatched quotes")
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, '%', '')
3170 let l:startingPos = l:endQuotePos + 1
3172 call setline(line('.'), l:line)
3174 " call Dret("AlignReplaceQuotedSpaces")
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.">)")
3194 " handle "..." args, which may include whitespace
3197 " call Decho("handle quoted arguments: args<".args.">")
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)
3209 " call Decho("args<".args."> iarg=".iarg." arglen=".arglen)
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))
3217 let qarglist= qarglist + split(strpart(args,0,iarg))
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")
3226 while args[iarg] != '"' && iarg < arglen
3227 if args[iarg] == '\'
3228 let args= strpart(args,1)
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)
3237 let qarglist = qarglist + split(args)
3241 " call Decho("qarglist".string(qarglist)." iarg=".iarg." args<".args.">")
3245 " split at all whitespace
3246 let qarglist= split(a:qarg)
3249 let qarglistlen= len(qarglist)
3250 let qarglist = insert(qarglist,qarglistlen)
3251 " call Dret("s:QArgSplitter ".string(qarglist))
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.
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)
3281 call setline(line("."),a:x)
3282 let ret= virtcol("$") - 1
3287 " at least give a decent default
3290 " call Dret("s:Strlen ".ret)
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 " ---------------------------------------------------------------------
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
3311 " ---------------------------------------------------------------------
3313 if &cp || exists("g:loaded_AlignMaps")
3316 let g:loaded_AlignMaps= "v41"
3317 let s:keepcpo = &cpo
3320 " =====================================================================
3323 " ---------------------------------------------------------------------
3324 " AlignMaps#WrapperStart: {{{2
3325 fun! AlignMaps#WrapperStart(vis) range
3326 " call Dfunc("AlignMaps#WrapperStart(vis=".a:vis.")")
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
3346 let s:alignmaps_zline = line("'z")
3347 exe "'y,'zs/@/\177/ge"
3349 " call Decho("embedded wrapper")
3350 let s:alignmaps_wrapcnt = s:alignmaps_wrapcnt + 1
3354 " change some settings to align-standard values
3359 " call Dret("AlignMaps#WrapperStart : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
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
3370 " restore AlignCtrl settings
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.
3385 " restore original 'y, 'z, and window positioning
3386 call RestoreMark(s:alignmaps_keepmy)
3387 call RestoreMark(s:alignmaps_keepmz)
3389 call RestoreWinPosn(s:alignmaps_posn)
3390 " call Decho("restored window positioning")
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
3407 " call Dret("AlignMaps#WrapperEnd : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
3410 " ---------------------------------------------------------------------
3411 " AlignMaps#StdAlign: some semi-standard align calls {{{2
3412 fun! AlignMaps#StdAlign(mode) range
3413 " call Dfunc("AlignMaps#StdAlign(mode=".a:mode.")")
3416 " call Decho("align on @")
3417 AlignCtrl mIp1P1=l @
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 @
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 @
3431 echoerr "(AlignMaps) AlignMaps#StdAlign doesn't support mode#".a:mode
3433 " call Dret("AlignMaps#StdAlign")
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
3445 while match(getline(aline),a:chr . "\s*$") != -1 && rep >= 0
3446 " while = at end-of-line, delete it and join with next
3451 " update rep(eat) count
3454 " terminate loop if at end-of-block
3457 " prepare for next line
3459 let aline = line("'a")
3461 " call Dret("AlignMaps#CharJoiner")
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
3473 AlignCtrl mIp1P1=l =
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")
3484 call AlignMaps#StdAlign(1)
3487 call AlignMaps#StdAlign(1)
3489 'y,'zs/^\(\s*\) @/\1/e
3493 " call Dret("AlignMaps#Equals")
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
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"))
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
3524 s/(\s*\(\S\)/(\r \1/e
3526 s/)\s*\(\/[*/]\)/)\r\1/e
3532 " insert newline after every comma only one parenthesis deep
3533 sil! exe "norm! `y\<right>h"
3538 " call Decho("parens=".parens." @a=".@a)
3539 exe 'norm! ma "ay`a '
3541 let parens= parens + 1
3543 let parens= parens - 1
3545 " comment bypass: /* ... */ or //...
3546 elseif cmmnt == 0 && @a == '/'
3550 let cmmnt = 2 " //...
3551 let cmmntline= line(".")
3553 let cmmnt= 3 " /*...
3557 elseif cmmnt == 2 && line(".") != cmmntline
3560 elseif cmmnt == 3 && @a == '*'
3564 let cmmnt= 0 " ...*/
3569 elseif @a == "," && parens == 1 && cmmnt == 0
3570 exe "norm! i\<CR>\<Esc>"
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
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 @
3589 sil! 'y,'zs%@\(/[*/]\)@%\t\1 %e
3590 sil! 'y,'zs%@\*/% */%e
3591 sil! 'y,'zs/@\([,)]\)/\1/
3593 AlignCtrl mIlrp0P0= # @
3597 sil! 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e
3600 call RestoreMark(mykeep)
3601 call RestoreMark(mzkeep)
3606 " call Dret("AlignMaps#Afnc")
3609 " ---------------------------------------------------------------------
3610 " AlignMaps#FixMultiDec: converts a type arg,arg,arg; line to multiple lines {{{2
3611 fun! AlignMaps#FixMultiDec()
3612 " call Dfunc("AlignMaps#FixMultiDec()")
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.">")
3624 exe 's/,/;\r'.@x.' /ge'
3629 " call Dret("AlignMaps#FixMultiDec : my=".line("'y")." mz=".line("'z"))
3632 " ---------------------------------------------------------------------
3636 " vim: ts=4 fdm=marker