1" Vim indent file 2" Language: PHP 3" Author: John Wellesz <John.wellesz (AT) teaser (DOT) fr> 4" URL: http://www.2072productions.com/vim/indent/php.vim 5" Home: https://github.com/2072/PHP-Indenting-for-VIm 6" Last Change: 2015 September 8th 7" Version: 1.60 8" 9" 10" Type :help php-indent for available options 11" 12" A fully commented version of this file is available on github 13" 14" 15" If you find a bug, please open a ticket on github.org 16" ( https://github.com/2072/PHP-Indenting-for-VIm/issues ) with an example of 17" code that breaks the algorithm. 18" 19 20" NOTE: This script must be used with PHP syntax ON and with the php syntax 21" script by Lutz Eymers (http://www.isp.de/data/php.vim ) or with the 22" script by Peter Hodge (http://www.vim.org/scripts/script.php?script_id=1571 ) 23" the later is bunbdled by default with Vim 7. 24" 25" 26" In the case you have syntax errors in your script such as HereDoc end 27" identifiers not at col 1 you'll have to indent your file 2 times (This 28" script will automatically put HereDoc end identifiers at col 1 if 29" they are followed by a ';'). 30" 31 32" NOTE: If you are editing files in Unix file format and that (by accident) 33" there are '\r' before new lines, this script won't be able to proceed 34" correctly and will make many mistakes because it won't be able to match 35" '\s*$' correctly. 36" So you have to remove those useless characters first with a command like: 37" 38" :%s /\r$//g 39" 40" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will 41" silently remove them when VIM load this script (at each bufread). 42 43 44 45if exists("b:did_indent") 46 finish 47endif 48let b:did_indent = 1 49 50 51let g:php_sync_method = 0 52 53if exists('*shiftwidth') 54 function! s:sw() 55 return shiftwidth() 56 endfunction 57else 58 function! s:sw() 59 return &shiftwidth 60 endfunction 61endif 62 63 64if exists("PHP_default_indenting") 65 let b:PHP_default_indenting = PHP_default_indenting * s:sw() 66else 67 let b:PHP_default_indenting = 0 68endif 69 70if exists("PHP_outdentSLComments") 71 let b:PHP_outdentSLComments = PHP_outdentSLComments * s:sw() 72else 73 let b:PHP_outdentSLComments = 0 74endif 75 76if exists("PHP_BracesAtCodeLevel") 77 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel 78else 79 let b:PHP_BracesAtCodeLevel = 0 80endif 81 82 83if exists("PHP_autoformatcomment") 84 let b:PHP_autoformatcomment = PHP_autoformatcomment 85else 86 let b:PHP_autoformatcomment = 1 87endif 88 89if exists("PHP_outdentphpescape") 90 let b:PHP_outdentphpescape = PHP_outdentphpescape 91else 92 let b:PHP_outdentphpescape = 1 93endif 94 95 96if exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent 97 let b:PHP_vintage_case_default_indent = 1 98else 99 let b:PHP_vintage_case_default_indent = 0 100endif 101 102 103 104let b:PHP_lastindented = 0 105let b:PHP_indentbeforelast = 0 106let b:PHP_indentinghuge = 0 107let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 108let b:PHP_LastIndentedWasComment = 0 109let b:PHP_InsideMultilineComment = 0 110let b:InPHPcode = 0 111let b:InPHPcode_checked = 0 112let b:InPHPcode_and_script = 0 113let b:InPHPcode_tofind = "" 114let b:PHP_oldchangetick = b:changedtick 115let b:UserIsTypingComment = 0 116let b:optionsset = 0 117 118setlocal nosmartindent 119setlocal noautoindent 120setlocal nocindent 121setlocal nolisp 122 123setlocal indentexpr=GetPhpIndent() 124setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e,*<Return>,=?>,=<?,=*/ 125 126 127 128let s:searchpairflags = 'bWr' 129 130if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix 131 silent! %s/\r$//g 132endif 133 134if exists("*GetPhpIndent") 135 call ResetPhpOptions() 136 finish 137endif 138 139 140let s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' 141let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\)' 142let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|\%(}\s*\)\?else\>\|do\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|trait\>\|use\>\|interface\>\|abstract\>\|final\>\|try\>\|\%(}\s*\)\=catch\>\|\%(}\s*\)\=finally\>\)' 143let s:functionDecl = '\<function\>\%(\s\+'.s:PHP_validVariable.'\)\=\s*(.*' 144let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$' 145 146 147let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)\|^[^''"`]*[''"`]$' 148let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!' 149 150 151 152let s:escapeDebugStops = 0 153function! DebugPrintReturn(scriptLine) 154 155 if ! s:escapeDebugStops 156 echo "debug:" . a:scriptLine 157 let c = getchar() 158 if c == "\<Del>" 159 let s:escapeDebugStops = 1 160 end 161 endif 162 163endfunction 164 165function! GetLastRealCodeLNum(startline) " {{{ 166 167 let lnum = a:startline 168 169 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1 170 let lnum = b:GetLastRealCodeLNum_ADD 171 endif 172 173 while lnum > 1 174 let lnum = prevnonblank(lnum) 175 let lastline = getline(lnum) 176 177 if b:InPHPcode_and_script && lastline =~ '?>\s*$' 178 let lnum = lnum - 1 179 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$' 180 let lnum = lnum - 1 181 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' 182 let lnum = lnum - 1 183 elseif lastline =~ '\*/\s*$' 184 call cursor(lnum, 1) 185 if lastline !~ '^\*/' 186 call search('\*/', 'W') 187 endif 188 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 189 190 let lastline = getline(lnum) 191 if lastline =~ '^\s*/\*' 192 let lnum = lnum - 1 193 else 194 break 195 endif 196 197 198 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>' 199 200 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1 201 let lnum = lnum - 1 202 let lastline = getline(lnum) 203 endwhile 204 if lastline =~ '^\s*?>' 205 let lnum = lnum - 1 206 else 207 break 208 endif 209 210 211 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc 212 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '') 213 while getline(lnum) !~? tofind && lnum > 1 214 let lnum = lnum - 1 215 endwhile 216 elseif lastline =~ '^[^''"`]*[''"`][;,]'.s:endline 217 let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$', '') 218 while getline(lnum) !~? tofind && lnum > 1 219 let lnum = lnum - 1 220 endwhile 221 else 222 break 223 endif 224 endwhile 225 226 if lnum==1 && getline(lnum) !~ '<?' 227 let lnum=0 228 endif 229 230 if b:InPHPcode_and_script && 1 > b:InPHPcode 231 let b:InPHPcode_and_script = 0 232 endif 233 234 return lnum 235endfunction " }}} 236 237function! Skippmatch2() 238 239 let line = getline(".") 240 241 if line =~ "\\([\"']\\).*/\\*.*\\1" || line =~ '\%(//\|#\).*/\*' 242 return 1 243 else 244 return 0 245 endif 246endfun 247 248function! Skippmatch() " {{{ 249 let synname = synIDattr(synID(line("."), col("."), 0), "name") 250 if synname == "Delimiter" || synname == "phpRegionDelimiter" || synname =~# "^phpParent" || synname == "phpArrayParens" || synname =~# '^php\%(Block\|Brace\)' || synname == "javaScriptBraces" || synname =~# '^php\%(Doc\)\?Comment' && b:UserIsTypingComment 251 return 0 252 else 253 return 1 254 endif 255endfun " }}} 256 257function! FindOpenBracket(lnum, blockStarter) " {{{ 258 call cursor(a:lnum, 1) 259 let line = searchpair('{', '', '}', 'bW', 'Skippmatch()') 260 261 if a:blockStarter == 1 262 while line > 1 263 let linec = getline(line) 264 265 if linec =~ s:terminated || linec =~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline 266 break 267 endif 268 269 let line = GetLastRealCodeLNum(line - 1) 270 endwhile 271 endif 272 273 return line 274endfun " }}} 275 276function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{ 277 278 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>' 279 let beforeelse = a:lnum 280 else 281 let beforeelse = GetLastRealCodeLNum(a:lnum - 1) 282 endif 283 284 if !s:level 285 let s:iftoskip = 0 286 endif 287 288 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>' 289 let s:iftoskip = s:iftoskip + 1 290 endif 291 292 if getline(beforeelse) =~ '^\s*}' 293 let beforeelse = FindOpenBracket(beforeelse, 0) 294 295 if getline(beforeelse) =~ '^\s*{' 296 let beforeelse = GetLastRealCodeLNum(beforeelse - 1) 297 endif 298 endif 299 300 301 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>' 302 return beforeelse 303 endif 304 305 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1 306 307 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>' 308 let s:iftoskip = s:iftoskip - 1 309 endif 310 311 let s:level = s:level + 1 312 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse) 313 endif 314 315 return beforeelse 316 317endfunction " }}} 318 319let s:defaultORcase = '^\s*\%(default\|case\).*:' 320 321function! FindTheSwitchIndent (lnum) " {{{ 322 323 let test = GetLastRealCodeLNum(a:lnum - 1) 324 325 if test <= 1 326 return indent(1) - s:sw() * b:PHP_vintage_case_default_indent 327 end 328 329 while getline(test) =~ '^\s*}' && test > 1 330 let test = GetLastRealCodeLNum(FindOpenBracket(test, 0) - 1) 331 332 if getline(test) =~ '^\s*switch\>' 333 let test = GetLastRealCodeLNum(test - 1) 334 endif 335 endwhile 336 337 if getline(test) =~# '^\s*switch\>' 338 return indent(test) 339 elseif getline(test) =~# s:defaultORcase 340 return indent(test) - s:sw() * b:PHP_vintage_case_default_indent 341 else 342 return FindTheSwitchIndent(test) 343 endif 344 345endfunction "}}} 346 347let s:SynPHPMatchGroups = {'phpParent':1, 'Delimiter':1, 'Define':1, 'Storageclass':1, 'StorageClass':1, 'Structure':1, 'Exception':1} 348function! IslinePHP (lnum, tofind) " {{{ 349 let cline = getline(a:lnum) 350 351 if a:tofind=="" 352 let tofind = "^\\s*[\"'`]*\\s*\\zs\\S" 353 else 354 let tofind = a:tofind 355 endif 356 357 let tofind = tofind . '\c' 358 359 let coltotest = match (cline, tofind) + 1 360 361 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name") 362 363 if synname == 'phpStringSingle' || synname == 'phpStringDouble' || synname == 'phpBacktick' 364 if cline !~ '^\s*[''"`]' 365 return "SpecStringEntrails" 366 else 367 return synname 368 end 369 end 370 371 if get(s:SynPHPMatchGroups, synname) || synname =~ '^php' || synname =~? '^javaScript' 372 return synname 373 else 374 return "" 375 endif 376endfunction " }}} 377 378let s:autoresetoptions = 0 379if ! s:autoresetoptions 380 let s:autoresetoptions = 1 381endif 382 383function! ResetPhpOptions() 384 if ! b:optionsset && &filetype =~ "php" 385 if b:PHP_autoformatcomment 386 387 setlocal comments=s1:/*,mb:*,ex:*/,://,:# 388 389 setlocal formatoptions-=t 390 setlocal formatoptions+=q 391 setlocal formatoptions+=r 392 setlocal formatoptions+=o 393 setlocal formatoptions+=c 394 setlocal formatoptions+=b 395 endif 396 let b:optionsset = 1 397 endif 398endfunc 399 400call ResetPhpOptions() 401 402function! GetPhpIndent() 403 404 let b:GetLastRealCodeLNum_ADD = 0 405 406 let UserIsEditing=0 407 if b:PHP_oldchangetick != b:changedtick 408 let b:PHP_oldchangetick = b:changedtick 409 let UserIsEditing=1 410 endif 411 412 if b:PHP_default_indenting 413 let b:PHP_default_indenting = g:PHP_default_indenting * s:sw() 414 endif 415 416 let cline = getline(v:lnum) 417 418 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast 419 if b:PHP_indentbeforelast 420 let b:PHP_indentinghuge = 1 421 endif 422 let b:PHP_indentbeforelast = b:PHP_lastindented 423 endif 424 425 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented 426 if b:PHP_indentinghuge 427 let b:PHP_indentinghuge = 0 428 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 429 endif 430 let real_PHP_lastindented = v:lnum 431 let b:PHP_LastIndentedWasComment=0 432 let b:PHP_InsideMultilineComment=0 433 let b:PHP_indentbeforelast = 0 434 435 let b:InPHPcode = 0 436 let b:InPHPcode_checked = 0 437 let b:InPHPcode_and_script = 0 438 let b:InPHPcode_tofind = "" 439 440 elseif v:lnum > b:PHP_lastindented 441 let real_PHP_lastindented = b:PHP_lastindented 442 else 443 let real_PHP_lastindented = v:lnum 444 endif 445 446 let b:PHP_lastindented = v:lnum 447 448 449 if !b:InPHPcode_checked " {{{ One time check 450 let b:InPHPcode_checked = 1 451 let b:UserIsTypingComment = 0 452 453 let synname = "" 454 if cline !~ '<?.*?>' 455 let synname = IslinePHP (prevnonblank(v:lnum), "") 456 endif 457 458 if synname!="" 459 if synname == "SpecStringEntrails" 460 let b:InPHPcode = -1 461 let b:InPHPcode_tofind = "" 462 elseif synname != "phpHereDoc" && synname != "phpHereDocDelimiter" 463 let b:InPHPcode = 1 464 let b:InPHPcode_tofind = "" 465 466 if synname =~# '^php\%(Doc\)\?Comment' 467 let b:UserIsTypingComment = 1 468 let b:InPHPcode_checked = 0 469 endif 470 471 if synname =~? '^javaScript' 472 let b:InPHPcode_and_script = 1 473 endif 474 475 else 476 let b:InPHPcode = 0 477 478 let lnum = v:lnum - 1 479 while getline(lnum) !~? '<<<\s*[''"]\=\a\w*[''"]\=$' && lnum > 1 480 let lnum = lnum - 1 481 endwhile 482 483 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '') 484 endif 485 else 486 let b:InPHPcode = 0 487 let b:InPHPcode_tofind = s:PHP_startindenttag 488 endif 489 endif "!b:InPHPcode_checked }}} 490 491 492 " Test if we are indenting PHP code {{{ 493 let lnum = prevnonblank(v:lnum - 1) 494 let last_line = getline(lnum) 495 let endline= s:endline 496 497 if b:InPHPcode_tofind!="" 498 if cline =~? b:InPHPcode_tofind 499 let b:InPHPcode_tofind = "" 500 let b:UserIsTypingComment = 0 501 502 if b:InPHPcode == -1 503 let b:InPHPcode = 1 504 return -1 505 end 506 507 let b:InPHPcode = 1 508 509 if cline =~ '\*/' 510 call cursor(v:lnum, 1) 511 if cline !~ '^\*/' 512 call search('\*/', 'W') 513 endif 514 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 515 516 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 517 518 let b:PHP_LastIndentedWasComment = 0 519 520 if cline =~ '^\s*\*/' 521 return indent(lnum) + 1 522 else 523 return indent(lnum) 524 endif 525 526 elseif cline =~? '<script\>' 527 let b:InPHPcode_and_script = 1 528 let b:GetLastRealCodeLNum_ADD = v:lnum 529 endif 530 endif 531 endif 532 533 if 1 == b:InPHPcode 534 535 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter" 536 if cline !~? s:PHP_startindenttag 537 let b:InPHPcode = 0 538 let b:InPHPcode_tofind = s:PHP_startindenttag 539 elseif cline =~? '<script\>' 540 let b:InPHPcode_and_script = 1 541 endif 542 543 elseif last_line =~ '^[^''"`]\+[''"`]$' 544 let b:InPHPcode = -1 545 let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '') 546 elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$' 547 let b:InPHPcode = 0 548 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '') 549 550 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*' 551 let b:InPHPcode = 0 552 let b:InPHPcode_tofind = '\*/' 553 554 elseif cline =~? '^\s*</script>' 555 let b:InPHPcode = 0 556 let b:InPHPcode_tofind = s:PHP_startindenttag 557 endif 558 endif " }}} 559 560 561 if 1 > b:InPHPcode && !b:InPHPcode_and_script 562 return -1 563 endif 564 565 " Indent successive // or # comment the same way the first is {{{ 566 let addSpecial = 0 567 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' 568 let addSpecial = b:PHP_outdentSLComments 569 if b:PHP_LastIndentedWasComment == 1 570 return indent(real_PHP_lastindented) 571 endif 572 let b:PHP_LastIndentedWasComment = 1 573 else 574 let b:PHP_LastIndentedWasComment = 0 575 endif " }}} 576 577 " Indent multiline /* comments correctly {{{ 578 579 if b:PHP_InsideMultilineComment || b:UserIsTypingComment 580 if cline =~ '^\s*\*\%(\/\)\@!' 581 if last_line =~ '^\s*/\*' 582 return indent(lnum) + 1 583 else 584 return indent(lnum) 585 endif 586 else 587 let b:PHP_InsideMultilineComment = 0 588 endif 589 endif 590 591 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*\%(.*\*/\)\@!' 592 if getline(v:lnum + 1) !~ '^\s*\*' 593 return -1 594 endif 595 let b:PHP_InsideMultilineComment = 1 596 endif " }}} 597 598 599 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{ 600 if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape 601 return 0 602 endif 603 604 if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape 605 return 0 606 endif 607 608 if cline =~? '^\s*\a\w*;$\|^\a\w*$\|^\s*[''"`][;,]' && cline !~? s:notPhpHereDoc 609 return 0 610 endif " }}} 611 612 let s:level = 0 613 614 let lnum = GetLastRealCodeLNum(v:lnum - 1) 615 616 let last_line = getline(lnum) 617 let ind = indent(lnum) 618 619 if ind==0 && b:PHP_default_indenting 620 let ind = b:PHP_default_indenting 621 endif 622 623 if lnum == 0 624 return b:PHP_default_indenting + addSpecial 625 endif 626 627 628 if cline =~ '^\s*}\%(}}\)\@!' 629 let ind = indent(FindOpenBracket(v:lnum, 1)) 630 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 631 return ind 632 endif 633 634 if cline =~ '^\s*\*/' 635 call cursor(v:lnum, 1) 636 if cline !~ '^\*/' 637 call search('\*/', 'W') 638 endif 639 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 640 641 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 642 643 if cline =~ '^\s*\*/' 644 return indent(lnum) + 1 645 else 646 return indent(lnum) 647 endif 648 endif 649 650 651 if last_line =~ '[;}]'.endline && last_line !~ '^[)\]]' && last_line !~# s:defaultORcase 652 if ind==b:PHP_default_indenting 653 return b:PHP_default_indenting + addSpecial 654 elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline 655 return b:PHP_CurrentIndentLevel + addSpecial 656 endif 657 endif 658 659 let LastLineClosed = 0 660 661 let terminated = s:terminated 662 663 let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline 664 665 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>' 666 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 667 return indent(FindTheIfOfAnElse(v:lnum, 1)) 668 elseif cline =~# s:defaultORcase 669 return FindTheSwitchIndent(v:lnum) + s:sw() * b:PHP_vintage_case_default_indent 670 elseif cline =~ '^\s*)\=\s*{' 671 let previous_line = last_line 672 let last_line_num = lnum 673 674 while last_line_num > 1 675 676 if previous_line =~ terminated || previous_line =~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . endline 677 678 let ind = indent(last_line_num) 679 680 if b:PHP_BracesAtCodeLevel 681 let ind = ind + s:sw() 682 endif 683 684 return ind 685 endif 686 687 let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 688 let previous_line = getline(last_line_num) 689 endwhile 690 691 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline 692 let ind = ind + s:sw() 693 return ind + addSpecial 694 695 elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated 696 let previous_line = last_line 697 let last_line_num = lnum 698 let LastLineClosed = 1 699 700 let isSingleLineBlock = 0 701 while 1 702 if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline 703 704 call cursor(last_line_num, 1) 705 if previous_line !~ '^}' 706 call search('}\|;\s*}'.endline, 'W') 707 end 708 let oldLastLine = last_line_num 709 let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()') 710 711 if getline(last_line_num) =~ '^\s*{' 712 let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 713 elseif oldLastLine == last_line_num 714 let isSingleLineBlock = 1 715 continue 716 endif 717 718 let previous_line = getline(last_line_num) 719 720 continue 721 else 722 let isSingleLineBlock = 0 723 724 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>' 725 let last_line_num = FindTheIfOfAnElse(last_line_num, 0) 726 continue 727 endif 728 729 730 let last_match = last_line_num 731 732 let one_ahead_indent = indent(last_line_num) 733 let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 734 let two_ahead_indent = indent(last_line_num) 735 let after_previous_line = previous_line 736 let previous_line = getline(last_line_num) 737 738 739 if previous_line =~# s:defaultORcase.'\|{'.endline 740 break 741 endif 742 743 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline 744 break 745 endif 746 747 if one_ahead_indent == two_ahead_indent || last_line_num < 1 748 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1 749 break 750 endif 751 endif 752 endif 753 endwhile 754 755 if indent(last_match) != ind 756 let ind = indent(last_match) 757 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 758 759 return ind + addSpecial 760 endif 761 endif 762 763 if (last_line !~ '^\s*}\%(}}\)\@!') 764 let plinnum = GetLastRealCodeLNum(lnum - 1) 765 else 766 let plinnum = GetLastRealCodeLNum(FindOpenBracket(lnum, 1) - 1) 767 endif 768 769 let AntepenultimateLine = getline(plinnum) 770 771 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') 772 773 774 if ind == b:PHP_default_indenting 775 if last_line =~ terminated && last_line !~# s:defaultORcase 776 let LastLineClosed = 1 777 endif 778 endif 779 780 if !LastLineClosed 781 782 783 if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline 784 785 let dontIndent = 0 786 if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*)\s*{'.endline && last_line !~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline 787 let dontIndent = 1 788 endif 789 790 if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{') 791 let ind = ind + s:sw() 792 endif 793 794 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1 795 let b:PHP_CurrentIndentLevel = ind 796 797 return ind + addSpecial 798 endif 799 800 elseif last_line =~ '\S\+\s*),'.endline 801 call cursor(lnum, 1) 802 call search('),'.endline, 'W') 803 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') 804 if openedparent != lnum 805 let ind = indent(openedparent) 806 endif 807 808 elseif last_line =~ '^\s*'.s:blockstart 809 let ind = ind + s:sw() 810 811 812 elseif AntepenultimateLine =~ '{'.endline || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase 813 let ind = ind + s:sw() 814 endif 815 816 endif 817 818 if cline =~ '^\s*[)\]];\=' 819 let ind = ind - s:sw() 820 endif 821 822 let b:PHP_CurrentIndentLevel = ind 823 return ind + addSpecial 824endfunction 825