├── autoload ├── Align.vim └── AlignMaps.vim ├── doc ├── Align.txt └── tags └── plugin ├── AlignMapsPlugin.vim ├── AlignPlugin.vim └── cecutil.vim /autoload/Align.vim: -------------------------------------------------------------------------------- 1 | " Align: tool to align multiple fields based on one or more separators 2 | " Author: Charles E. Campbell, Jr. 3 | " Date: Mar 03, 2009 4 | " Version: 35 5 | " GetLatestVimScripts: 294 1 :AutoInstall: Align.vim 6 | " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim 7 | " Copyright: Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1 8 | " Permission is hereby granted to use and distribute this code, 9 | " with or without modifications, provided that this copyright 10 | " notice is copied with it. Like anything else that's free, 11 | " Align.vim is provided *as is* and comes with no warranty 12 | " of any kind, either expressed or implied. By using this 13 | " plugin, you agree that in no event will the copyright 14 | " holder be liable for any damages resulting from the use 15 | " of this software. 16 | " 17 | " Romans 1:16,17a : For I am not ashamed of the gospel of Christ, for it is {{{1 18 | " the power of God for salvation for everyone who believes; for the Jew first, 19 | " and also for the Greek. For in it is revealed God's righteousness from 20 | " faith to faith. 21 | 22 | " --------------------------------------------------------------------- 23 | " Load Once: {{{1 24 | if exists("g:loaded_Align") || &cp 25 | finish 26 | endif 27 | let g:loaded_Align = "v35" 28 | if v:version < 700 29 | echohl WarningMsg 30 | echo "***warning*** this version of Align needs vim 7.0" 31 | echohl Normal 32 | finish 33 | endif 34 | let s:keepcpo= &cpo 35 | set cpo&vim 36 | "DechoTabOn 37 | 38 | " --------------------------------------------------------------------- 39 | " Debugging Support: {{{1 40 | "if !exists("g:loaded_Decho") | runtime plugin/Decho.vim | endif 41 | 42 | " --------------------------------------------------------------------- 43 | " Options: {{{1 44 | if !exists("g:Align_xstrlen") 45 | if &enc == "latin1" || $LANG == "en_US.UTF-8" || !has("multi_byte") 46 | let g:Align_xstrlen= 0 47 | else 48 | let g:Align_xstrlen= 1 49 | endif 50 | endif 51 | 52 | " --------------------------------------------------------------------- 53 | " Align#AlignCtrl: enter alignment patterns here {{{1 54 | " 55 | " Styles = all alignment-break patterns are equivalent 56 | " C cycle through alignment-break pattern(s) 57 | " l left-justified alignment 58 | " r right-justified alignment 59 | " c center alignment 60 | " - skip separator, treat as part of field 61 | " : treat rest of line as field 62 | " + repeat previous [lrc] style 63 | " < left justify separators 64 | " > right justify separators 65 | " | center separators 66 | " 67 | " Builds = s:AlignPat s:AlignCtrl s:AlignPatQty 68 | " C s:AlignPat s:AlignCtrl s:AlignPatQty 69 | " p s:AlignPrePad 70 | " P s:AlignPostPad 71 | " w s:AlignLeadKeep 72 | " W s:AlignLeadKeep 73 | " I s:AlignLeadKeep 74 | " l s:AlignStyle 75 | " r s:AlignStyle 76 | " - s:AlignStyle 77 | " + s:AlignStyle 78 | " : s:AlignStyle 79 | " c s:AlignStyle 80 | " g s:AlignGPat 81 | " v s:AlignVPat 82 | " < s:AlignSep 83 | " > s:AlignSep 84 | " | s:AlignSep 85 | fun! Align#AlignCtrl(...) 86 | 87 | " call Dfunc("AlignCtrl(...) a:0=".a:0) 88 | 89 | " save options that will be changed 90 | let keep_search = @/ 91 | let keep_ic = &ic 92 | 93 | " turn ignorecase off 94 | set noic 95 | 96 | " clear visual mode so that old visual-mode selections don't 97 | " get applied to new invocations of Align(). 98 | if v:version < 602 99 | if !exists("s:Align_gavemsg") 100 | let s:Align_gavemsg= 1 101 | echomsg "Align needs at least Vim version 6.2 to clear visual-mode selection" 102 | endif 103 | elseif exists("s:dovisclear") 104 | " call Decho("clearing visual mode a:0=".a:0." a:1<".a:1.">") 105 | let clearvmode= visualmode(1) 106 | endif 107 | 108 | " set up a list akin to an argument list 109 | if a:0 > 0 110 | let A= s:QArgSplitter(a:1) 111 | else 112 | let A=[0] 113 | endif 114 | 115 | if A[0] > 0 116 | let style = A[1] 117 | 118 | " Check for bad separator patterns (zero-length matches) 119 | " (but zero-length patterns for g/v is ok) 120 | if style !~# '[gv]' 121 | let ipat= 2 122 | while ipat <= A[0] 123 | if "" =~ A[ipat] 124 | echoerr "AlignCtrl: separator<".A[ipat]."> matches zero-length string" 125 | let &ic= keep_ic 126 | " call Dret("AlignCtrl") 127 | return 128 | endif 129 | let ipat= ipat + 1 130 | endwhile 131 | endif 132 | endif 133 | 134 | " call Decho("AlignCtrl() A[0]=".A[0]) 135 | if !exists("s:AlignStyle") 136 | let s:AlignStyle= "l" 137 | endif 138 | if !exists("s:AlignPrePad") 139 | let s:AlignPrePad= 0 140 | endif 141 | if !exists("s:AlignPostPad") 142 | let s:AlignPostPad= 0 143 | endif 144 | if !exists("s:AlignLeadKeep") 145 | let s:AlignLeadKeep= 'w' 146 | endif 147 | 148 | if A[0] == 0 149 | " ---------------------- 150 | " List current selection 151 | " ---------------------- 152 | if !exists("s:AlignPatQty") 153 | let s:AlignPatQty= 0 154 | endif 155 | echo "AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep 156 | " call Decho("AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep) 157 | if exists("s:AlignGPat") && !exists("s:AlignVPat") 158 | echo "AlignGPat<".s:AlignGPat.">" 159 | elseif !exists("s:AlignGPat") && exists("s:AlignVPat") 160 | echo "AlignVPat<".s:AlignVPat.">" 161 | elseif exists("s:AlignGPat") && exists("s:AlignVPat") 162 | echo "AlignGPat<".s:AlignGPat."> AlignVPat<".s:AlignVPat.">" 163 | endif 164 | let ipat= 1 165 | while ipat <= s:AlignPatQty 166 | echo "Pat".ipat."<".s:AlignPat_{ipat}.">" 167 | " call Decho("Pat".ipat."<".s:AlignPat_{ipat}.">") 168 | let ipat= ipat + 1 169 | endwhile 170 | 171 | else 172 | " ---------------------------------- 173 | " Process alignment control settings 174 | " ---------------------------------- 175 | " call Decho("process the alignctrl settings") 176 | " call Decho("style<".style.">") 177 | 178 | if style ==? "default" 179 | " Default: preserve initial leading whitespace, left-justified, 180 | " alignment on '=', one space padding on both sides 181 | if exists("s:AlignCtrlStackQty") 182 | " clear AlignCtrl stack 183 | while s:AlignCtrlStackQty > 0 184 | call Align#AlignPop() 185 | endwhile 186 | unlet s:AlignCtrlStackQty 187 | endif 188 | " Set AlignCtrl to its default value 189 | call Align#AlignCtrl("Ilp1P1=<",'=') 190 | call Align#AlignCtrl("g") 191 | call Align#AlignCtrl("v") 192 | let s:dovisclear = 1 193 | let &ic = keep_ic 194 | let @/ = keep_search 195 | " call Dret("AlignCtrl") 196 | return 197 | endif 198 | 199 | if style =~# 'm' 200 | " map support: Do an AlignPush now and the next call to Align() 201 | " will do an AlignPop at exit 202 | " call Decho("style case m: do AlignPush") 203 | call Align#AlignPush() 204 | let s:DoAlignPop= 1 205 | endif 206 | 207 | " = : record a list of alignment patterns that are equivalent 208 | if style =~# "=" 209 | " call Decho("style case =: record list of equiv alignment patterns") 210 | let s:AlignCtrl = '=' 211 | if A[0] >= 2 212 | let s:AlignPatQty= 1 213 | let s:AlignPat_1 = A[2] 214 | let ipat = 3 215 | while ipat <= A[0] 216 | let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat] 217 | let ipat = ipat + 1 218 | endwhile 219 | let s:AlignPat_1= '\('.s:AlignPat_1.'\)' 220 | " call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">") 221 | endif 222 | 223 | "c : cycle through alignment pattern(s) 224 | elseif style =~# 'C' 225 | " call Decho("style case C: cycle through alignment pattern(s)") 226 | let s:AlignCtrl = 'C' 227 | if A[0] >= 2 228 | let s:AlignPatQty= A[0] - 1 229 | let ipat = 1 230 | while ipat < A[0] 231 | let s:AlignPat_{ipat}= A[ipat+1] 232 | " call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">") 233 | let ipat= ipat + 1 234 | endwhile 235 | endif 236 | endif 237 | 238 | if style =~# 'p' 239 | let s:AlignPrePad= substitute(style,'^.*p\(\d\+\).*$','\1','') 240 | " call Decho("style case p".s:AlignPrePad.": pre-separator padding") 241 | if s:AlignPrePad == "" 242 | echoerr "AlignCtrl: 'p' needs to be followed by a numeric argument' 243 | let @/ = keep_search 244 | let &ic= keep_ic 245 | " call Dret("AlignCtrl") 246 | return 247 | endif 248 | endif 249 | 250 | if style =~# 'P' 251 | let s:AlignPostPad= substitute(style,'^.*P\(\d\+\).*$','\1','') 252 | " call Decho("style case P".s:AlignPostPad.": post-separator padding") 253 | if s:AlignPostPad == "" 254 | echoerr "AlignCtrl: 'P' needs to be followed by a numeric argument' 255 | let @/ = keep_search 256 | let &ic= keep_ic 257 | " call Dret("AlignCtrl") 258 | return 259 | endif 260 | endif 261 | 262 | if style =~# 'w' 263 | " call Decho("style case w: ignore leading whitespace") 264 | let s:AlignLeadKeep= 'w' 265 | elseif style =~# 'W' 266 | " call Decho("style case w: keep leading whitespace") 267 | let s:AlignLeadKeep= 'W' 268 | elseif style =~# 'I' 269 | " call Decho("style case w: retain initial leading whitespace") 270 | let s:AlignLeadKeep= 'I' 271 | endif 272 | 273 | if style =~# 'g' 274 | " first list item is a "g" selector pattern 275 | " call Decho("style case g: global selector pattern") 276 | if A[0] < 2 277 | if exists("s:AlignGPat") 278 | unlet s:AlignGPat 279 | " call Decho("unlet s:AlignGPat") 280 | endif 281 | else 282 | let s:AlignGPat= A[2] 283 | " call Decho("s:AlignGPat<".s:AlignGPat.">") 284 | endif 285 | elseif style =~# 'v' 286 | " first list item is a "v" selector pattern 287 | " call Decho("style case v: global selector anti-pattern") 288 | if A[0] < 2 289 | if exists("s:AlignVPat") 290 | unlet s:AlignVPat 291 | " call Decho("unlet s:AlignVPat") 292 | endif 293 | else 294 | let s:AlignVPat= A[2] 295 | " call Decho("s:AlignVPat<".s:AlignVPat.">") 296 | endif 297 | endif 298 | 299 | "[-lrc+:] : set up s:AlignStyle 300 | if style =~# '[-lrc+:]' 301 | " call Decho("style case [-lrc+:]: field justification") 302 | let s:AlignStyle= substitute(style,'[^-lrc:+]','','g') 303 | " call Decho("AlignStyle<".s:AlignStyle.">") 304 | endif 305 | 306 | "[<>|] : set up s:AlignSep 307 | if style =~# '[<>|]' 308 | " call Decho("style case [-lrc+:]: separator justification") 309 | let s:AlignSep= substitute(style,'[^<>|]','','g') 310 | " call Decho("AlignSep ".s:AlignSep) 311 | endif 312 | endif 313 | 314 | " sanity 315 | if !exists("s:AlignCtrl") 316 | let s:AlignCtrl= '=' 317 | endif 318 | 319 | " restore search and options 320 | let @/ = keep_search 321 | let &ic= keep_ic 322 | 323 | " call Dret("AlignCtrl ".s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle) 324 | return s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle 325 | endfun 326 | 327 | " --------------------------------------------------------------------- 328 | " s:MakeSpace: returns a string with spacecnt blanks {{{1 329 | fun! s:MakeSpace(spacecnt) 330 | " call Dfunc("MakeSpace(spacecnt=".a:spacecnt.")") 331 | let str = "" 332 | let spacecnt = a:spacecnt 333 | while spacecnt > 0 334 | let str = str . " " 335 | let spacecnt = spacecnt - 1 336 | endwhile 337 | " call Dret("MakeSpace <".str.">") 338 | return str 339 | endfun 340 | 341 | " --------------------------------------------------------------------- 342 | " Align#Align: align selected text based on alignment pattern(s) {{{1 343 | fun! Align#Align(hasctrl,...) range 344 | " call Dfunc("Align#Align(hasctrl=".a:hasctrl.",...) a:0=".a:0) 345 | 346 | " sanity checks 347 | if string(a:hasctrl) != "0" && string(a:hasctrl) != "1" 348 | echohl Error|echo 'usage: Align#Align(hasctrl<'.a:hasctrl.'> (should be 0 or 1),"separator(s)" (you have '.a:0.') )'|echohl None 349 | " call Dret("Align#Align") 350 | return 351 | endif 352 | if exists("s:AlignStyle") && s:AlignStyle == ":" 353 | echohl Error |echo '(Align#Align) your AlignStyle is ":", which implies "do-no-alignment"!'|echohl None 354 | " call Dret("Align#Align") 355 | return 356 | endif 357 | 358 | " set up a list akin to an argument list 359 | if a:0 > 0 360 | let A= s:QArgSplitter(a:1) 361 | else 362 | let A=[0] 363 | endif 364 | 365 | " if :Align! was used, then the first argument is (should be!) an AlignCtrl string 366 | " Note that any alignment control set this way will be temporary. 367 | let hasctrl= a:hasctrl 368 | " call Decho("hasctrl=".hasctrl) 369 | if a:hasctrl && A[0] >= 1 370 | " call Decho("Align! : using A[1]<".A[1]."> for AlignCtrl") 371 | if A[1] =~ '[gv]' 372 | let hasctrl= hasctrl + 1 373 | call Align#AlignCtrl('m') 374 | call Align#AlignCtrl(A[1],A[2]) 375 | " call Decho("Align! : also using A[2]<".A[2]."> for AlignCtrl") 376 | elseif A[1] !~ 'm' 377 | call Align#AlignCtrl(A[1]."m") 378 | else 379 | call Align#AlignCtrl(A[1]) 380 | endif 381 | endif 382 | 383 | " Check for bad separator patterns (zero-length matches) 384 | let ipat= 1 + hasctrl 385 | while ipat <= A[0] 386 | if "" =~ A[ipat] 387 | echoerr "Align: separator<".A[ipat]."> matches zero-length string" 388 | " call Dret("Align#Align") 389 | return 390 | endif 391 | let ipat= ipat + 1 392 | endwhile 393 | 394 | " record current search pattern for subsequent restoration 395 | let keep_search= @/ 396 | let keep_ic = &ic 397 | let keep_report= &report 398 | set noic report=10000 399 | 400 | if A[0] > hasctrl 401 | " Align will accept a list of separator regexps 402 | " call Decho("A[0]=".A[0].": accepting list of separator regexp") 403 | 404 | if s:AlignCtrl =~# "=" 405 | "= : consider all separators to be equivalent 406 | " call Decho("AlignCtrl: record list of equivalent alignment patterns") 407 | let s:AlignCtrl = '=' 408 | let s:AlignPat_1 = A[1 + hasctrl] 409 | let s:AlignPatQty= 1 410 | let ipat = 2 + hasctrl 411 | while ipat <= A[0] 412 | let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat] 413 | let ipat = ipat + 1 414 | endwhile 415 | let s:AlignPat_1= '\('.s:AlignPat_1.'\)' 416 | " call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">") 417 | 418 | elseif s:AlignCtrl =~# 'C' 419 | "c : cycle through alignment pattern(s) 420 | " call Decho("AlignCtrl: cycle through alignment pattern(s)") 421 | let s:AlignCtrl = 'C' 422 | let s:AlignPatQty= A[0] - hasctrl 423 | let ipat = 1 424 | while ipat <= s:AlignPatQty 425 | let s:AlignPat_{ipat}= A[(ipat + hasctrl)] 426 | " call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">") 427 | let ipat= ipat + 1 428 | endwhile 429 | endif 430 | endif 431 | 432 | " Initialize so that begline 434 | " is greater than the line's string length -> ragged right. 435 | " Have to be careful about visualmode() -- it returns the last visual 436 | " mode used whether or not it was used currently. 437 | let begcol = virtcol("'<")-1 438 | let endcol = virtcol("'>")-1 439 | if begcol > endcol 440 | let begcol = virtcol("'>")-1 441 | let endcol = virtcol("'<")-1 442 | endif 443 | " call Decho("begcol=".begcol." endcol=".endcol) 444 | let begline = a:firstline 445 | let endline = a:lastline 446 | if begline > endline 447 | let begline = a:lastline 448 | let endline = a:firstline 449 | endif 450 | " call Decho("begline=".begline." endline=".endline) 451 | let fieldcnt = 0 452 | if (begline == line("'>") && endline == line("'<")) || (begline == line("'<") && endline == line("'>")) 453 | let vmode= visualmode() 454 | " call Decho("vmode=".vmode) 455 | if vmode == "\" 456 | if exists("g:Align_xstrlen") && g:Align_xstrlen 457 | let ragged = ( col("'>") > s:Strlen(getline("'>")) || col("'<") > s:Strlen(getline("'<")) ) 458 | else 459 | let ragged = ( col("'>") > strlen(getline("'>")) || col("'<") > strlen(getline("'<")) ) 460 | endif 461 | else 462 | let ragged= 1 463 | endif 464 | else 465 | let ragged= 1 466 | endif 467 | if ragged 468 | let begcol= 0 469 | endif 470 | " call Decho("lines[".begline.",".endline."] col[".begcol.",".endcol."] ragged=".ragged." AlignCtrl<".s:AlignCtrl.">") 471 | 472 | " Keep user options 473 | let etkeep = &l:et 474 | let pastekeep= &l:paste 475 | setlocal et paste 476 | 477 | " convert selected range of lines to use spaces instead of tabs 478 | " but if first line's initial white spaces are to be retained 479 | " then use 'em 480 | if begcol <= 0 && s:AlignLeadKeep == 'I' 481 | " retain first leading whitespace for all subsequent lines 482 | let bgntxt= substitute(getline(begline),'^\(\s*\).\{-}$','\1','') 483 | " call Decho("retaining 1st leading whitespace: bgntxt<".bgntxt.">") 484 | set noet 485 | endif 486 | exe begline.",".endline."ret" 487 | 488 | " Execute two passes 489 | " First pass: collect alignment data (max field sizes) 490 | " Second pass: perform alignment 491 | let pass= 1 492 | while pass <= 2 493 | " call Decho(" ") 494 | " call Decho("---- Pass ".pass.": ----") 495 | 496 | let line= begline 497 | while line <= endline 498 | " Process each line 499 | let txt = getline(line) 500 | " call Decho(" ") 501 | " call Decho("Pass".pass.": Line ".line." <".txt.">") 502 | 503 | " AlignGPat support: allows a selector pattern (akin to g/selector/cmd ) 504 | if exists("s:AlignGPat") 505 | " call Decho("Pass".pass.": AlignGPat<".s:AlignGPat.">") 506 | if match(txt,s:AlignGPat) == -1 507 | " call Decho("Pass".pass.": skipping") 508 | let line= line + 1 509 | continue 510 | endif 511 | endif 512 | 513 | " AlignVPat support: allows a selector pattern (akin to v/selector/cmd ) 514 | if exists("s:AlignVPat") 515 | " call Decho("Pass".pass.": AlignVPat<".s:AlignVPat.">") 516 | if match(txt,s:AlignVPat) != -1 517 | " call Decho("Pass".pass.": skipping") 518 | let line= line + 1 519 | continue 520 | endif 521 | endif 522 | 523 | " Always skip blank lines 524 | if match(txt,'^\s*$') != -1 525 | " call Decho("Pass".pass.": skipping") 526 | let line= line + 1 527 | continue 528 | endif 529 | 530 | " Extract visual-block selected text (init bgntxt, endtxt) 531 | if exists("g:Align_xstrlen") && g:Align_xstrlen 532 | let txtlen= s:Strlen(txt) 533 | else 534 | let txtlen= strlen(txt) 535 | endif 536 | if begcol > 0 537 | " Record text to left of selected area 538 | let bgntxt= strpart(txt,0,begcol) 539 | " call Decho("Pass".pass.": record text to left: bgntxt<".bgntxt.">") 540 | elseif s:AlignLeadKeep == 'W' 541 | let bgntxt= substitute(txt,'^\(\s*\).\{-}$','\1','') 542 | " call Decho("Pass".pass.": retaining all leading ws: bgntxt<".bgntxt.">") 543 | elseif s:AlignLeadKeep == 'w' || !exists("bgntxt") 544 | " No beginning text 545 | let bgntxt= "" 546 | " call Decho("Pass".pass.": no beginning text") 547 | endif 548 | if ragged 549 | let endtxt= "" 550 | else 551 | " Elide any text lying outside selected columnar region 552 | let endtxt= strpart(txt,endcol+1,txtlen-endcol) 553 | let txt = strpart(txt,begcol,endcol-begcol+1) 554 | endif 555 | " call Decho(" ") 556 | " call Decho("Pass".pass.": bgntxt<".bgntxt.">") 557 | " call Decho("Pass".pass.": txt<". txt .">") 558 | " call Decho("Pass".pass.": endtxt<".endtxt.">") 559 | if !exists("s:AlignPat_{1}") 560 | echohl Error|echo "no separators specified!"|echohl None 561 | " call Dret("Align#Align") 562 | return 563 | endif 564 | 565 | " Initialize for both passes 566 | let seppat = s:AlignPat_{1} 567 | let ifield = 1 568 | let ipat = 1 569 | let bgnfield = 0 570 | let endfield = 0 571 | let alignstyle = s:AlignStyle 572 | let doend = 1 573 | let newtxt = "" 574 | let alignprepad = s:AlignPrePad 575 | let alignpostpad= s:AlignPostPad 576 | let alignsep = s:AlignSep 577 | let alignophold = " " 578 | let alignop = "l" 579 | " call Decho("Pass".pass.": initial alignstyle<".alignstyle."> seppat<".seppat.">") 580 | 581 | " Process each field on the line 582 | while doend > 0 583 | 584 | " C-style: cycle through pattern(s) 585 | if s:AlignCtrl == 'C' && doend == 1 586 | let seppat = s:AlignPat_{ipat} 587 | " call Decho("Pass".pass.": processing field: AlignCtrl=".s:AlignCtrl." ipat=".ipat." seppat<".seppat.">") 588 | let ipat = ipat + 1 589 | if ipat > s:AlignPatQty 590 | let ipat = 1 591 | endif 592 | endif 593 | 594 | " cyclic alignment/justification operator handling 595 | let alignophold = alignop 596 | let alignop = strpart(alignstyle,0,1) 597 | if alignop == '+' || doend == 2 598 | let alignop= alignophold 599 | else 600 | let alignstyle = strpart(alignstyle,1).strpart(alignstyle,0,1) 601 | let alignopnxt = strpart(alignstyle,0,1) 602 | if alignop == ':' 603 | let seppat = '$' 604 | let doend = 2 605 | " call Decho("Pass".pass.": alignop<:> case: setting seppat<$> doend==2") 606 | endif 607 | endif 608 | 609 | " cylic separator alignment specification handling 610 | let alignsepop= strpart(alignsep,0,1) 611 | let alignsep = strpart(alignsep,1).alignsepop 612 | 613 | " mark end-of-field and the subsequent end-of-separator. 614 | " Extend field if alignop is '-' 615 | let endfield = match(txt,seppat,bgnfield) 616 | let sepfield = matchend(txt,seppat,bgnfield) 617 | let skipfield= sepfield 618 | " call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield) 619 | while alignop == '-' && endfield != -1 620 | let endfield = match(txt,seppat,skipfield) 621 | let sepfield = matchend(txt,seppat,skipfield) 622 | let skipfield = sepfield 623 | let alignop = strpart(alignstyle,0,1) 624 | let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1) 625 | " call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">") 626 | endwhile 627 | let seplen= sepfield - endfield 628 | " call Decho("Pass".pass.": seplen=[sepfield=".sepfield."] - [endfield=".endfield."]=".seplen) 629 | 630 | if endfield != -1 631 | if pass == 1 632 | " --------------------------------------------------------------------- 633 | " Pass 1: Update FieldSize to max 634 | " call Decho("Pass".pass.": before lead/trail remove: field<".strpart(txt,bgnfield,endfield-bgnfield).">") 635 | let field = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','') 636 | if s:AlignLeadKeep == 'W' 637 | let field = bgntxt.field 638 | let bgntxt= "" 639 | endif 640 | if exists("g:Align_xstrlen") && g:Align_xstrlen 641 | let fieldlen = s:Strlen(field) 642 | else 643 | let fieldlen = strlen(field) 644 | endif 645 | let sFieldSize = "FieldSize_".ifield 646 | if !exists(sFieldSize) 647 | let FieldSize_{ifield}= fieldlen 648 | " call Decho("Pass".pass.": set FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field.">") 649 | elseif fieldlen > FieldSize_{ifield} 650 | let FieldSize_{ifield}= fieldlen 651 | " call Decho("Pass".pass.": oset FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field.">") 652 | endif 653 | let sSepSize= "SepSize_".ifield 654 | if !exists(sSepSize) 655 | let SepSize_{ifield}= seplen 656 | " call Decho(" set SepSize_{".ifield."}=".SepSize_{ifield}." <".field.">") 657 | elseif seplen > SepSize_{ifield} 658 | let SepSize_{ifield}= seplen 659 | " call Decho("Pass".pass.": oset SepSize_{".ifield."}=".SepSize_{ifield}." <".field.">") 660 | endif 661 | 662 | else 663 | " --------------------------------------------------------------------- 664 | " Pass 2: Perform Alignment 665 | let prepad = strpart(alignprepad,0,1) 666 | let postpad = strpart(alignpostpad,0,1) 667 | let alignprepad = strpart(alignprepad,1).strpart(alignprepad,0,1) 668 | let alignpostpad = strpart(alignpostpad,1).strpart(alignpostpad,0,1) 669 | let field = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','') 670 | if s:AlignLeadKeep == 'W' 671 | let field = bgntxt.field 672 | let bgntxt= "" 673 | endif 674 | if doend == 2 675 | let prepad = 0 676 | let postpad= 0 677 | endif 678 | if exists("g:Align_xstrlen") && g:Align_xstrlen 679 | let fieldlen = s:Strlen(field) 680 | else 681 | let fieldlen = strlen(field) 682 | endif 683 | let sep = s:MakeSpace(prepad).strpart(txt,endfield,sepfield-endfield).s:MakeSpace(postpad) 684 | if seplen < SepSize_{ifield} 685 | if alignsepop == "<" 686 | " left-justify separators 687 | let sep = sep.s:MakeSpace(SepSize_{ifield}-seplen) 688 | elseif alignsepop == ">" 689 | " right-justify separators 690 | let sep = s:MakeSpace(SepSize_{ifield}-seplen).sep 691 | else 692 | " center-justify separators 693 | let sepleft = (SepSize_{ifield} - seplen)/2 694 | let sepright = SepSize_{ifield} - seplen - sepleft 695 | let sep = s:MakeSpace(sepleft).sep.s:MakeSpace(sepright) 696 | endif 697 | endif 698 | let spaces = FieldSize_{ifield} - fieldlen 699 | " 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.">") 700 | 701 | " Perform alignment according to alignment style justification 702 | if spaces > 0 703 | if alignop == 'c' 704 | " center the field 705 | let spaceleft = spaces/2 706 | let spaceright= FieldSize_{ifield} - spaceleft - fieldlen 707 | let newtxt = newtxt.s:MakeSpace(spaceleft).field.s:MakeSpace(spaceright).sep 708 | elseif alignop == 'r' 709 | " right justify the field 710 | let newtxt= newtxt.s:MakeSpace(spaces).field.sep 711 | elseif ragged && doend == 2 712 | " left justify rightmost field (no trailing blanks needed) 713 | let newtxt= newtxt.field 714 | else 715 | " left justfiy the field 716 | let newtxt= newtxt.field.s:MakeSpace(spaces).sep 717 | endif 718 | elseif ragged && doend == 2 719 | " field at maximum field size and no trailing blanks needed 720 | let newtxt= newtxt.field 721 | else 722 | " field is at maximum field size already 723 | let newtxt= newtxt.field.sep 724 | endif 725 | " call Decho("Pass".pass.": newtxt<".newtxt.">") 726 | endif " pass 1/2 727 | 728 | " bgnfield indexes to end of separator at right of current field 729 | " Update field counter 730 | let bgnfield= sepfield 731 | let ifield = ifield + 1 732 | if doend == 2 733 | let doend= 0 734 | endif 735 | " handle end-of-text as end-of-field 736 | elseif doend == 1 737 | let seppat = '$' 738 | let doend = 2 739 | else 740 | let doend = 0 741 | endif " endfield != -1 742 | endwhile " doend loop (as well as regularly separated fields) 743 | 744 | if pass == 2 745 | " Write altered line to buffer 746 | " call Decho("Pass".pass.": bgntxt<".bgntxt."> line=".line) 747 | " call Decho("Pass".pass.": newtxt<".newtxt.">") 748 | " call Decho("Pass".pass.": endtxt<".endtxt.">") 749 | call setline(line,bgntxt.newtxt.endtxt) 750 | endif 751 | 752 | let line = line + 1 753 | endwhile " line loop 754 | 755 | let pass= pass + 1 756 | endwhile " pass loop 757 | " call Decho("end of two pass loop") 758 | 759 | " Restore user options 760 | let &l:et = etkeep 761 | let &l:paste = pastekeep 762 | 763 | if exists("s:DoAlignPop") 764 | " AlignCtrl Map support 765 | call Align#AlignPop() 766 | unlet s:DoAlignPop 767 | endif 768 | 769 | " restore current search pattern 770 | let @/ = keep_search 771 | let &ic = keep_ic 772 | let &report = keep_report 773 | 774 | " call Dret("Align#Align") 775 | return 776 | endfun 777 | 778 | " --------------------------------------------------------------------- 779 | " Align#AlignPush: this command/function pushes an alignment control string onto a stack {{{1 780 | fun! Align#AlignPush() 781 | " call Dfunc("AlignPush()") 782 | 783 | " initialize the stack 784 | if !exists("s:AlignCtrlStackQty") 785 | let s:AlignCtrlStackQty= 1 786 | else 787 | let s:AlignCtrlStackQty= s:AlignCtrlStackQty + 1 788 | endif 789 | 790 | " construct an AlignCtrlStack entry 791 | if !exists("s:AlignSep") 792 | let s:AlignSep= '' 793 | endif 794 | let s:AlignCtrlStack_{s:AlignCtrlStackQty}= s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle.s:AlignSep 795 | " call Decho("AlignPush: AlignCtrlStack_".s:AlignCtrlStackQty."<".s:AlignCtrlStack_{s:AlignCtrlStackQty}.">") 796 | 797 | " push [GV] patterns onto their own stack 798 | if exists("s:AlignGPat") 799 | let s:AlignGPat_{s:AlignCtrlStackQty}= s:AlignGPat 800 | else 801 | let s:AlignGPat_{s:AlignCtrlStackQty}= "" 802 | endif 803 | if exists("s:AlignVPat") 804 | let s:AlignVPat_{s:AlignCtrlStackQty}= s:AlignVPat 805 | else 806 | let s:AlignVPat_{s:AlignCtrlStackQty}= "" 807 | endif 808 | 809 | " call Dret("AlignPush") 810 | endfun 811 | 812 | " --------------------------------------------------------------------- 813 | " Align#AlignPop: this command/function pops an alignment pattern from a stack {{{1 814 | " and into the AlignCtrl variables. 815 | fun! Align#AlignPop() 816 | " call Dfunc("Align#AlignPop()") 817 | 818 | " sanity checks 819 | if !exists("s:AlignCtrlStackQty") 820 | echoerr "AlignPush needs to be used prior to AlignPop" 821 | " call Dret("Align#AlignPop <> : AlignPush needs to have been called first") 822 | return "" 823 | endif 824 | if s:AlignCtrlStackQty <= 0 825 | unlet s:AlignCtrlStackQty 826 | echoerr "AlignPush needs to be used prior to AlignPop" 827 | " call Dret("Align#AlignPop <> : AlignPop needs to have been called first") 828 | return "" 829 | endif 830 | 831 | " pop top of AlignCtrlStack and pass value to AlignCtrl 832 | let retval=s:AlignCtrlStack_{s:AlignCtrlStackQty} 833 | unlet s:AlignCtrlStack_{s:AlignCtrlStackQty} 834 | call Align#AlignCtrl(retval) 835 | 836 | " pop G pattern stack 837 | if s:AlignGPat_{s:AlignCtrlStackQty} != "" 838 | call Align#AlignCtrl('g',s:AlignGPat_{s:AlignCtrlStackQty}) 839 | else 840 | call Align#AlignCtrl('g') 841 | endif 842 | unlet s:AlignGPat_{s:AlignCtrlStackQty} 843 | 844 | " pop V pattern stack 845 | if s:AlignVPat_{s:AlignCtrlStackQty} != "" 846 | call Align#AlignCtrl('v',s:AlignVPat_{s:AlignCtrlStackQty}) 847 | else 848 | call Align#AlignCtrl('v') 849 | endif 850 | 851 | unlet s:AlignVPat_{s:AlignCtrlStackQty} 852 | let s:AlignCtrlStackQty= s:AlignCtrlStackQty - 1 853 | 854 | " call Dret("Align#AlignPop <".retval."> : AlignCtrlStackQty=".s:AlignCtrlStackQty) 855 | return retval 856 | endfun 857 | 858 | " --------------------------------------------------------------------- 859 | " Align#AlignReplaceQuotedSpaces: {{{1 860 | fun! Align#AlignReplaceQuotedSpaces() 861 | " call Dfunc("AlignReplaceQuotedSpaces()") 862 | 863 | let l:line = getline(line(".")) 864 | if exists("g:Align_xstrlen") && g:Align_xstrlen 865 | let l:linelen = s:Strlen(l:line) 866 | else 867 | let l:linelen = strlen(l:line) 868 | endif 869 | let l:startingPos = 0 870 | let l:startQuotePos = 0 871 | let l:endQuotePos = 0 872 | let l:spacePos = 0 873 | let l:quoteRe = '\\\@, is needed. {{{1 904 | " However, doesn't split at all, so this function returns a list 905 | " of arguments which has been: 906 | " * split at whitespace 907 | " * unless inside "..."s. One may escape characters with a backslash inside double quotes. 908 | " along with a leading length-of-list. 909 | " 910 | " Examples: %Align "\"" will align on "s 911 | " %Align " " will align on spaces 912 | " 913 | " The resulting list: qarglist[0] corresponds to a:0 914 | " qarglist[i] corresponds to a:{i} 915 | fun! s:QArgSplitter(qarg) 916 | " call Dfunc("s:QArgSplitter(qarg<".a:qarg.">)") 917 | 918 | if a:qarg =~ '".*"' 919 | " handle "..." args, which may include whitespace 920 | let qarglist = [] 921 | let args = a:qarg 922 | " call Decho("handle quoted arguments: args<".args.">") 923 | while args != "" 924 | let iarg = 0 925 | let arglen = strlen(args) 926 | " call Decho("args[".iarg."]<".args[iarg]."> arglen=".arglen) 927 | " find index to first not-escaped '"' 928 | while args[iarg] != '"' && iarg < arglen 929 | if args[iarg] == '\' 930 | let args= strpart(args,1) 931 | endif 932 | let iarg= iarg + 1 933 | endwhile 934 | " call Decho("args<".args."> iarg=".iarg." arglen=".arglen) 935 | 936 | if iarg > 0 937 | " handle left of quote or remaining section 938 | " call Decho("handle left of quote or remaining section") 939 | if args[iarg] == '"' 940 | let qarglist= qarglist + split(strpart(args,0,iarg-1)) 941 | else 942 | let qarglist= qarglist + split(strpart(args,0,iarg)) 943 | endif 944 | let args = strpart(args,iarg) 945 | let arglen = strlen(args) 946 | 947 | elseif iarg < arglen && args[0] == '"' 948 | " handle "quoted" section 949 | " call Decho("handle quoted section") 950 | let iarg= 1 951 | while args[iarg] != '"' && iarg < arglen 952 | if args[iarg] == '\' 953 | let args= strpart(args,1) 954 | endif 955 | let iarg= iarg + 1 956 | endwhile 957 | " call Decho("args<".args."> iarg=".iarg." arglen=".arglen) 958 | if args[iarg] == '"' 959 | call add(qarglist,strpart(args,1,iarg-1)) 960 | let args= strpart(args,iarg+1) 961 | else 962 | let qarglist = qarglist + split(args) 963 | let args = "" 964 | endif 965 | endif 966 | " call Decho("qarglist".string(qarglist)." iarg=".iarg." args<".args.">") 967 | endwhile 968 | 969 | else 970 | " split at all whitespace 971 | let qarglist= split(a:qarg) 972 | endif 973 | 974 | let qarglistlen= len(qarglist) 975 | let qarglist = insert(qarglist,qarglistlen) 976 | " call Dret("s:QArgSplitter ".string(qarglist)) 977 | return qarglist 978 | endfun 979 | 980 | " --------------------------------------------------------------------- 981 | " s:Strlen: this function returns the length of a string, even if its {{{1 982 | " using two-byte etc characters. 983 | " Currently, its only used if g:Align_xstrlen is set to a 984 | " nonzero value. Solution from Nicolai Weibull, vim docs 985 | " (:help strlen()), Tony Mechelynck, and my own invention. 986 | fun! s:Strlen(x) 987 | " call Dfunc("s:Strlen(x<".a:x.">") 988 | if g:Align_xstrlen == 1 989 | " number of codepoints (Latin a + combining circumflex is two codepoints) 990 | " (comment from TM, solution from NW) 991 | let ret= strlen(substitute(a:x,'.','c','g')) 992 | 993 | elseif g:Align_xstrlen == 2 994 | " number of spacing codepoints (Latin a + combining circumflex is one spacing 995 | " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.) 996 | " (comment from TM, solution from TM) 997 | let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) 998 | 999 | elseif g:Align_xstrlen == 3 1000 | " virtual length (counting, for instance, tabs as anything between 1 and 1001 | " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately 1002 | " preceded by lam, one otherwise, etc.) 1003 | " (comment from TM, solution from me) 1004 | let modkeep= &l:mod 1005 | exe "norm! o\" 1006 | call setline(line("."),a:x) 1007 | let ret= virtcol("$") - 1 1008 | d 1009 | let &l:mod= modkeep 1010 | 1011 | else 1012 | " at least give a decent default 1013 | ret= strlen(a:x) 1014 | endif 1015 | " call Dret("s:Strlen ".ret) 1016 | return ret 1017 | endfun 1018 | 1019 | " --------------------------------------------------------------------- 1020 | " Set up default values: {{{1 1021 | "call Decho("-- Begin AlignCtrl Initialization --") 1022 | call Align#AlignCtrl("default") 1023 | "call Decho("-- End AlignCtrl Initialization --") 1024 | 1025 | " --------------------------------------------------------------------- 1026 | " Restore: {{{1 1027 | let &cpo= s:keepcpo 1028 | unlet s:keepcpo 1029 | " vim: ts=4 fdm=marker 1030 | -------------------------------------------------------------------------------- /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! ' 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/==/\="\\"/ge 165 | 'a,'zs/\([!<>:]\)=/\=submatch(1)."\"/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\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\\" 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 331 | -------------------------------------------------------------------------------- /doc/Align.txt: -------------------------------------------------------------------------------- 1 | *align.txt* The Alignment Tool Mar 04, 2009 2 | 3 | Author: Charles E. Campbell, Jr. 4 | (remove NOSPAM from Campbell's email first) 5 | Copyright: (c) 2004-2008 by Charles E. Campbell, Jr. *Align-copyright* 6 | The VIM LICENSE applies to Align.vim, AlignMaps.vim, and Align.txt 7 | (see |copyright|) except use "Align and AlignMaps" instead of "Vim" 8 | NO WARRANTY, EXPRESS OR IMPLIED. USE AT-YOUR-OWN-RISK. 9 | 10 | ============================================================================== 11 | 1. Contents *align* *align-contents* {{{1 12 | 13 | 1. Contents.................: |align-contents| 14 | 2. Alignment Manual.........: |align-manual| 15 | 3. Alignment Usage..........: |align-usage| 16 | Alignment Concepts.......: |align-concepts| 17 | Alignment Commands.......: |align-commands| 18 | Alignment Control........: |align-control| 19 | Separators.............: |alignctrl-separators| 20 | Initial Whitespace.....: |alignctrl-w| |alignctrl-W| |alignctrl-I| 21 | Justification..........: |alignctrl-l| |alignctrl-r| |alignctrl-c| 22 | Justification Control..: |alignctrl--| |alignctrl-+| |alignctrl-:| 23 | Cyclic/Sequential......: |alignctrl-=| |alignctrl-C| 24 | Separator Justification: |alignctrl-<| |alignctrl->| |alignctrl-|| 25 | Line (de)Selection.....: |alignctrl-g| |alignctrl-v| 26 | Temporary Settings.....: |alignctrl-m| 27 | Padding................: |alignctrl-p| |alignctrl-P| 28 | Current Options........: |alignctrl-settings| |alignctrl-| 29 | Alignment................: |align-align| 30 | 4. Alignment Maps...........: |align-maps| 31 | \a,....................: |alignmap-a,| 32 | \a?....................: |alignmap-a?| 33 | \a<....................: |alignmap-a<| 34 | \abox..................: |alignmap-abox| 35 | \acom..................: |alignmap-acom| 36 | \anum..................: |alignmap-anum| 37 | \ascom.................: |alignmap-ascom| 38 | \adec..................: |alignmap-adec| 39 | \adef..................: |alignmap-adef| 40 | \afnc..................: |alignmap-afnc| 41 | \adcom.................: |alignmap-adcom| 42 | \aocom.................: |alignmap-aocom| 43 | \tsp...................: |alignmap-tsp| 44 | \tsq...................: |alignmap-tsq| 45 | \tt....................: |alignmap-tt| 46 | \t=....................: |alignmap-t=| 47 | \T=....................: |alignmap-T=| 48 | \Htd...................: |alignmap-Htd| 49 | 5. Alignment Tool History...: |align-history| 50 | 51 | ============================================================================== 52 | 2. Align Manual *alignman* *alignmanual* *align-manual* {{{1 53 | 54 | Align comes as a vimball; simply typing > 55 | vim Align.vba.gz 56 | :so % 57 | < should put its components where they belong. The components are: > 58 | .vim/plugin/AlignPlugin.vim 59 | .vim/plugin/AlignMapsPlugin.vim 60 | .vim/plugin/cecutil.vim 61 | .vim/autoload/Align.vim 62 | .vim/autoload/AlignMaps.vim 63 | .vim/doc/Align.txt 64 | < To see a user's guide, see |align-userguide| 65 | To see examples, see |alignctrl| and |alignmaps| 66 | > 67 | /=============+=========+=====================================================\ 68 | || \ Default/ || 69 | || Commands \ Value/ Explanation || 70 | || | | || 71 | ++==============+====+=======================================================++ 72 | || AlignCtrl | | =Clrc-+:pPIWw [..list-of-separator-patterns..] || 73 | || | +-------------------------------------------------------+| 74 | || | | may be called as a command or as a function: || 75 | || | | :AlignCtrl =lp0P0W & \\ || 76 | || | | :call Align#AlignCtrl('=lp0P0W','&','\\') || 77 | || | | || 78 | || | +-------------------------------------------------------++ 79 | || 1st arg | = | = all separator patterns are equivalent and are || 80 | || | | simultaneously active. Patterns are |regexp|. || 81 | || | | C cycle through separator patterns. Patterns are || 82 | || | | |regexp| and are active sequentially. || 83 | || | | || 84 | || | < | < left justify separator Separators are justified, || 85 | || | | > right justify separator too. Separator styles || 86 | || | | | center separator are cyclic. || 87 | || | | || 88 | || | l | l left justify Justification styles are always || 89 | || | | r right justify cyclic (ie. lrc would mean left j., || 90 | || | | c center then right j., then center, repeat. || 91 | || | | - skip this separator || 92 | || | | + re-use last justification method || 93 | || | | : treat rest of text as a field || 94 | || | | || 95 | || | p1 | p### pad separator on left by # blanks || 96 | || | P1 | P### pad separator on right by # blanks || 97 | || | | || 98 | || | I | I preserve and apply first line's leading white || 99 | || | | space to all lines || 100 | || | | W preserve leading white space on every line, even || 101 | || | | if it varies from line to line || 102 | || | | w don't preserve leading white space || 103 | || | | || 104 | || | | g second argument is a selection pattern -- only || 105 | || | | align on lines that have a match (inspired by || 106 | || | | :g/selection pattern/command) || 107 | || | | v second argument is a selection pattern -- only || 108 | || | | align on lines that _don't_ have a match (inspired || 109 | || | | by :v/selection pattern/command) || 110 | || | | || 111 | || | | m Map support: AlignCtrl will immediately do an || 112 | || | | AlignPush() and the next call to Align() will do || 113 | || | | an AlignPop at the end. This feature allows maps || 114 | || | | to preserve user settings. || 115 | || | | || 116 | || | | default || 117 | || | | AlignCtrl default || 118 | || | | will clear the AlignCtrl || 119 | || | | stack & set the default: AlignCtrl "Ilp1P1=" '=' || 120 | || | | || 121 | || +----+-------------------------------------------------------+| 122 | || More args | More arguments are interpreted as describing separators || 123 | || +------------------------------------------------------------+| 124 | || No args | AlignCtrl will display its current settings || 125 | ||==============+============================================================+| 126 | ||[range]Align | [..list-of-separators..] || 127 | ||[range]Align! | [AlignCtrl settings] [..list-of-separators..] || 128 | || +------------------------------------------------------------+| 129 | || | Aligns text over the given range. The range may be || 130 | || | selected via visual mode (v, V, or ctrl-v) or via || 131 | || | the command line. The Align operation may be invoked || 132 | || | as a command or as a function; as a function, the first || 133 | || | argument is 0=separators only, 1=AlignCtrl option string || 134 | || | followed by a list of separators. || 135 | || | :[range]Align || 136 | || | :[range]Align [list of separators] || 137 | || | :[range]call Align#Align(0) || 138 | || | :[range]call Align#Align(0,"list","of","separators",...) || 139 | \=============================================================================/ 140 | 141 | ============================================================================== 142 | 3. Alignment Usage *alignusage* *align-usage* *align-userguide* {{{1 143 | 144 | 145 | ALIGNMENT CONCEPTS *align-concept* *align-concepts* {{{2 146 | 147 | The typical text to be aligned is considered to be: 148 | 149 | * composed of two or more fields 150 | * separated by one or more separator pattern(s): 151 | * two or more lines 152 | > 153 | ws field ws separator ws field ws separator ... 154 | ws field ws separator ws field ws separator ... 155 | < 156 | where "ws" stands for "white space" such as blanks and/or tabs, 157 | and "fields" are arbitrary text. For example, consider > 158 | 159 | x= y= z= 3; 160 | xx= yy= zz= 4; 161 | zzz= yyy= zzz= 5; 162 | a= b= c= 3; 163 | < 164 | Assume that it is desired to line up all the "=" signs; these, 165 | then, are the separators. The fields are composed of all the 166 | alphameric text. Assuming they lie on lines 1-4, one may align 167 | those "=" signs with: > 168 | :AlignCtrl l 169 | :1,4Align = 170 | < The result is: > 171 | x = y = z = 3; 172 | xx = yy = zz = 4; 173 | zzz = yyy = zzz = 5; 174 | a = b = c = 3; 175 | 176 | < Note how each "=" sign is surrounded by a single space; the 177 | default padding is p1P1 (p1 means one space before the separator, 178 | and P1 means one space after it). If you wish to change the 179 | padding, say to no padding, use (see |alignctrl-p|) > 180 | :AlignCtrl lp0P0 181 | 182 | < Next, note how each field is left justified; that's what the "l" 183 | (a small letter "ell") does. If right-justification of the fields 184 | had been desired, an "r" could've been used: > 185 | :AlignCtrl r 186 | < yielding > 187 | x = y = z = 3; 188 | xx = yy = zz = 4; 189 | zzz = yyy = zzz = 5; 190 | a = b = c = 3; 191 | < There are many more options available for field justification: see 192 | |alignctrl-c| and |alignctrl--|. 193 | 194 | Separators, although commonly only one character long, are actually 195 | specified by regular expressions (see |regexp|), and one may left 196 | justify, right justify, or center them, too (see |alignctrl-<|). 197 | 198 | Assume that for some reason a left-right-left-right-... justification 199 | sequence was wished. This wish is simply achieved with > 200 | :AlignCtrl lr 201 | :1,4Align = 202 | < because the justification commands are considered to be "cylic"; ie. 203 | lr is the same as lrlrlrlrlrlrlr... 204 | 205 | There's a lot more discussed under |alignctrl|; hopefully the examples 206 | there will help, too. 207 | 208 | 209 | ALIGNMENT COMMANDS *align-command* *align-commands* {{{2 210 | 211 | The script includes two primary commands and two 212 | minor commands: 213 | 214 | AlignCtrl : this command/function sets up alignment options 215 | which persist until changed for later Align calls. 216 | It controls such things as: how to specify field 217 | separators, initial white space, padding about 218 | separators, left/right/center justification, etc. > 219 | ex. AlignCtrl wp0P1 220 | Interpretation: during subsequent alignment 221 | operations, preserve each line's initial 222 | whitespace. Use no padding before separators 223 | but provide one padding space after separators. 224 | < 225 | Align : this command/function operates on the range given it to 226 | align text based on one or more separator patterns. The 227 | patterns may be provided via AlignCtrl or via Align 228 | itself. > 229 | 230 | ex. :%Align , 231 | Interpretation: align all commas over the entire 232 | file. 233 | < The :Align! format permits alignment control commands 234 | to precede the alignment patterns. > 235 | ex. :%Align! p2P2 = 236 | < This will align all "=" in the file with two padding 237 | spaces on both sides of each "=" sign. 238 | 239 | NOTE ON USING PATTERNS WITH ALIGN:~ 240 | Align and AlignCtrl use || to obtain their 241 | input patterns and they use an internal function to 242 | split arguments at whitespace unless inside "..."s. 243 | One may escape characters inside a double-quote string 244 | by preceding such characters with a backslash. 245 | 246 | AlignPush : this command/function pushes the current AlignCtrl 247 | state onto an internal stack. > 248 | ex. :AlignPush 249 | Interpretation: save the current AlignCtrl 250 | settings, whatever they may be. They'll 251 | also remain as the current settings until 252 | AlignCtrl is used to change them. 253 | < 254 | AlignPop : this command/function pops the current AlignCtrl 255 | state from an internal stack. > 256 | ex. :AlignPop 257 | Interpretation: presumably AlignPush was 258 | used (at least once) previously; this command 259 | restores the AlignCtrl settings when AlignPush 260 | was last used. 261 | < Also see |alignctrl-m| for a way to automatically do 262 | an AlignPop after an Align (primarily this is for maps). 263 | 264 | ALIGNMENT OPTIONS *align-option* *align-options* {{{2 265 | *align-utf8* *align-utf* *align-codepoint* *align-strlen* *align-multibyte* 266 | 267 | For those of you who are using 2-byte (or more) characters such as are 268 | available with utf-8, Align now provides a special option which you 269 | may choose based upon your needs: 270 | 271 | Use Built-in strlen() ~ 272 | > 273 | let g:Align_xstrlen= 0 274 | 275 | < This is the fastest method, but it doesn't handle multibyte characters 276 | well. It is the default for: 277 | 278 | enc=latin1 279 | vim compiled without multi-byte support 280 | $LANG is en_US.UTF-8 (assuming USA english) 281 | 282 | Number of codepoints (Latin a + combining circumflex is two codepoints)~ 283 | > 284 | let g:Align_xstrlen= 1 (default) 285 | < 286 | Number of spacing codepoints (Latin a + combining circumflex is one~ 287 | spacing codepoint; a hard tab is one; wide and narrow CJK are one~ 288 | each; etc.)~ 289 | > 290 | let g:Align_xstrlen= 2 291 | < 292 | Virtual length (counting, for instance, tabs as anything between 1 and~ 293 | 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when~ 294 | immediately preceded by lam, one otherwise, etc.)~ 295 | > 296 | let g:Align_xstrlen= 3 297 | < 298 | By putting one of these settings into your <.vimrc>, Align will use an 299 | internal (interpreted) function to determine a string's length instead 300 | of the Vim's built-in |strlen()| function. Since the function is 301 | interpreted, Align will run a bit slower but will handle such strings 302 | correctly. The last setting (g:Align_xstrlen= 3) probably will run 303 | the slowest but be the most accurate. (thanks to Tony Mechelynck for 304 | these) 305 | 306 | 307 | ALIGNMENT CONTROL *alignctrl* *align-control* {{{2 308 | 309 | This command doesn't do the alignment operation itself; instead, it 310 | controls subsequent alignment operation(s). 311 | 312 | The first argument to AlignCtrl is a string which may contain one or 313 | more alignment control settings. Most of the settings are specified 314 | by single letters; the exceptions are the p# and P# commands which 315 | interpret a digit following the p or P as specifying padding about the 316 | separator. 317 | 318 | The typical text line is considered to be composed of two or more 319 | fields separated by one or more separator pattern(s): > 320 | 321 | ws field ws separator ws field ws separator ... 322 | < 323 | where "ws" stands for "white space" such as blanks and/or tabs. 324 | 325 | 326 | SEPARATORS *alignctrl-separators* {{{3 327 | 328 | As a result, separators may not have white space (tabs or blanks) on 329 | their outsides (ie. ": :" is fine as a separator, but " :: " is 330 | not). Usually such separators are not needed, although a map has been 331 | provided which works around this limitation and aligns on whitespace 332 | (see |alignmap-tsp|). 333 | 334 | However, if you really need to have separators with leading or 335 | trailing whitespace, consider handling them by performing a substitute 336 | first (ie. s/ :: /@/g), do the alignment on the temporary pattern 337 | (ie. @), and then perform a substitute to revert the separators back 338 | to their desired condition (ie. s/@/ :: /g). 339 | 340 | The Align#Align() function will first convert tabs over the region into 341 | spaces and then apply alignment control. Except for initial white 342 | space, white space surrounding the fields is ignored. One has three 343 | options just for handling initial white space: 344 | 345 | 346 | --- *alignctrl-w* 347 | wWI INITIAL WHITE SPACE *alignctrl-W* {{{3 348 | --- *alignctrl-I* 349 | w : ignore all selected lines' initial white space 350 | W : retain all selected lines' initial white space 351 | I : retain only the first line's initial white space and 352 | re-use it for subsequent lines 353 | 354 | Example: Leading white space options: > 355 | +---------------+-------------------+-----------------+ 356 | |AlignCtrl w= :=| AlignCtrl W= := | AlignCtrl I= := | 357 | +------------------+---------------+-------------------+-----------------+ 358 | | Original | w option | W option | I option | 359 | +------------------+---------------+-------------------+-----------------+ 360 | | a := baaa |a := baaa | a : = baaa | a := baaa | 361 | | caaaa := deeee |caaaa := deeee | caaaa : = deeee| caaaa := deeee| 362 | | ee := f |ee := f | ee : = f | ee := f | 363 | +------------------+---------------+-------------------+-----------------+ 364 | < 365 | The original has at least one leading white space on every line. 366 | Using Align with w eliminated each line's leading white space. 367 | Using Align with W preserved each line's leading white space. 368 | Using Align with I applied the first line's leading white space 369 | (three spaces) to each line. 370 | 371 | 372 | ------ *alignctrl-l* 373 | lrc-+: FIELD JUSTIFICATION *alignctrl-r* {{{3 374 | ------ *alignctrl-c* 375 | 376 | With "lrc", the fields will be left-justified, right-justified, or 377 | centered as indicated by the justification specifiers (lrc). The 378 | "lrc" options are re-used by cycling through them as needed: 379 | 380 | l means llllll.... 381 | r means rrrrrr.... 382 | lr means lrlrlr.... 383 | llr means llrllr.... 384 | 385 | Example: Justification options: Align = > 386 | +------------+-------------------+-------------------+-------------------+ 387 | | Original | AlignCtrl l | AlignCtrl r | AlignCtrl lr | 388 | +------------+-------------------+-------------------+-------------------+ 389 | | a=bb=ccc=1 |a = bb = ccc = 1| a = bb = ccc = 1|a = bb = ccc = 1| 390 | | ccc=a=bb=2 |ccc = a = bb = 2|ccc = a = bb = 2|ccc = a = bb = 2| 391 | | dd=eee=f=3 |dd = eee = f = 3| dd = eee = f = 3|dd = eee = f = 3| 392 | +------------+-------------------+-------------------+-------------------+ 393 | | Alignment |l l l l| r r r r|l r l r| 394 | +------------+-------------------+-------------------+-------------------+ 395 | < 396 | AlignCtrl l : The = separator is repeatedly re-used, as the 397 | cycle only consists of one character (the "l"). 398 | Every time left-justification is used for fields. 399 | AlignCtrl r : The = separator is repeatedly re-used, as the 400 | cycle only consists of one character (the "l"). 401 | Every time right-justification is used for fields 402 | AlignCtrl lr: Again, the "=" separator is repeatedly re-used, 403 | but the fields are justified alternately between 404 | left and right. 405 | 406 | Even more separator control is available. With "-+:": 407 | 408 | - : skip treating the separator as a separator. *alignctrl--* 409 | + : repeat use of the last "lrc" justification *alignctrl-+* 410 | : : treat the rest of the line as a single field *alignctrl-:* 411 | 412 | Example: More justification options: Align = > 413 | +------------+---------------+--------------------+---------------+ 414 | | Original | AlignCtrl -l | AlignCtrl rl+ | AlignCtrl l: | 415 | +------------+---------------+--------------------+---------------+ 416 | | a=bb=ccc=1 |a=bb = ccc=1 | a = bb = ccc = 1 |a = bb=ccc=1 | 417 | | ccc=a=bb=2 |ccc=a = bb=2 |ccc = a = bb = 2 |ccc = a=bb=2 | 418 | | dd=eee=f=3 |dd=eee = f=3 | dd = eee = f = 3 |dd = eee=f=3 | 419 | +------------+---------------+--------------------+---------------+ 420 | | Alignment |l l | r l l l |l l | 421 | +------------+---------------+--------------------+---------------+ 422 | < 423 | In the first example in "More justification options": 424 | 425 | The first "=" separator is skipped by the "-" specification, 426 | and so "a=bb", "ccc=a", and "dd=eee" are considered as single fields. 427 | 428 | The next "=" separator has its (left side) field left-justified. 429 | Due to the cyclic nature of separator patterns, the "-l" 430 | specification is equivalent to "-l-l-l ...". 431 | 432 | Hence the next specification is a "skip", so "ccc=1", etc are fields. 433 | 434 | In the second example in "More justification options": 435 | 436 | The first field is right-justified, the second field is left 437 | justified, and all remaining fields repeat the last justification 438 | command (ie. they are left justified, too). 439 | 440 | Hence rl+ is equivalent to rlllllllll ... 441 | (whereas plain rl is equivalent to rlrlrlrlrl ... ). 442 | 443 | In the third example in "More justification options": 444 | 445 | The text following the first separator is treated as a single field. 446 | 447 | Thus using the - and : operators one can apply justification to a 448 | single separator. 449 | 450 | ex. 1st separator only: AlignCtrl l: 451 | 2nd separator only: AlignCtrl -l: 452 | 3rd separator only: AlignCtrl --l: 453 | etc. 454 | 455 | 456 | --- *alignctrl-=* 457 | =C CYCLIC VS ALL-ACTIVE SEPARATORS *alignctrl-C* {{{3 458 | --- 459 | 460 | The separators themselves may be considered as equivalent and 461 | simultaneously active ("=") or sequentially cycled through ("C"). 462 | Separators are regular expressions (|regexp|) and are specified as the 463 | second, third, etc arguments. When the separator patterns are 464 | equivalent and simultaneously active, there will be one pattern 465 | constructed: > 466 | 467 | AlignCtrl ... pat1 pat2 pat3 468 | \(pat1\|pat2\|pat3\) 469 | < 470 | Each separator pattern is thus equivalent and simultaneously active. 471 | The cyclic separator AlignCtrl option stores a list of patterns, only 472 | one of which is active for each field at a time. 473 | 474 | Example: Equivalent/Simultaneously-Active vs Cyclic Separators > 475 | +-------------+------------------+---------------------+----------------------+ 476 | | Original | AlignCtrl = = + -| AlignCtrl = = | AlignCtrl C = + - | 477 | +-------------+------------------+---------------------+----------------------+ 478 | |a = b + c - d|a = b + c - d |a = b + c - d |a = b + c - d | 479 | |x = y = z + 2|x = y = z + 2 |x = y = z + 2|x = y = z + 2 | 480 | |w = s - t = 0|w = s - t = 0 |w = s - t = 0 |w = s - t = 0 | 481 | +-------------+------------------+---------------------+----------------------+ 482 | < 483 | The original is initially aligned with all operators (=+-) being 484 | considered as equivalent and simultaneously active field separators. 485 | Thus the "AlignCtrl = = + -" example shows no change. 486 | 487 | The second example only accepts the '=' as a field separator; 488 | consequently "b + c - d" is now a single field. 489 | 490 | The third example illustrates cyclic field separators and is analyzed 491 | in the following illustration: > 492 | 493 | field1 separator field2 separator field3 separator field4 494 | a = b + c - d 495 | x = y = z + 2 496 | w = s - t = 0 497 | < 498 | The word "cyclic" is used because the patterns form a cycle of use; in 499 | the above case, its = + - = + - = + - = + -... 500 | 501 | Example: Cyclic separators > 502 | Label : this is some text discussing ":"s | ex. abc:def:ghi 503 | Label : this is some text with a ":" in it | ex. abc:def 504 | < 505 | apply AlignCtrl lWC : | | 506 | (select lines)Align > 507 | Label : this is some text discussing ":"s | ex. abc:def:ghi 508 | Label : this is some text with a ":" in it | ex. abcd:efg 509 | < 510 | In the current example, 511 | : is the first separator So the first ":"s are aligned 512 | | is the second separator but subsequent ":"s are not. 513 | | is the third separator The "|"s are aligned, too. 514 | : is the fourth separator Since there aren't two bars, 515 | | is the fifth separator the subsequent potential cycles 516 | | is the sixth separator don't appear. 517 | ... 518 | 519 | In this case it would probably have been a better idea to have used > 520 | AlignCtrl WCl: : | 521 | < as that alignment control would guarantee that no more cycling 522 | would be used after the vertical bar. 523 | 524 | Example: Cyclic separators 525 | 526 | Original: > 527 | a| b&c | (d|e) & f-g-h 528 | aa| bb&cc | (dd|ee) & ff-gg-hh 529 | aaa| bbb&ccc | (ddd|eee) & fff-ggg-hhh 530 | < 531 | AlignCtrl C | | & - > 532 | a | b&c | (d|e) & f - g-h 533 | aa | bb&cc | (dd|ee) & ff - gg-hh 534 | aaa | bbb&ccc | (ddd|eee) & fff - ggg-hhh 535 | < 536 | In this example, 537 | the first and second separators are "|", 538 | the third separator is "&", and 539 | the fourth separator is "-", 540 | 541 | (cycling) 542 | the fifth and sixth separators are "|", 543 | the seventh separator is "&", and 544 | the eighth separator is "-", etc. 545 | 546 | Thus the first "&"s are (not yet) separators, and hence are treated as 547 | part of the field. Ignoring white space for the moment, the AlignCtrl 548 | shown here means that Align will work with > 549 | 550 | field | field | field & field - field | field | field & field - ... 551 | < 552 | 553 | --- *alignctrl-<* 554 | <>| SEPARATOR JUSTIFICATION *alignctrl->* {{{3 555 | --- *alignctrl-|* 556 | 557 | Separators may be of differing lengths as shown in the example below. 558 | Hence they too may be justified left, right, or centered. 559 | Furthermore, separator justification specifications are cyclic: 560 | 561 | < means <<<<<... justify separator(s) to the left 562 | > means >>>>>... justify separator(s) to the right 563 | | means |||||... center separator(s) 564 | 565 | Example: Separator Justification: Align -\+ > 566 | +-----------------+ 567 | | Original | 568 | +-----------------+ 569 | | a - bbb - c | 570 | | aa -- bb -- ccc | 571 | | aaa --- b --- cc| 572 | +---------------------+-+-----------------+-+---------------------+ 573 | | AlignCtrl < | AlignCtrl > | AlignCtrl | | 574 | +---------------------+---------------------+---------------------+ 575 | | a - bbb - c | a - bbb - c | a - bbb - c | 576 | | aa -- bb -- ccc | aa -- bb -- ccc | aa -- bb -- ccc | 577 | | aaa --- b --- cc | aaa --- b --- cc | aaa --- b --- cc | 578 | +---------------------+---------------------+---------------------+ 579 | < 580 | 581 | --- *alignctrl-g* 582 | gv SELECTIVE APPLICATION *alignctrl-v* {{{3 583 | --- 584 | 585 | 586 | These two options provide a way to select (g) or to deselect (v) lines 587 | based on a pattern. Ideally :g/pat/Align would work; unfortunately 588 | it results in Align#Align() being called on each line satisfying the 589 | pattern separately. > 590 | 591 | AlignCtrl g pattern 592 | < 593 | Align will only consider those lines which have the given pattern. > 594 | 595 | AlignCtrl v pattern 596 | < 597 | Align will only consider those lines without the given pattern. As an 598 | example of use, consider the following example: > 599 | 600 | :AlignCtrl v ^\s*/\* 601 | Original :Align = :Align = 602 | +----------------+------------------+----------------+ 603 | |one= 2; |one = 2; |one = 2; | 604 | |three= 4; |three = 4; |three = 4; | 605 | |/* skip=this */ |/* skip = this */ |/* skip=this */ | 606 | |five= 6; |five = 6; |five = 6; | 607 | +----------------+------------------+----------------+ 608 | < 609 | The first "Align =" aligned with all "="s, including that one in the 610 | "skip=this" comment. 611 | 612 | The second "Align =" had a AlignCtrl v-pattern which caused it to skip 613 | (ignore) the "skip=this" line when aligning. 614 | 615 | To remove AlignCtrl's g and v patterns, use (as appropriate) > 616 | 617 | AlignCtrl g 618 | AlignCtrl v 619 | < 620 | To see what g/v patterns are currently active, just use the reporting 621 | capability of an unadorned call to AlignCtrl: > 622 | 623 | AlignCtrl 624 | < 625 | 626 | --- 627 | m MAP SUPPORT *alignctrl-m* {{{3 628 | --- 629 | 630 | This option primarily supports the development of maps. The 631 | Align#AlignCtrl() call will first do an Align#AlignPush() (ie. retain 632 | current alignment control settings). The next Align#Align() will, in 633 | addition to its alignment job, finish up with an Align#AlignPop(). 634 | Thus the Align#AlignCtrl settings that follow the "m" are only 635 | temporarily in effect for just the next Align#Align(). 636 | 637 | 638 | --- 639 | p### *alignctrl-p* 640 | P### PADDING *alignctrl-P* {{{3 641 | --- 642 | 643 | These two options control pre-padding and post-padding with blanks 644 | about the separator. One may pad separators with zero to nine spaces; 645 | the padding number(s) is/are treated as a cyclic parameter. Thus one 646 | may specify padding separately for each field or re-use a padding 647 | pattern. > 648 | 649 | Example: AlignCtrl p102P0 650 | +---------+----------------------------------+ 651 | | Original| a=b=c=d=e=f=g=h=1 | 652 | | Align = | a =b=c =d =e=f =g =h=1 | 653 | +---------+----------------------------------+ 654 | | prepad | 1 0 2 1 0 2 1 0 | 655 | +---------+----------------------------------+ 656 | < 657 | This example will cause Align to: 658 | 659 | pre-pad the first "=" with a single blank, 660 | pre-pad the second "=" with no blanks, 661 | pre-pad the third "=" with two blanks, 662 | pre-pad the fourth "=" with a single blank, 663 | pre-pad the fifth "=" with no blanks, 664 | pre-pad the sixth "=" with two blanks, 665 | etc. 666 | 667 | --------------- *alignctrl-settings* 668 | No option given DISPLAY STATUS *alignctrl-* {{{3 669 | --------------- *alignctrl-no-option* 670 | 671 | AlignCtrl, when called with no arguments, will display the current 672 | alignment control settings. A typical display is shown below: > 673 | 674 | AlignCtrl<=> qty=1 AlignStyle Padding<1|1> 675 | Pat1<\(=\)> 676 | < 677 | Interpreting, this means that the separator patterns are all 678 | equivalent; in this case, there's only one (qty=1). Fields will be 679 | padded on the right with spaces (left justification), and separators 680 | will be padded on each side with a single space. 681 | 682 | To change one of these items, see: 683 | 684 | AlignCtrl......|alignctrl| 685 | qty............|align-concept| 686 | AlignStyle.....|alignctrl--| |alignctrl-+| |alignctrl-:||alignctrl-c| 687 | Padding........|alignctrl-p| |alignctrl-P| 688 | 689 | One may get a string which can be fed back into AlignCtrl: > 690 | 691 | :let alignctrl= Align#AlignCtrl() 692 | < 693 | This form will put a string describing the current AlignCtrl options, 694 | except for the "g" and "v" patterns, into a variable. The 695 | Align#AlignCtrl() function will still echo its settings, however. One 696 | can feed any non-supported "option" to AlignCtrl() to prevent this, 697 | however: > 698 | 699 | :let alignctrl= Align#AlignCtrl("d") 700 | < 701 | 702 | ALIGNMENT *align-align* {{{2 703 | 704 | Once the alignment control has been determined, the user specifies a 705 | range of lines for the Align command/function to do its thing. 706 | Alignment is often done on a line-range basis, but one may also 707 | restrict alignment to a visual block using ctrl-v. For any visual 708 | mode, one types the colon (:) and then "Align". One may, of course, 709 | specify a range of lines: > 710 | 711 | :[range]Align [list-of-separators] 712 | < 713 | where the |:range| is the usual Vim-powered set of possibilities; the 714 | list of separators is the same as the AlignCtrl capability. There is 715 | only one list of separators, but either AlignCtrl or Align can be used 716 | to specify that list. 717 | 718 | An alternative form of the Align command can handle both alignment 719 | control and the separator list: > 720 | 721 | :[range]Align! [alignment-control-string] [list-of-separators] 722 | < 723 | The alignment control string will be applied only for this particular 724 | application of Align (it uses |alignctrl-m|). The "g pattern" and 725 | "v pattern" alignment controls (see |alignctrl-g| and |alignctrl-v|) 726 | are also available via this form of the Align command. 727 | 728 | Align makes two passes over the text to be aligned. The first pass 729 | determines how many fields there are and determines the maximum sizes 730 | of each field; these sizes are then stored in a vector. The second 731 | pass pads the field (left/right/centered as specified) to bring its 732 | length up to the maximum size of the field. Then the separator and 733 | its AlignCtrl-specified padding is appended. 734 | 735 | Pseudo-Code:~ 736 | During pass 1 737 | | For all fields in the current line 738 | || Determine current separator 739 | || Examine field specified by current separator 740 | || Determine length of field and save if largest thus far 741 | Initialize newline based on initial whitespace option (wWI) 742 | During pass 2 743 | | For all fields in current line 744 | || Determine current separator 745 | || Extract field specified by current separator 746 | || Prepend/append padding as specified by AlignCtrl 747 | || (right/left/center)-justify to fit field into max-size field 748 | || Append separator with AlignCtrl-specified separator padding 749 | || Delete current line, install newly aligned line 750 | 751 | The g and v AlignCtrl patterns cause the passes not to consider lines 752 | for alignment, either by requiring that the g-pattern be present or 753 | that the v-pattern not be present. 754 | 755 | The whitespace on either side of a separator is ignored. 756 | 757 | 758 | ============================================================================== 759 | 4. Alignment Maps *alignmaps* *align-maps* {{{1 760 | 761 | There are a number of maps using Align#AlignCtrl() and Align#Align() 762 | in the file. This file may also be put into the 763 | plugins subdirectory. Since AlignCtrl and Align supercede textab and 764 | its file, the maps either have a leading "t" (for 765 | "textab") or the more complicated ones an "a" (for "alignment") for 766 | backwards compatibility. 767 | 768 | The maps are shown below with a leading backslash (\). Actually, the 769 | construct is used (see |mapleader|), so the maps' leading 770 | kick-off character is easily customized. 771 | 772 | Furthermore, all AlignMapsPlugin.vim maps use the construct (see 773 | ||and |usr_41.txt|). Hence, if one wishes to override the 774 | mapping entirely, one may do that, too. As an example: > 775 | map ACOM AM_acom 776 | < would have \ACOM do what \acom previously did (assuming that the 777 | mapleader has been left at its default value of a backslash). 778 | 779 | \a, : useful for breaking up comma-separated 780 | declarations prior to \adec |alignmap-a,| 781 | \a( : aligns ( and , (useful for prototypes) *alignmap-a(* 782 | \a? : aligns (...)? ...:... expressions on ? and : |alignmap-a?| 783 | \a< : aligns << and >> for c++ |alignmap-a<| 784 | \a= : aligns := assignments |alignmap-a=| 785 | \abox : draw a C-style comment box around text lines |alignmap-abox| 786 | \acom : useful for aligning comments |alignmap-acom| 787 | \adcom: useful for aligning comments in declarations |alignmap-adcom| 788 | \anum : useful for aligning numbers |alignmap-anum| 789 | NOTE: For the visual-mode use of \anum, is needed! 790 | See http://mysite.verizon.net/astronaut/vim/index.html#VIS 791 | \aenum: align a European-style number |alignmap-anum| 792 | \aunum: align a USA-style number |alignmap-anum| 793 | \adec : useful for aligning declarations |alignmap-adec| 794 | \adef : useful for aligning definitions |alignmap-adef| 795 | \afnc : useful for aligning ansi-c style functions' 796 | argument lists |alignmap-afnc| 797 | \adcom: a variant of \acom, restricted to comment |alignmap-adcom| 798 | containing lines only, but also only for 799 | those which don't begin with a comment. 800 | Good for certain declaration styles. 801 | \aocom: a variant of \acom, restricted to comment |alignmap-aocom| 802 | containing lines only 803 | \tab : align a table based on tabs *alignmap-tab* 804 | (converts to spaces) 805 | \tml : useful for aligning the trailing backslashes |alignmap-tml| 806 | used to continue lines (shell programming, etc) 807 | \tsp : use Align to make a table separated by blanks |alignmap-tsp| 808 | (left justified) 809 | \ts, : like \t, but swaps whitespace on the right of *alignmap-ts,* 810 | the commas to their left 811 | \ts: : like \t: but swaps whitespace on the right of *alignmap-ts:* 812 | the colons to their left 813 | \ts< : like \t< but swaps whitespace on the right of *alignmap-ts<* 814 | the less-than signs to their left 815 | \ts= : like \t= but swaps whitespace on the right of *alignmap-ts=* 816 | the equals signs to their left 817 | \Tsp : use Align to make a table separated by blanks |alignmap-Tsp| 818 | (right justified) 819 | \tsq : use Align to make a table separated by blanks |alignmap-tsq| 820 | (left justified) -- "strings" are not split up 821 | \tt : useful for aligning LaTeX tabular tables |alignmap-tt| 822 | \Htd : tabularizes html tables: |alignmap-Htd| 823 | ...field... ...field... 824 | 825 | *alignmap-t|* *alignmap-t#* *alignmap-t,* *alignmap-t:* 826 | *alignmap-t;* *alignmap-t<* *alignmap-t?* *alignmap-t~* 827 | *alignmap-m=* 828 | \tx : make a left-justified alignment on 829 | character "x" where "x" is: ,:<=@|# |alignmap-t=| 830 | \Tx : make a right-justified alignment on 831 | character "x" where "x" is: ,:<=@# |alignmap-T=| 832 | \m= : like \t= but aligns with %... style comments 833 | 834 | The leading backslash is actually (see |mapleader| for how to 835 | customize the leader to be whatever you like). These maps use the 836 | package and are defined in the file. 837 | Although the maps use AlignCtrl options, they typically use the "m" 838 | option which pushes the options (AlignPush). The associated Align 839 | call which follows will then AlignPop the user's original options 840 | back. 841 | 842 | ALIGNMENT MAP USE WITH MARK AND MOVE~ 843 | In the examples below, one may select the text with a "ma" at the 844 | first line, move to the last line, then execute the map. 845 | 846 | ALIGNMENT MAP USE WITH VISUAL MODE~ 847 | Alternatively, one may select the text with the "V" visual mode 848 | command. 849 | 850 | ALIGNMENT MAP USE WITH MENUS~ 851 | One may use the mark-and-move style (ma, move, use the menu) or 852 | the visual mode style (use the V visual mode, move, then select 853 | the alignment map with menu selection). The alignment map menu 854 | items are under DrChip.AlignMaps . 855 | 856 | One may even change the top level menu name to whatever is wished; by 857 | default, its > 858 | let g:DrChipTopLvlMenu= "DrChip." 859 | < If you set the variable to the empty string (""), then no menu items 860 | will be produced. Of course, one must have a vim with +menu, the gui 861 | must be running, and |'go'| must have the menu bar suboption (ie. m 862 | must be included). 863 | 864 | COMPLEX ALIGNMENT MAP METHOD~ 865 | 866 | For those complex alignment maps which do alignment on constructs 867 | (e.g. \acom, \adec, etc), a series of substitutes is used to insert 868 | "@" symbols in appropriate locations. Align#Align() is then used to 869 | do alignment directly on "@"s; then it is followed by further 870 | substitutes to do clean-up. However, the maps \WS and \WE, used by 871 | every map supported by AlignMaps, protect any original embedded "@" 872 | symbols by first converting them to characters, doing the 873 | requested job, and then converting them back. > 874 | 875 | \WS calls AlignMaps#WrapperStart() 876 | \WE calls AlignMaps#WrapperEnd() 877 | < 878 | 879 | --------------------------- 880 | Alignment Map Examples: \a, *alignmap-a,* {{{3 881 | --------------------------- 882 | 883 | Original: illustrates comma-separated declaration splitting: > 884 | int a,b,c; 885 | struct ABC_str abc,def; 886 | < 887 | Becomes: > 888 | int a; 889 | int b; 890 | int c; 891 | struct ABC_str abc; 892 | struct ABC_str def; 893 | < 894 | 895 | --------------------------- 896 | Alignment Map Examples: \a? *alignmap-a?* {{{3 897 | --------------------------- 898 | 899 | Original: illustrates ()?: aligning > 900 | printf("<%s>\n", 901 | (x == ABC)? "abc" : 902 | (x == DEFG)? "defg" : 903 | (x == HIJKL)? "hijkl" : "???"); 904 | < 905 | Becomes: select "(x == ..." lines, then \a? > 906 | printf("<%s>\n", 907 | (x == ABC)? "abc" : 908 | (x == DEFG)? "defg" : 909 | (x == HIJKL)? "hijkl" : "???"); 910 | < 911 | 912 | --------------------------- 913 | Alignment Map Examples: \a< *alignmap-a<* {{{3 914 | --------------------------- 915 | 916 | Original: illustrating aligning of << and >> > 917 | cin << x; 918 | cin << y; 919 | cout << "this is x=" << x; 920 | cout << "but y=" << y << "is not"; 921 | < 922 | Becomes: select "(x == ..." lines, then \a< > 923 | cin << x; 924 | cin << y; 925 | cout << "this is x=" << x; 926 | cout << "but y=" << y << "is not"; 927 | < 928 | 929 | --------------------------- 930 | Alignment Map Examples: \a= *alignmap-a=* {{{3 931 | --------------------------- 932 | 933 | Original: illustrates how to align := assignments > 934 | aa:=bb:=cc:=1; 935 | a:=b:=c:=1; 936 | aaa:=bbb:=ccc:=1; 937 | < 938 | Bcomes: select the three assignment lines, then \a:= > 939 | aa := bb := cc := 1; 940 | a := b := c := 1; 941 | aaa := bbb := ccc := 1; 942 | < 943 | 944 | --------------------------- 945 | Alignment Map Examples: \abox *alignmap-abox* {{{3 946 | --------------------------- 947 | 948 | Original: illustrates how to comment-box some text > 949 | This is some plain text 950 | which will 951 | soon be surrounded by a 952 | comment box. 953 | < 954 | Becomes: Select "This..box." with ctrl-v, press \abox > 955 | /*************************** 956 | * This is some plain text * 957 | * which will * 958 | * soon be surrounded by a * 959 | * comment box. * 960 | ***************************/ 961 | < 962 | 963 | --------------------------- 964 | Alignment Map Examples: \acom *alignmap-acom* {{{3 965 | --------------------------- 966 | 967 | Original: illustrates aligning C-style comments (works for //, too) > 968 | if(itworks) { /* this */ 969 | then= dothis; /* is a */ 970 | } /* set of three comments */ 971 | < 972 | Becomes: Select the three lines, press \acom > 973 | if(itworks) { /* this */ 974 | then= dothis; /* is a */ 975 | } /* set of three comments */ 976 | < 977 | Also see |alignmap-aocom| 978 | 979 | 980 | --------------------------- 981 | Alignment Map Examples: \anum *alignmap-anum* {{{3 982 | --------------------------- 983 | 984 | Original: illustrates how to get numbers lined up > 985 | -1.234 .5678 -.901e-4 986 | 1.234 5.678 9.01e-4 987 | 12.34 56.78 90.1e-4 988 | 123.4 567.8 901.e-4 989 | < 990 | Becomes: Go to first line, ma. Go to last line, press \anum > 991 | -1.234 .5678 -.901e-4 992 | 1.234 5.678 9.01e-4 993 | 12.34 56.78 90.1e-4 994 | 123.4 567.8 901.e-4 995 | < 996 | Original: > 997 | | -1.234 .5678 -.901e-4 | 998 | | 1.234 5.678 9.01e-4 | 999 | | 12.34 56.78 90.1e-4 | 1000 | | 123.4 567.8 901.e-4 | 1001 | < 1002 | Becomes: Select the numbers with ctrl-v (visual-block mode), > 1003 | press \anum 1004 | | -1.234 .5678 -.901e-4 | 1005 | | 1.234 5.678 9.01e-4 | 1006 | | 12.34 56.78 90.1e-4 | 1007 | | 123.4 567.8 901.e-4 | 1008 | < 1009 | Original: > 1010 | -1,234 ,5678 -,901e-4 1011 | 1,234 5,678 9,01e-4 1012 | 12,34 56,78 90,1e-4 1013 | 123,4 567,8 901,e-4 1014 | < 1015 | Becomes: Go to first line, ma. Go to last line, press \anum > 1016 | -1,234 ,5678 -,901e-4 1017 | 1,234 5,678 9,01e-4 1018 | 12,34 56,78 90,1e-4 1019 | 123,4 567,8 901,e-4 1020 | < 1021 | In addition: 1022 | \aenum is provided to support European-style numbers 1023 | \aunum is provided to support USA-style numbers 1024 | 1025 | One may get \aenum behavior for \anum > 1026 | let g:alignmaps_euronumber= 1 1027 | < or \aunum behavior for \anum if one puts > 1028 | let g:alignmaps_usanumber= 1 1029 | < in one's <.vimrc>. 1030 | 1031 | 1032 | --------------------------- 1033 | Alignment Map Examples: \ascom *alignmap-ascom* {{{3 1034 | --------------------------- 1035 | 1036 | Original: > 1037 | /* A Title */ 1038 | int x; /* this is a comment */ 1039 | int yzw; /* this is another comment*/ 1040 | < 1041 | Becomes: Select the three lines, press \ascom > 1042 | /* A Title */ 1043 | int x; /* this is a comment */ 1044 | int yzw; /* this is another comment */ 1045 | < 1046 | 1047 | --------------------------- 1048 | Alignment Map Examples: \adec *alignmap-adec* {{{3 1049 | --------------------------- 1050 | 1051 | Original: illustrates how to clean up C/C++ declarations > 1052 | int a; 1053 | float b; 1054 | double *c=NULL; 1055 | char x[5]; 1056 | struct abc_str abc; 1057 | struct abc_str *pabc; 1058 | int a; /* a */ 1059 | float b; /* b */ 1060 | double *c=NULL; /* b */ 1061 | char x[5]; /* x[5] */ 1062 | struct abc_str abc; /* abc */ 1063 | struct abc_str *pabc; /* pabc */ 1064 | static int a; /* a */ 1065 | static float b; /* b */ 1066 | static double *c=NULL; /* b */ 1067 | static char x[5]; /* x[5] */ 1068 | static struct abc_str abc; /* abc */ 1069 | static struct abc_str *pabc; /* pabc */ 1070 | < 1071 | Becomes: Select the declarations text, then \adec > 1072 | int a; 1073 | float b; 1074 | double *c = NULL; 1075 | char x[5]; 1076 | struct abc_str abc; 1077 | struct abc_str *pabc; 1078 | int a; /* a */ 1079 | float b; /* b */ 1080 | double *c = NULL; /* b */ 1081 | char x[5]; /* x[5] */ 1082 | struct abc_str abc; /* abc */ 1083 | struct abc_str *pabc; /* pabc */ 1084 | static int a; /* a */ 1085 | static float b; /* b */ 1086 | static double *c = NULL; /* b */ 1087 | static char x[5]; /* x[5] */ 1088 | static struct abc_str abc; /* abc */ 1089 | static struct abc_str *pabc; /* pabc */ 1090 | < 1091 | 1092 | --------------------------- 1093 | Alignment Map Examples: \adef *alignmap-adef* {{{3 1094 | --------------------------- 1095 | 1096 | Original: illustrates how to line up #def'initions > 1097 | #define ONE 1 1098 | #define TWO 22 1099 | #define THREE 333 1100 | #define FOUR 4444 1101 | < 1102 | Becomes: Select four definition lines, apply \adef > 1103 | # define ONE 1 1104 | # define TWO 22 1105 | # define THREE 333 1106 | # define FOUR 4444 1107 | < 1108 | 1109 | --------------------------- 1110 | Alignment Map Examples: \afnc *alignmap-afnc* {{{3 1111 | --------------------------- 1112 | 1113 | This map is an exception to the usual selection rules. 1114 | It uses "]]" to find the function body's leading "{". 1115 | Just put the cursor anywhere in the function arguments and 1116 | the entire function declaration should be processed. 1117 | 1118 | Because "]]" looks for that "{" in the first column, the 1119 | "original" and "becomes" examples are in the first column, 1120 | too. 1121 | 1122 | Original: illustrates lining up ansi-c style function definitions > 1123 | int f( 1124 | struct abc_str ***a, /* one */ 1125 | long *b, /* two */ 1126 | int c) /* three */ 1127 | { 1128 | } 1129 | < 1130 | Becomes: put cursor anywhere before the '{', press \afnc > 1131 | int f( 1132 | struct abc_str ***a, /* one */ 1133 | long *b, /* two */ 1134 | int c) /* three */ 1135 | { 1136 | } 1137 | < 1138 | 1139 | --------------------------- 1140 | Alignment Map Examples: \adcom *alignmap-adcom* {{{3 1141 | --------------------------- 1142 | 1143 | Original: illustrates aligning comments that don't begin 1144 | lines (optionally after some whitespace). > 1145 | struct { 1146 | /* this is a test */ 1147 | int x; /* of how */ 1148 | double y; /* to use adcom */ 1149 | }; 1150 | < 1151 | Becomes: Select the inside lines of the structure, 1152 | then press \adcom. The comment-only 1153 | line is ignored but the other two comments 1154 | get aligned. > 1155 | struct { 1156 | /* this is a test */ 1157 | int x; /* of how */ 1158 | double y; /* to use adcom */ 1159 | }; 1160 | < 1161 | 1162 | --------------------------- 1163 | Alignment Map Examples: \aocom *alignmap-aocom* {{{3 1164 | --------------------------- 1165 | 1166 | Original: illustrates how to align C-style comments (works for //, too) 1167 | but restricted only to aligning with those lines containing 1168 | comments. See the difference from \acom (|alignmap-acom|). > 1169 | if(itworks) { /* this comment */ 1170 | then= dothis; 1171 | } /* only appears on two lines */ 1172 | < 1173 | Becomes: Select the three lines, press \aocom > 1174 | if(itworks) { /* this comment */ 1175 | then= dothis; 1176 | } /* only appears on two lines */ 1177 | < 1178 | Also see |alignmap-acom| 1179 | 1180 | 1181 | --------------------------- *alignmap-Tsp* 1182 | Alignment Map Examples: \tsp *alignmap-tsp* {{{3 1183 | --------------------------- 1184 | 1185 | Normally Align can't use white spaces for field separators as such 1186 | characters are ignored surrounding field separators. The \tsp and 1187 | \Tsp maps get around this limitation. 1188 | 1189 | Original: > 1190 | one two three four five 1191 | six seven eight nine ten 1192 | eleven twelve thirteen fourteen fifteen 1193 | < 1194 | Becomes: Select the lines, \tsp > 1195 | one two three four five 1196 | six seven eight nine ten 1197 | eleven twelve thirteen fourteen fifteen 1198 | < 1199 | Becomes: Select the lines, \Tsp > 1200 | one two three four five 1201 | six seven eight nine ten 1202 | eleven twelve thirteen fourteen fifteen 1203 | < 1204 | 1205 | --------------------------- 1206 | Alignment Map Examples: \tsq *alignmap-tsq* {{{3 1207 | --------------------------- 1208 | 1209 | The \tsp map is useful for aligning tables based on white space, 1210 | but sometimes one wants double-quoted strings to act as a single 1211 | object in spite of embedded spaces. The \tsq map was invented 1212 | to support this. (thanks to Leif Wickland) 1213 | 1214 | Original: > 1215 | "one two" three 1216 | four "five six" 1217 | < 1218 | Becomes: Select the lines, \tsq > 1219 | "one two" three 1220 | four "five six" 1221 | < 1222 | 1223 | --------------------------- 1224 | Alignment Map Examples: \tt *alignmap-tt* {{{3 1225 | --------------------------- 1226 | 1227 | Original: illustrates aligning a LaTex Table > 1228 | \begin{tabular}{||c|l|r||} 1229 | \hline\hline 1230 | one&two&three\\ \hline 1231 | four&five&six\\ 1232 | seven&eight&nine\\ 1233 | \hline\hline 1234 | \end{tabular} 1235 | < 1236 | Becomes: Select the three lines inside the table > 1237 | (ie. one..,four..,seven..) and press \tt 1238 | \begin{tabular}{||c|l|r||} 1239 | \hline\hline 1240 | one & two & three \\ \hline 1241 | four & five & six \\ 1242 | seven & eight & nine \\ 1243 | \hline\hline 1244 | \end{tabular} 1245 | < 1246 | 1247 | ---------------------------- 1248 | Alignment Map Examples: \tml *alignmap-tml* {{{3 1249 | ---------------------------- 1250 | 1251 | Original: illustrates aligning multi-line continuation marks > 1252 | one \ 1253 | two three \ 1254 | four five six \ 1255 | seven \\ \ 1256 | eight \nine \ 1257 | ten \ 1258 | < 1259 | Becomes: > 1260 | one \ 1261 | two three \ 1262 | four five six \ 1263 | seven \\ \ 1264 | eight \nine \ 1265 | ten \ 1266 | < 1267 | 1268 | --------------------------- 1269 | Alignment Map Examples: \t= *alignmap-t=* {{{3 1270 | --------------------------- 1271 | 1272 | Original: illustrates left-justified aligning of = > 1273 | aa=bb=cc=1;/*one*/ 1274 | a=b=c=1;/*two*/ 1275 | aaa=bbb=ccc=1;/*three*/ 1276 | < 1277 | Becomes: Select the three equations, press \t= > 1278 | aa = bb = cc = 1; /* one */ 1279 | a = b = c = 1; /* two */ 1280 | aaa = bbb = ccc = 1; /* three */ 1281 | < 1282 | 1283 | --------------------------- 1284 | Alignment Map Examples: \T= *alignmap-T=* {{{3 1285 | --------------------------- 1286 | 1287 | Original: illustrates right-justified aligning of = > 1288 | aa=bb=cc=1; /* one */ 1289 | a=b=c=1; /* two */ 1290 | aaa=bbb=ccc=1; /* three */ 1291 | < 1292 | Becomes: Select the three equations, press \T= > 1293 | aa = bb = cc = 1; /* one */ 1294 | a = b = c = 1; /* two */ 1295 | aaa = bbb = ccc = 1; /* three */ 1296 | < 1297 | 1298 | --------------------------- 1299 | Alignment Map Examples: \Htd *alignmap-Htd* {{{3 1300 | --------------------------- 1301 | 1302 | Original: for aligning tables with html > 1303 | ...field one......field two... 1304 | ...field three......field four... 1305 | < 1306 | Becomes: Select ... lines, press \Htd > 1307 | ...field one... ...field two... 1308 | ...field three... ...field four... 1309 | < 1310 | ============================================================================== 1311 | 4. Alignment Tools' History *align-history* {{{1 1312 | 1313 | ALIGN HISTORY {{{2 1314 | 35 : Nov 02, 2008 * g:loaded_AlignPlugin testing to prevent re-loading 1315 | installed 1316 | Nov 19, 2008 * new sanity check for an AlignStyle of just ":" 1317 | Jan 08, 2009 * save&restore of |'mod'| now done with local 1318 | variant 1319 | 34 : Jul 08, 2008 * using :AlignCtrl before entering any alignment 1320 | control commands was causing an error. 1321 | 33 : Sep 20, 2007 * s:Strlen() introduced to support various ways 1322 | used to represent characters and their effects 1323 | on string lengths. See |align-strlen|. 1324 | * Align now accepts "..." -- so it can accept 1325 | whitespace as separators. 1326 | 32 : Aug 18, 2007 * uses || instead of || plus a 1327 | custom argument splitter to allow patterns with 1328 | backslashes to slide in unaltered. 1329 | 31 : Aug 06, 2007 * :[range]Align! [AlignCtrl settings] pattern(s) 1330 | implemented. 1331 | 30 : Feb 12, 2007 * now uses |setline()| 1332 | 29 : Jan 18, 2006 * cecutil updated to use keepjumps 1333 | Feb 23, 2006 * Align now converted to vim 7.0 style using 1334 | auto-loading functions. 1335 | 28 : Aug 17, 2005 * report option workaround 1336 | Oct 24, 2005 * AlignCtrl l: wasn't behaving as expected; fixed 1337 | 27 : Apr 15, 2005 : cpo workaround 1338 | ignorecase workaround 1339 | 26 : Aug 20, 2004 : loaded_align now also indicates version number 1340 | GetLatestVimScripts :AutoInstall: now supported 1341 | 25 : Jul 27, 2004 : For debugging, uses Dfunc(), Dret(), and Decho() 1342 | 24 : Mar 03, 2004 : (should've done this earlier!) visualmode(1) 1343 | not supported until v6.2, now Align will avoid 1344 | calling it for earlier versions. Visualmode 1345 | clearing won't take place then, of course. 1346 | 23 : Oct 07, 2003 : Included Leif Wickland's ReplaceQuotedSpaces() 1347 | function which supports \tsq 1348 | 22 : Jan 29, 2003 : Now requires 6.1.308 or later to clear visualmode() 1349 | 21 : Jan 10, 2003 : BugFix: similar problem to #19; new code 1350 | bypasses "norm! v\" until initialization 1351 | is over. 1352 | 20 : Dec 30, 2002 : BugFix: more on "unable to highlight" fixed 1353 | 19 : Nov 21, 2002 : BugFix: some terminals gave an "unable to highlight" 1354 | message at startup; Hari Krishna Dara tracked it 1355 | down; a silent! now included to prevent noise. 1356 | 18 : Nov 04, 2002 : BugFix: re-enabled anti-repeated-loading 1357 | 17 : Nov 04, 2002 : BugFix: forgot to have AlignPush() push s:AlignSep 1358 | AlignCtrl now clears visual-block mode when used so 1359 | that Align won't try to use old visual-block 1360 | selection marks '< '> 1361 | 16 : Sep 18, 2002 : AlignCtrl <>| options implemented (separator 1362 | justification) 1363 | 15 : Aug 22, 2002 : bug fix: AlignCtrl's ":" now acts as a modifier of 1364 | the preceding alignment operator (lrc) 1365 | 14 : Aug 20, 2002 : bug fix: AlignCtrl default now keeps &ic unchanged 1366 | bug fix: Align, on end-field, wasn't using correct 1367 | alignop bug fix: Align, on end-field, was appending 1368 | padding 1369 | 13 : Aug 19, 2002 : bug fix: zero-length g/v patterns are accepted 1370 | bug fix: always skip blank lines 1371 | bug fix: AlignCtrl default now also clears g and v 1372 | patterns 1373 | 12 : Aug 16, 2002 : moved keep_ic above zero-length pattern checks 1374 | added "AlignCtrl default" 1375 | fixed bug with last field getting separator spaces 1376 | at end line 1377 | 11 : Jul 08, 2002 : prevent separator patterns which match zero length 1378 | -+: included as additional alignment/justification 1379 | styles 1380 | 10 : Jun 26, 2002 : =~# used instead of =~ (for matching case) 1381 | ignorecase option handled 1382 | 9 : Jun 25, 2002 : implemented cyclic padding 1383 | 1384 | ALIGNMENT MAP HISTORY *alignmap-history* {{{2 1385 | v41 Nov 02, 2008 * g:loaded_AlignMapsPlugin testing to prevent 1386 | re-loading installed 1387 | * AlignMaps now use 0x0f (ctrl-p) for special 1388 | character substitutions (instead of 0xff). 1389 | Seems to avoid some problems with having to 1390 | use Strlen(). 1391 | * bug fixed with \ts, 1392 | * new maps: \ts; \ts, \ts: \ts< \ts= \a( 1393 | v40 Oct 21, 2008 * Modified AlignMaps so that its maps use s 1394 | and