blob: 0e623689d5e05c0f9fd8d45453e0f9f7167d6f58 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim indent file
2" Language: PHP
Bram Moolenaar54775062019-07-31 21:07:14 +02003" Author: John Wellesz <John.wellesz (AT) gmail (DOT) com>
4" URL: https://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 Moolenaarb17893a2020-03-14 08:19:51 +01006" Last Change: 2020 Mar 05
Bram Moolenaar54775062019-07-31 21:07:14 +02007" Version: 1.70
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 Moolenaar54775062019-07-31 21:07:14 +020022" script by Peter Hodge (https://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 Moolenaar071d4272004-06-13 20:20:40 +000044if exists("b:did_indent")
Bram Moolenaar1e015462005-09-25 22:16:38 +000045 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +000046endif
47let b:did_indent = 1
48
Bram Moolenaar9ff70112005-07-11 22:29:03 +000049
Bram Moolenaared32d942014-12-06 23:33:00 +010050let g:php_sync_method = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000051
Bram Moolenaare6ae6222013-05-21 21:01:10 +020052
Bram Moolenaar9ff70112005-07-11 22:29:03 +000053if exists("PHP_default_indenting")
Bram Moolenaar3ec574f2017-06-13 18:12:01 +020054 let b:PHP_default_indenting = PHP_default_indenting * shiftwidth()
Bram Moolenaar9ff70112005-07-11 22:29:03 +000055else
Bram Moolenaar1e015462005-09-25 22:16:38 +000056 let b:PHP_default_indenting = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000057endif
58
Bram Moolenaare6ae6222013-05-21 21:01:10 +020059if exists("PHP_outdentSLComments")
Bram Moolenaar3ec574f2017-06-13 18:12:01 +020060 let b:PHP_outdentSLComments = PHP_outdentSLComments * shiftwidth()
Bram Moolenaare6ae6222013-05-21 21:01:10 +020061else
62 let b:PHP_outdentSLComments = 0
63endif
64
Bram Moolenaar9ff70112005-07-11 22:29:03 +000065if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000066 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000067else
Bram Moolenaar1e015462005-09-25 22:16:38 +000068 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000069endif
70
Bram Moolenaarc236c162008-07-13 17:41:49 +000071
Bram Moolenaara5792f52005-11-23 21:25:05 +000072if exists("PHP_autoformatcomment")
73 let b:PHP_autoformatcomment = PHP_autoformatcomment
74else
75 let b:PHP_autoformatcomment = 1
76endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000077
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020078if exists("PHP_outdentphpescape")
79 let b:PHP_outdentphpescape = PHP_outdentphpescape
80else
81 let b:PHP_outdentphpescape = 1
82endif
83
Bram Moolenaar0b0f0992018-05-22 21:41:30 +020084if exists("PHP_noArrowMatching")
85 let b:PHP_noArrowMatching = PHP_noArrowMatching
86else
87 let b:PHP_noArrowMatching = 0
88endif
89
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020090
91if exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent
92 let b:PHP_vintage_case_default_indent = 1
Bram Moolenaarc236c162008-07-13 17:41:49 +000093else
94 let b:PHP_vintage_case_default_indent = 0
95endif
96
Bram Moolenaar54775062019-07-31 21:07:14 +020097if exists("PHP_IndentFunctionCallParameters")
98 let b:PHP_IndentFunctionCallParameters = PHP_IndentFunctionCallParameters
99else
100 let b:PHP_IndentFunctionCallParameters = 0
101endif
Bram Moolenaarc236c162008-07-13 17:41:49 +0000102
Bram Moolenaar54775062019-07-31 21:07:14 +0200103if exists("PHP_IndentFunctionDeclarationParameters")
104 let b:PHP_IndentFunctionDeclarationParameters = PHP_IndentFunctionDeclarationParameters
105else
106 let b:PHP_IndentFunctionDeclarationParameters = 0
107endif
Bram Moolenaarc236c162008-07-13 17:41:49 +0000108
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000109let b:PHP_lastindented = 0
110let b:PHP_indentbeforelast = 0
111let b:PHP_indentinghuge = 0
112let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
113let b:PHP_LastIndentedWasComment = 0
114let b:PHP_InsideMultilineComment = 0
115let b:InPHPcode = 0
116let b:InPHPcode_checked = 0
117let b:InPHPcode_and_script = 0
118let b:InPHPcode_tofind = ""
119let b:PHP_oldchangetick = b:changedtick
120let b:UserIsTypingComment = 0
121let b:optionsset = 0
122
123setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000124setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000125setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +0000126setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000127
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128setlocal indentexpr=GetPhpIndent()
Bram Moolenaared32d942014-12-06 23:33:00 +0100129setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000130
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000131
Bram Moolenaar1e015462005-09-25 22:16:38 +0000132
133let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000134
135if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000136 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000137endif
138
Bram Moolenaar071d4272004-06-13 20:20:40 +0000139if exists("*GetPhpIndent")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100140 call ResetPhpOptions()
Bram Moolenaar54775062019-07-31 21:07:14 +0200141 finish " XXX -- comment this line for easy dev
Bram Moolenaar071d4272004-06-13 20:20:40 +0000142endif
143
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200144
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200145let s:endline = '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
Bram Moolenaar54775062019-07-31 21:07:14 +0200146let s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
147let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\|end\%(if\|while\|for\|foreach\|switch\)\)'
148let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|\%(}\s*\)\?else\>\|do\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|trait\>\|\%()\s*\)\=use\>\|interface\>\|abstract\>\|final\>\|try\>\|\%(}\s*\)\=catch\>\|\%(}\s*\)\=finally\>\)'
149let s:functionDeclPrefix = '\<function\>\%(\s\+&\='.s:PHP_validVariable.'\)\=\s*('
150let s:functionDecl = s:functionDeclPrefix.'.*'
151let s:multilineFunctionDecl = s:functionDeclPrefix.s:endline
152let s:arrayDecl = '\<array\>\s*(.*'
153let s:multilineFunctionCall = s:PHP_validVariable.'\s*('.s:endline
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200154let s:unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.s:endline
Bram Moolenaared32d942014-12-06 23:33:00 +0100155
156
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200157let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000158let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200159let s:structureHead = '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline . '\|\<new\s\+class\>'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000160
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000161
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200162let s:escapeDebugStops = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200163function! DebugPrintReturn(scriptLine)
164
Bram Moolenaared32d942014-12-06 23:33:00 +0100165 if ! s:escapeDebugStops
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200166 echo "debug:" . a:scriptLine
167 let c = getchar()
168 if c == "\<Del>"
169 let s:escapeDebugStops = 1
170 end
171 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200172
173endfunction
174
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000175function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000176
Bram Moolenaar1e015462005-09-25 22:16:38 +0000177 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000178
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000179 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
180 let lnum = b:GetLastRealCodeLNum_ADD
181 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000182
Bram Moolenaar1e015462005-09-25 22:16:38 +0000183 while lnum > 1
184 let lnum = prevnonblank(lnum)
185 let lastline = getline(lnum)
186
187 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
188 let lnum = lnum - 1
189 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
190 let lnum = lnum - 1
191 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
192 let lnum = lnum - 1
193 elseif lastline =~ '\*/\s*$'
194 call cursor(lnum, 1)
195 if lastline !~ '^\*/'
196 call search('\*/', 'W')
197 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000198 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000199
200 let lastline = getline(lnum)
201 if lastline =~ '^\s*/\*'
202 let lnum = lnum - 1
203 else
204 break
205 endif
206
207
208 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
209
210 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
211 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000212 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000213 endwhile
214 if lastline =~ '^\s*?>'
215 let lnum = lnum - 1
216 else
217 break
218 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000219
220
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200221 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100222 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000223 while getline(lnum) !~? tofind && lnum > 1
224 let lnum = lnum - 1
225 endwhile
Bram Moolenaar54775062019-07-31 21:07:14 +0200226 elseif lastline =~ '^\s*[''"`][;,]' || (lastline =~ '^[^''"`]*[''"`][;,]'.s:endline && IslinePHP(lnum, "") == "SpecStringEntrails")
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200227
228 let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '')
229 let trylnum = lnum
230 while getline(trylnum) !~? tofind && trylnum > 1
231 let trylnum = trylnum - 1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200232 endwhile
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200233
234 if trylnum == 1
235 break
236 else
237 if lastline =~ ';'.s:endline
238 while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1
239 let trylnum = prevnonblank(trylnum - 1)
240 endwhile
241
242
243 if trylnum == 1
244 break
245 end
246 end
247 let lnum = trylnum
248 end
Bram Moolenaar1e015462005-09-25 22:16:38 +0000249 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000250 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000251 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000252 endwhile
253
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200254 if lnum==1 && getline(lnum) !~ '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000255 let lnum=0
256 endif
257
Bram Moolenaared32d942014-12-06 23:33:00 +0100258 if b:InPHPcode_and_script && 1 > b:InPHPcode
Bram Moolenaar1e015462005-09-25 22:16:38 +0000259 let b:InPHPcode_and_script = 0
260 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000261
Bram Moolenaar1e015462005-09-25 22:16:38 +0000262 return lnum
263endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000264
Bram Moolenaara5792f52005-11-23 21:25:05 +0000265function! Skippmatch2()
266
267 let line = getline(".")
268
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200269 if line =~ "\\([\"']\\).*/\\*.*\\1" || line =~ '\%(//\|#\).*/\*'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200270 return 1
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200271 else
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200272 return 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200273 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000274endfun
275
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200276function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000277 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200278 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 +0000279 return 0
280 else
281 return 1
282 endif
283endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000284
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200285function! FindOpenBracket(lnum, blockStarter) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000286 call cursor(a:lnum, 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200287 let line = searchpair('{', '', '}', 'bW', 'Skippmatch()')
288
289 if a:blockStarter == 1
Bram Moolenaared32d942014-12-06 23:33:00 +0100290 while line > 1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200291 let linec = getline(line)
292
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200293 if linec =~ s:terminated || linec =~ s:structureHead
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200294 break
295 endif
296
297 let line = GetLastRealCodeLNum(line - 1)
298 endwhile
299 endif
300
301 return line
Bram Moolenaar1e015462005-09-25 22:16:38 +0000302endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000303
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200304let s:blockChars = {'{':1, '[': 1, '(': 1, ')':-1, ']':-1, '}':-1}
Bram Moolenaar54775062019-07-31 21:07:14 +0200305let s:blockCharsLUT = {'{':'{', '}':'{', '[':'[', ']':'[', '(':'(', ')':'('}
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200306function! BalanceDirection (str)
307
Bram Moolenaar54775062019-07-31 21:07:14 +0200308 let balance = {'{':0, '[': 0, '(': 0, 'none':0}
309 let director = 'none'
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200310
311 for c in split(a:str, '\zs')
312 if has_key(s:blockChars, c)
Bram Moolenaar54775062019-07-31 21:07:14 +0200313 let balance[s:blockCharsLUT[c]] += s:blockChars[c]
314
315 if balance[s:blockCharsLUT[c]]
316 let director = s:blockCharsLUT[c]
317 endif
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200318 endif
319 endfor
320
Bram Moolenaar54775062019-07-31 21:07:14 +0200321 return balance[director]
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200322endfun
323
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200324function! StripEndlineComments (line)
325 return substitute(a:line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
326endfun
327
328function! FindArrowIndent (lnum) " {{{
329
Bram Moolenaar54775062019-07-31 21:07:14 +0200330 let parrentArrowPos = -1
331 let cursorPos = -1
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200332 let lnum = a:lnum
333 while lnum > 1
334 let last_line = getline(lnum)
335 if last_line =~ '^\s*->'
336 let parrentArrowPos = indent(a:lnum)
337 break
338 else
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200339
Bram Moolenaar54775062019-07-31 21:07:14 +0200340 if b:PHP_noArrowMatching
341 break
342 endif
343
344 let cleanedLnum = StripEndlineComments(last_line)
345
346 if cleanedLnum =~ ')'.s:endline
347 if BalanceDirection(cleanedLnum) <= 0
348 call cursor(lnum, 1)
349 call searchpos(')'.s:endline, 'cW', lnum)
350 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
351 let cursorPos = col(".")
352 if openedparent != lnum
353 let lnum = openedparent
354 continue
355 else
356 endif
357 else
358 let parrentArrowPos = -1
359 break
360 end
361 endif
362
363 if cleanedLnum =~ '->'
364 call cursor(lnum, cursorPos == -1 ? strwidth(cleanedLnum) : cursorPos)
365 let parrentArrowPos = searchpos('->', 'cWb', lnum)[1] - 1
366
367 break
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200368 else
Bram Moolenaar54775062019-07-31 21:07:14 +0200369 let parrentArrowPos = -1
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200370 break
371 endif
372 endif
373 endwhile
374
Bram Moolenaar54775062019-07-31 21:07:14 +0200375 if parrentArrowPos == -1
376 let parrentArrowPos = indent(lnum) + shiftwidth()
377 end
378
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200379 return parrentArrowPos
380endfun "}}}
381
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000382function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000383
384 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
385 let beforeelse = a:lnum
386 else
387 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
388 endif
389
390 if !s:level
391 let s:iftoskip = 0
392 endif
393
394 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
395 let s:iftoskip = s:iftoskip + 1
396 endif
397
398 if getline(beforeelse) =~ '^\s*}'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200399 let beforeelse = FindOpenBracket(beforeelse, 0)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000400
401 if getline(beforeelse) =~ '^\s*{'
402 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000403 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000404 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000405
406
Bram Moolenaar1e015462005-09-25 22:16:38 +0000407 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000408 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000409 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000410
Bram Moolenaar1e015462005-09-25 22:16:38 +0000411 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
412
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200413 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000414 let s:iftoskip = s:iftoskip - 1
415 endif
416
417 let s:level = s:level + 1
418 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
419 endif
420
421 return beforeelse
422
423endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000424
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200425let s:defaultORcase = '^\s*\%(default\|case\).*:'
426
427function! FindTheSwitchIndent (lnum) " {{{
428
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200429 let test = GetLastRealCodeLNum(a:lnum - 1)
430
431 if test <= 1
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200432 return indent(1) - shiftwidth() * b:PHP_vintage_case_default_indent
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200433 end
434
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200435 while getline(test) =~ '^\s*}' && test > 1
436 let test = GetLastRealCodeLNum(FindOpenBracket(test, 0) - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200437
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200438 if getline(test) =~ '^\s*switch\>'
439 let test = GetLastRealCodeLNum(test - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200440 endif
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200441 endwhile
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200442
443 if getline(test) =~# '^\s*switch\>'
444 return indent(test)
445 elseif getline(test) =~# s:defaultORcase
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200446 return indent(test) - shiftwidth() * b:PHP_vintage_case_default_indent
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200447 else
448 return FindTheSwitchIndent(test)
449 endif
450
451endfunction "}}}
452
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200453let s:SynPHPMatchGroups = {'phpparent':1, 'delimiter':1, 'define':1, 'storageclass':1, 'structure':1, 'exception':1}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000454function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000455 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000456
Bram Moolenaar1e015462005-09-25 22:16:38 +0000457 if a:tofind==""
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200458 let tofind = "^\\s*[\"'`]*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000459 else
460 let tofind = a:tofind
461 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000462
Bram Moolenaar1e015462005-09-25 22:16:38 +0000463 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000464
Bram Moolenaar1e015462005-09-25 22:16:38 +0000465 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000466
Bram Moolenaar1e015462005-09-25 22:16:38 +0000467 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
468
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200469 if synname ==? 'phpStringSingle' || synname ==? 'phpStringDouble' || synname ==? 'phpBacktick'
Bram Moolenaar54775062019-07-31 21:07:14 +0200470 if cline !~ '^\s*[''"`]' " ??? XXX
Bram Moolenaared32d942014-12-06 23:33:00 +0100471 return "SpecStringEntrails"
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200472 else
473 return synname
474 end
475 end
476
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200477 if get(s:SynPHPMatchGroups, tolower(synname)) || synname =~ '^php' || synname =~? '^javaScript'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000478 return synname
479 else
480 return ""
481 endif
482endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000483
Bram Moolenaar5c736222010-01-06 20:54:52 +0100484let s:autoresetoptions = 0
485if ! s:autoresetoptions
486 let s:autoresetoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000487endif
488
Bram Moolenaar5c736222010-01-06 20:54:52 +0100489function! ResetPhpOptions()
Bram Moolenaared32d942014-12-06 23:33:00 +0100490 if ! b:optionsset && &filetype =~ "php"
Bram Moolenaara5792f52005-11-23 21:25:05 +0000491 if b:PHP_autoformatcomment
492
493 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000494
Bram Moolenaarc236c162008-07-13 17:41:49 +0000495 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000496 setlocal formatoptions+=q
497 setlocal formatoptions+=r
498 setlocal formatoptions+=o
Bram Moolenaara5792f52005-11-23 21:25:05 +0000499 setlocal formatoptions+=c
500 setlocal formatoptions+=b
501 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000502 let b:optionsset = 1
503 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000504endfunc
505
Bram Moolenaar5c736222010-01-06 20:54:52 +0100506call ResetPhpOptions()
507
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200508function! GetPhpIndentVersion()
Bram Moolenaar54775062019-07-31 21:07:14 +0200509 return "1.70-bundle"
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200510endfun
511
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000512function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000513
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000514 let b:GetLastRealCodeLNum_ADD = 0
515
Bram Moolenaar1e015462005-09-25 22:16:38 +0000516 let UserIsEditing=0
517 if b:PHP_oldchangetick != b:changedtick
518 let b:PHP_oldchangetick = b:changedtick
519 let UserIsEditing=1
520 endif
521
522 if b:PHP_default_indenting
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200523 let b:PHP_default_indenting = g:PHP_default_indenting * shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000524 endif
525
526 let cline = getline(v:lnum)
527
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000528 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000529 if b:PHP_indentbeforelast
530 let b:PHP_indentinghuge = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000531 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000532 let b:PHP_indentbeforelast = b:PHP_lastindented
533 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000534
Bram Moolenaar1e015462005-09-25 22:16:38 +0000535 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
536 if b:PHP_indentinghuge
Bram Moolenaar1e015462005-09-25 22:16:38 +0000537 let b:PHP_indentinghuge = 0
538 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000539 endif
Bram Moolenaared32d942014-12-06 23:33:00 +0100540 let real_PHP_lastindented = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000541 let b:PHP_LastIndentedWasComment=0
542 let b:PHP_InsideMultilineComment=0
543 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000544
Bram Moolenaar1e015462005-09-25 22:16:38 +0000545 let b:InPHPcode = 0
546 let b:InPHPcode_checked = 0
547 let b:InPHPcode_and_script = 0
548 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000549
Bram Moolenaar1e015462005-09-25 22:16:38 +0000550 elseif v:lnum > b:PHP_lastindented
551 let real_PHP_lastindented = b:PHP_lastindented
Bram Moolenaared32d942014-12-06 23:33:00 +0100552 else
553 let real_PHP_lastindented = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000554 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000555
Bram Moolenaared32d942014-12-06 23:33:00 +0100556 let b:PHP_lastindented = v:lnum
557
Bram Moolenaar1e015462005-09-25 22:16:38 +0000558
559 if !b:InPHPcode_checked " {{{ One time check
560 let b:InPHPcode_checked = 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100561 let b:UserIsTypingComment = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000562
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000563 let synname = ""
564 if cline !~ '<?.*?>'
565 let synname = IslinePHP (prevnonblank(v:lnum), "")
566 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000567
568 if synname!=""
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200569 if synname ==? "SpecStringEntrails"
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200570 let b:InPHPcode = -1 " thumb down
Bram Moolenaared32d942014-12-06 23:33:00 +0100571 let b:InPHPcode_tofind = ""
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200572 elseif synname !=? "phpHereDoc" && synname !=? "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000573 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000574 let b:InPHPcode_tofind = ""
575
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200576 if synname =~? '^php\%(Doc\)\?Comment'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000577 let b:UserIsTypingComment = 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100578 let b:InPHPcode_checked = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000579 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000580
Bram Moolenaar1e015462005-09-25 22:16:38 +0000581 if synname =~? '^javaScript'
582 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000583 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000584
Bram Moolenaar1e015462005-09-25 22:16:38 +0000585 else
586 let b:InPHPcode = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000587
Bram Moolenaar1e015462005-09-25 22:16:38 +0000588 let lnum = v:lnum - 1
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100589 while getline(lnum) !~? '<<<\s*[''"]\=\a\w*[''"]\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000590 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000591 endwhile
592
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100593 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000594 endif
595 else
596 let b:InPHPcode = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200597 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000598 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000599 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000600
601
Bram Moolenaar1e015462005-09-25 22:16:38 +0000602 " Test if we are indenting PHP code {{{
603 let lnum = prevnonblank(v:lnum - 1)
604 let last_line = getline(lnum)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200605 let endline= s:endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000606
607 if b:InPHPcode_tofind!=""
608 if cline =~? b:InPHPcode_tofind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000609 let b:InPHPcode_tofind = ""
610 let b:UserIsTypingComment = 0
Bram Moolenaared32d942014-12-06 23:33:00 +0100611
612 if b:InPHPcode == -1
613 let b:InPHPcode = 1
614 return -1
615 end
616
617 let b:InPHPcode = 1
618
Bram Moolenaar1e015462005-09-25 22:16:38 +0000619 if cline =~ '\*/'
620 call cursor(v:lnum, 1)
621 if cline !~ '^\*/'
622 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000623 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000624 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000625
Bram Moolenaar1e015462005-09-25 22:16:38 +0000626 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000627
Bram Moolenaar1e015462005-09-25 22:16:38 +0000628 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000629
Bram Moolenaar1e015462005-09-25 22:16:38 +0000630 if cline =~ '^\s*\*/'
631 return indent(lnum) + 1
632 else
633 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000634 endif
635
Bram Moolenaar1e015462005-09-25 22:16:38 +0000636 elseif cline =~? '<script\>'
637 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000638 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000639 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000640 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000641 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000642
Bram Moolenaared32d942014-12-06 23:33:00 +0100643 if 1 == b:InPHPcode
Bram Moolenaar1e015462005-09-25 22:16:38 +0000644
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200645 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~?"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000646 if cline !~? s:PHP_startindenttag
647 let b:InPHPcode = 0
648 let b:InPHPcode_tofind = s:PHP_startindenttag
649 elseif cline =~? '<script\>'
650 let b:InPHPcode_and_script = 1
651 endif
652
Bram Moolenaar54775062019-07-31 21:07:14 +0200653 elseif last_line =~ '^[^''"`]\+[''"`]$' && last_line !~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' " a string identifier with nothing after it and no other string identifier before
Bram Moolenaared32d942014-12-06 23:33:00 +0100654 let b:InPHPcode = -1
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200655 let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '')
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100656 elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000657 let b:InPHPcode = 0
Bram Moolenaarcbebd482016-02-07 23:02:56 +0100658 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000659
660 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
661 let b:InPHPcode = 0
662 let b:InPHPcode_tofind = '\*/'
663
664 elseif cline =~? '^\s*</script>'
665 let b:InPHPcode = 0
666 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000667 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000668 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000669
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000670
Bram Moolenaared32d942014-12-06 23:33:00 +0100671 if 1 > b:InPHPcode && !b:InPHPcode_and_script
Bram Moolenaar1e015462005-09-25 22:16:38 +0000672 return -1
673 endif
674
Bram Moolenaar1e015462005-09-25 22:16:38 +0000675 " Indent successive // or # comment the same way the first is {{{
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200676 let addSpecial = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000677 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200678 let addSpecial = b:PHP_outdentSLComments
Bram Moolenaar1e015462005-09-25 22:16:38 +0000679 if b:PHP_LastIndentedWasComment == 1
680 return indent(real_PHP_lastindented)
681 endif
682 let b:PHP_LastIndentedWasComment = 1
683 else
684 let b:PHP_LastIndentedWasComment = 0
685 endif " }}}
686
687 " Indent multiline /* comments correctly {{{
688
689 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
690 if cline =~ '^\s*\*\%(\/\)\@!'
691 if last_line =~ '^\s*/\*'
692 return indent(lnum) + 1
693 else
694 return indent(lnum)
695 endif
696 else
697 let b:PHP_InsideMultilineComment = 0
698 endif
699 endif
700
Bram Moolenaared32d942014-12-06 23:33:00 +0100701 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*\%(.*\*/\)\@!'
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000702 if getline(v:lnum + 1) !~ '^\s*\*'
703 return -1
704 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000705 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000706 endif " }}}
707
708
709 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200710 if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000711 return 0
712 endif
713
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200714 if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000715 return 0
716 endif
717
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200718 if cline =~? '^\s*\a\w*;$\|^\a\w*$\|^\s*[''"`][;,]' && cline !~? s:notPhpHereDoc
Bram Moolenaar1e015462005-09-25 22:16:38 +0000719 return 0
720 endif " }}}
721
722 let s:level = 0
723
724 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000725
Bram Moolenaar1e015462005-09-25 22:16:38 +0000726 let last_line = getline(lnum)
727 let ind = indent(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000728
729 if ind==0 && b:PHP_default_indenting
730 let ind = b:PHP_default_indenting
731 endif
732
733 if lnum == 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200734 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000735 endif
736
737
738 if cline =~ '^\s*}\%(}}\)\@!'
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200739 let ind = indent(FindOpenBracket(v:lnum, 1))
Bram Moolenaar1e015462005-09-25 22:16:38 +0000740 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000741 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000742 endif
743
744 if cline =~ '^\s*\*/'
745 call cursor(v:lnum, 1)
746 if cline !~ '^\*/'
747 call search('\*/', 'W')
748 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000749 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000750
751 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
752
753 if cline =~ '^\s*\*/'
754 return indent(lnum) + 1
755 else
756 return indent(lnum)
757 endif
758 endif
759
Bram Moolenaar1e015462005-09-25 22:16:38 +0000760
Bram Moolenaar54775062019-07-31 21:07:14 +0200761 if last_line =~ '[;}]'.endline && last_line !~ '^[)\]]' && last_line !~# s:defaultORcase && last_line !~ '^\s*[''"`][;,]'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000762 if ind==b:PHP_default_indenting
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200763 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000764 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 +0200765 return b:PHP_CurrentIndentLevel + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000766 endif
767 endif
768
769 let LastLineClosed = 0
770
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200771 let terminated = s:terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000772
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200773 let unstated = s:unstated
774
Bram Moolenaar1e015462005-09-25 22:16:38 +0000775
776 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
777 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
778 return indent(FindTheIfOfAnElse(v:lnum, 1))
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200779 elseif cline =~# s:defaultORcase
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200780 return FindTheSwitchIndent(v:lnum) + shiftwidth() * b:PHP_vintage_case_default_indent
Bram Moolenaarc236c162008-07-13 17:41:49 +0000781 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000782 let previous_line = last_line
783 let last_line_num = lnum
784
785 while last_line_num > 1
786
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200787 if previous_line =~ terminated || previous_line =~ s:structureHead
Bram Moolenaar1e015462005-09-25 22:16:38 +0000788
789 let ind = indent(last_line_num)
790
791 if b:PHP_BracesAtCodeLevel
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200792 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000793 endif
794
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000795 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000796 endif
797
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200798 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000799 let previous_line = getline(last_line_num)
800 endwhile
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200801 elseif cline =~ '^\s*->'
802 return FindArrowIndent(lnum)
Bram Moolenaarc236c162008-07-13 17:41:49 +0000803 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200804 let ind = ind + shiftwidth() " we indent one level further when the preceding line is not stated
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200805 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000806
Bram Moolenaared32d942014-12-06 23:33:00 +0100807 elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000808 let previous_line = last_line
809 let last_line_num = lnum
810 let LastLineClosed = 1
811
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200812 let isSingleLineBlock = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000813 while 1
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200814 if ! isSingleLineBlock && previous_line =~ '^\s*}\|;\s*}'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000815
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200816 call cursor(last_line_num, 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200817 if previous_line !~ '^}'
818 call search('}\|;\s*}'.endline, 'W')
819 end
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200820 let oldLastLine = last_line_num
821 let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()')
822
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200823 if getline(last_line_num) =~ '^\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000824 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200825 elseif oldLastLine == last_line_num
826 let isSingleLineBlock = 1
827 continue
Bram Moolenaar1e015462005-09-25 22:16:38 +0000828 endif
829
830 let previous_line = getline(last_line_num)
831
832 continue
833 else
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200834 let isSingleLineBlock = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000835
836 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
837 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
838 continue
839 endif
840
841
842 let last_match = last_line_num
843
844 let one_ahead_indent = indent(last_line_num)
845 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
846 let two_ahead_indent = indent(last_line_num)
847 let after_previous_line = previous_line
848 let previous_line = getline(last_line_num)
849
850
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200851 if previous_line =~# s:defaultORcase.'\|{'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000852 break
853 endif
854
855 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
856 break
857 endif
858
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000859 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000860 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000861 break
862 endif
863 endif
864 endif
865 endwhile
866
867 if indent(last_match) != ind
868 let ind = indent(last_match)
869 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
870
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200871 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000872 endif
873 endif
874
Bram Moolenaared32d942014-12-06 23:33:00 +0100875 if (last_line !~ '^\s*}\%(}}\)\@!')
876 let plinnum = GetLastRealCodeLNum(lnum - 1)
877 else
878 let plinnum = GetLastRealCodeLNum(FindOpenBracket(lnum, 1) - 1)
879 endif
880
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200881 let AntepenultimateLine = getline(plinnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000882
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200883 let last_line = StripEndlineComments(last_line)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000884
885 if ind == b:PHP_default_indenting
Bram Moolenaared32d942014-12-06 23:33:00 +0100886 if last_line =~ terminated && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000887 let LastLineClosed = 1
888 endif
889 endif
890
891 if !LastLineClosed
892
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200893 let openedparent = -1
894
Bram Moolenaar5c736222010-01-06 20:54:52 +0100895
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200896 if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline && BalanceDirection(last_line) > 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000897
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200898 let dontIndent = 0
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200899 if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*[)\]]\+\(\s*:\s*'.s:PHP_validVariable.'\)\=\s*{'.endline && last_line !~ s:structureHead
Bram Moolenaarbcb98982014-05-01 14:08:19 +0200900 let dontIndent = 1
901 endif
902
903 if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{')
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200904 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000905 endif
906
Bram Moolenaar54775062019-07-31 21:07:14 +0200907 if b:PHP_IndentFunctionCallParameters && last_line =~ s:multilineFunctionCall && last_line !~ s:structureHead && last_line !~ s:arrayDecl
908 let ind = ind + b:PHP_IndentFunctionCallParameters * shiftwidth()
909 endif
910
911 if b:PHP_IndentFunctionDeclarationParameters && last_line =~ s:multilineFunctionDecl
912 let ind = ind + b:PHP_IndentFunctionDeclarationParameters * shiftwidth()
913 endif
914
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200915 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000916 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaarc236c162008-07-13 17:41:49 +0000917
Bram Moolenaar1e015462005-09-25 22:16:38 +0000918 endif
919
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200920 elseif last_line =~ '),'.endline && BalanceDirection(last_line) < 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000921 call cursor(lnum, 1)
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200922 call searchpos('),'.endline, 'cW')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000923 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
924 if openedparent != lnum
925 let ind = indent(openedparent)
926 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200927
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200928 elseif last_line =~ s:structureHead
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200929 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000930
Bram Moolenaarc236c162008-07-13 17:41:49 +0000931
Bram Moolenaare0720cb2017-03-29 13:48:40 +0200932 elseif AntepenultimateLine =~ '{'.endline && AntepenultimateLine !~? '^\s*use\>' || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200933 let ind = ind + shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000934 endif
935
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200936
937 if openedparent >= 0
938 let last_line = StripEndlineComments(getline(openedparent))
939 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000940 endif
941
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200942 if cline =~ '^\s*[)\]];\='
Bram Moolenaar54775062019-07-31 21:07:14 +0200943 call cursor(v:lnum, 1)
944 call searchpos('[)\]]', 'cW')
945 let matchedBlockChar = cline[col('.')-1]
946 let openedparent = searchpair('\M'.s:blockCharsLUT[matchedBlockChar], '', '\M'.matchedBlockChar, 'bW', 'Skippmatch()')
947 if openedparent != v:lnum
948 let ind = indent(openedparent)
949 endif
Bram Moolenaar0b0f0992018-05-22 21:41:30 +0200950
Bram Moolenaar54775062019-07-31 21:07:14 +0200951 elseif last_line =~ '^\s*->' && last_line !~? s:structureHead && BalanceDirection(last_line) <= 0
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200952 let ind = ind - shiftwidth()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000953 endif
954
955 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200956 return ind + addSpecial
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000957endfunction