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" Last Change: 2007 February 25th 6" Newsletter: http://www.2072productions.com/?to=php-indent-for-vim-newsletter.php 7" Version: 1.24 8" 9" The change log and all the comments have been removed from this file. 10" 11" For a complete change log and fully commented code, download the script on 12" 2072productions.com at the URI provided above. 13" 14" If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr 15" with an example of code that breaks the algorithm. 16" 17" 18" Thanks a lot for using this script. 19" 20" 21" NOTE: This script must be used with PHP syntax ON and with the php syntax 22" script by Lutz Eymers ( http://www.isp.de/data/php.vim ) that's the script bundled with Vim. 23" 24" 25" In the case you have syntax errors in your script such as end of HereDoc 26" tags not at col 1 you'll have to indent your file 2 times (This script 27" will automatically put HereDoc end tags at col 1). 28" 29" 30" NOTE: If you are editing file in Unix file format and that (by accident) 31" there are '\r' before new lines, this script won't be able to proceed 32" correctly and will make many mistakes because it won't be able to match 33" '\s*$' correctly. 34" So you have to remove those useless characters first with a command like: 35" 36" :%s /\r$//g 37" 38" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will 39" silently remove them when VIM load this script (at each bufread). 40 41 42" Options: PHP_autoformatcomment = 0 to not enable autoformating of comment by 43" default, if set to 0, this script will let the 'formatoptions' setting intact. 44" 45" Options: PHP_default_indenting = # of sw (default is 0), # of sw will be 46" added to the indent of each line of PHP code. 47" 48" Options: PHP_removeCRwhenUnix = 1 to make the script automatically remove CR 49" at end of lines (by default this option is unset), NOTE that you 50" MUST remove CR when the fileformat is UNIX else the indentation 51" won't be correct... 52" 53" Options: PHP_BracesAtCodeLevel = 1 to indent the '{' and '}' at the same 54" level than the code they contain. 55" Exemple: 56" Instead of: 57" if ($foo) 58" { 59" foo(); 60" } 61" 62" You will write: 63" if ($foo) 64" { 65" foo(); 66" } 67" 68" NOTE: The script will be a bit slower if you use this option because 69" some optimizations won't be available. 70 71if exists("b:did_indent") 72 finish 73endif 74let b:did_indent = 1 75 76 77let php_sync_method = 0 78 79 80if exists("PHP_default_indenting") 81 let b:PHP_default_indenting = PHP_default_indenting * &sw 82else 83 let b:PHP_default_indenting = 0 84endif 85 86if exists("PHP_BracesAtCodeLevel") 87 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel 88else 89 let b:PHP_BracesAtCodeLevel = 0 90endif 91 92if exists("PHP_autoformatcomment") 93 let b:PHP_autoformatcomment = PHP_autoformatcomment 94else 95 let b:PHP_autoformatcomment = 1 96endif 97 98let b:PHP_lastindented = 0 99let b:PHP_indentbeforelast = 0 100let b:PHP_indentinghuge = 0 101let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 102let b:PHP_LastIndentedWasComment = 0 103let b:PHP_InsideMultilineComment = 0 104let b:InPHPcode = 0 105let b:InPHPcode_checked = 0 106let b:InPHPcode_and_script = 0 107let b:InPHPcode_tofind = "" 108let b:PHP_oldchangetick = b:changedtick 109let b:UserIsTypingComment = 0 110let b:optionsset = 0 111 112setlocal nosmartindent 113setlocal noautoindent 114setlocal nocindent 115setlocal nolisp 116 117setlocal indentexpr=GetPhpIndent() 118setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/ 119 120 121 122let s:searchpairflags = 'bWr' 123 124if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix 125 silent! %s/\r$//g 126endif 127 128if exists("*GetPhpIndent") 129 finish " XXX 130endif 131 132let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$' 133let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!' 134"setlocal debug=msg " XXX 135 136 137function! GetLastRealCodeLNum(startline) " {{{ 138 139 let lnum = a:startline 140 141 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1 142 let lnum = b:GetLastRealCodeLNum_ADD 143 endif 144 145 let old_lnum = lnum 146 147 while lnum > 1 148 let lnum = prevnonblank(lnum) 149 let lastline = getline(lnum) 150 151 if b:InPHPcode_and_script && lastline =~ '?>\s*$' 152 let lnum = lnum - 1 153 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$' 154 let lnum = lnum - 1 155 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' 156 let lnum = lnum - 1 157 elseif lastline =~ '\*/\s*$' 158 call cursor(lnum, 1) 159 if lastline !~ '^\*/' 160 call search('\*/', 'W') 161 endif 162 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 163 164 let lastline = getline(lnum) 165 if lastline =~ '^\s*/\*' 166 let lnum = lnum - 1 167 else 168 break 169 endif 170 171 172 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>' 173 174 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1 175 let lnum = lnum - 1 176 let lastline = getline(lnum) 177 endwhile 178 if lastline =~ '^\s*?>' 179 let lnum = lnum - 1 180 else 181 break 182 endif 183 184 185 elseif lastline =~? '^\a\w*;$' && lastline !~? s:notPhpHereDoc 186 let tofind=substitute( lastline, '\([^;]\+\);', '<<<\1$', '') 187 while getline(lnum) !~? tofind && lnum > 1 188 let lnum = lnum - 1 189 endwhile 190 else 191 break 192 endif 193 endwhile 194 195 if lnum==1 && getline(lnum)!~ '<?' 196 let lnum=0 197 endif 198 199 if b:InPHPcode_and_script && !b:InPHPcode 200 let b:InPHPcode_and_script = 0 201 endif 202 203 204 205 return lnum 206endfunction " }}} 207 208function! Skippmatch2() 209 210 let line = getline(".") 211 212 if line =~ '\%(".*\)\@<=/\*\%(.*"\)\@=' || line =~ '\%(//.*\)\@<=/\*' 213 return 1 214 else 215 return 0 216 endif 217endfun 218 219function! Skippmatch() " {{{ 220 let synname = synIDattr(synID(line("."), col("."), 0), "name") 221 if synname == "Delimiter" || synname == "phpRegionDelimiter" || synname =~# "^phpParent" || synname == "phpArrayParens" || synname =~# '^php\%(Block\|Brace\)' || synname == "javaScriptBraces" || synname == "phpComment" && b:UserIsTypingComment 222 return 0 223 else 224 return 1 225 endif 226endfun " }}} 227 228function! FindOpenBracket(lnum) " {{{ 229 call cursor(a:lnum, 1) 230 return searchpair('{', '', '}', 'bW', 'Skippmatch()') 231endfun " }}} 232 233function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{ 234 235 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>' 236 let beforeelse = a:lnum 237 else 238 let beforeelse = GetLastRealCodeLNum(a:lnum - 1) 239 endif 240 241 if !s:level 242 let s:iftoskip = 0 243 endif 244 245 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>' 246 let s:iftoskip = s:iftoskip + 1 247 endif 248 249 if getline(beforeelse) =~ '^\s*}' 250 let beforeelse = FindOpenBracket(beforeelse) 251 252 if getline(beforeelse) =~ '^\s*{' 253 let beforeelse = GetLastRealCodeLNum(beforeelse - 1) 254 endif 255 endif 256 257 258 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>' 259 return beforeelse 260 endif 261 262 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1 263 264 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>' 265 let s:iftoskip = s:iftoskip - 1 266 endif 267 268 let s:level = s:level + 1 269 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse) 270 endif 271 272 return beforeelse 273 274endfunction " }}} 275 276function! IslinePHP (lnum, tofind) " {{{ 277 let cline = getline(a:lnum) 278 279 if a:tofind=="" 280 let tofind = "^\\s*[\"']*\\s*\\zs\\S" 281 else 282 let tofind = a:tofind 283 endif 284 285 let tofind = tofind . '\c' 286 287 let coltotest = match (cline, tofind) + 1 288 289 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name") 290 291 if synname =~ '^php' || synname=="Delimiter" || synname =~? '^javaScript' 292 return synname 293 else 294 return "" 295 endif 296endfunction " }}} 297 298let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\);' 299let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|else\>\|while\>\|switch\>\|for\%(each\)\=\>\|declare\>\|class\>\|interface\>\|abstract\>\|try\>\|catch\>\|[|&]\)' 300 301let s:autorestoptions = 0 302if ! s:autorestoptions 303 au BufWinEnter,Syntax *.php,*.php3,*.php4,*.php5 call ResetOptions() 304 let s:autorestoptions = 1 305endif 306 307function! ResetOptions() 308 if ! b:optionsset 309 if b:PHP_autoformatcomment 310 311 setlocal comments=s1:/*,mb:*,ex:*/,://,:# 312 313 setlocal formatoptions-=t 314 setlocal formatoptions+=q 315 setlocal formatoptions+=r 316 setlocal formatoptions+=o 317 setlocal formatoptions+=w 318 setlocal formatoptions+=c 319 setlocal formatoptions+=b 320 endif 321 let b:optionsset = 1 322 endif 323endfunc 324 325function! GetPhpIndent() 326 327 let b:GetLastRealCodeLNum_ADD = 0 328 329 let UserIsEditing=0 330 if b:PHP_oldchangetick != b:changedtick 331 let b:PHP_oldchangetick = b:changedtick 332 let UserIsEditing=1 333 endif 334 335 if b:PHP_default_indenting 336 let b:PHP_default_indenting = g:PHP_default_indenting * &sw 337 endif 338 339 let cline = getline(v:lnum) 340 341 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast 342 if b:PHP_indentbeforelast 343 let b:PHP_indentinghuge = 1 344 echom 'Large indenting detected, speed optimizations engaged' 345 endif 346 let b:PHP_indentbeforelast = b:PHP_lastindented 347 endif 348 349 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented 350 if b:PHP_indentinghuge 351 echom 'Large indenting deactivated' 352 let b:PHP_indentinghuge = 0 353 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 354 endif 355 let b:PHP_lastindented = v:lnum 356 let b:PHP_LastIndentedWasComment=0 357 let b:PHP_InsideMultilineComment=0 358 let b:PHP_indentbeforelast = 0 359 360 let b:InPHPcode = 0 361 let b:InPHPcode_checked = 0 362 let b:InPHPcode_and_script = 0 363 let b:InPHPcode_tofind = "" 364 365 elseif v:lnum > b:PHP_lastindented 366 let real_PHP_lastindented = b:PHP_lastindented 367 let b:PHP_lastindented = v:lnum 368 endif 369 370 371 if !b:InPHPcode_checked " {{{ One time check 372 let b:InPHPcode_checked = 1 373 374 let synname = "" 375 if cline !~ '<?.*?>' 376 let synname = IslinePHP (prevnonblank(v:lnum), "") 377 endif 378 379 if synname!="" 380 if synname != "phpHereDoc" && synname != "phpHereDocDelimiter" 381 let b:InPHPcode = 1 382 let b:InPHPcode_tofind = "" 383 384 if synname == "phpComment" 385 let b:UserIsTypingComment = 1 386 else 387 let b:UserIsTypingComment = 0 388 endif 389 390 if synname =~? '^javaScript' 391 let b:InPHPcode_and_script = 1 392 endif 393 394 else 395 let b:InPHPcode = 0 396 let b:UserIsTypingComment = 0 397 398 let lnum = v:lnum - 1 399 while getline(lnum) !~? '<<<\a\w*$' && lnum > 1 400 let lnum = lnum - 1 401 endwhile 402 403 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\(\a\w*\)\c', '^\\s*\1;$', '') 404 endif 405 else 406 let b:InPHPcode = 0 407 let b:UserIsTypingComment = 0 408 let b:InPHPcode_tofind = '<?\%(.*?>\)\@!\|<script.*>' 409 endif 410 endif "!b:InPHPcode_checked }}} 411 412 413 " Test if we are indenting PHP code {{{ 414 let lnum = prevnonblank(v:lnum - 1) 415 let last_line = getline(lnum) 416 417 if b:InPHPcode_tofind!="" 418 if cline =~? b:InPHPcode_tofind 419 let b:InPHPcode = 1 420 let b:InPHPcode_tofind = "" 421 let b:UserIsTypingComment = 0 422 if cline =~ '\*/' 423 call cursor(v:lnum, 1) 424 if cline !~ '^\*/' 425 call search('\*/', 'W') 426 endif 427 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 428 429 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 430 431 let b:PHP_LastIndentedWasComment = 0 432 433 if cline =~ '^\s*\*/' 434 return indent(lnum) + 1 435 else 436 return indent(lnum) 437 endif 438 439 elseif cline =~? '<script\>' 440 let b:InPHPcode_and_script = 1 441 let b:GetLastRealCodeLNum_ADD = v:lnum 442 endif 443 endif 444 endif 445 446 if b:InPHPcode 447 448 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter" 449 if cline !~? s:PHP_startindenttag 450 let b:InPHPcode = 0 451 let b:InPHPcode_tofind = s:PHP_startindenttag 452 elseif cline =~? '<script\>' 453 let b:InPHPcode_and_script = 1 454 endif 455 456 elseif last_line =~? '<<<\a\w*$' 457 let b:InPHPcode = 0 458 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\(\a\w*\)\c', '^\\s*\1;$', '') 459 460 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*' 461 let b:InPHPcode = 0 462 let b:InPHPcode_tofind = '\*/' 463 464 elseif cline =~? '^\s*</script>' 465 let b:InPHPcode = 0 466 let b:InPHPcode_tofind = s:PHP_startindenttag 467 endif 468 endif " }}} 469 470 471 if !b:InPHPcode && !b:InPHPcode_and_script 472 return -1 473 endif 474 475 " Indent successive // or # comment the same way the first is {{{ 476 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' 477 if b:PHP_LastIndentedWasComment == 1 478 return indent(real_PHP_lastindented) 479 endif 480 let b:PHP_LastIndentedWasComment = 1 481 else 482 let b:PHP_LastIndentedWasComment = 0 483 endif " }}} 484 485 " Indent multiline /* comments correctly {{{ 486 487 if b:PHP_InsideMultilineComment || b:UserIsTypingComment 488 if cline =~ '^\s*\*\%(\/\)\@!' 489 if last_line =~ '^\s*/\*' 490 return indent(lnum) + 1 491 else 492 return indent(lnum) 493 endif 494 else 495 let b:PHP_InsideMultilineComment = 0 496 endif 497 endif 498 499 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$' 500 if getline(v:lnum + 1) !~ '^\s*\*' 501 return -1 502 endif 503 let b:PHP_InsideMultilineComment = 1 504 endif " }}} 505 506 507 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{ 508 if cline =~# '^\s*<?' && cline !~ '?>' 509 return 0 510 endif 511 512 if cline =~ '^\s*?>' && cline !~# '<?' 513 return 0 514 endif 515 516 if cline =~? '^\s*\a\w*;$' && cline !~? s:notPhpHereDoc 517 return 0 518 endif " }}} 519 520 let s:level = 0 521 522 let lnum = GetLastRealCodeLNum(v:lnum - 1) 523 524 let last_line = getline(lnum) 525 let ind = indent(lnum) 526 let endline= s:endline 527 528 if ind==0 && b:PHP_default_indenting 529 let ind = b:PHP_default_indenting 530 endif 531 532 if lnum == 0 533 return b:PHP_default_indenting 534 endif 535 536 537 if cline =~ '^\s*}\%(}}\)\@!' 538 let ind = indent(FindOpenBracket(v:lnum)) 539 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 540 return ind 541 endif 542 543 if cline =~ '^\s*\*/' 544 call cursor(v:lnum, 1) 545 if cline !~ '^\*/' 546 call search('\*/', 'W') 547 endif 548 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 549 550 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 551 552 if cline =~ '^\s*\*/' 553 return indent(lnum) + 1 554 else 555 return indent(lnum) 556 endif 557 endif 558 559 let defaultORcase = '^\s*\%(default\|case\).*:' 560 561 if last_line =~ '[;}]'.endline && last_line !~# defaultORcase 562 if ind==b:PHP_default_indenting 563 return b:PHP_default_indenting 564 elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline 565 return b:PHP_CurrentIndentLevel 566 endif 567 endif 568 569 let LastLineClosed = 0 570 571 let terminated = '\%(;\%(\s*?>\)\=\|<<<\a\w*\|}\)'.endline 572 573 let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline 574 575 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>' 576 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 577 return indent(FindTheIfOfAnElse(v:lnum, 1)) 578 elseif cline =~ '^\s*{' 579 let previous_line = last_line 580 let last_line_num = lnum 581 582 while last_line_num > 1 583 584 if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)' && previous_line !~ '^\s*[|&]' 585 586 let ind = indent(last_line_num) 587 588 if b:PHP_BracesAtCodeLevel 589 let ind = ind + &sw 590 endif 591 592 return ind 593 endif 594 595 let last_line_num = last_line_num - 1 596 let previous_line = getline(last_line_num) 597 endwhile 598 599 elseif last_line =~# unstated && cline !~ '^\s*{\|^\s*);\='.endline 600 let ind = ind + &sw 601 return ind 602 603 elseif ind != b:PHP_default_indenting && last_line =~ terminated 604 let previous_line = last_line 605 let last_line_num = lnum 606 let LastLineClosed = 1 607 608 while 1 609 if previous_line =~ '^\s*}' 610 let last_line_num = FindOpenBracket(last_line_num) 611 612 if getline(last_line_num) =~ '^\s*{' 613 let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 614 endif 615 616 let previous_line = getline(last_line_num) 617 618 continue 619 else 620 621 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>' 622 let last_line_num = FindTheIfOfAnElse(last_line_num, 0) 623 continue 624 endif 625 626 627 let last_match = last_line_num 628 629 let one_ahead_indent = indent(last_line_num) 630 let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 631 let two_ahead_indent = indent(last_line_num) 632 let after_previous_line = previous_line 633 let previous_line = getline(last_line_num) 634 635 636 if previous_line =~# defaultORcase.'\|{'.endline 637 break 638 endif 639 640 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline 641 break 642 endif 643 644 if one_ahead_indent == two_ahead_indent || last_line_num < 1 645 if previous_line =~# '[;}]'.endline || last_line_num < 1 646 break 647 endif 648 endif 649 endif 650 endwhile 651 652 if indent(last_match) != ind 653 let ind = indent(last_match) 654 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 655 656 if cline =~# defaultORcase 657 let ind = ind - &sw 658 endif 659 return ind 660 endif 661 endif 662 663 let plinnum = GetLastRealCodeLNum(lnum - 1) 664 let pline = getline(plinnum) 665 666 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') 667 668 669 if ind == b:PHP_default_indenting 670 if last_line =~ terminated 671 let LastLineClosed = 1 672 endif 673 endif 674 675 if !LastLineClosed 676 677 if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && pline !~ '[,(]'.endline 678 679 if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{' 680 let ind = ind + &sw 681 endif 682 683 if b:PHP_BracesAtCodeLevel || cline !~# defaultORcase 684 let b:PHP_CurrentIndentLevel = ind 685 return ind 686 endif 687 688 elseif last_line =~ '\S\+\s*),'.endline 689 call cursor(lnum, 1) 690 call search('),'.endline, 'W') 691 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') 692 if openedparent != lnum 693 let ind = indent(openedparent) 694 endif 695 696 697 elseif cline !~ '^\s*{' && pline =~ '\%(;\%(\s*?>\)\=\|<<<\a\w*\|{\|^\s*'.s:blockstart.'\s*(.*)\)'.endline.'\|^\s*}\|'.defaultORcase 698 699 let ind = ind + &sw 700 701 endif 702 703 elseif last_line =~# defaultORcase 704 let ind = ind + &sw 705 endif 706 707 if cline =~ '^\s*);\=' 708 let ind = ind - &sw 709 elseif cline =~# defaultORcase 710 let ind = ind - &sw 711 712 endif 713 714 let b:PHP_CurrentIndentLevel = ind 715 return ind 716endfunction 717