1 " AlignMaps.vim : support functions for AlignMaps
2 " Author: Charles E. Campbell, Jr.
5 " ---------------------------------------------------------------------
7 if &cp || exists("g:loaded_AlignMaps")
10 let g:loaded_AlignMaps= "v41"
14 " =====================================================================
17 " ---------------------------------------------------------------------
18 " AlignMaps#WrapperStart: {{{2
19 fun! AlignMaps#WrapperStart(vis) range
20 " call Dfunc("AlignMaps#WrapperStart(vis=".a:vis.")")
26 if line("'y") == 0 || line("'z") == 0 || !exists("s:alignmaps_wrapcnt") || s:alignmaps_wrapcnt <= 0
27 " call Decho("wrapper initialization")
28 let s:alignmaps_wrapcnt = 1
29 let s:alignmaps_keepgd = &gdefault
30 let s:alignmaps_keepsearch = @/
31 let s:alignmaps_keepch = &ch
32 let s:alignmaps_keepmy = SaveMark("'y")
33 let s:alignmaps_keepmz = SaveMark("'z")
34 let s:alignmaps_posn = SaveWinPosn(0)
35 " set up fencepost blank lines
40 let s:alignmaps_zline = line("'z")
41 exe "'y,'zs/@/\177/ge"
43 " call Decho("embedded wrapper")
44 let s:alignmaps_wrapcnt = s:alignmaps_wrapcnt + 1
48 " change some settings to align-standard values
53 " call Dret("AlignMaps#WrapperStart : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
56 " ---------------------------------------------------------------------
57 " AlignMaps#WrapperEnd: {{{2
58 fun! AlignMaps#WrapperEnd() range
59 " call Dfunc("AlignMaps#WrapperEnd() alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
61 " remove trailing white space introduced by whatever in the modification zone
64 " restore AlignCtrl settings
67 let s:alignmaps_wrapcnt= s:alignmaps_wrapcnt - 1
68 if s:alignmaps_wrapcnt <= 0
69 " initial wrapper ending
70 exe "'y,'zs/\177/@/ge"
72 " if the 'z line hasn't moved, then go ahead and restore window position
73 let zstationary= s:alignmaps_zline == line("'z")
75 " remove fencepost blank lines.
79 " restore original 'y, 'z, and window positioning
80 call RestoreMark(s:alignmaps_keepmy)
81 call RestoreMark(s:alignmaps_keepmz)
83 call RestoreWinPosn(s:alignmaps_posn)
84 " call Decho("restored window positioning")
87 " restoration of options
88 let &gd= s:alignmaps_keepgd
89 let &ch= s:alignmaps_keepch
90 let @/ = s:alignmaps_keepsearch
92 " remove script variables
93 unlet s:alignmaps_keepch
94 unlet s:alignmaps_keepsearch
95 unlet s:alignmaps_keepmy
96 unlet s:alignmaps_keepmz
97 unlet s:alignmaps_keepgd
98 unlet s:alignmaps_posn
101 " call Dret("AlignMaps#WrapperEnd : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
104 " ---------------------------------------------------------------------
105 " AlignMaps#StdAlign: some semi-standard align calls {{{2
106 fun! AlignMaps#StdAlign(mode) range
107 " call Dfunc("AlignMaps#StdAlign(mode=".a:mode.")")
110 " call Decho("align on @")
114 " align on @, retaining all initial white space on each line
115 " call Decho("align on @, retaining all initial white space on each line")
119 " like mode 2, but ignore /* */-style comments
120 " call Decho("like mode 2, but ignore /* */-style comments")
121 AlignCtrl v ^\s*/[/*]
125 echoerr "(AlignMaps) AlignMaps#StdAlign doesn't support mode#".a:mode
127 " call Dret("AlignMaps#StdAlign")
130 " ---------------------------------------------------------------------
131 " AlignMaps#CharJoiner: joins lines which end in the given character (spaces {{{2
132 " at end are ignored)
133 fun! AlignMaps#CharJoiner(chr)
134 " call Dfunc("AlignMaps#CharJoiner(chr=".a:chr.")")
135 let aline = line("'a")
136 let rep = line(".") - aline
139 while match(getline(aline),a:chr . "\s*$") != -1 && rep >= 0
140 " while = at end-of-line, delete it and join with next
145 " update rep(eat) count
148 " terminate loop if at end-of-block
151 " prepare for next line
153 let aline = line("'a")
155 " call Dret("AlignMaps#CharJoiner")
158 " ---------------------------------------------------------------------
159 " AlignMaps#Equals: supports \t= and \T= {{{2
160 fun! AlignMaps#Equals() range
161 " call Dfunc("AlignMaps#Equals()")
162 'a,'zs/\s\+\([*/+\-%|&\~^]\==\)/ \1/e
163 'a,'zs@ \+\([*/+\-%|&\~^]\)=@\1=@ge
164 'a,'zs/==/\="\<Char-0x0f>\<Char-0x0f>"/ge
165 'a,'zs/\([!<>:]\)=/\=submatch(1)."\<Char-0x0f>"/ge
170 'a,'z-1s@\([*/+\-%|&\~^!=]\)\( \+\)=@\2\1=@ge
171 'a,'z-1s/\( \+\);/;\1/ge
172 if &ft == "c" || &ft == "cpp"
173 " call Decho("exception for ".&ft)
174 'a,'z-1v/^\s*\/[*/]/s/\/[*/]/@&@/e
175 'a,'z-1v/^\s*\/[*/]/s/\*\//@&/e
176 if exists("g:mapleader")
178 call AlignMaps#StdAlign(1)
181 call AlignMaps#StdAlign(1)
183 'y,'zs/^\(\s*\) @/\1/e
187 " call Dret("AlignMaps#Equals")
190 " ---------------------------------------------------------------------
191 " AlignMaps#Afnc: useful for splitting one-line function beginnings {{{2
192 " into one line per argument format
193 fun! AlignMaps#Afnc()
194 " call Dfunc("AlignMaps#Afnc()")
202 " will use marks y,z ; save current values
203 let mykeep = SaveMark("'y")
204 let mzkeep = SaveMark("'z")
206 " Find beginning of function -- be careful to skip over comments
207 let cmmntid = synIDtrans(hlID("Comment"))
208 let stringid = synIDtrans(hlID("String"))
210 while search(")","bW") != 0
211 " call Decho("line=".line(".")." col=".col("."))
212 let parenid= synIDtrans(synID(line("."),col("."),1))
213 if parenid != cmmntid && parenid != stringid
218 s/(\s*\(\S\)/(\r \1/e
220 s/)\s*\(\/[*/]\)/)\r\1/e
226 " insert newline after every comma only one parenthesis deep
227 sil! exe "norm! `y\<right>h"
232 " call Decho("parens=".parens." @a=".@a)
233 exe 'norm! ma "ay`a '
235 let parens= parens + 1
237 let parens= parens - 1
239 " comment bypass: /* ... */ or //...
240 elseif cmmnt == 0 && @a == '/'
244 let cmmnt = 2 " //...
245 let cmmntline= line(".")
251 elseif cmmnt == 2 && line(".") != cmmntline
254 elseif cmmnt == 3 && @a == '*'
263 elseif @a == "," && parens == 1 && cmmnt == 0
264 exe "norm! i\<CR>\<Esc>"
270 " perform substitutes to mark fields for Align
271 sil! 'y+1,'zv/^\//s/^\s\+\(\S\)/ \1/e
272 sil! 'y+1,'zv/^\//s/\(\S\)\s\+/\1 /eg
273 sil! 'y+1,'zv/^\//s/\* \+/*/ge
274 sil! 'y+1,'zv/^\//s/\w\zs\s*\*/ */ge
276 " ws <- declaration -> <-ptr -> <-var-> <-[array][] -> <-glop-> <-end->
277 sil! 'y+1,'zv/^\//s/^\s*\(\(\K\k*\s*\)\+\)\s\+\([(*]*\)\s*\(\K\k*\)\s*\(\(\[.\{-}]\)*\)\s*\(.\{-}\)\=\s*\([,)]\)\s*$/ \1@#\3@\4\5@\7\8/e
278 sil! 'y+1,'z+1g/^\s*\/[*/]/norm! kJ
279 sil! 'y+1,'z+1s%/[*/]%@&@%ge
280 sil! 'y+1,'z+1s%*/%@&%ge
283 sil! 'y,'zs%@\(/[*/]\)@%\t\1 %e
284 sil! 'y,'zs%@\*/% */%e
285 sil! 'y,'zs/@\([,)]\)/\1/
287 AlignCtrl mIlrp0P0= # @
291 sil! 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e
294 call RestoreMark(mykeep)
295 call RestoreMark(mzkeep)
300 " call Dret("AlignMaps#Afnc")
303 " ---------------------------------------------------------------------
304 " AlignMaps#FixMultiDec: converts a type arg,arg,arg; line to multiple lines {{{2
305 fun! AlignMaps#FixMultiDec()
306 " call Dfunc("AlignMaps#FixMultiDec()")
310 let curline = getline(".")
311 " call Decho("curline<".curline.">")
313 " Get the type. I'm assuming one type per line (ie. int x; double y; on one line will not be handled properly)
314 let @x=substitute(curline,'^\(\s*[a-zA-Z_ \t][a-zA-Z0-9_ \t]*\)\s\+[(*]*\h.*$','\1','')
315 " call Decho("@x<".@x.">")
318 exe 's/,/;\r'.@x.' /ge'
323 " call Dret("AlignMaps#FixMultiDec : my=".line("'y")." mz=".line("'z"))
326 " ---------------------------------------------------------------------
330 " vim: ts=4 fdm=marker