1071d4279SBram Moolenaar" Vim indent file 2071d4279SBram Moolenaar" Language: PHP 35477506aSBram Moolenaar" Author: John Wellesz <John.wellesz (AT) gmail (DOT) com> 45477506aSBram Moolenaar" URL: https://www.2072productions.com/vim/indent/php.vim 5e6ae6225SBram Moolenaar" Home: https://github.com/2072/PHP-Indenting-for-VIm 6*b17893aaSBram Moolenaar" Last Change: 2020 Mar 05 75477506aSBram Moolenaar" Version: 1.70 8071d4279SBram Moolenaar" 9071d4279SBram Moolenaar" 10e6ae6225SBram Moolenaar" Type :help php-indent for available options 11e6ae6225SBram Moolenaar" 12e6ae6225SBram Moolenaar" A fully commented version of this file is available on github 13a5792f58SBram Moolenaar" 14a5792f58SBram Moolenaar" 15259f26acSBram Moolenaar" If you find a bug, please open a ticket on github.com 16e6ae6225SBram Moolenaar" ( https://github.com/2072/PHP-Indenting-for-VIm/issues ) with an example of 17e6ae6225SBram Moolenaar" code that breaks the algorithm. 189ff7011bSBram Moolenaar" 19e6ae6225SBram Moolenaar 209ff7011bSBram Moolenaar" NOTE: This script must be used with PHP syntax ON and with the php syntax 21e6ae6225SBram Moolenaar" script by Lutz Eymers (http://www.isp.de/data/php.vim ) or with the 225477506aSBram Moolenaar" script by Peter Hodge (https://www.vim.org/scripts/script.php?script_id=1571 ) 235c73622aSBram Moolenaar" the later is bunbdled by default with Vim 7. 249ff7011bSBram Moolenaar" 259ff7011bSBram Moolenaar" 26c236c16dSBram Moolenaar" In the case you have syntax errors in your script such as HereDoc end 27c236c16dSBram Moolenaar" identifiers not at col 1 you'll have to indent your file 2 times (This 28c236c16dSBram Moolenaar" script will automatically put HereDoc end identifiers at col 1 if 29c236c16dSBram Moolenaar" they are followed by a ';'). 309ff7011bSBram Moolenaar" 31e6ae6225SBram Moolenaar 325c73622aSBram Moolenaar" NOTE: If you are editing files in Unix file format and that (by accident) 339ff7011bSBram Moolenaar" there are '\r' before new lines, this script won't be able to proceed 349ff7011bSBram Moolenaar" correctly and will make many mistakes because it won't be able to match 359ff7011bSBram Moolenaar" '\s*$' correctly. 369ff7011bSBram Moolenaar" So you have to remove those useless characters first with a command like: 379ff7011bSBram Moolenaar" 389ff7011bSBram Moolenaar" :%s /\r$//g 399ff7011bSBram Moolenaar" 409ff7011bSBram Moolenaar" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will 419ff7011bSBram Moolenaar" silently remove them when VIM load this script (at each bufread). 42bcb9898eSBram Moolenaar 43bcb9898eSBram Moolenaar 44071d4279SBram Moolenaarif exists("b:did_indent") 45071d4279SBram Moolenaar finish 46071d4279SBram Moolenaarendif 47071d4279SBram Moolenaarlet b:did_indent = 1 48071d4279SBram Moolenaar 49071d4279SBram Moolenaar 50ed32d942SBram Moolenaarlet g:php_sync_method = 0 51071d4279SBram Moolenaar 52e6ae6225SBram Moolenaar 539ff7011bSBram Moolenaarif exists("PHP_default_indenting") 543ec574f2SBram Moolenaar let b:PHP_default_indenting = PHP_default_indenting * shiftwidth() 556bb68366SBram Moolenaarelse 569ff7011bSBram Moolenaar let b:PHP_default_indenting = 0 57071d4279SBram Moolenaarendif 58071d4279SBram Moolenaar 59e6ae6225SBram Moolenaarif exists("PHP_outdentSLComments") 603ec574f2SBram Moolenaar let b:PHP_outdentSLComments = PHP_outdentSLComments * shiftwidth() 61e6ae6225SBram Moolenaarelse 62e6ae6225SBram Moolenaar let b:PHP_outdentSLComments = 0 63e6ae6225SBram Moolenaarendif 64e6ae6225SBram Moolenaar 659ff7011bSBram Moolenaarif exists("PHP_BracesAtCodeLevel") 669ff7011bSBram Moolenaar let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel 679ff7011bSBram Moolenaarelse 689ff7011bSBram Moolenaar let b:PHP_BracesAtCodeLevel = 0 69071d4279SBram Moolenaarendif 709ff7011bSBram Moolenaar 71c236c16dSBram Moolenaar 72a5792f58SBram Moolenaarif exists("PHP_autoformatcomment") 73a5792f58SBram Moolenaar let b:PHP_autoformatcomment = PHP_autoformatcomment 74a5792f58SBram Moolenaarelse 75a5792f58SBram Moolenaar let b:PHP_autoformatcomment = 1 76a5792f58SBram Moolenaarendif 779ff7011bSBram Moolenaar 788408a9adSBram Moolenaarif exists("PHP_outdentphpescape") 798408a9adSBram Moolenaar let b:PHP_outdentphpescape = PHP_outdentphpescape 808408a9adSBram Moolenaarelse 818408a9adSBram Moolenaar let b:PHP_outdentphpescape = 1 828408a9adSBram Moolenaarendif 838408a9adSBram Moolenaar 840b0f0992SBram Moolenaarif exists("PHP_noArrowMatching") 850b0f0992SBram Moolenaar let b:PHP_noArrowMatching = PHP_noArrowMatching 860b0f0992SBram Moolenaarelse 870b0f0992SBram Moolenaar let b:PHP_noArrowMatching = 0 880b0f0992SBram Moolenaarendif 890b0f0992SBram Moolenaar 908408a9adSBram Moolenaar 918408a9adSBram Moolenaarif exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent 928408a9adSBram Moolenaar let b:PHP_vintage_case_default_indent = 1 93c236c16dSBram Moolenaarelse 94c236c16dSBram Moolenaar let b:PHP_vintage_case_default_indent = 0 95c236c16dSBram Moolenaarendif 96c236c16dSBram Moolenaar 975477506aSBram Moolenaarif exists("PHP_IndentFunctionCallParameters") 985477506aSBram Moolenaar let b:PHP_IndentFunctionCallParameters = PHP_IndentFunctionCallParameters 995477506aSBram Moolenaarelse 1005477506aSBram Moolenaar let b:PHP_IndentFunctionCallParameters = 0 1015477506aSBram Moolenaarendif 102c236c16dSBram Moolenaar 1035477506aSBram Moolenaarif exists("PHP_IndentFunctionDeclarationParameters") 1045477506aSBram Moolenaar let b:PHP_IndentFunctionDeclarationParameters = PHP_IndentFunctionDeclarationParameters 1055477506aSBram Moolenaarelse 1065477506aSBram Moolenaar let b:PHP_IndentFunctionDeclarationParameters = 0 1075477506aSBram Moolenaarendif 108c236c16dSBram Moolenaar 1099ff7011bSBram Moolenaarlet b:PHP_lastindented = 0 1109ff7011bSBram Moolenaarlet b:PHP_indentbeforelast = 0 1119ff7011bSBram Moolenaarlet b:PHP_indentinghuge = 0 1129ff7011bSBram Moolenaarlet b:PHP_CurrentIndentLevel = b:PHP_default_indenting 1139ff7011bSBram Moolenaarlet b:PHP_LastIndentedWasComment = 0 1149ff7011bSBram Moolenaarlet b:PHP_InsideMultilineComment = 0 1159ff7011bSBram Moolenaarlet b:InPHPcode = 0 1169ff7011bSBram Moolenaarlet b:InPHPcode_checked = 0 1179ff7011bSBram Moolenaarlet b:InPHPcode_and_script = 0 1189ff7011bSBram Moolenaarlet b:InPHPcode_tofind = "" 1199ff7011bSBram Moolenaarlet b:PHP_oldchangetick = b:changedtick 1209ff7011bSBram Moolenaarlet b:UserIsTypingComment = 0 1219ff7011bSBram Moolenaarlet b:optionsset = 0 1229ff7011bSBram Moolenaar 1239ff7011bSBram Moolenaarsetlocal nosmartindent 1249ff7011bSBram Moolenaarsetlocal noautoindent 1259ff7011bSBram Moolenaarsetlocal nocindent 1261e015460SBram Moolenaarsetlocal nolisp 1279ff7011bSBram Moolenaar 1289ff7011bSBram Moolenaarsetlocal indentexpr=GetPhpIndent() 129ed32d942SBram Moolenaarsetlocal indentkeys=0{,0},0),0],:,!^F,o,O,e,*<Return>,=?>,=<?,=*/ 1309ff7011bSBram Moolenaar 1319ff7011bSBram Moolenaar 1321e015460SBram Moolenaar 1339ff7011bSBram Moolenaarlet s:searchpairflags = 'bWr' 1349ff7011bSBram Moolenaar 1359ff7011bSBram Moolenaarif &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix 1369ff7011bSBram Moolenaar silent! %s/\r$//g 1379ff7011bSBram Moolenaarendif 1389ff7011bSBram Moolenaar 1399ff7011bSBram Moolenaarif exists("*GetPhpIndent") 1405c73622aSBram Moolenaar call ResetPhpOptions() 1415477506aSBram Moolenaar finish " XXX -- comment this line for easy dev 1429ff7011bSBram Moolenaarendif 1439ff7011bSBram Moolenaar 144bcb9898eSBram Moolenaar 1459ff7011bSBram Moolenaarlet s:endline = '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$' 1465477506aSBram Moolenaarlet s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' 1475477506aSBram Moolenaarlet s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\|end\%(if\|while\|for\|foreach\|switch\)\)' 1485477506aSBram Moolenaarlet s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|\%(}\s*\)\?else\>\|do\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|trait\>\|\%()\s*\)\=use\>\|interface\>\|abstract\>\|final\>\|try\>\|\%(}\s*\)\=catch\>\|\%(}\s*\)\=finally\>\)' 1495477506aSBram Moolenaarlet s:functionDeclPrefix = '\<function\>\%(\s\+&\='.s:PHP_validVariable.'\)\=\s*(' 1505477506aSBram Moolenaarlet s:functionDecl = s:functionDeclPrefix.'.*' 1515477506aSBram Moolenaarlet s:multilineFunctionDecl = s:functionDeclPrefix.s:endline 1525477506aSBram Moolenaarlet s:arrayDecl = '\<array\>\s*(.*' 1535477506aSBram Moolenaarlet s:multilineFunctionCall = s:PHP_validVariable.'\s*('.s:endline 154e0720cbfSBram Moolenaarlet s:unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.s:endline 155ed32d942SBram Moolenaar 156ed32d942SBram Moolenaar 157e0720cbfSBram Moolenaarlet s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)' 1589ff7011bSBram Moolenaarlet s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!' 159e0720cbfSBram Moolenaarlet s:structureHead = '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline . '\|\<new\s\+class\>' 1609ff7011bSBram Moolenaar 1619ff7011bSBram Moolenaar 162bcb9898eSBram Moolenaarlet s:escapeDebugStops = 0 163e6ae6225SBram Moolenaarfunction! DebugPrintReturn(scriptLine) 164e6ae6225SBram Moolenaar 165bcb9898eSBram Moolenaar if ! s:escapeDebugStops 166e6ae6225SBram Moolenaar echo "debug:" . a:scriptLine 167bcb9898eSBram Moolenaar let c = getchar() 168bcb9898eSBram Moolenaar if c == "\<Del>" 169bcb9898eSBram Moolenaar let s:escapeDebugStops = 1 170bcb9898eSBram Moolenaar end 171bcb9898eSBram Moolenaar endif 172e6ae6225SBram Moolenaar 173e6ae6225SBram Moolenaarendfunction 174e6ae6225SBram Moolenaar 1759ff7011bSBram Moolenaarfunction! GetLastRealCodeLNum(startline) " {{{ 17605a7bb36SBram Moolenaar 1779ff7011bSBram Moolenaar let lnum = a:startline 17805a7bb36SBram Moolenaar 17905a7bb36SBram Moolenaar if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1 18005a7bb36SBram Moolenaar let lnum = b:GetLastRealCodeLNum_ADD 18105a7bb36SBram Moolenaar endif 18205a7bb36SBram Moolenaar 1839ff7011bSBram Moolenaar while lnum > 1 1849ff7011bSBram Moolenaar let lnum = prevnonblank(lnum) 1859ff7011bSBram Moolenaar let lastline = getline(lnum) 1869ff7011bSBram Moolenaar 1879ff7011bSBram Moolenaar if b:InPHPcode_and_script && lastline =~ '?>\s*$' 1889ff7011bSBram Moolenaar let lnum = lnum - 1 1899ff7011bSBram Moolenaar elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$' 1909ff7011bSBram Moolenaar let lnum = lnum - 1 1911e015460SBram Moolenaar elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' 1929ff7011bSBram Moolenaar let lnum = lnum - 1 1931e015460SBram Moolenaar elseif lastline =~ '\*/\s*$' 1949ff7011bSBram Moolenaar call cursor(lnum, 1) 1951e015460SBram Moolenaar if lastline !~ '^\*/' 1961e015460SBram Moolenaar call search('\*/', 'W') 1971e015460SBram Moolenaar endif 198a5792f58SBram Moolenaar let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 1999ff7011bSBram Moolenaar 2009ff7011bSBram Moolenaar let lastline = getline(lnum) 2011e015460SBram Moolenaar if lastline =~ '^\s*/\*' 2021e015460SBram Moolenaar let lnum = lnum - 1 2039ff7011bSBram Moolenaar else 2049ff7011bSBram Moolenaar break 2059ff7011bSBram Moolenaar endif 2069ff7011bSBram Moolenaar 2079ff7011bSBram Moolenaar 2081e015460SBram Moolenaar elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>' 2099ff7011bSBram Moolenaar 2109ff7011bSBram Moolenaar while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1 2119ff7011bSBram Moolenaar let lnum = lnum - 1 2129ff7011bSBram Moolenaar let lastline = getline(lnum) 2139ff7011bSBram Moolenaar endwhile 2141e015460SBram Moolenaar if lastline =~ '^\s*?>' 2159ff7011bSBram Moolenaar let lnum = lnum - 1 2169ff7011bSBram Moolenaar else 2171e015460SBram Moolenaar break 2189ff7011bSBram Moolenaar endif 2199ff7011bSBram Moolenaar 2209ff7011bSBram Moolenaar 2218408a9adSBram Moolenaar elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc 222cbebd487SBram Moolenaar let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '') 2239ff7011bSBram Moolenaar while getline(lnum) !~? tofind && lnum > 1 2249ff7011bSBram Moolenaar let lnum = lnum - 1 2259ff7011bSBram Moolenaar endwhile 2265477506aSBram Moolenaar elseif lastline =~ '^\s*[''"`][;,]' || (lastline =~ '^[^''"`]*[''"`][;,]'.s:endline && IslinePHP(lnum, "") == "SpecStringEntrails") 227e0720cbfSBram Moolenaar 228e0720cbfSBram Moolenaar let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '') 229e0720cbfSBram Moolenaar let trylnum = lnum 230e0720cbfSBram Moolenaar while getline(trylnum) !~? tofind && trylnum > 1 231e0720cbfSBram Moolenaar let trylnum = trylnum - 1 232bcb9898eSBram Moolenaar endwhile 233e0720cbfSBram Moolenaar 234e0720cbfSBram Moolenaar if trylnum == 1 235e0720cbfSBram Moolenaar break 236e0720cbfSBram Moolenaar else 237e0720cbfSBram Moolenaar if lastline =~ ';'.s:endline 238e0720cbfSBram Moolenaar while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1 239e0720cbfSBram Moolenaar let trylnum = prevnonblank(trylnum - 1) 240e0720cbfSBram Moolenaar endwhile 241e0720cbfSBram Moolenaar 242e0720cbfSBram Moolenaar 243e0720cbfSBram Moolenaar if trylnum == 1 244e0720cbfSBram Moolenaar break 245e0720cbfSBram Moolenaar end 246e0720cbfSBram Moolenaar end 247e0720cbfSBram Moolenaar let lnum = trylnum 248e0720cbfSBram Moolenaar end 2499ff7011bSBram Moolenaar else 2501e015460SBram Moolenaar break 2519ff7011bSBram Moolenaar endif 2529ff7011bSBram Moolenaar endwhile 2539ff7011bSBram Moolenaar 2549ff7011bSBram Moolenaar if lnum==1 && getline(lnum) !~ '<?' 2559ff7011bSBram Moolenaar let lnum=0 2569ff7011bSBram Moolenaar endif 2579ff7011bSBram Moolenaar 258ed32d942SBram Moolenaar if b:InPHPcode_and_script && 1 > b:InPHPcode 2599ff7011bSBram Moolenaar let b:InPHPcode_and_script = 0 2609ff7011bSBram Moolenaar endif 261d5ab34bdSBram Moolenaar 2629ff7011bSBram Moolenaar return lnum 2631e015460SBram Moolenaarendfunction " }}} 2649ff7011bSBram Moolenaar 265a5792f58SBram Moolenaarfunction! Skippmatch2() 266a5792f58SBram Moolenaar 267a5792f58SBram Moolenaar let line = getline(".") 268a5792f58SBram Moolenaar 269e6ae6225SBram Moolenaar if line =~ "\\([\"']\\).*/\\*.*\\1" || line =~ '\%(//\|#\).*/\*' 270a5792f58SBram Moolenaar return 1 271a5792f58SBram Moolenaar else 272a5792f58SBram Moolenaar return 0 273a5792f58SBram Moolenaar endif 274a5792f58SBram Moolenaarendfun 275a5792f58SBram Moolenaar 2769ff7011bSBram Moolenaarfunction! Skippmatch() " {{{ 2779ff7011bSBram Moolenaar let synname = synIDattr(synID(line("."), col("."), 0), "name") 2780b0f0992SBram Moolenaar if synname ==? "Delimiter" || synname ==? "phpRegionDelimiter" || synname =~? "^phpParent" || synname ==? "phpArrayParens" || synname =~? '^php\%(Block\|Brace\)' || synname ==? "javaScriptBraces" || synname =~? '^php\%(Doc\)\?Comment' && b:UserIsTypingComment 2799ff7011bSBram Moolenaar return 0 2809ff7011bSBram Moolenaar else 2819ff7011bSBram Moolenaar return 1 2829ff7011bSBram Moolenaar endif 2831e015460SBram Moolenaarendfun " }}} 2849ff7011bSBram Moolenaar 285bcb9898eSBram Moolenaarfunction! FindOpenBracket(lnum, blockStarter) " {{{ 2861e015460SBram Moolenaar call cursor(a:lnum, 1) 287bcb9898eSBram Moolenaar let line = searchpair('{', '', '}', 'bW', 'Skippmatch()') 288bcb9898eSBram Moolenaar 289bcb9898eSBram Moolenaar if a:blockStarter == 1 290bcb9898eSBram Moolenaar while line > 1 291bcb9898eSBram Moolenaar let linec = getline(line) 292bcb9898eSBram Moolenaar 293e0720cbfSBram Moolenaar if linec =~ s:terminated || linec =~ s:structureHead 294bcb9898eSBram Moolenaar break 295bcb9898eSBram Moolenaar endif 296bcb9898eSBram Moolenaar 297bcb9898eSBram Moolenaar let line = GetLastRealCodeLNum(line - 1) 298bcb9898eSBram Moolenaar endwhile 299bcb9898eSBram Moolenaar endif 300bcb9898eSBram Moolenaar 301bcb9898eSBram Moolenaar return line 3021e015460SBram Moolenaarendfun " }}} 3039ff7011bSBram Moolenaar 304e0720cbfSBram Moolenaarlet s:blockChars = {'{':1, '[': 1, '(': 1, ')':-1, ']':-1, '}':-1} 3055477506aSBram Moolenaarlet s:blockCharsLUT = {'{':'{', '}':'{', '[':'[', ']':'[', '(':'(', ')':'('} 306e0720cbfSBram Moolenaarfunction! BalanceDirection (str) 307e0720cbfSBram Moolenaar 3085477506aSBram Moolenaar let balance = {'{':0, '[': 0, '(': 0, 'none':0} 3095477506aSBram Moolenaar let director = 'none' 310e0720cbfSBram Moolenaar 311e0720cbfSBram Moolenaar for c in split(a:str, '\zs') 312e0720cbfSBram Moolenaar if has_key(s:blockChars, c) 3135477506aSBram Moolenaar let balance[s:blockCharsLUT[c]] += s:blockChars[c] 3145477506aSBram Moolenaar 3155477506aSBram Moolenaar if balance[s:blockCharsLUT[c]] 3165477506aSBram Moolenaar let director = s:blockCharsLUT[c] 3175477506aSBram Moolenaar endif 318e0720cbfSBram Moolenaar endif 319e0720cbfSBram Moolenaar endfor 320e0720cbfSBram Moolenaar 3215477506aSBram Moolenaar return balance[director] 322e0720cbfSBram Moolenaarendfun 323e0720cbfSBram Moolenaar 3240b0f0992SBram Moolenaarfunction! StripEndlineComments (line) 3250b0f0992SBram Moolenaar return substitute(a:line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') 3260b0f0992SBram Moolenaarendfun 3270b0f0992SBram Moolenaar 3280b0f0992SBram Moolenaarfunction! FindArrowIndent (lnum) " {{{ 3290b0f0992SBram Moolenaar 3305477506aSBram Moolenaar let parrentArrowPos = -1 3315477506aSBram Moolenaar let cursorPos = -1 3320b0f0992SBram Moolenaar let lnum = a:lnum 3330b0f0992SBram Moolenaar while lnum > 1 3340b0f0992SBram Moolenaar let last_line = getline(lnum) 3350b0f0992SBram Moolenaar if last_line =~ '^\s*->' 3360b0f0992SBram Moolenaar let parrentArrowPos = indent(a:lnum) 3370b0f0992SBram Moolenaar break 3380b0f0992SBram Moolenaar else 3395477506aSBram Moolenaar 3405477506aSBram Moolenaar if b:PHP_noArrowMatching 3410b0f0992SBram Moolenaar break 3420b0f0992SBram Moolenaar endif 3430b0f0992SBram Moolenaar 3445477506aSBram Moolenaar let cleanedLnum = StripEndlineComments(last_line) 3455477506aSBram Moolenaar 3465477506aSBram Moolenaar if cleanedLnum =~ ')'.s:endline 3475477506aSBram Moolenaar if BalanceDirection(cleanedLnum) <= 0 3485477506aSBram Moolenaar call cursor(lnum, 1) 3495477506aSBram Moolenaar call searchpos(')'.s:endline, 'cW', lnum) 3505477506aSBram Moolenaar let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') 3515477506aSBram Moolenaar let cursorPos = col(".") 3525477506aSBram Moolenaar if openedparent != lnum 3535477506aSBram Moolenaar let lnum = openedparent 3545477506aSBram Moolenaar continue 3550b0f0992SBram Moolenaar else 3565477506aSBram Moolenaar endif 3575477506aSBram Moolenaar else 3585477506aSBram Moolenaar let parrentArrowPos = -1 3595477506aSBram Moolenaar break 3605477506aSBram Moolenaar end 3615477506aSBram Moolenaar endif 3625477506aSBram Moolenaar 3635477506aSBram Moolenaar if cleanedLnum =~ '->' 3645477506aSBram Moolenaar call cursor(lnum, cursorPos == -1 ? strwidth(cleanedLnum) : cursorPos) 3655477506aSBram Moolenaar let parrentArrowPos = searchpos('->', 'cWb', lnum)[1] - 1 3665477506aSBram Moolenaar 3675477506aSBram Moolenaar break 3685477506aSBram Moolenaar else 3695477506aSBram Moolenaar let parrentArrowPos = -1 3700b0f0992SBram Moolenaar break 3710b0f0992SBram Moolenaar endif 3720b0f0992SBram Moolenaar endif 3730b0f0992SBram Moolenaar endwhile 3740b0f0992SBram Moolenaar 3755477506aSBram Moolenaar if parrentArrowPos == -1 3765477506aSBram Moolenaar let parrentArrowPos = indent(lnum) + shiftwidth() 3775477506aSBram Moolenaar end 3785477506aSBram Moolenaar 3790b0f0992SBram Moolenaar return parrentArrowPos 3800b0f0992SBram Moolenaarendfun "}}} 3810b0f0992SBram Moolenaar 3829ff7011bSBram Moolenaarfunction! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{ 3839ff7011bSBram Moolenaar 3849ff7011bSBram Moolenaar if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>' 3851e015460SBram Moolenaar let beforeelse = a:lnum 3869ff7011bSBram Moolenaar else 3879ff7011bSBram Moolenaar let beforeelse = GetLastRealCodeLNum(a:lnum - 1) 3889ff7011bSBram Moolenaar endif 3899ff7011bSBram Moolenaar 3909ff7011bSBram Moolenaar if !s:level 3919ff7011bSBram Moolenaar let s:iftoskip = 0 3929ff7011bSBram Moolenaar endif 3939ff7011bSBram Moolenaar 3949ff7011bSBram Moolenaar if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>' 3959ff7011bSBram Moolenaar let s:iftoskip = s:iftoskip + 1 3969ff7011bSBram Moolenaar endif 3979ff7011bSBram Moolenaar 3989ff7011bSBram Moolenaar if getline(beforeelse) =~ '^\s*}' 399bcb9898eSBram Moolenaar let beforeelse = FindOpenBracket(beforeelse, 0) 4009ff7011bSBram Moolenaar 4019ff7011bSBram Moolenaar if getline(beforeelse) =~ '^\s*{' 4029ff7011bSBram Moolenaar let beforeelse = GetLastRealCodeLNum(beforeelse - 1) 4039ff7011bSBram Moolenaar endif 4049ff7011bSBram Moolenaar endif 4059ff7011bSBram Moolenaar 4069ff7011bSBram Moolenaar 4079ff7011bSBram Moolenaar if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>' 4089ff7011bSBram Moolenaar return beforeelse 4099ff7011bSBram Moolenaar endif 4109ff7011bSBram Moolenaar 4119ff7011bSBram Moolenaar if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1 4129ff7011bSBram Moolenaar 4139ff7011bSBram Moolenaar if s:iftoskip && getline(beforeelse) =~# '^\s*if\>' 4149ff7011bSBram Moolenaar let s:iftoskip = s:iftoskip - 1 4159ff7011bSBram Moolenaar endif 4169ff7011bSBram Moolenaar 4179ff7011bSBram Moolenaar let s:level = s:level + 1 4189ff7011bSBram Moolenaar let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse) 4199ff7011bSBram Moolenaar endif 4209ff7011bSBram Moolenaar 4219ff7011bSBram Moolenaar return beforeelse 4229ff7011bSBram Moolenaar 4231e015460SBram Moolenaarendfunction " }}} 4249ff7011bSBram Moolenaar 4258408a9adSBram Moolenaarlet s:defaultORcase = '^\s*\%(default\|case\).*:' 4268408a9adSBram Moolenaar 4278408a9adSBram Moolenaarfunction! FindTheSwitchIndent (lnum) " {{{ 4288408a9adSBram Moolenaar 4298408a9adSBram Moolenaar let test = GetLastRealCodeLNum(a:lnum - 1) 4308408a9adSBram Moolenaar 4318408a9adSBram Moolenaar if test <= 1 4323ec574f2SBram Moolenaar return indent(1) - shiftwidth() * b:PHP_vintage_case_default_indent 4338408a9adSBram Moolenaar end 4348408a9adSBram Moolenaar 435bcb9898eSBram Moolenaar while getline(test) =~ '^\s*}' && test > 1 436bcb9898eSBram Moolenaar let test = GetLastRealCodeLNum(FindOpenBracket(test, 0) - 1) 4378408a9adSBram Moolenaar 438bcb9898eSBram Moolenaar if getline(test) =~ '^\s*switch\>' 439bcb9898eSBram Moolenaar let test = GetLastRealCodeLNum(test - 1) 4408408a9adSBram Moolenaar endif 441bcb9898eSBram Moolenaar endwhile 4428408a9adSBram Moolenaar 4438408a9adSBram Moolenaar if getline(test) =~# '^\s*switch\>' 4448408a9adSBram Moolenaar return indent(test) 4458408a9adSBram Moolenaar elseif getline(test) =~# s:defaultORcase 4463ec574f2SBram Moolenaar return indent(test) - shiftwidth() * b:PHP_vintage_case_default_indent 4478408a9adSBram Moolenaar else 4488408a9adSBram Moolenaar return FindTheSwitchIndent(test) 4498408a9adSBram Moolenaar endif 4508408a9adSBram Moolenaar 4518408a9adSBram Moolenaarendfunction "}}} 4528408a9adSBram Moolenaar 4530b0f0992SBram Moolenaarlet s:SynPHPMatchGroups = {'phpparent':1, 'delimiter':1, 'define':1, 'storageclass':1, 'structure':1, 'exception':1} 4549ff7011bSBram Moolenaarfunction! IslinePHP (lnum, tofind) " {{{ 4559ff7011bSBram Moolenaar let cline = getline(a:lnum) 4569ff7011bSBram Moolenaar 4579ff7011bSBram Moolenaar if a:tofind=="" 458bcb9898eSBram Moolenaar let tofind = "^\\s*[\"'`]*\\s*\\zs\\S" 4599ff7011bSBram Moolenaar else 4609ff7011bSBram Moolenaar let tofind = a:tofind 4619ff7011bSBram Moolenaar endif 4629ff7011bSBram Moolenaar 4631e015460SBram Moolenaar let tofind = tofind . '\c' 4649ff7011bSBram Moolenaar 4651e015460SBram Moolenaar let coltotest = match (cline, tofind) + 1 4669ff7011bSBram Moolenaar 4671e015460SBram Moolenaar let synname = synIDattr(synID(a:lnum, coltotest, 0), "name") 4689ff7011bSBram Moolenaar 4690b0f0992SBram Moolenaar if synname ==? 'phpStringSingle' || synname ==? 'phpStringDouble' || synname ==? 'phpBacktick' 4705477506aSBram Moolenaar if cline !~ '^\s*[''"`]' " ??? XXX 471ed32d942SBram Moolenaar return "SpecStringEntrails" 472bcb9898eSBram Moolenaar else 473bcb9898eSBram Moolenaar return synname 474bcb9898eSBram Moolenaar end 475bcb9898eSBram Moolenaar end 476bcb9898eSBram Moolenaar 4770b0f0992SBram Moolenaar if get(s:SynPHPMatchGroups, tolower(synname)) || synname =~ '^php' || synname =~? '^javaScript' 4789ff7011bSBram Moolenaar return synname 4799ff7011bSBram Moolenaar else 4809ff7011bSBram Moolenaar return "" 481071d4279SBram Moolenaar endif 4821e015460SBram Moolenaarendfunction " }}} 4839ff7011bSBram Moolenaar 4845c73622aSBram Moolenaarlet s:autoresetoptions = 0 4855c73622aSBram Moolenaarif ! s:autoresetoptions 4865c73622aSBram Moolenaar let s:autoresetoptions = 1 4879ff7011bSBram Moolenaarendif 4889ff7011bSBram Moolenaar 4895c73622aSBram Moolenaarfunction! ResetPhpOptions() 490ed32d942SBram Moolenaar if ! b:optionsset && &filetype =~ "php" 491a5792f58SBram Moolenaar if b:PHP_autoformatcomment 492a5792f58SBram Moolenaar 493a5792f58SBram Moolenaar setlocal comments=s1:/*,mb:*,ex:*/,://,:# 494a5792f58SBram Moolenaar 495c236c16dSBram Moolenaar setlocal formatoptions-=t 496a5792f58SBram Moolenaar setlocal formatoptions+=q 497a5792f58SBram Moolenaar setlocal formatoptions+=r 498a5792f58SBram Moolenaar setlocal formatoptions+=o 499a5792f58SBram Moolenaar setlocal formatoptions+=c 500a5792f58SBram Moolenaar setlocal formatoptions+=b 501a5792f58SBram Moolenaar endif 5029ff7011bSBram Moolenaar let b:optionsset = 1 5039ff7011bSBram Moolenaar endif 5049ff7011bSBram Moolenaarendfunc 5059ff7011bSBram Moolenaar 5065c73622aSBram Moolenaarcall ResetPhpOptions() 5075c73622aSBram Moolenaar 5080b0f0992SBram Moolenaarfunction! GetPhpIndentVersion() 5095477506aSBram Moolenaar return "1.70-bundle" 5100b0f0992SBram Moolenaarendfun 5110b0f0992SBram Moolenaar 5129ff7011bSBram Moolenaarfunction! GetPhpIndent() 5139ff7011bSBram Moolenaar 51405a7bb36SBram Moolenaar let b:GetLastRealCodeLNum_ADD = 0 51505a7bb36SBram Moolenaar 5169ff7011bSBram Moolenaar let UserIsEditing=0 5179ff7011bSBram Moolenaar if b:PHP_oldchangetick != b:changedtick 5189ff7011bSBram Moolenaar let b:PHP_oldchangetick = b:changedtick 5199ff7011bSBram Moolenaar let UserIsEditing=1 5209ff7011bSBram Moolenaar endif 5219ff7011bSBram Moolenaar 5229ff7011bSBram Moolenaar if b:PHP_default_indenting 5233ec574f2SBram Moolenaar let b:PHP_default_indenting = g:PHP_default_indenting * shiftwidth() 5249ff7011bSBram Moolenaar endif 5259ff7011bSBram Moolenaar 5261e015460SBram Moolenaar let cline = getline(v:lnum) 5279ff7011bSBram Moolenaar 5289ff7011bSBram Moolenaar if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast 5299ff7011bSBram Moolenaar if b:PHP_indentbeforelast 5309ff7011bSBram Moolenaar let b:PHP_indentinghuge = 1 5319ff7011bSBram Moolenaar endif 5329ff7011bSBram Moolenaar let b:PHP_indentbeforelast = b:PHP_lastindented 5339ff7011bSBram Moolenaar endif 5349ff7011bSBram Moolenaar 5359ff7011bSBram Moolenaar if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented 5369ff7011bSBram Moolenaar if b:PHP_indentinghuge 5379ff7011bSBram Moolenaar let b:PHP_indentinghuge = 0 5389ff7011bSBram Moolenaar let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 5399ff7011bSBram Moolenaar endif 540ed32d942SBram Moolenaar let real_PHP_lastindented = v:lnum 5419ff7011bSBram Moolenaar let b:PHP_LastIndentedWasComment=0 5429ff7011bSBram Moolenaar let b:PHP_InsideMultilineComment=0 5439ff7011bSBram Moolenaar let b:PHP_indentbeforelast = 0 5449ff7011bSBram Moolenaar 5459ff7011bSBram Moolenaar let b:InPHPcode = 0 5469ff7011bSBram Moolenaar let b:InPHPcode_checked = 0 5479ff7011bSBram Moolenaar let b:InPHPcode_and_script = 0 5489ff7011bSBram Moolenaar let b:InPHPcode_tofind = "" 5499ff7011bSBram Moolenaar 5501e015460SBram Moolenaar elseif v:lnum > b:PHP_lastindented 5519ff7011bSBram Moolenaar let real_PHP_lastindented = b:PHP_lastindented 552ed32d942SBram Moolenaar else 553ed32d942SBram Moolenaar let real_PHP_lastindented = v:lnum 5549ff7011bSBram Moolenaar endif 5559ff7011bSBram Moolenaar 556ed32d942SBram Moolenaar let b:PHP_lastindented = v:lnum 557ed32d942SBram Moolenaar 5589ff7011bSBram Moolenaar 5599ff7011bSBram Moolenaar if !b:InPHPcode_checked " {{{ One time check 5609ff7011bSBram Moolenaar let b:InPHPcode_checked = 1 561cbebd487SBram Moolenaar let b:UserIsTypingComment = 0 5629ff7011bSBram Moolenaar 56305a7bb36SBram Moolenaar let synname = "" 56405a7bb36SBram Moolenaar if cline !~ '<?.*?>' 5651e015460SBram Moolenaar let synname = IslinePHP (prevnonblank(v:lnum), "") 56605a7bb36SBram Moolenaar endif 5679ff7011bSBram Moolenaar 5689ff7011bSBram Moolenaar if synname!="" 5690b0f0992SBram Moolenaar if synname ==? "SpecStringEntrails" 570e0720cbfSBram Moolenaar let b:InPHPcode = -1 " thumb down 571ed32d942SBram Moolenaar let b:InPHPcode_tofind = "" 5720b0f0992SBram Moolenaar elseif synname !=? "phpHereDoc" && synname !=? "phpHereDocDelimiter" 5739ff7011bSBram Moolenaar let b:InPHPcode = 1 5749ff7011bSBram Moolenaar let b:InPHPcode_tofind = "" 5759ff7011bSBram Moolenaar 5760b0f0992SBram Moolenaar if synname =~? '^php\%(Doc\)\?Comment' 5779ff7011bSBram Moolenaar let b:UserIsTypingComment = 1 578cbebd487SBram Moolenaar let b:InPHPcode_checked = 0 5799ff7011bSBram Moolenaar endif 5809ff7011bSBram Moolenaar 5819ff7011bSBram Moolenaar if synname =~? '^javaScript' 5829ff7011bSBram Moolenaar let b:InPHPcode_and_script = 1 5839ff7011bSBram Moolenaar endif 5849ff7011bSBram Moolenaar 5859ff7011bSBram Moolenaar else 5869ff7011bSBram Moolenaar let b:InPHPcode = 0 5879ff7011bSBram Moolenaar 5889ff7011bSBram Moolenaar let lnum = v:lnum - 1 589cbebd487SBram Moolenaar while getline(lnum) !~? '<<<\s*[''"]\=\a\w*[''"]\=$' && lnum > 1 5909ff7011bSBram Moolenaar let lnum = lnum - 1 5919ff7011bSBram Moolenaar endwhile 5929ff7011bSBram Moolenaar 593cbebd487SBram Moolenaar let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '') 5949ff7011bSBram Moolenaar endif 5951e015460SBram Moolenaar else 5969ff7011bSBram Moolenaar let b:InPHPcode = 0 597e6ae6225SBram Moolenaar let b:InPHPcode_tofind = s:PHP_startindenttag 5989ff7011bSBram Moolenaar endif 5999ff7011bSBram Moolenaar endif "!b:InPHPcode_checked }}} 6009ff7011bSBram Moolenaar 6019ff7011bSBram Moolenaar 6021e015460SBram Moolenaar " Test if we are indenting PHP code {{{ 6039ff7011bSBram Moolenaar let lnum = prevnonblank(v:lnum - 1) 6049ff7011bSBram Moolenaar let last_line = getline(lnum) 605bcb9898eSBram Moolenaar let endline= s:endline 6069ff7011bSBram Moolenaar 6079ff7011bSBram Moolenaar if b:InPHPcode_tofind!="" 6089ff7011bSBram Moolenaar if cline =~? b:InPHPcode_tofind 6099ff7011bSBram Moolenaar let b:InPHPcode_tofind = "" 6109ff7011bSBram Moolenaar let b:UserIsTypingComment = 0 611ed32d942SBram Moolenaar 612ed32d942SBram Moolenaar if b:InPHPcode == -1 613ed32d942SBram Moolenaar let b:InPHPcode = 1 614ed32d942SBram Moolenaar return -1 615ed32d942SBram Moolenaar end 616ed32d942SBram Moolenaar 617ed32d942SBram Moolenaar let b:InPHPcode = 1 618ed32d942SBram Moolenaar 6191e015460SBram Moolenaar if cline =~ '\*/' 6209ff7011bSBram Moolenaar call cursor(v:lnum, 1) 6211e015460SBram Moolenaar if cline !~ '^\*/' 6221e015460SBram Moolenaar call search('\*/', 'W') 6231e015460SBram Moolenaar endif 624a5792f58SBram Moolenaar let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 6259ff7011bSBram Moolenaar 6269ff7011bSBram Moolenaar let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 6271e015460SBram Moolenaar 6281e015460SBram Moolenaar let b:PHP_LastIndentedWasComment = 0 6299ff7011bSBram Moolenaar 6309ff7011bSBram Moolenaar if cline =~ '^\s*\*/' 6319ff7011bSBram Moolenaar return indent(lnum) + 1 6329ff7011bSBram Moolenaar else 6339ff7011bSBram Moolenaar return indent(lnum) 6349ff7011bSBram Moolenaar endif 6359ff7011bSBram Moolenaar 6361e015460SBram Moolenaar elseif cline =~? '<script\>' 6379ff7011bSBram Moolenaar let b:InPHPcode_and_script = 1 63805a7bb36SBram Moolenaar let b:GetLastRealCodeLNum_ADD = v:lnum 6399ff7011bSBram Moolenaar endif 6409ff7011bSBram Moolenaar endif 6419ff7011bSBram Moolenaar endif 6429ff7011bSBram Moolenaar 643ed32d942SBram Moolenaar if 1 == b:InPHPcode 6449ff7011bSBram Moolenaar 6450b0f0992SBram Moolenaar if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~?"Delimiter" 6469ff7011bSBram Moolenaar if cline !~? s:PHP_startindenttag 6479ff7011bSBram Moolenaar let b:InPHPcode = 0 6489ff7011bSBram Moolenaar let b:InPHPcode_tofind = s:PHP_startindenttag 6499ff7011bSBram Moolenaar elseif cline =~? '<script\>' 6509ff7011bSBram Moolenaar let b:InPHPcode_and_script = 1 6519ff7011bSBram Moolenaar endif 6529ff7011bSBram Moolenaar 6535477506aSBram Moolenaar elseif last_line =~ '^[^''"`]\+[''"`]$' && last_line !~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' " a string identifier with nothing after it and no other string identifier before 654ed32d942SBram Moolenaar let b:InPHPcode = -1 655bcb9898eSBram Moolenaar let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '') 656cbebd487SBram Moolenaar elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$' 6579ff7011bSBram Moolenaar let b:InPHPcode = 0 658cbebd487SBram Moolenaar let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '') 6599ff7011bSBram Moolenaar 6601e015460SBram Moolenaar elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*' 6619ff7011bSBram Moolenaar let b:InPHPcode = 0 6629ff7011bSBram Moolenaar let b:InPHPcode_tofind = '\*/' 6639ff7011bSBram Moolenaar 6649ff7011bSBram Moolenaar elseif cline =~? '^\s*</script>' 6659ff7011bSBram Moolenaar let b:InPHPcode = 0 6669ff7011bSBram Moolenaar let b:InPHPcode_tofind = s:PHP_startindenttag 6679ff7011bSBram Moolenaar endif 6689ff7011bSBram Moolenaar endif " }}} 6699ff7011bSBram Moolenaar 67005a7bb36SBram Moolenaar 671ed32d942SBram Moolenaar if 1 > b:InPHPcode && !b:InPHPcode_and_script 6729ff7011bSBram Moolenaar return -1 6739ff7011bSBram Moolenaar endif 6749ff7011bSBram Moolenaar 6759ff7011bSBram Moolenaar " Indent successive // or # comment the same way the first is {{{ 676e6ae6225SBram Moolenaar let addSpecial = 0 6779ff7011bSBram Moolenaar if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' 678e6ae6225SBram Moolenaar let addSpecial = b:PHP_outdentSLComments 6799ff7011bSBram Moolenaar if b:PHP_LastIndentedWasComment == 1 6801e015460SBram Moolenaar return indent(real_PHP_lastindented) 6819ff7011bSBram Moolenaar endif 6829ff7011bSBram Moolenaar let b:PHP_LastIndentedWasComment = 1 6839ff7011bSBram Moolenaar else 6849ff7011bSBram Moolenaar let b:PHP_LastIndentedWasComment = 0 6851e015460SBram Moolenaar endif " }}} 6869ff7011bSBram Moolenaar 6879ff7011bSBram Moolenaar " Indent multiline /* comments correctly {{{ 6889ff7011bSBram Moolenaar 6899ff7011bSBram Moolenaar if b:PHP_InsideMultilineComment || b:UserIsTypingComment 6901e015460SBram Moolenaar if cline =~ '^\s*\*\%(\/\)\@!' 6911e015460SBram Moolenaar if last_line =~ '^\s*/\*' 6929ff7011bSBram Moolenaar return indent(lnum) + 1 6939ff7011bSBram Moolenaar else 6949ff7011bSBram Moolenaar return indent(lnum) 6959ff7011bSBram Moolenaar endif 6969ff7011bSBram Moolenaar else 6979ff7011bSBram Moolenaar let b:PHP_InsideMultilineComment = 0 6989ff7011bSBram Moolenaar endif 6999ff7011bSBram Moolenaar endif 7009ff7011bSBram Moolenaar 701ed32d942SBram Moolenaar if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*\%(.*\*/\)\@!' 70205a7bb36SBram Moolenaar if getline(v:lnum + 1) !~ '^\s*\*' 7039ff7011bSBram Moolenaar return -1 70405a7bb36SBram Moolenaar endif 70505a7bb36SBram Moolenaar let b:PHP_InsideMultilineComment = 1 7061e015460SBram Moolenaar endif " }}} 7079ff7011bSBram Moolenaar 7081e015460SBram Moolenaar 7091e015460SBram Moolenaar " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{ 7108408a9adSBram Moolenaar if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape 7119ff7011bSBram Moolenaar return 0 7129ff7011bSBram Moolenaar endif 7139ff7011bSBram Moolenaar 7148408a9adSBram Moolenaar if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape 7159ff7011bSBram Moolenaar return 0 7169ff7011bSBram Moolenaar endif 7179ff7011bSBram Moolenaar 718bcb9898eSBram Moolenaar if cline =~? '^\s*\a\w*;$\|^\a\w*$\|^\s*[''"`][;,]' && cline !~? s:notPhpHereDoc 7199ff7011bSBram Moolenaar return 0 7201e015460SBram Moolenaar endif " }}} 7219ff7011bSBram Moolenaar 7229ff7011bSBram Moolenaar let s:level = 0 7239ff7011bSBram Moolenaar 7249ff7011bSBram Moolenaar let lnum = GetLastRealCodeLNum(v:lnum - 1) 72505a7bb36SBram Moolenaar 7261e015460SBram Moolenaar let last_line = getline(lnum) 7271e015460SBram Moolenaar let ind = indent(lnum) 7289ff7011bSBram Moolenaar 7299ff7011bSBram Moolenaar if ind==0 && b:PHP_default_indenting 7309ff7011bSBram Moolenaar let ind = b:PHP_default_indenting 7319ff7011bSBram Moolenaar endif 7329ff7011bSBram Moolenaar 7339ff7011bSBram Moolenaar if lnum == 0 734e6ae6225SBram Moolenaar return b:PHP_default_indenting + addSpecial 7359ff7011bSBram Moolenaar endif 7369ff7011bSBram Moolenaar 7379ff7011bSBram Moolenaar 7389ff7011bSBram Moolenaar if cline =~ '^\s*}\%(}}\)\@!' 739bcb9898eSBram Moolenaar let ind = indent(FindOpenBracket(v:lnum, 1)) 7409ff7011bSBram Moolenaar let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 7419ff7011bSBram Moolenaar return ind 7429ff7011bSBram Moolenaar endif 7439ff7011bSBram Moolenaar 7441e015460SBram Moolenaar if cline =~ '^\s*\*/' 7459ff7011bSBram Moolenaar call cursor(v:lnum, 1) 7461e015460SBram Moolenaar if cline !~ '^\*/' 7471e015460SBram Moolenaar call search('\*/', 'W') 7481e015460SBram Moolenaar endif 749a5792f58SBram Moolenaar let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()') 7509ff7011bSBram Moolenaar 7519ff7011bSBram Moolenaar let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 7529ff7011bSBram Moolenaar 7539ff7011bSBram Moolenaar if cline =~ '^\s*\*/' 7549ff7011bSBram Moolenaar return indent(lnum) + 1 7559ff7011bSBram Moolenaar else 7569ff7011bSBram Moolenaar return indent(lnum) 7579ff7011bSBram Moolenaar endif 7589ff7011bSBram Moolenaar endif 7599ff7011bSBram Moolenaar 7609ff7011bSBram Moolenaar 7615477506aSBram Moolenaar if last_line =~ '[;}]'.endline && last_line !~ '^[)\]]' && last_line !~# s:defaultORcase && last_line !~ '^\s*[''"`][;,]' 7621e015460SBram Moolenaar if ind==b:PHP_default_indenting 763e6ae6225SBram Moolenaar return b:PHP_default_indenting + addSpecial 7649ff7011bSBram Moolenaar elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline 765e6ae6225SBram Moolenaar return b:PHP_CurrentIndentLevel + addSpecial 7669ff7011bSBram Moolenaar endif 7679ff7011bSBram Moolenaar endif 7689ff7011bSBram Moolenaar 7691e015460SBram Moolenaar let LastLineClosed = 0 7709ff7011bSBram Moolenaar 771bcb9898eSBram Moolenaar let terminated = s:terminated 7729ff7011bSBram Moolenaar 773e0720cbfSBram Moolenaar let unstated = s:unstated 774e0720cbfSBram Moolenaar 7759ff7011bSBram Moolenaar 7769ff7011bSBram Moolenaar if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>' 7771e015460SBram Moolenaar let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 7789ff7011bSBram Moolenaar return indent(FindTheIfOfAnElse(v:lnum, 1)) 7798408a9adSBram Moolenaar elseif cline =~# s:defaultORcase 7803ec574f2SBram Moolenaar return FindTheSwitchIndent(v:lnum) + shiftwidth() * b:PHP_vintage_case_default_indent 781c236c16dSBram Moolenaar elseif cline =~ '^\s*)\=\s*{' 7821e015460SBram Moolenaar let previous_line = last_line 7831e015460SBram Moolenaar let last_line_num = lnum 7841e015460SBram Moolenaar 7851e015460SBram Moolenaar while last_line_num > 1 7861e015460SBram Moolenaar 787e0720cbfSBram Moolenaar if previous_line =~ terminated || previous_line =~ s:structureHead 7881e015460SBram Moolenaar 7891e015460SBram Moolenaar let ind = indent(last_line_num) 7901e015460SBram Moolenaar 7911e015460SBram Moolenaar if b:PHP_BracesAtCodeLevel 7923ec574f2SBram Moolenaar let ind = ind + shiftwidth() 7931e015460SBram Moolenaar endif 7941e015460SBram Moolenaar 7951e015460SBram Moolenaar return ind 7961e015460SBram Moolenaar endif 7971e015460SBram Moolenaar 798bcb9898eSBram Moolenaar let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 7991e015460SBram Moolenaar let previous_line = getline(last_line_num) 8001e015460SBram Moolenaar endwhile 8010b0f0992SBram Moolenaar elseif cline =~ '^\s*->' 8020b0f0992SBram Moolenaar return FindArrowIndent(lnum) 803c236c16dSBram Moolenaar elseif last_line =~# unstated && cline !~ '^\s*);\='.endline 8043ec574f2SBram Moolenaar let ind = ind + shiftwidth() " we indent one level further when the preceding line is not stated 805e6ae6225SBram Moolenaar return ind + addSpecial 8069ff7011bSBram Moolenaar 807ed32d942SBram Moolenaar elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated 8089ff7011bSBram Moolenaar let previous_line = last_line 8099ff7011bSBram Moolenaar let last_line_num = lnum 8109ff7011bSBram Moolenaar let LastLineClosed = 1 8119ff7011bSBram Moolenaar 812bcb9898eSBram Moolenaar let isSingleLineBlock = 0 8139ff7011bSBram Moolenaar while 1 8140b0f0992SBram Moolenaar if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline 8159ff7011bSBram Moolenaar 816e6ae6225SBram Moolenaar call cursor(last_line_num, 1) 817bcb9898eSBram Moolenaar if previous_line !~ '^}' 818bcb9898eSBram Moolenaar call search('}\|;\s*}'.endline, 'W') 819bcb9898eSBram Moolenaar end 820e6ae6225SBram Moolenaar let oldLastLine = last_line_num 821e6ae6225SBram Moolenaar let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()') 822e6ae6225SBram Moolenaar 823bcb9898eSBram Moolenaar if getline(last_line_num) =~ '^\s*{' 8249ff7011bSBram Moolenaar let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 825bcb9898eSBram Moolenaar elseif oldLastLine == last_line_num 826bcb9898eSBram Moolenaar let isSingleLineBlock = 1 827bcb9898eSBram Moolenaar continue 8289ff7011bSBram Moolenaar endif 8299ff7011bSBram Moolenaar 8309ff7011bSBram Moolenaar let previous_line = getline(last_line_num) 8319ff7011bSBram Moolenaar 8329ff7011bSBram Moolenaar continue 8339ff7011bSBram Moolenaar else 834bcb9898eSBram Moolenaar let isSingleLineBlock = 0 8351e015460SBram Moolenaar 8369ff7011bSBram Moolenaar if getline(last_line_num) =~# '^\s*else\%(if\)\=\>' 8379ff7011bSBram Moolenaar let last_line_num = FindTheIfOfAnElse(last_line_num, 0) 8381e015460SBram Moolenaar continue 8399ff7011bSBram Moolenaar endif 8409ff7011bSBram Moolenaar 8419ff7011bSBram Moolenaar 8421e015460SBram Moolenaar let last_match = last_line_num 8439ff7011bSBram Moolenaar 8449ff7011bSBram Moolenaar let one_ahead_indent = indent(last_line_num) 8459ff7011bSBram Moolenaar let last_line_num = GetLastRealCodeLNum(last_line_num - 1) 8469ff7011bSBram Moolenaar let two_ahead_indent = indent(last_line_num) 8479ff7011bSBram Moolenaar let after_previous_line = previous_line 8489ff7011bSBram Moolenaar let previous_line = getline(last_line_num) 8499ff7011bSBram Moolenaar 8509ff7011bSBram Moolenaar 8518408a9adSBram Moolenaar if previous_line =~# s:defaultORcase.'\|{'.endline 8529ff7011bSBram Moolenaar break 8539ff7011bSBram Moolenaar endif 8549ff7011bSBram Moolenaar 8559ff7011bSBram Moolenaar if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline 8569ff7011bSBram Moolenaar break 8579ff7011bSBram Moolenaar endif 8589ff7011bSBram Moolenaar 8599ff7011bSBram Moolenaar if one_ahead_indent == two_ahead_indent || last_line_num < 1 860c236c16dSBram Moolenaar if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1 8619ff7011bSBram Moolenaar break 8629ff7011bSBram Moolenaar endif 8639ff7011bSBram Moolenaar endif 8649ff7011bSBram Moolenaar endif 8659ff7011bSBram Moolenaar endwhile 8669ff7011bSBram Moolenaar 8671e015460SBram Moolenaar if indent(last_match) != ind 8681e015460SBram Moolenaar let ind = indent(last_match) 8691e015460SBram Moolenaar let b:PHP_CurrentIndentLevel = b:PHP_default_indenting 8709ff7011bSBram Moolenaar 871e6ae6225SBram Moolenaar return ind + addSpecial 8729ff7011bSBram Moolenaar endif 8739ff7011bSBram Moolenaar endif 8749ff7011bSBram Moolenaar 875ed32d942SBram Moolenaar if (last_line !~ '^\s*}\%(}}\)\@!') 8769ff7011bSBram Moolenaar let plinnum = GetLastRealCodeLNum(lnum - 1) 877ed32d942SBram Moolenaar else 878ed32d942SBram Moolenaar let plinnum = GetLastRealCodeLNum(FindOpenBracket(lnum, 1) - 1) 879ed32d942SBram Moolenaar endif 880ed32d942SBram Moolenaar 8818408a9adSBram Moolenaar let AntepenultimateLine = getline(plinnum) 8829ff7011bSBram Moolenaar 8830b0f0992SBram Moolenaar let last_line = StripEndlineComments(last_line) 8849ff7011bSBram Moolenaar 8859ff7011bSBram Moolenaar if ind == b:PHP_default_indenting 886ed32d942SBram Moolenaar if last_line =~ terminated && last_line !~# s:defaultORcase 8879ff7011bSBram Moolenaar let LastLineClosed = 1 8889ff7011bSBram Moolenaar endif 8899ff7011bSBram Moolenaar endif 8909ff7011bSBram Moolenaar 8911e015460SBram Moolenaar if !LastLineClosed 8921e015460SBram Moolenaar 8930b0f0992SBram Moolenaar let openedparent = -1 8940b0f0992SBram Moolenaar 8955c73622aSBram Moolenaar 896e0720cbfSBram Moolenaar if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline && BalanceDirection(last_line) > 0 8979ff7011bSBram Moolenaar 898bcb9898eSBram Moolenaar let dontIndent = 0 8990b0f0992SBram Moolenaar if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*[)\]]\+\(\s*:\s*'.s:PHP_validVariable.'\)\=\s*{'.endline && last_line !~ s:structureHead 900bcb9898eSBram Moolenaar let dontIndent = 1 901bcb9898eSBram Moolenaar endif 902bcb9898eSBram Moolenaar 903bcb9898eSBram Moolenaar if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{') 9043ec574f2SBram Moolenaar let ind = ind + shiftwidth() 9059ff7011bSBram Moolenaar endif 9069ff7011bSBram Moolenaar 9075477506aSBram Moolenaar if b:PHP_IndentFunctionCallParameters && last_line =~ s:multilineFunctionCall && last_line !~ s:structureHead && last_line !~ s:arrayDecl 9085477506aSBram Moolenaar let ind = ind + b:PHP_IndentFunctionCallParameters * shiftwidth() 9095477506aSBram Moolenaar endif 9105477506aSBram Moolenaar 9115477506aSBram Moolenaar if b:PHP_IndentFunctionDeclarationParameters && last_line =~ s:multilineFunctionDecl 9125477506aSBram Moolenaar let ind = ind + b:PHP_IndentFunctionDeclarationParameters * shiftwidth() 9135477506aSBram Moolenaar endif 9145477506aSBram Moolenaar 9158408a9adSBram Moolenaar if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1 9169ff7011bSBram Moolenaar let b:PHP_CurrentIndentLevel = ind 917c236c16dSBram Moolenaar 9189ff7011bSBram Moolenaar endif 9199ff7011bSBram Moolenaar 9200b0f0992SBram Moolenaar elseif last_line =~ '),'.endline && BalanceDirection(last_line) < 0 9219ff7011bSBram Moolenaar call cursor(lnum, 1) 9220b0f0992SBram Moolenaar call searchpos('),'.endline, 'cW') 9239ff7011bSBram Moolenaar let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') 9249ff7011bSBram Moolenaar if openedparent != lnum 9259ff7011bSBram Moolenaar let ind = indent(openedparent) 9269ff7011bSBram Moolenaar endif 9278408a9adSBram Moolenaar 9280b0f0992SBram Moolenaar elseif last_line =~ s:structureHead 9293ec574f2SBram Moolenaar let ind = ind + shiftwidth() 9309ff7011bSBram Moolenaar 931c236c16dSBram Moolenaar 932e0720cbfSBram Moolenaar elseif AntepenultimateLine =~ '{'.endline && AntepenultimateLine !~? '^\s*use\>' || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase 9333ec574f2SBram Moolenaar let ind = ind + shiftwidth() 934c236c16dSBram Moolenaar endif 935c236c16dSBram Moolenaar 9360b0f0992SBram Moolenaar 9370b0f0992SBram Moolenaar if openedparent >= 0 9380b0f0992SBram Moolenaar let last_line = StripEndlineComments(getline(openedparent)) 9390b0f0992SBram Moolenaar endif 9409ff7011bSBram Moolenaar endif 9419ff7011bSBram Moolenaar 942e6ae6225SBram Moolenaar if cline =~ '^\s*[)\]];\=' 9435477506aSBram Moolenaar call cursor(v:lnum, 1) 9445477506aSBram Moolenaar call searchpos('[)\]]', 'cW') 9455477506aSBram Moolenaar let matchedBlockChar = cline[col('.')-1] 9465477506aSBram Moolenaar let openedparent = searchpair('\M'.s:blockCharsLUT[matchedBlockChar], '', '\M'.matchedBlockChar, 'bW', 'Skippmatch()') 9475477506aSBram Moolenaar if openedparent != v:lnum 9485477506aSBram Moolenaar let ind = indent(openedparent) 9499ff7011bSBram Moolenaar endif 9509ff7011bSBram Moolenaar 9515477506aSBram Moolenaar elseif last_line =~ '^\s*->' && last_line !~? s:structureHead && BalanceDirection(last_line) <= 0 9520b0f0992SBram Moolenaar let ind = ind - shiftwidth() 9530b0f0992SBram Moolenaar endif 9540b0f0992SBram Moolenaar 9559ff7011bSBram Moolenaar let b:PHP_CurrentIndentLevel = ind 956e6ae6225SBram Moolenaar return ind + addSpecial 9579ff7011bSBram Moolenaarendfunction 958