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