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