]>
Commit | Line | Data |
---|---|---|
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 |