blob: d13a0a103455db1a3d8bf84fd64428e69ce812dc [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 Moolenaar259f26a2018-05-15 22:25:40 +02006" Last Change: 2018 May 14
Bram Moolenaare0720cb2017-03-29 13:48:40 +02007" 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 Moolenaar259f26a2018-05-15 22:25:40 +020015" If you find a bug, please open a ticket on github.com
Bram Moolenaare6ae6222013-05-21 21:01:10 +020016" ( 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 Moolenaare6ae6222013-05-21 21:01:10 +020053
Bram Moolenaar9ff70112005-07-11 22:29:03 +000054if exists("PHP_default_indenting")
Bram Moolenaar3ec574f2017-06-13 18:12:01 +020055 let b:PHP_default_indenting = PHP_default_indenting * shiftwidth()
Bram Moolenaar9ff70112005-07-11 22:29:03 +000056else
Bram Moolenaar1e015462005-09-25 22:16:38 +000057 let b:PHP_default_indenting = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000058endif
59
Bram Moolenaare6ae6222013-05-21 21:01:10 +020060if exists("PHP_outdentSLComments")
Bram Moolenaar3ec574f2017-06-13 18:12:01 +020061 let b:PHP_outdentSLComments = PHP_outdentSLComments * shiftwidth()
Bram Moolenaare6ae6222013-05-21 21:01:10 +020062else
63 let b:PHP_outdentSLComments = 0
64endif
65
Bram Moolenaar9ff70112005-07-11 22:29:03 +000066if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000067 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000068else
Bram Moolenaar1e015462005-09-25 22:16:38 +000069 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000070endif
71
Bram Moolenaarc236c162008-07-13 17:41:49 +000072
Bram Moolenaara5792f52005-11-23 21:25:05 +000073if exists("PHP_autoformatcomment")
74 let b:PHP_autoformatcomment = PHP_autoformatcomment
75else
76 let b:PHP_autoformatcomment = 1
77endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000078
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020079if exists("PHP_outdentphpescape")
80 let b:PHP_outdentphpescape = PHP_outdentphpescape
81else
82 let b:PHP_outdentphpescape = 1
83endif
84
85
86if exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent
87 let b:PHP_vintage_case_default_indent = 1
Bram Moolenaarc236c162008-07-13 17:41:49 +000088else
89 let b:PHP_vintage_case_default_indent = 0
90endif
91
92
93
Bram Moolenaar9ff70112005-07-11 22:29:03 +000094let b:PHP_lastindented = 0
95let b:PHP_indentbeforelast = 0
96let b:PHP_indentinghuge = 0
97let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
98let b:PHP_LastIndentedWasComment = 0
99let b:PHP_InsideMultilineComment = 0
100let b:InPHPcode = 0
101let b:InPHPcode_checked = 0
102let b:InPHPcode_and_script = 0
103let b:InPHPcode_tofind = ""
104let b:PHP_oldchangetick = b:changedtick
105let b:UserIsTypingComment = 0
106let b:optionsset = 0
107
108setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000109setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000110setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +0000111setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000112
Bram Moolenaar071d4272004-06-13 20:20:40 +0000113setlocal indentexpr=GetPhpIndent()
Bram Moolenaared32d942014-12-06 23:33:00 +0100114setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000115
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000116
Bram Moolenaar1e015462005-09-25 22:16:38 +0000117
118let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000119
120if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000121 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000122endif
123
Bram Moolenaar071d4272004-06-13 20:20:40 +0000124if exists("*GetPhpIndent")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100125 call ResetPhpOptions()
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100126 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +0000127endif
128
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200129
Bram Moolenaared32d942014-12-06 23:33:00 +0100130let s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200131let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\)'
132let 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 +0100133let s:functionDecl = '\<function\>\%(\s\+'.s:PHP_validVariable.'\)\=\s*(.*'
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200134let s:endline = '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
135let s:unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.s:endline
Bram Moolenaared32d942014-12-06 23:33:00 +0100136
137
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200138let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000139let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200140let s:structureHead = '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline . '\|\<new\s\+class\>'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000141
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000142
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200143
144let s:escapeDebugStops = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200145function! DebugPrintReturn(scriptLine)
146
Bram Moolenaared32d942014-12-06 23:33:00 +0100147 if ! s:escapeDebugStops
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200148 echo "debug:" . a:scriptLine
149 let c = getchar()
150 if c == "\<Del>"
151 let s:escapeDebugStops = 1
152 end
153 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200154
155endfunction
156
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000157function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000158
Bram Moolenaar1e015462005-09-25 22:16:38 +0000159 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000160
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000161 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
162 let lnum = b:GetLastRealCodeLNum_ADD
163 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000164
Bram Moolenaar1e015462005-09-25 22:16:38 +0000165 while lnum > 1
166 let lnum = prevnonblank(lnum)
167 let lastline = getline(lnum)
168
169 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
170 let lnum = lnum - 1
171 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
172 let lnum = lnum - 1
173 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
174 let lnum = lnum - 1
175 elseif lastline =~ '\*/\s*$'
176 call cursor(lnum, 1)
177 if lastline !~ '^\*/'
178 call search('\*/', 'W')
179 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000180 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000181
182 let lastline = getline(lnum)
183 if lastline =~ '^\s*/\*'
184 let lnum = lnum - 1
185 else
186 break
187 endif
188
189
190 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
191
192 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
193 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000194 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000195 endwhile
196 if lastline =~ '^\s*?>'
197 let lnum = lnum - 1
198 else
199 break
200 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000201
202
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200203 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100204 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000205 while getline(lnum) !~? tofind && lnum > 1
206 let lnum = lnum - 1
207 endwhile
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200208 elseif lastline =~ '^[^''"`]*[''"`][;,]'.s:endline
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200209
210 let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '')
211 let trylnum = lnum
212 while getline(trylnum) !~? tofind && trylnum > 1
213 let trylnum = trylnum - 1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200214 endwhile
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200215
216 if trylnum == 1
217 break
218 else
219 if lastline =~ ';'.s:endline
220 while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1
221 let trylnum = prevnonblank(trylnum - 1)
222 endwhile
223
224
225 if trylnum == 1
226 break
227 end
228 end
229 let lnum = trylnum
230 end
Bram Moolenaar1e015462005-09-25 22:16:38 +0000231 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000232 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000233 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000234 endwhile
235
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200236 if lnum==1 && getline(lnum) !~ '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000237 let lnum=0
238 endif
239
Bram Moolenaared32d942014-12-06 23:33:00 +0100240 if b:InPHPcode_and_script && 1 > b:InPHPcode
Bram Moolenaar1e015462005-09-25 22:16:38 +0000241 let b:InPHPcode_and_script = 0
242 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000243
Bram Moolenaar1e015462005-09-25 22:16:38 +0000244 return lnum
245endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000246
Bram Moolenaara5792f52005-11-23 21:25:05 +0000247function! Skippmatch2()
248
249 let line = getline(".")
250
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200251 if line =~ "\\([\"']\\).*/\\*.*\\1" || line =~ '\%(//\|#\).*/\*'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200252 return 1
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200253 else
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200254 return 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200255 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000256endfun
257
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200258function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000259 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaared32d942014-12-06 23:33:00 +0100260 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 +0000261 return 0
262 else
263 return 1
264 endif
265endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000266
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200267function! FindOpenBracket(lnum, blockStarter) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000268 call cursor(a:lnum, 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200269 let line = searchpair('{', '', '}', 'bW', 'Skippmatch()')
270
271 if a:blockStarter == 1
Bram Moolenaared32d942014-12-06 23:33:00 +0100272 while line > 1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200273 let linec = getline(line)
274
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200275 if linec =~ s:terminated || linec =~ s:structureHead
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200276 break
277 endif
278
279 let line = GetLastRealCodeLNum(line - 1)
280 endwhile
281 endif
282
283 return line
Bram Moolenaar1e015462005-09-25 22:16:38 +0000284endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000285
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200286let s:blockChars = {'{':1, '[': 1, '(': 1, ')':-1, ']':-1, '}':-1}
287function! BalanceDirection (str)
288
289 let balance = 0
290
291 for c in split(a:str, '\zs')
292 if has_key(s:blockChars, c)
293 let balance += s:blockChars[c]
294 endif
295 endfor
296
297 return balance
298endfun
299
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000300function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000301
302 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
303 let beforeelse = a:lnum
304 else
305 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
306 endif
307
308 if !s:level
309 let s:iftoskip = 0
310 endif
311
312 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
313 let s:iftoskip = s:iftoskip + 1
314 endif
315
316 if getline(beforeelse) =~ '^\s*}'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200317 let beforeelse = FindOpenBracket(beforeelse, 0)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000318
319 if getline(beforeelse) =~ '^\s*{'
320 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000321 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000322 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000323
324
Bram Moolenaar1e015462005-09-25 22:16:38 +0000325 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000326 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000327 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000328
Bram Moolenaar1e015462005-09-25 22:16:38 +0000329 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
330
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200331 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000332 let s:iftoskip = s:iftoskip - 1
333 endif
334
335 let s:level = s:level + 1
336 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
337 endif
338
339 return beforeelse
340
341endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000342
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200343let s:defaultORcase = '^\s*\%(default\|case\).*:'
344
345function! FindTheSwitchIndent (lnum) " {{{
346
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200347 let test = GetLastRealCodeLNum(a:lnum - 1)
348
349 if test <= 1
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200350 return indent(1) - shiftwidth() * b:PHP_vintage_case_default_indent
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200351 end
352
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200353 while getline(test) =~ '^\s*}' && test > 1
354 let test = GetLastRealCodeLNum(FindOpenBracket(test, 0) - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200355
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200356 if getline(test) =~ '^\s*switch\>'
357 let test = GetLastRealCodeLNum(test - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200358 endif
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200359 endwhile
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200360
361 if getline(test) =~# '^\s*switch\>'
362 return indent(test)
363 elseif getline(test) =~# s:defaultORcase
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200364 return indent(test) - shiftwidth() * b:PHP_vintage_case_default_indent
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200365 else
366 return FindTheSwitchIndent(test)
367 endif
368
369endfunction "}}}
370
Bram Moolenaar3b1db362013-08-10 15:00:24 +0200371let s:SynPHPMatchGroups = {'phpParent':1, 'Delimiter':1, 'Define':1, 'Storageclass':1, 'StorageClass':1, 'Structure':1, 'Exception':1}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000372function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000373 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000374
Bram Moolenaar1e015462005-09-25 22:16:38 +0000375 if a:tofind==""
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200376 let tofind = "^\\s*[\"'`]*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000377 else
378 let tofind = a:tofind
379 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000380
Bram Moolenaar1e015462005-09-25 22:16:38 +0000381 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000382
Bram Moolenaar1e015462005-09-25 22:16:38 +0000383 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000384
Bram Moolenaar1e015462005-09-25 22:16:38 +0000385 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
386
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200387 if synname == 'phpStringSingle' || synname == 'phpStringDouble' || synname == 'phpBacktick'
388 if cline !~ '^\s*[''"`]'
Bram Moolenaared32d942014-12-06 23:33:00 +0100389 return "SpecStringEntrails"
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200390 else
391 return synname
392 end
393 end
394
Bram Moolenaar9d98fe92013-08-03 18:35:36 +0200395 if get(s:SynPHPMatchGroups, synname) || synname =~ '^php' || synname =~? '^javaScript'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000396 return synname
397 else
398 return ""
399 endif
400endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000401
Bram Moolenaar5c736222010-01-06 20:54:52 +0100402let s:autoresetoptions = 0
403if ! s:autoresetoptions
404 let s:autoresetoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000405endif
406
Bram Moolenaar5c736222010-01-06 20:54:52 +0100407function! ResetPhpOptions()
Bram Moolenaared32d942014-12-06 23:33:00 +0100408 if ! b:optionsset && &filetype =~ "php"
Bram Moolenaara5792f52005-11-23 21:25:05 +0000409 if b:PHP_autoformatcomment
410
411 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000412
Bram Moolenaarc236c162008-07-13 17:41:49 +0000413 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000414 setlocal formatoptions+=q
415 setlocal formatoptions+=r
416 setlocal formatoptions+=o
Bram Moolenaara5792f52005-11-23 21:25:05 +0000417 setlocal formatoptions+=c
418 setlocal formatoptions+=b
419 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000420 let b:optionsset = 1
421 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000422endfunc
423
Bram Moolenaar5c736222010-01-06 20:54:52 +0100424call ResetPhpOptions()
425
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000426function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000427
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000428 let b:GetLastRealCodeLNum_ADD = 0
429
Bram Moolenaar1e015462005-09-25 22:16:38 +0000430 let UserIsEditing=0
431 if b:PHP_oldchangetick != b:changedtick
432 let b:PHP_oldchangetick = b:changedtick
433 let UserIsEditing=1
434 endif
435
436 if b:PHP_default_indenting
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200437 let b:PHP_default_indenting = g:PHP_default_indenting * shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000438 endif
439
440 let cline = getline(v:lnum)
441
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000442 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000443 if b:PHP_indentbeforelast
444 let b:PHP_indentinghuge = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000445 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000446 let b:PHP_indentbeforelast = b:PHP_lastindented
447 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000448
Bram Moolenaar1e015462005-09-25 22:16:38 +0000449 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
450 if b:PHP_indentinghuge
Bram Moolenaar1e015462005-09-25 22:16:38 +0000451 let b:PHP_indentinghuge = 0
452 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000453 endif
Bram Moolenaared32d942014-12-06 23:33:00 +0100454 let real_PHP_lastindented = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000455 let b:PHP_LastIndentedWasComment=0
456 let b:PHP_InsideMultilineComment=0
457 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000458
Bram Moolenaar1e015462005-09-25 22:16:38 +0000459 let b:InPHPcode = 0
460 let b:InPHPcode_checked = 0
461 let b:InPHPcode_and_script = 0
462 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000463
Bram Moolenaar1e015462005-09-25 22:16:38 +0000464 elseif v:lnum > b:PHP_lastindented
465 let real_PHP_lastindented = b:PHP_lastindented
Bram Moolenaared32d942014-12-06 23:33:00 +0100466 else
467 let real_PHP_lastindented = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000468 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000469
Bram Moolenaared32d942014-12-06 23:33:00 +0100470 let b:PHP_lastindented = v:lnum
471
Bram Moolenaar1e015462005-09-25 22:16:38 +0000472
473 if !b:InPHPcode_checked " {{{ One time check
474 let b:InPHPcode_checked = 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100475 let b:UserIsTypingComment = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000476
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000477 let synname = ""
478 if cline !~ '<?.*?>'
479 let synname = IslinePHP (prevnonblank(v:lnum), "")
480 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000481
482 if synname!=""
Bram Moolenaared32d942014-12-06 23:33:00 +0100483 if synname == "SpecStringEntrails"
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200484 let b:InPHPcode = -1 " thumb down
Bram Moolenaared32d942014-12-06 23:33:00 +0100485 let b:InPHPcode_tofind = ""
486 elseif synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000487 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000488 let b:InPHPcode_tofind = ""
489
Bram Moolenaared32d942014-12-06 23:33:00 +0100490 if synname =~# '^php\%(Doc\)\?Comment'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000491 let b:UserIsTypingComment = 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100492 let b:InPHPcode_checked = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000493 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000494
Bram Moolenaar1e015462005-09-25 22:16:38 +0000495 if synname =~? '^javaScript'
496 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000497 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000498
Bram Moolenaar1e015462005-09-25 22:16:38 +0000499 else
500 let b:InPHPcode = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000501
Bram Moolenaar1e015462005-09-25 22:16:38 +0000502 let lnum = v:lnum - 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100503 while getline(lnum) !~? '<<<\s*[''"]\=\a\w*[''"]\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000504 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000505 endwhile
506
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100507 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000508 endif
509 else
510 let b:InPHPcode = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200511 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000512 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000513 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000514
515
Bram Moolenaar1e015462005-09-25 22:16:38 +0000516 " Test if we are indenting PHP code {{{
517 let lnum = prevnonblank(v:lnum - 1)
518 let last_line = getline(lnum)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200519 let endline= s:endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000520
521 if b:InPHPcode_tofind!=""
522 if cline =~? b:InPHPcode_tofind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000523 let b:InPHPcode_tofind = ""
524 let b:UserIsTypingComment = 0
Bram Moolenaared32d942014-12-06 23:33:00 +0100525
526 if b:InPHPcode == -1
527 let b:InPHPcode = 1
528 return -1
529 end
530
531 let b:InPHPcode = 1
532
Bram Moolenaar1e015462005-09-25 22:16:38 +0000533 if cline =~ '\*/'
534 call cursor(v:lnum, 1)
535 if cline !~ '^\*/'
536 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000537 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000538 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000539
Bram Moolenaar1e015462005-09-25 22:16:38 +0000540 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000541
Bram Moolenaar1e015462005-09-25 22:16:38 +0000542 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000543
Bram Moolenaar1e015462005-09-25 22:16:38 +0000544 if cline =~ '^\s*\*/'
545 return indent(lnum) + 1
546 else
547 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000548 endif
549
Bram Moolenaar1e015462005-09-25 22:16:38 +0000550 elseif cline =~? '<script\>'
551 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000552 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000553 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000554 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000555 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000556
Bram Moolenaared32d942014-12-06 23:33:00 +0100557 if 1 == b:InPHPcode
Bram Moolenaar1e015462005-09-25 22:16:38 +0000558
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000559 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000560 if cline !~? s:PHP_startindenttag
561 let b:InPHPcode = 0
562 let b:InPHPcode_tofind = s:PHP_startindenttag
563 elseif cline =~? '<script\>'
564 let b:InPHPcode_and_script = 1
565 endif
566
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200567 elseif last_line =~ '^[^''"`]\+[''"`]$' " a string identifier with nothing after it and no other string identifier before
Bram Moolenaared32d942014-12-06 23:33:00 +0100568 let b:InPHPcode = -1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200569 let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '')
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100570 elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000571 let b:InPHPcode = 0
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100572 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000573
574 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
575 let b:InPHPcode = 0
576 let b:InPHPcode_tofind = '\*/'
577
578 elseif cline =~? '^\s*</script>'
579 let b:InPHPcode = 0
580 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000581 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000582 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000583
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000584
Bram Moolenaared32d942014-12-06 23:33:00 +0100585 if 1 > b:InPHPcode && !b:InPHPcode_and_script
Bram Moolenaar1e015462005-09-25 22:16:38 +0000586 return -1
587 endif
588
Bram Moolenaar1e015462005-09-25 22:16:38 +0000589 " Indent successive // or # comment the same way the first is {{{
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200590 let addSpecial = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000591 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200592 let addSpecial = b:PHP_outdentSLComments
Bram Moolenaar1e015462005-09-25 22:16:38 +0000593 if b:PHP_LastIndentedWasComment == 1
594 return indent(real_PHP_lastindented)
595 endif
596 let b:PHP_LastIndentedWasComment = 1
597 else
598 let b:PHP_LastIndentedWasComment = 0
599 endif " }}}
600
601 " Indent multiline /* comments correctly {{{
602
603 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
604 if cline =~ '^\s*\*\%(\/\)\@!'
605 if last_line =~ '^\s*/\*'
606 return indent(lnum) + 1
607 else
608 return indent(lnum)
609 endif
610 else
611 let b:PHP_InsideMultilineComment = 0
612 endif
613 endif
614
Bram Moolenaared32d942014-12-06 23:33:00 +0100615 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*\%(.*\*/\)\@!'
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000616 if getline(v:lnum + 1) !~ '^\s*\*'
617 return -1
618 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000619 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000620 endif " }}}
621
622
623 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200624 if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000625 return 0
626 endif
627
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200628 if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000629 return 0
630 endif
631
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200632 if cline =~? '^\s*\a\w*;$\|^\a\w*$\|^\s*[''"`][;,]' && cline !~? s:notPhpHereDoc
Bram Moolenaar1e015462005-09-25 22:16:38 +0000633 return 0
634 endif " }}}
635
636 let s:level = 0
637
638 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000639
Bram Moolenaar1e015462005-09-25 22:16:38 +0000640 let last_line = getline(lnum)
641 let ind = indent(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000642
643 if ind==0 && b:PHP_default_indenting
644 let ind = b:PHP_default_indenting
645 endif
646
647 if lnum == 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200648 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000649 endif
650
651
652 if cline =~ '^\s*}\%(}}\)\@!'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200653 let ind = indent(FindOpenBracket(v:lnum, 1))
Bram Moolenaar1e015462005-09-25 22:16:38 +0000654 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000655 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000656 endif
657
658 if cline =~ '^\s*\*/'
659 call cursor(v:lnum, 1)
660 if cline !~ '^\*/'
661 call search('\*/', 'W')
662 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000663 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000664
665 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
666
667 if cline =~ '^\s*\*/'
668 return indent(lnum) + 1
669 else
670 return indent(lnum)
671 endif
672 endif
673
Bram Moolenaar1e015462005-09-25 22:16:38 +0000674
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200675 if last_line =~ '[;}]'.endline && last_line !~ '^[)\]]' && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000676 if ind==b:PHP_default_indenting
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200677 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000678 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 +0200679 return b:PHP_CurrentIndentLevel + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000680 endif
681 endif
682
683 let LastLineClosed = 0
684
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200685 let terminated = s:terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000686
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200687 let unstated = s:unstated
688
Bram Moolenaar1e015462005-09-25 22:16:38 +0000689
690 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
691 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
692 return indent(FindTheIfOfAnElse(v:lnum, 1))
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200693 elseif cline =~# s:defaultORcase
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200694 return FindTheSwitchIndent(v:lnum) + shiftwidth() * b:PHP_vintage_case_default_indent
Bram Moolenaarc236c162008-07-13 17:41:49 +0000695 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000696 let previous_line = last_line
697 let last_line_num = lnum
698
699 while last_line_num > 1
700
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200701 if previous_line =~ terminated || previous_line =~ s:structureHead
Bram Moolenaar1e015462005-09-25 22:16:38 +0000702
703 let ind = indent(last_line_num)
704
705 if b:PHP_BracesAtCodeLevel
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200706 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000707 endif
708
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000709 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000710 endif
711
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200712 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000713 let previous_line = getline(last_line_num)
714 endwhile
715
Bram Moolenaarc236c162008-07-13 17:41:49 +0000716 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200717 let ind = ind + shiftwidth() " we indent one level further when the preceding line is not stated
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200718 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000719
Bram Moolenaared32d942014-12-06 23:33:00 +0100720 elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000721 let previous_line = last_line
722 let last_line_num = lnum
723 let LastLineClosed = 1
724
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200725 let isSingleLineBlock = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000726 while 1
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200727 if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline " XXX
Bram Moolenaar1e015462005-09-25 22:16:38 +0000728
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200729 call cursor(last_line_num, 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200730 if previous_line !~ '^}'
731 call search('}\|;\s*}'.endline, 'W')
732 end
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200733 let oldLastLine = last_line_num
734 let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()')
735
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200736 if getline(last_line_num) =~ '^\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000737 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200738 elseif oldLastLine == last_line_num
739 let isSingleLineBlock = 1
740 continue
Bram Moolenaar1e015462005-09-25 22:16:38 +0000741 endif
742
743 let previous_line = getline(last_line_num)
744
745 continue
746 else
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200747 let isSingleLineBlock = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000748
749 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
750 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
751 continue
752 endif
753
754
755 let last_match = last_line_num
756
757 let one_ahead_indent = indent(last_line_num)
758 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
759 let two_ahead_indent = indent(last_line_num)
760 let after_previous_line = previous_line
761 let previous_line = getline(last_line_num)
762
763
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200764 if previous_line =~# s:defaultORcase.'\|{'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000765 break
766 endif
767
768 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
769 break
770 endif
771
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000772 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000773 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000774 break
775 endif
776 endif
777 endif
778 endwhile
779
780 if indent(last_match) != ind
781 let ind = indent(last_match)
782 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
783
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200784 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000785 endif
786 endif
787
Bram Moolenaared32d942014-12-06 23:33:00 +0100788 if (last_line !~ '^\s*}\%(}}\)\@!')
789 let plinnum = GetLastRealCodeLNum(lnum - 1)
790 else
791 let plinnum = GetLastRealCodeLNum(FindOpenBracket(lnum, 1) - 1)
792 endif
793
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200794 let AntepenultimateLine = getline(plinnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000795
796 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
797
798
799 if ind == b:PHP_default_indenting
Bram Moolenaared32d942014-12-06 23:33:00 +0100800 if last_line =~ terminated && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000801 let LastLineClosed = 1
802 endif
803 endif
804
805 if !LastLineClosed
806
Bram Moolenaar5c736222010-01-06 20:54:52 +0100807
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200808 if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline && BalanceDirection(last_line) > 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000809
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200810 let dontIndent = 0
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200811 if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*[)\]]\+\s*{'.endline && last_line !~ s:structureHead
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200812 let dontIndent = 1
813 endif
814
815 if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{')
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200816 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000817 endif
818
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200819 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000820 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaarc236c162008-07-13 17:41:49 +0000821
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200822 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000823 endif
824
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200825 elseif last_line =~ '\S\+\s*),'.endline && BalanceDirection(last_line) < 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000826 call cursor(lnum, 1)
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200827 call search('),'.endline, 'W') " line never begins with ) so no need for 'c' flag
Bram Moolenaar1e015462005-09-25 22:16:38 +0000828 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
829 if openedparent != lnum
830 let ind = indent(openedparent)
831 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200832
Bram Moolenaarc236c162008-07-13 17:41:49 +0000833 elseif last_line =~ '^\s*'.s:blockstart
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200834 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000835
Bram Moolenaarc236c162008-07-13 17:41:49 +0000836
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200837 elseif AntepenultimateLine =~ '{'.endline && AntepenultimateLine !~? '^\s*use\>' || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200838 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000839 endif
840
Bram Moolenaar1e015462005-09-25 22:16:38 +0000841 endif
842
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200843 if cline =~ '^\s*[)\]];\='
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200844 let ind = ind - shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000845 endif
846
847 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200848 return ind + addSpecial
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000849endfunction