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