blob: 06b49f3cb675963a5db8e73ba19f2bf5b79f185a [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim indent file
2" Language: PHP
Bram Moolenaar9ff70112005-07-11 22:29:03 +00003" Author: John Wellesz <John.wellesz (AT) teaser (DOT) fr>
4" URL: http://www.2072productions.com/vim/indent/php.vim
Bram Moolenaare6ae6222013-05-21 21:01:10 +02005" Home: https://github.com/2072/PHP-Indenting-for-VIm
Bram Moolenaare0720cb2017-03-29 13:48:40 +02006" Last Change: 2017 March 12th
7" Version: 1.62
Bram Moolenaar071d4272004-06-13 20:20:40 +00008"
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00009"
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010" Type :help php-indent for available options
11"
12" A fully commented version of this file is available on github
Bram Moolenaara5792f52005-11-23 21:25:05 +000013"
14"
Bram Moolenaare6ae6222013-05-21 21:01:10 +020015" If you find a bug, please open a ticket on github.org
16" ( https://github.com/2072/PHP-Indenting-for-VIm/issues ) with an example of
17" code that breaks the algorithm.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000018"
Bram Moolenaare6ae6222013-05-21 21:01:10 +020019
Bram Moolenaar9ff70112005-07-11 22:29:03 +000020" NOTE: This script must be used with PHP syntax ON and with the php syntax
Bram Moolenaare6ae6222013-05-21 21:01:10 +020021" script by Lutz Eymers (http://www.isp.de/data/php.vim ) or with the
Bram Moolenaarc236c162008-07-13 17:41:49 +000022" script by Peter Hodge (http://www.vim.org/scripts/script.php?script_id=1571 )
Bram Moolenaar5c736222010-01-06 20:54:52 +010023" the later is bunbdled by default with Vim 7.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000024"
25"
Bram Moolenaarc236c162008-07-13 17:41:49 +000026" In the case you have syntax errors in your script such as HereDoc end
27" identifiers not at col 1 you'll have to indent your file 2 times (This
28" script will automatically put HereDoc end identifiers at col 1 if
29" they are followed by a ';').
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000030"
Bram Moolenaare6ae6222013-05-21 21:01:10 +020031
Bram Moolenaar5c736222010-01-06 20:54:52 +010032" NOTE: If you are editing files in Unix file format and that (by accident)
33" there are '\r' before new lines, this script won't be able to proceed
34" correctly and will make many mistakes because it won't be able to match
35" '\s*$' correctly.
36" So you have to remove those useless characters first with a command like:
Bram Moolenaar9ff70112005-07-11 22:29:03 +000037"
Bram Moolenaar5c736222010-01-06 20:54:52 +010038" :%s /\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +000039"
Bram Moolenaar5c736222010-01-06 20:54:52 +010040" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will
41" silently remove them when VIM load this script (at each bufread).
Bram Moolenaarbcb98982014-05-01 14:08:19 +020042
43
Bram Moolenaara5792f52005-11-23 21:25:05 +000044
Bram Moolenaar071d4272004-06-13 20:20:40 +000045if exists("b:did_indent")
Bram Moolenaar1e015462005-09-25 22:16:38 +000046 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +000047endif
48let b:did_indent = 1
49
Bram Moolenaar9ff70112005-07-11 22:29:03 +000050
Bram Moolenaared32d942014-12-06 23:33:00 +010051let g:php_sync_method = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000052
Bram Moolenaarcbebd482016-02-07 23:02:56 +010053if exists('*shiftwidth')
54 function! s:sw()
55 return shiftwidth()
56 endfunction
57else
58 function! s:sw()
59 return &shiftwidth
60 endfunction
61endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000062
Bram Moolenaare6ae6222013-05-21 21:01:10 +020063
Bram Moolenaar9ff70112005-07-11 22:29:03 +000064if exists("PHP_default_indenting")
Bram Moolenaarcbebd482016-02-07 23:02:56 +010065 let b:PHP_default_indenting = PHP_default_indenting * s:sw()
Bram Moolenaar9ff70112005-07-11 22:29:03 +000066else
Bram Moolenaar1e015462005-09-25 22:16:38 +000067 let b:PHP_default_indenting = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000068endif
69
Bram Moolenaare6ae6222013-05-21 21:01:10 +020070if exists("PHP_outdentSLComments")
Bram Moolenaarcbebd482016-02-07 23:02:56 +010071 let b:PHP_outdentSLComments = PHP_outdentSLComments * s:sw()
Bram Moolenaare6ae6222013-05-21 21:01:10 +020072else
73 let b:PHP_outdentSLComments = 0
74endif
75
Bram Moolenaar9ff70112005-07-11 22:29:03 +000076if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000077 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000078else
Bram Moolenaar1e015462005-09-25 22:16:38 +000079 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000080endif
81
Bram Moolenaarc236c162008-07-13 17:41:49 +000082
Bram Moolenaara5792f52005-11-23 21:25:05 +000083if exists("PHP_autoformatcomment")
84 let b:PHP_autoformatcomment = PHP_autoformatcomment
85else
86 let b:PHP_autoformatcomment = 1
87endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000088
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020089if exists("PHP_outdentphpescape")
90 let b:PHP_outdentphpescape = PHP_outdentphpescape
91else
92 let b:PHP_outdentphpescape = 1
93endif
94
95
96if exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent
97 let b:PHP_vintage_case_default_indent = 1
Bram Moolenaarc236c162008-07-13 17:41:49 +000098else
99 let b:PHP_vintage_case_default_indent = 0
100endif
101
102
103
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000104let b:PHP_lastindented = 0
105let b:PHP_indentbeforelast = 0
106let b:PHP_indentinghuge = 0
107let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
108let b:PHP_LastIndentedWasComment = 0
109let b:PHP_InsideMultilineComment = 0
110let b:InPHPcode = 0
111let b:InPHPcode_checked = 0
112let b:InPHPcode_and_script = 0
113let b:InPHPcode_tofind = ""
114let b:PHP_oldchangetick = b:changedtick
115let b:UserIsTypingComment = 0
116let b:optionsset = 0
117
118setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000119setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000120setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +0000121setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000122
Bram Moolenaar071d4272004-06-13 20:20:40 +0000123setlocal indentexpr=GetPhpIndent()
Bram Moolenaared32d942014-12-06 23:33:00 +0100124setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000125
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000126
Bram Moolenaar1e015462005-09-25 22:16:38 +0000127
128let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000129
130if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000131 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000132endif
133
Bram Moolenaar071d4272004-06-13 20:20:40 +0000134if exists("*GetPhpIndent")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100135 call ResetPhpOptions()
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100136 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +0000137endif
138
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200139
Bram Moolenaared32d942014-12-06 23:33:00 +0100140let s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200141let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\)'
142let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|\%(}\s*\)\?else\>\|do\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|trait\>\|use\>\|interface\>\|abstract\>\|final\>\|try\>\|\%(}\s*\)\=catch\>\|\%(}\s*\)\=finally\>\)'
Bram Moolenaared32d942014-12-06 23:33:00 +0100143let s:functionDecl = '\<function\>\%(\s\+'.s:PHP_validVariable.'\)\=\s*(.*'
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200144let s:endline = '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
145let s:unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.s:endline
Bram Moolenaared32d942014-12-06 23:33:00 +0100146
147
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200148let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000149let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200150let s:structureHead = '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline . '\|\<new\s\+class\>'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000151
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000152
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200153
154let s:escapeDebugStops = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200155function! DebugPrintReturn(scriptLine)
156
Bram Moolenaared32d942014-12-06 23:33:00 +0100157 if ! s:escapeDebugStops
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200158 echo "debug:" . a:scriptLine
159 let c = getchar()
160 if c == "\<Del>"
161 let s:escapeDebugStops = 1
162 end
163 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200164
165endfunction
166
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000167function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000168
Bram Moolenaar1e015462005-09-25 22:16:38 +0000169 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000170
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000171 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
172 let lnum = b:GetLastRealCodeLNum_ADD
173 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000174
Bram Moolenaar1e015462005-09-25 22:16:38 +0000175 while lnum > 1
176 let lnum = prevnonblank(lnum)
177 let lastline = getline(lnum)
178
179 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
180 let lnum = lnum - 1
181 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
182 let lnum = lnum - 1
183 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
184 let lnum = lnum - 1
185 elseif lastline =~ '\*/\s*$'
186 call cursor(lnum, 1)
187 if lastline !~ '^\*/'
188 call search('\*/', 'W')
189 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000190 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000191
192 let lastline = getline(lnum)
193 if lastline =~ '^\s*/\*'
194 let lnum = lnum - 1
195 else
196 break
197 endif
198
199
200 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
201
202 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
203 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000204 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000205 endwhile
206 if lastline =~ '^\s*?>'
207 let lnum = lnum - 1
208 else
209 break
210 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000211
212
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200213 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100214 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000215 while getline(lnum) !~? tofind && lnum > 1
216 let lnum = lnum - 1
217 endwhile
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200218 elseif lastline =~ '^[^''"`]*[''"`][;,]'.s:endline
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200219
220 let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '')
221 let trylnum = lnum
222 while getline(trylnum) !~? tofind && trylnum > 1
223 let trylnum = trylnum - 1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200224 endwhile
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200225
226 if trylnum == 1
227 break
228 else
229 if lastline =~ ';'.s:endline
230 while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1
231 let trylnum = prevnonblank(trylnum - 1)
232 endwhile
233
234
235 if trylnum == 1
236 break
237 end
238 end
239 let lnum = trylnum
240 end
Bram Moolenaar1e015462005-09-25 22:16:38 +0000241 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000242 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000243 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000244 endwhile
245
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200246 if lnum==1 && getline(lnum) !~ '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000247 let lnum=0
248 endif
249
Bram Moolenaared32d942014-12-06 23:33:00 +0100250 if b:InPHPcode_and_script && 1 > b:InPHPcode
Bram Moolenaar1e015462005-09-25 22:16:38 +0000251 let b:InPHPcode_and_script = 0
252 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000253
Bram Moolenaar1e015462005-09-25 22:16:38 +0000254 return lnum
255endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000256
Bram Moolenaara5792f52005-11-23 21:25:05 +0000257function! Skippmatch2()
258
259 let line = getline(".")
260
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200261 if line =~ "\\([\"']\\).*/\\*.*\\1" || line =~ '\%(//\|#\).*/\*'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200262 return 1
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200263 else
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200264 return 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200265 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000266endfun
267
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200268function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000269 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaared32d942014-12-06 23:33:00 +0100270 if synname == "Delimiter" || synname == "phpRegionDelimiter" || synname =~# "^phpParent" || synname == "phpArrayParens" || synname =~# '^php\%(Block\|Brace\)' || synname == "javaScriptBraces" || synname =~# '^php\%(Doc\)\?Comment' && b:UserIsTypingComment
Bram Moolenaar1e015462005-09-25 22:16:38 +0000271 return 0
272 else
273 return 1
274 endif
275endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000276
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200277function! FindOpenBracket(lnum, blockStarter) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000278 call cursor(a:lnum, 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200279 let line = searchpair('{', '', '}', 'bW', 'Skippmatch()')
280
281 if a:blockStarter == 1
Bram Moolenaared32d942014-12-06 23:33:00 +0100282 while line > 1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200283 let linec = getline(line)
284
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200285 if linec =~ s:terminated || linec =~ s:structureHead
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200286 break
287 endif
288
289 let line = GetLastRealCodeLNum(line - 1)
290 endwhile
291 endif
292
293 return line
Bram Moolenaar1e015462005-09-25 22:16:38 +0000294endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000295
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200296let s:blockChars = {'{':1, '[': 1, '(': 1, ')':-1, ']':-1, '}':-1}
297function! BalanceDirection (str)
298
299 let balance = 0
300
301 for c in split(a:str, '\zs')
302 if has_key(s:blockChars, c)
303 let balance += s:blockChars[c]
304 endif
305 endfor
306
307 return balance
308endfun
309
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000310function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000311
312 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
313 let beforeelse = a:lnum
314 else
315 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
316 endif
317
318 if !s:level
319 let s:iftoskip = 0
320 endif
321
322 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
323 let s:iftoskip = s:iftoskip + 1
324 endif
325
326 if getline(beforeelse) =~ '^\s*}'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200327 let beforeelse = FindOpenBracket(beforeelse, 0)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000328
329 if getline(beforeelse) =~ '^\s*{'
330 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000331 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000332 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000333
334
Bram Moolenaar1e015462005-09-25 22:16:38 +0000335 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000336 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000337 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000338
Bram Moolenaar1e015462005-09-25 22:16:38 +0000339 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
340
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200341 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000342 let s:iftoskip = s:iftoskip - 1
343 endif
344
345 let s:level = s:level + 1
346 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
347 endif
348
349 return beforeelse
350
351endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000352
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200353let s:defaultORcase = '^\s*\%(default\|case\).*:'
354
355function! FindTheSwitchIndent (lnum) " {{{
356
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200357 let test = GetLastRealCodeLNum(a:lnum - 1)
358
359 if test <= 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100360 return indent(1) - s:sw() * b:PHP_vintage_case_default_indent
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200361 end
362
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200363 while getline(test) =~ '^\s*}' && test > 1
364 let test = GetLastRealCodeLNum(FindOpenBracket(test, 0) - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200365
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200366 if getline(test) =~ '^\s*switch\>'
367 let test = GetLastRealCodeLNum(test - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200368 endif
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200369 endwhile
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200370
371 if getline(test) =~# '^\s*switch\>'
372 return indent(test)
373 elseif getline(test) =~# s:defaultORcase
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100374 return indent(test) - s:sw() * b:PHP_vintage_case_default_indent
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200375 else
376 return FindTheSwitchIndent(test)
377 endif
378
379endfunction "}}}
380
Bram Moolenaar3b1db362013-08-10 15:00:24 +0200381let s:SynPHPMatchGroups = {'phpParent':1, 'Delimiter':1, 'Define':1, 'Storageclass':1, 'StorageClass':1, 'Structure':1, 'Exception':1}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000382function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000383 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000384
Bram Moolenaar1e015462005-09-25 22:16:38 +0000385 if a:tofind==""
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200386 let tofind = "^\\s*[\"'`]*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000387 else
388 let tofind = a:tofind
389 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000390
Bram Moolenaar1e015462005-09-25 22:16:38 +0000391 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000392
Bram Moolenaar1e015462005-09-25 22:16:38 +0000393 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000394
Bram Moolenaar1e015462005-09-25 22:16:38 +0000395 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
396
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200397 if synname == 'phpStringSingle' || synname == 'phpStringDouble' || synname == 'phpBacktick'
398 if cline !~ '^\s*[''"`]'
Bram Moolenaared32d942014-12-06 23:33:00 +0100399 return "SpecStringEntrails"
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200400 else
401 return synname
402 end
403 end
404
Bram Moolenaar9d98fe92013-08-03 18:35:36 +0200405 if get(s:SynPHPMatchGroups, synname) || synname =~ '^php' || synname =~? '^javaScript'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000406 return synname
407 else
408 return ""
409 endif
410endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000411
Bram Moolenaar5c736222010-01-06 20:54:52 +0100412let s:autoresetoptions = 0
413if ! s:autoresetoptions
414 let s:autoresetoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000415endif
416
Bram Moolenaar5c736222010-01-06 20:54:52 +0100417function! ResetPhpOptions()
Bram Moolenaared32d942014-12-06 23:33:00 +0100418 if ! b:optionsset && &filetype =~ "php"
Bram Moolenaara5792f52005-11-23 21:25:05 +0000419 if b:PHP_autoformatcomment
420
421 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000422
Bram Moolenaarc236c162008-07-13 17:41:49 +0000423 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000424 setlocal formatoptions+=q
425 setlocal formatoptions+=r
426 setlocal formatoptions+=o
Bram Moolenaara5792f52005-11-23 21:25:05 +0000427 setlocal formatoptions+=c
428 setlocal formatoptions+=b
429 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000430 let b:optionsset = 1
431 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000432endfunc
433
Bram Moolenaar5c736222010-01-06 20:54:52 +0100434call ResetPhpOptions()
435
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000436function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000437
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000438 let b:GetLastRealCodeLNum_ADD = 0
439
Bram Moolenaar1e015462005-09-25 22:16:38 +0000440 let UserIsEditing=0
441 if b:PHP_oldchangetick != b:changedtick
442 let b:PHP_oldchangetick = b:changedtick
443 let UserIsEditing=1
444 endif
445
446 if b:PHP_default_indenting
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100447 let b:PHP_default_indenting = g:PHP_default_indenting * s:sw()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000448 endif
449
450 let cline = getline(v:lnum)
451
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000452 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000453 if b:PHP_indentbeforelast
454 let b:PHP_indentinghuge = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000455 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000456 let b:PHP_indentbeforelast = b:PHP_lastindented
457 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000458
Bram Moolenaar1e015462005-09-25 22:16:38 +0000459 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
460 if b:PHP_indentinghuge
Bram Moolenaar1e015462005-09-25 22:16:38 +0000461 let b:PHP_indentinghuge = 0
462 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000463 endif
Bram Moolenaared32d942014-12-06 23:33:00 +0100464 let real_PHP_lastindented = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000465 let b:PHP_LastIndentedWasComment=0
466 let b:PHP_InsideMultilineComment=0
467 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000468
Bram Moolenaar1e015462005-09-25 22:16:38 +0000469 let b:InPHPcode = 0
470 let b:InPHPcode_checked = 0
471 let b:InPHPcode_and_script = 0
472 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000473
Bram Moolenaar1e015462005-09-25 22:16:38 +0000474 elseif v:lnum > b:PHP_lastindented
475 let real_PHP_lastindented = b:PHP_lastindented
Bram Moolenaared32d942014-12-06 23:33:00 +0100476 else
477 let real_PHP_lastindented = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000478 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000479
Bram Moolenaared32d942014-12-06 23:33:00 +0100480 let b:PHP_lastindented = v:lnum
481
Bram Moolenaar1e015462005-09-25 22:16:38 +0000482
483 if !b:InPHPcode_checked " {{{ One time check
484 let b:InPHPcode_checked = 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100485 let b:UserIsTypingComment = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000486
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000487 let synname = ""
488 if cline !~ '<?.*?>'
489 let synname = IslinePHP (prevnonblank(v:lnum), "")
490 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000491
492 if synname!=""
Bram Moolenaared32d942014-12-06 23:33:00 +0100493 if synname == "SpecStringEntrails"
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200494 let b:InPHPcode = -1 " thumb down
Bram Moolenaared32d942014-12-06 23:33:00 +0100495 let b:InPHPcode_tofind = ""
496 elseif synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000497 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000498 let b:InPHPcode_tofind = ""
499
Bram Moolenaared32d942014-12-06 23:33:00 +0100500 if synname =~# '^php\%(Doc\)\?Comment'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000501 let b:UserIsTypingComment = 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100502 let b:InPHPcode_checked = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000503 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000504
Bram Moolenaar1e015462005-09-25 22:16:38 +0000505 if synname =~? '^javaScript'
506 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000507 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000508
Bram Moolenaar1e015462005-09-25 22:16:38 +0000509 else
510 let b:InPHPcode = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000511
Bram Moolenaar1e015462005-09-25 22:16:38 +0000512 let lnum = v:lnum - 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100513 while getline(lnum) !~? '<<<\s*[''"]\=\a\w*[''"]\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000514 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000515 endwhile
516
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100517 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000518 endif
519 else
520 let b:InPHPcode = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200521 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000522 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000523 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000524
525
Bram Moolenaar1e015462005-09-25 22:16:38 +0000526 " Test if we are indenting PHP code {{{
527 let lnum = prevnonblank(v:lnum - 1)
528 let last_line = getline(lnum)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200529 let endline= s:endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000530
531 if b:InPHPcode_tofind!=""
532 if cline =~? b:InPHPcode_tofind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000533 let b:InPHPcode_tofind = ""
534 let b:UserIsTypingComment = 0
Bram Moolenaared32d942014-12-06 23:33:00 +0100535
536 if b:InPHPcode == -1
537 let b:InPHPcode = 1
538 return -1
539 end
540
541 let b:InPHPcode = 1
542
Bram Moolenaar1e015462005-09-25 22:16:38 +0000543 if cline =~ '\*/'
544 call cursor(v:lnum, 1)
545 if cline !~ '^\*/'
546 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000547 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000548 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000549
Bram Moolenaar1e015462005-09-25 22:16:38 +0000550 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000551
Bram Moolenaar1e015462005-09-25 22:16:38 +0000552 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000553
Bram Moolenaar1e015462005-09-25 22:16:38 +0000554 if cline =~ '^\s*\*/'
555 return indent(lnum) + 1
556 else
557 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000558 endif
559
Bram Moolenaar1e015462005-09-25 22:16:38 +0000560 elseif cline =~? '<script\>'
561 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000562 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000563 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000564 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000565 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000566
Bram Moolenaared32d942014-12-06 23:33:00 +0100567 if 1 == b:InPHPcode
Bram Moolenaar1e015462005-09-25 22:16:38 +0000568
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000569 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000570 if cline !~? s:PHP_startindenttag
571 let b:InPHPcode = 0
572 let b:InPHPcode_tofind = s:PHP_startindenttag
573 elseif cline =~? '<script\>'
574 let b:InPHPcode_and_script = 1
575 endif
576
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200577 elseif last_line =~ '^[^''"`]\+[''"`]$' " a string identifier with nothing after it and no other string identifier before
Bram Moolenaared32d942014-12-06 23:33:00 +0100578 let b:InPHPcode = -1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200579 let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '')
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100580 elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000581 let b:InPHPcode = 0
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100582 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000583
584 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
585 let b:InPHPcode = 0
586 let b:InPHPcode_tofind = '\*/'
587
588 elseif cline =~? '^\s*</script>'
589 let b:InPHPcode = 0
590 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000591 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000592 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000593
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000594
Bram Moolenaared32d942014-12-06 23:33:00 +0100595 if 1 > b:InPHPcode && !b:InPHPcode_and_script
Bram Moolenaar1e015462005-09-25 22:16:38 +0000596 return -1
597 endif
598
Bram Moolenaar1e015462005-09-25 22:16:38 +0000599 " Indent successive // or # comment the same way the first is {{{
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200600 let addSpecial = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000601 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200602 let addSpecial = b:PHP_outdentSLComments
Bram Moolenaar1e015462005-09-25 22:16:38 +0000603 if b:PHP_LastIndentedWasComment == 1
604 return indent(real_PHP_lastindented)
605 endif
606 let b:PHP_LastIndentedWasComment = 1
607 else
608 let b:PHP_LastIndentedWasComment = 0
609 endif " }}}
610
611 " Indent multiline /* comments correctly {{{
612
613 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
614 if cline =~ '^\s*\*\%(\/\)\@!'
615 if last_line =~ '^\s*/\*'
616 return indent(lnum) + 1
617 else
618 return indent(lnum)
619 endif
620 else
621 let b:PHP_InsideMultilineComment = 0
622 endif
623 endif
624
Bram Moolenaared32d942014-12-06 23:33:00 +0100625 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*\%(.*\*/\)\@!'
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000626 if getline(v:lnum + 1) !~ '^\s*\*'
627 return -1
628 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000629 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000630 endif " }}}
631
632
633 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200634 if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000635 return 0
636 endif
637
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200638 if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000639 return 0
640 endif
641
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200642 if cline =~? '^\s*\a\w*;$\|^\a\w*$\|^\s*[''"`][;,]' && cline !~? s:notPhpHereDoc
Bram Moolenaar1e015462005-09-25 22:16:38 +0000643 return 0
644 endif " }}}
645
646 let s:level = 0
647
648 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000649
Bram Moolenaar1e015462005-09-25 22:16:38 +0000650 let last_line = getline(lnum)
651 let ind = indent(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000652
653 if ind==0 && b:PHP_default_indenting
654 let ind = b:PHP_default_indenting
655 endif
656
657 if lnum == 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200658 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000659 endif
660
661
662 if cline =~ '^\s*}\%(}}\)\@!'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200663 let ind = indent(FindOpenBracket(v:lnum, 1))
Bram Moolenaar1e015462005-09-25 22:16:38 +0000664 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000665 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000666 endif
667
668 if cline =~ '^\s*\*/'
669 call cursor(v:lnum, 1)
670 if cline !~ '^\*/'
671 call search('\*/', 'W')
672 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000673 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000674
675 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
676
677 if cline =~ '^\s*\*/'
678 return indent(lnum) + 1
679 else
680 return indent(lnum)
681 endif
682 endif
683
Bram Moolenaar1e015462005-09-25 22:16:38 +0000684
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200685 if last_line =~ '[;}]'.endline && last_line !~ '^[)\]]' && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000686 if ind==b:PHP_default_indenting
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200687 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000688 elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200689 return b:PHP_CurrentIndentLevel + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000690 endif
691 endif
692
693 let LastLineClosed = 0
694
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200695 let terminated = s:terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000696
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200697 let unstated = s:unstated
698
Bram Moolenaar1e015462005-09-25 22:16:38 +0000699
700 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
701 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
702 return indent(FindTheIfOfAnElse(v:lnum, 1))
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200703 elseif cline =~# s:defaultORcase
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100704 return FindTheSwitchIndent(v:lnum) + s:sw() * b:PHP_vintage_case_default_indent
Bram Moolenaarc236c162008-07-13 17:41:49 +0000705 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000706 let previous_line = last_line
707 let last_line_num = lnum
708
709 while last_line_num > 1
710
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200711 if previous_line =~ terminated || previous_line =~ s:structureHead
Bram Moolenaar1e015462005-09-25 22:16:38 +0000712
713 let ind = indent(last_line_num)
714
715 if b:PHP_BracesAtCodeLevel
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100716 let ind = ind + s:sw()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000717 endif
718
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000719 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000720 endif
721
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200722 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000723 let previous_line = getline(last_line_num)
724 endwhile
725
Bram Moolenaarc236c162008-07-13 17:41:49 +0000726 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200727 let ind = ind + s:sw() " we indent one level further when the preceding line is not stated
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200728 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000729
Bram Moolenaared32d942014-12-06 23:33:00 +0100730 elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000731 let previous_line = last_line
732 let last_line_num = lnum
733 let LastLineClosed = 1
734
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200735 let isSingleLineBlock = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000736 while 1
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200737 if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline " XXX
Bram Moolenaar1e015462005-09-25 22:16:38 +0000738
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200739 call cursor(last_line_num, 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200740 if previous_line !~ '^}'
741 call search('}\|;\s*}'.endline, 'W')
742 end
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200743 let oldLastLine = last_line_num
744 let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()')
745
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200746 if getline(last_line_num) =~ '^\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000747 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200748 elseif oldLastLine == last_line_num
749 let isSingleLineBlock = 1
750 continue
Bram Moolenaar1e015462005-09-25 22:16:38 +0000751 endif
752
753 let previous_line = getline(last_line_num)
754
755 continue
756 else
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200757 let isSingleLineBlock = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000758
759 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
760 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
761 continue
762 endif
763
764
765 let last_match = last_line_num
766
767 let one_ahead_indent = indent(last_line_num)
768 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
769 let two_ahead_indent = indent(last_line_num)
770 let after_previous_line = previous_line
771 let previous_line = getline(last_line_num)
772
773
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200774 if previous_line =~# s:defaultORcase.'\|{'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000775 break
776 endif
777
778 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
779 break
780 endif
781
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000782 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000783 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000784 break
785 endif
786 endif
787 endif
788 endwhile
789
790 if indent(last_match) != ind
791 let ind = indent(last_match)
792 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
793
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200794 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000795 endif
796 endif
797
Bram Moolenaared32d942014-12-06 23:33:00 +0100798 if (last_line !~ '^\s*}\%(}}\)\@!')
799 let plinnum = GetLastRealCodeLNum(lnum - 1)
800 else
801 let plinnum = GetLastRealCodeLNum(FindOpenBracket(lnum, 1) - 1)
802 endif
803
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200804 let AntepenultimateLine = getline(plinnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000805
806 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
807
808
809 if ind == b:PHP_default_indenting
Bram Moolenaared32d942014-12-06 23:33:00 +0100810 if last_line =~ terminated && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000811 let LastLineClosed = 1
812 endif
813 endif
814
815 if !LastLineClosed
816
Bram Moolenaar5c736222010-01-06 20:54:52 +0100817
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200818 if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline && BalanceDirection(last_line) > 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000819
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200820 let dontIndent = 0
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200821 if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*[)\]]\+\s*{'.endline && last_line !~ s:structureHead
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200822 let dontIndent = 1
823 endif
824
825 if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{')
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100826 let ind = ind + s:sw()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000827 endif
828
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200829 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000830 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaarc236c162008-07-13 17:41:49 +0000831
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200832 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000833 endif
834
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200835 elseif last_line =~ '\S\+\s*),'.endline && BalanceDirection(last_line) < 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000836 call cursor(lnum, 1)
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200837 call search('),'.endline, 'W') " line never begins with ) so no need for 'c' flag
Bram Moolenaar1e015462005-09-25 22:16:38 +0000838 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
839 if openedparent != lnum
840 let ind = indent(openedparent)
841 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200842
Bram Moolenaarc236c162008-07-13 17:41:49 +0000843 elseif last_line =~ '^\s*'.s:blockstart
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100844 let ind = ind + s:sw()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000845
Bram Moolenaarc236c162008-07-13 17:41:49 +0000846
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200847 elseif AntepenultimateLine =~ '{'.endline && AntepenultimateLine !~? '^\s*use\>' || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100848 let ind = ind + s:sw()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000849 endif
850
Bram Moolenaar1e015462005-09-25 22:16:38 +0000851 endif
852
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200853 if cline =~ '^\s*[)\]];\='
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100854 let ind = ind - s:sw()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000855 endif
856
857 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200858 return ind + addSpecial
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000859endfunction