]> git.r.bdr.sh - rbdr/dotfiles/blob - vim/autoload/AlignMaps.vim
ace2de8e39cd633a75ba15ad1616b5824a7ff302
[rbdr/dotfiles] / vim / autoload / AlignMaps.vim
1 " AlignMaps.vim : support functions for AlignMaps
2 " Author: Charles E. Campbell, Jr.
3 " Date: Mar 03, 2009
4 " Version: 41
5 " ---------------------------------------------------------------------
6 " Load Once: {{{1
7 if &cp || exists("g:loaded_AlignMaps")
8 finish
9 endif
10 let g:loaded_AlignMaps= "v41"
11 let s:keepcpo = &cpo
12 set cpo&vim
13
14 " =====================================================================
15 " Functions: {{{1
16
17 " ---------------------------------------------------------------------
18 " AlignMaps#WrapperStart: {{{2
19 fun! AlignMaps#WrapperStart(vis) range
20 " call Dfunc("AlignMaps#WrapperStart(vis=".a:vis.")")
21
22 if a:vis
23 norm! '<ma'>
24 endif
25
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
36 put =''
37 norm! mz'a
38 put! =''
39 ky
40 let s:alignmaps_zline = line("'z")
41 exe "'y,'zs/@/\177/ge"
42 else
43 " call Decho("embedded wrapper")
44 let s:alignmaps_wrapcnt = s:alignmaps_wrapcnt + 1
45 norm! 'yjma'zk
46 endif
47
48 " change some settings to align-standard values
49 set nogd
50 set ch=2
51 AlignPush
52 norm! 'zk
53 " call Dret("AlignMaps#WrapperStart : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
54 endfun
55
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"))
60
61 " remove trailing white space introduced by whatever in the modification zone
62 'y,'zs/ \+$//e
63
64 " restore AlignCtrl settings
65 AlignPop
66
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"
71
72 " if the 'z line hasn't moved, then go ahead and restore window position
73 let zstationary= s:alignmaps_zline == line("'z")
74
75 " remove fencepost blank lines.
76 " restore 'a
77 norm! 'yjmakdd'zdd
78
79 " restore original 'y, 'z, and window positioning
80 call RestoreMark(s:alignmaps_keepmy)
81 call RestoreMark(s:alignmaps_keepmz)
82 if zstationary > 0
83 call RestoreWinPosn(s:alignmaps_posn)
84 " call Decho("restored window positioning")
85 endif
86
87 " restoration of options
88 let &gd= s:alignmaps_keepgd
89 let &ch= s:alignmaps_keepch
90 let @/ = s:alignmaps_keepsearch
91
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
99 endif
100
101 " call Dret("AlignMaps#WrapperEnd : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z"))
102 endfun
103
104 " ---------------------------------------------------------------------
105 " AlignMaps#StdAlign: some semi-standard align calls {{{2
106 fun! AlignMaps#StdAlign(mode) range
107 " call Dfunc("AlignMaps#StdAlign(mode=".a:mode.")")
108 if a:mode == 1
109 " align on @
110 " call Decho("align on @")
111 AlignCtrl mIp1P1=l @
112 'a,.Align
113 elseif a:mode == 2
114 " align on @, retaining all initial white space on each line
115 " call Decho("align on @, retaining all initial white space on each line")
116 AlignCtrl mWp1P1=l @
117 'a,.Align
118 elseif a:mode == 3
119 " like mode 2, but ignore /* */-style comments
120 " call Decho("like mode 2, but ignore /* */-style comments")
121 AlignCtrl v ^\s*/[/*]
122 AlignCtrl mWp1P1=l @
123 'a,.Align
124 else
125 echoerr "(AlignMaps) AlignMaps#StdAlign doesn't support mode#".a:mode
126 endif
127 " call Dret("AlignMaps#StdAlign")
128 endfun
129
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
137 while rep > 0
138 norm! 'a
139 while match(getline(aline),a:chr . "\s*$") != -1 && rep >= 0
140 " while = at end-of-line, delete it and join with next
141 norm! 'a$
142 j!
143 let rep = rep - 1
144 endwhile
145 " update rep(eat) count
146 let rep = rep - 1
147 if rep <= 0
148 " terminate loop if at end-of-block
149 break
150 endif
151 " prepare for next line
152 norm! jma
153 let aline = line("'a")
154 endwhile
155 " call Dret("AlignMaps#CharJoiner")
156 endfun
157
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
166 norm g'zk
167 AlignCtrl mIp1P1=l =
168 AlignCtrl g =
169 'a,'z-1Align
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")
177 exe "norm 'zk"
178 call AlignMaps#StdAlign(1)
179 else
180 exe "norm 'zk"
181 call AlignMaps#StdAlign(1)
182 endif
183 'y,'zs/^\(\s*\) @/\1/e
184 endif
185 'a,'z-1s/\%x0f/=/ge
186 'y,'zs/ @//eg
187 " call Dret("AlignMaps#Equals")
188 endfun
189
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()")
195
196 " keep display quiet
197 let chkeep = &ch
198 let gdkeep = &gd
199 let vekeep = &ve
200 set ch=2 nogd ve=
201
202 " will use marks y,z ; save current values
203 let mykeep = SaveMark("'y")
204 let mzkeep = SaveMark("'z")
205
206 " Find beginning of function -- be careful to skip over comments
207 let cmmntid = synIDtrans(hlID("Comment"))
208 let stringid = synIDtrans(hlID("String"))
209 exe "norm! ]]"
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
214 break
215 endif
216 endwhile
217 norm! %my
218 s/(\s*\(\S\)/(\r \1/e
219 exe "norm! `y%"
220 s/)\s*\(\/[*/]\)/)\r\1/e
221 exe "norm! `y%mz"
222 'y,'zs/\s\+$//e
223 'y,'zs/^\s\+//e
224 'y+1,'zs/^/ /
225
226 " insert newline after every comma only one parenthesis deep
227 sil! exe "norm! `y\<right>h"
228 let parens = 1
229 let cmmnt = 0
230 let cmmntline= -1
231 while parens >= 1
232 " call Decho("parens=".parens." @a=".@a)
233 exe 'norm! ma "ay`a '
234 if @a == "("
235 let parens= parens + 1
236 elseif @a == ")"
237 let parens= parens - 1
238
239 " comment bypass: /* ... */ or //...
240 elseif cmmnt == 0 && @a == '/'
241 let cmmnt= 1
242 elseif cmmnt == 1
243 if @a == '/'
244 let cmmnt = 2 " //...
245 let cmmntline= line(".")
246 elseif @a == '*'
247 let cmmnt= 3 " /*...
248 else
249 let cmmnt= 0
250 endif
251 elseif cmmnt == 2 && line(".") != cmmntline
252 let cmmnt = 0
253 let cmmntline= -1
254 elseif cmmnt == 3 && @a == '*'
255 let cmmnt= 4
256 elseif cmmnt == 4
257 if @a == '/'
258 let cmmnt= 0 " ...*/
259 elseif @a != '*'
260 let cmmnt= 3
261 endif
262
263 elseif @a == "," && parens == 1 && cmmnt == 0
264 exe "norm! i\<CR>\<Esc>"
265 endif
266 endwhile
267 norm! `y%mz%
268 sil! 'y,'zg/^\s*$/d
269
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
275 " func
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
281 AlignCtrl mIp0P0=l @
282 sil! 'y+1,'zAlign
283 sil! 'y,'zs%@\(/[*/]\)@%\t\1 %e
284 sil! 'y,'zs%@\*/% */%e
285 sil! 'y,'zs/@\([,)]\)/\1/
286 sil! 'y,'zs/@/ /
287 AlignCtrl mIlrp0P0= # @
288 sil! 'y+1,'zAlign
289 sil! 'y+1,'zs/#/ /
290 sil! 'y+1,'zs/@//
291 sil! 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e
292
293 " Restore
294 call RestoreMark(mykeep)
295 call RestoreMark(mzkeep)
296 let &ch= chkeep
297 let &gd= gdkeep
298 let &ve= vekeep
299
300 " call Dret("AlignMaps#Afnc")
301 endfun
302
303 " ---------------------------------------------------------------------
304 " AlignMaps#FixMultiDec: converts a type arg,arg,arg; line to multiple lines {{{2
305 fun! AlignMaps#FixMultiDec()
306 " call Dfunc("AlignMaps#FixMultiDec()")
307
308 " save register x
309 let xkeep = @x
310 let curline = getline(".")
311 " call Decho("curline<".curline.">")
312
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.">")
316
317 " transform line
318 exe 's/,/;\r'.@x.' /ge'
319
320 "restore register x
321 let @x= xkeep
322
323 " call Dret("AlignMaps#FixMultiDec : my=".line("'y")." mz=".line("'z"))
324 endfun
325
326 " ---------------------------------------------------------------------
327 " Restore: {{{1
328 let &cpo= s:keepcpo
329 unlet s:keepcpo
330 " vim: ts=4 fdm=marker