blob: fd18664308ad05fd318b7485862c211efc7851aa [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 Moolenaar8d043172014-01-23 14:24:41 +01006" Last Change: 2014 Jan 21
Bram Moolenaar3b1db362013-08-10 15:00:24 +02007" Version: 1.39
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 Moolenaarc236c162008-07-13 17:41:49 +000042"
Bram Moolenaara5792f52005-11-23 21:25:05 +000043
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
50let php_sync_method = 0
51
52
Bram Moolenaare6ae6222013-05-21 21:01:10 +020053
Bram Moolenaar9ff70112005-07-11 22:29:03 +000054if exists("PHP_default_indenting")
Bram Moolenaar1e015462005-09-25 22:16:38 +000055 let b:PHP_default_indenting = PHP_default_indenting * &sw
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")
61 let b:PHP_outdentSLComments = PHP_outdentSLComments * &sw
62else
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 Moolenaar9ff70112005-07-11 22:29:03 +0000114setlocal indentkeys=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 Moolenaare6ae6222013-05-21 21:01:10 +0200126 finish " XXX -- comment this line for easy dev
Bram Moolenaar071d4272004-06-13 20:20:40 +0000127endif
128
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000129let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
130let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000131
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000132
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200133function! DebugPrintReturn(scriptLine)
134
135 echo "debug:" . a:scriptLine
136 call getchar()
137
138endfunction
139
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000140function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000141
Bram Moolenaar1e015462005-09-25 22:16:38 +0000142 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000143
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000144 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
145 let lnum = b:GetLastRealCodeLNum_ADD
146 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000147
Bram Moolenaar1e015462005-09-25 22:16:38 +0000148 let old_lnum = lnum
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000149
Bram Moolenaar1e015462005-09-25 22:16:38 +0000150 while lnum > 1
151 let lnum = prevnonblank(lnum)
152 let lastline = getline(lnum)
153
154 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
155 let lnum = lnum - 1
156 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
157 let lnum = lnum - 1
158 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
159 let lnum = lnum - 1
160 elseif lastline =~ '\*/\s*$'
161 call cursor(lnum, 1)
162 if lastline !~ '^\*/'
163 call search('\*/', 'W')
164 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000165 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000166
167 let lastline = getline(lnum)
168 if lastline =~ '^\s*/\*'
169 let lnum = lnum - 1
170 else
171 break
172 endif
173
174
175 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
176
177 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
178 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000179 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000180 endwhile
181 if lastline =~ '^\s*?>'
182 let lnum = lnum - 1
183 else
184 break
185 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000186
187
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200188 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc
189 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<''\\=\1''\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000190 while getline(lnum) !~? tofind && lnum > 1
191 let lnum = lnum - 1
192 endwhile
193 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000194 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000195 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000196 endwhile
197
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200198 if lnum==1 && getline(lnum) !~ '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000199 let lnum=0
200 endif
201
202 if b:InPHPcode_and_script && !b:InPHPcode
203 let b:InPHPcode_and_script = 0
204 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000205
Bram Moolenaar1e015462005-09-25 22:16:38 +0000206 return lnum
207endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000208
Bram Moolenaara5792f52005-11-23 21:25:05 +0000209function! Skippmatch2()
210
211 let line = getline(".")
212
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200213 if line =~ "\\([\"']\\).*/\\*.*\\1" || line =~ '\%(//\|#\).*/\*'
214 return 1
215 else
216 return 0
217 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000218endfun
219
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200220function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000221 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000222 if synname == "Delimiter" || synname == "phpRegionDelimiter" || synname =~# "^phpParent" || synname == "phpArrayParens" || synname =~# '^php\%(Block\|Brace\)' || synname == "javaScriptBraces" || synname =~# "^phpComment" && b:UserIsTypingComment
Bram Moolenaar1e015462005-09-25 22:16:38 +0000223 return 0
224 else
225 return 1
226 endif
227endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000228
229function! FindOpenBracket(lnum) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000230 call cursor(a:lnum, 1)
231 return searchpair('{', '', '}', 'bW', 'Skippmatch()')
232endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000233
234function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000235
236 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
237 let beforeelse = a:lnum
238 else
239 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
240 endif
241
242 if !s:level
243 let s:iftoskip = 0
244 endif
245
246 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
247 let s:iftoskip = s:iftoskip + 1
248 endif
249
250 if getline(beforeelse) =~ '^\s*}'
251 let beforeelse = FindOpenBracket(beforeelse)
252
253 if getline(beforeelse) =~ '^\s*{'
254 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000255 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000256 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000257
258
Bram Moolenaar1e015462005-09-25 22:16:38 +0000259 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000260 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000261 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000262
Bram Moolenaar1e015462005-09-25 22:16:38 +0000263 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
264
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200265 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000266 let s:iftoskip = s:iftoskip - 1
267 endif
268
269 let s:level = s:level + 1
270 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
271 endif
272
273 return beforeelse
274
275endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000276
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200277let s:defaultORcase = '^\s*\%(default\|case\).*:'
278
279function! FindTheSwitchIndent (lnum) " {{{
280
281
282 let test = GetLastRealCodeLNum(a:lnum - 1)
283
284 if test <= 1
285 return indent(1) - &sw * b:PHP_vintage_case_default_indent
286 end
287
288 if getline(test) =~ '^\s*}'
289 let test = FindOpenBracket(test)
290
291 if getline(test) =~ '^\s*{'
292 let test = GetLastRealCodeLNum(GetLastRealCodeLNum(test - 1) - 1)
293 endif
294 endif
295
296 if getline(test) =~# '^\s*switch\>'
297 return indent(test)
298 elseif getline(test) =~# s:defaultORcase
299 return indent(test) - &sw * b:PHP_vintage_case_default_indent
300 else
301 return FindTheSwitchIndent(test)
302 endif
303
304endfunction "}}}
305
Bram Moolenaar3b1db362013-08-10 15:00:24 +0200306let s:SynPHPMatchGroups = {'phpParent':1, 'Delimiter':1, 'Define':1, 'Storageclass':1, 'StorageClass':1, 'Structure':1, 'Exception':1}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000307function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000308 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000309
Bram Moolenaar1e015462005-09-25 22:16:38 +0000310 if a:tofind==""
Bram Moolenaara5792f52005-11-23 21:25:05 +0000311 let tofind = "^\\s*[\"']*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000312 else
313 let tofind = a:tofind
314 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000315
Bram Moolenaar1e015462005-09-25 22:16:38 +0000316 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000317
Bram Moolenaar1e015462005-09-25 22:16:38 +0000318 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000319
Bram Moolenaar1e015462005-09-25 22:16:38 +0000320 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
321
Bram Moolenaar9d98fe92013-08-03 18:35:36 +0200322 if get(s:SynPHPMatchGroups, synname) || synname =~ '^php' || synname =~? '^javaScript'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000323 return synname
324 else
325 return ""
326 endif
327endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000328
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200329let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\)'
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200330let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|else\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|interface\>\|abstract\>\|try\>\|catch\>\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000331
Bram Moolenaar5c736222010-01-06 20:54:52 +0100332let s:autoresetoptions = 0
333if ! s:autoresetoptions
334 let s:autoresetoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000335endif
336
Bram Moolenaar5c736222010-01-06 20:54:52 +0100337function! ResetPhpOptions()
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200338 if ! b:optionsset && &filetype == "php"
Bram Moolenaara5792f52005-11-23 21:25:05 +0000339 if b:PHP_autoformatcomment
340
341 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000342
Bram Moolenaarc236c162008-07-13 17:41:49 +0000343 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000344 setlocal formatoptions+=q
345 setlocal formatoptions+=r
346 setlocal formatoptions+=o
Bram Moolenaarc236c162008-07-13 17:41:49 +0000347 setlocal formatoptions+=w
Bram Moolenaara5792f52005-11-23 21:25:05 +0000348 setlocal formatoptions+=c
349 setlocal formatoptions+=b
350 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000351 let b:optionsset = 1
352 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000353endfunc
354
Bram Moolenaar5c736222010-01-06 20:54:52 +0100355call ResetPhpOptions()
356
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000357function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000358
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000359 let b:GetLastRealCodeLNum_ADD = 0
360
Bram Moolenaar1e015462005-09-25 22:16:38 +0000361 let UserIsEditing=0
362 if b:PHP_oldchangetick != b:changedtick
363 let b:PHP_oldchangetick = b:changedtick
364 let UserIsEditing=1
365 endif
366
367 if b:PHP_default_indenting
368 let b:PHP_default_indenting = g:PHP_default_indenting * &sw
369 endif
370
371 let cline = getline(v:lnum)
372
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000373 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000374 if b:PHP_indentbeforelast
375 let b:PHP_indentinghuge = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000376 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000377 let b:PHP_indentbeforelast = b:PHP_lastindented
378 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000379
Bram Moolenaar1e015462005-09-25 22:16:38 +0000380 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
381 if b:PHP_indentinghuge
Bram Moolenaar1e015462005-09-25 22:16:38 +0000382 let b:PHP_indentinghuge = 0
383 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000384 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000385 let b:PHP_lastindented = v:lnum
386 let b:PHP_LastIndentedWasComment=0
387 let b:PHP_InsideMultilineComment=0
388 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000389
Bram Moolenaar1e015462005-09-25 22:16:38 +0000390 let b:InPHPcode = 0
391 let b:InPHPcode_checked = 0
392 let b:InPHPcode_and_script = 0
393 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000394
Bram Moolenaar1e015462005-09-25 22:16:38 +0000395 elseif v:lnum > b:PHP_lastindented
396 let real_PHP_lastindented = b:PHP_lastindented
397 let b:PHP_lastindented = v:lnum
398 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000399
Bram Moolenaar1e015462005-09-25 22:16:38 +0000400
401 if !b:InPHPcode_checked " {{{ One time check
402 let b:InPHPcode_checked = 1
403
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000404 let synname = ""
405 if cline !~ '<?.*?>'
406 let synname = IslinePHP (prevnonblank(v:lnum), "")
407 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000408
409 if synname!=""
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000410 if synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000411 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000412 let b:InPHPcode_tofind = ""
413
Bram Moolenaarc236c162008-07-13 17:41:49 +0000414 if synname =~# "^phpComment"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000415 let b:UserIsTypingComment = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000416 else
Bram Moolenaar1e015462005-09-25 22:16:38 +0000417 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000418 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000419
Bram Moolenaar1e015462005-09-25 22:16:38 +0000420 if synname =~? '^javaScript'
421 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000422 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000423
Bram Moolenaar1e015462005-09-25 22:16:38 +0000424 else
425 let b:InPHPcode = 0
426 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000427
Bram Moolenaar1e015462005-09-25 22:16:38 +0000428 let lnum = v:lnum - 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000429 while getline(lnum) !~? '<<<''\=\a\w*''\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000430 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000431 endwhile
432
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200433 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000434 endif
435 else
436 let b:InPHPcode = 0
437 let b:UserIsTypingComment = 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200438 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000439 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000440 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000441
442
Bram Moolenaar1e015462005-09-25 22:16:38 +0000443 " Test if we are indenting PHP code {{{
444 let lnum = prevnonblank(v:lnum - 1)
445 let last_line = getline(lnum)
446
447 if b:InPHPcode_tofind!=""
448 if cline =~? b:InPHPcode_tofind
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200449 let b:InPHPcode = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000450 let b:InPHPcode_tofind = ""
451 let b:UserIsTypingComment = 0
452 if cline =~ '\*/'
453 call cursor(v:lnum, 1)
454 if cline !~ '^\*/'
455 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000456 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000457 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000458
Bram Moolenaar1e015462005-09-25 22:16:38 +0000459 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000460
Bram Moolenaar1e015462005-09-25 22:16:38 +0000461 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000462
Bram Moolenaar1e015462005-09-25 22:16:38 +0000463 if cline =~ '^\s*\*/'
464 return indent(lnum) + 1
465 else
466 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000467 endif
468
Bram Moolenaar1e015462005-09-25 22:16:38 +0000469 elseif cline =~? '<script\>'
470 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000471 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000472 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000473 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000474 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000475
Bram Moolenaar1e015462005-09-25 22:16:38 +0000476 if b:InPHPcode
477
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000478 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000479 if cline !~? s:PHP_startindenttag
480 let b:InPHPcode = 0
481 let b:InPHPcode_tofind = s:PHP_startindenttag
482 elseif cline =~? '<script\>'
483 let b:InPHPcode_and_script = 1
484 endif
485
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200486 elseif last_line =~? '<<<''\=\a\w*''\=$'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000487 let b:InPHPcode = 0
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200488 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000489
490 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
491 let b:InPHPcode = 0
492 let b:InPHPcode_tofind = '\*/'
493
494 elseif cline =~? '^\s*</script>'
495 let b:InPHPcode = 0
496 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000497 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000498 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000499
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000500
Bram Moolenaar1e015462005-09-25 22:16:38 +0000501 if !b:InPHPcode && !b:InPHPcode_and_script
502 return -1
503 endif
504
Bram Moolenaar1e015462005-09-25 22:16:38 +0000505 " Indent successive // or # comment the same way the first is {{{
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200506 let addSpecial = 0
Bram Moolenaar1e015462005-09-25 22:16:38 +0000507 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200508 let addSpecial = b:PHP_outdentSLComments
Bram Moolenaar1e015462005-09-25 22:16:38 +0000509 if b:PHP_LastIndentedWasComment == 1
510 return indent(real_PHP_lastindented)
511 endif
512 let b:PHP_LastIndentedWasComment = 1
513 else
514 let b:PHP_LastIndentedWasComment = 0
515 endif " }}}
516
517 " Indent multiline /* comments correctly {{{
518
519 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
520 if cline =~ '^\s*\*\%(\/\)\@!'
521 if last_line =~ '^\s*/\*'
522 return indent(lnum) + 1
523 else
524 return indent(lnum)
525 endif
526 else
527 let b:PHP_InsideMultilineComment = 0
528 endif
529 endif
530
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000531 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$'
532 if getline(v:lnum + 1) !~ '^\s*\*'
533 return -1
534 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000535 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000536 endif " }}}
537
538
539 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200540 if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000541 return 0
542 endif
543
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200544 if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000545 return 0
546 endif
547
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200548 if cline =~? '^\s*\a\w*;$\|^\a\w*$' && cline !~? s:notPhpHereDoc
Bram Moolenaar1e015462005-09-25 22:16:38 +0000549 return 0
550 endif " }}}
551
552 let s:level = 0
553
554 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000555
Bram Moolenaar1e015462005-09-25 22:16:38 +0000556 let last_line = getline(lnum)
557 let ind = indent(lnum)
558 let endline= s:endline
559
560 if ind==0 && b:PHP_default_indenting
561 let ind = b:PHP_default_indenting
562 endif
563
564 if lnum == 0
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200565 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000566 endif
567
568
569 if cline =~ '^\s*}\%(}}\)\@!'
570 let ind = indent(FindOpenBracket(v:lnum))
571 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000572 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000573 endif
574
575 if cline =~ '^\s*\*/'
576 call cursor(v:lnum, 1)
577 if cline !~ '^\*/'
578 call search('\*/', 'W')
579 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000580 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000581
582 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
583
584 if cline =~ '^\s*\*/'
585 return indent(lnum) + 1
586 else
587 return indent(lnum)
588 endif
589 endif
590
Bram Moolenaar1e015462005-09-25 22:16:38 +0000591
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200592 if last_line =~ '[;}]'.endline && last_line !~ '^[)\]]' && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000593 if ind==b:PHP_default_indenting
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200594 return b:PHP_default_indenting + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000595 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 +0200596 return b:PHP_CurrentIndentLevel + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000597 endif
598 endif
599
600 let LastLineClosed = 0
601
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200602 let terminated = '\%(;\%(\s*\%(?>\|}\)\)\=\|<<<''\=\a\w*''\=$\|^\s*}\)'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000603
604 let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline
605
606 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
607 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
608 return indent(FindTheIfOfAnElse(v:lnum, 1))
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200609 elseif cline =~# s:defaultORcase
610 return FindTheSwitchIndent(v:lnum) + &sw * b:PHP_vintage_case_default_indent
Bram Moolenaarc236c162008-07-13 17:41:49 +0000611 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000612 let previous_line = last_line
613 let last_line_num = lnum
614
615 while last_line_num > 1
616
Bram Moolenaarc236c162008-07-13 17:41:49 +0000617 if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000618
619 let ind = indent(last_line_num)
620
621 if b:PHP_BracesAtCodeLevel
622 let ind = ind + &sw
623 endif
624
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000625 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000626 endif
627
628 let last_line_num = last_line_num - 1
629 let previous_line = getline(last_line_num)
630 endwhile
631
Bram Moolenaarc236c162008-07-13 17:41:49 +0000632 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200633 let ind = ind + &sw " we indent one level further when the preceding line is not stated
634 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000635
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200636 elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated " Added || last_line =~ '^)' on 2007-12-30 (array indenting problem broke other things)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000637 let previous_line = last_line
638 let last_line_num = lnum
639 let LastLineClosed = 1
640
641 while 1
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200642 if previous_line =~ '^\s*}\|;\s*}'.endline " XXX
Bram Moolenaar1e015462005-09-25 22:16:38 +0000643
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200644 call cursor(last_line_num, 1)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100645 call search('}\|;\s*}'.endline, 'cW')
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200646 let oldLastLine = last_line_num
647 let last_line_num = searchpair('{', '', '}', 'bW', 'Skippmatch()')
648
649 if oldLastLine == last_line_num || getline(last_line_num) =~ '^\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000650 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
651 endif
652
653 let previous_line = getline(last_line_num)
654
655 continue
656 else
657
658 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
659 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
660 continue
661 endif
662
663
664 let last_match = last_line_num
665
666 let one_ahead_indent = indent(last_line_num)
667 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
668 let two_ahead_indent = indent(last_line_num)
669 let after_previous_line = previous_line
670 let previous_line = getline(last_line_num)
671
672
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200673 if previous_line =~# s:defaultORcase.'\|{'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000674 break
675 endif
676
677 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
678 break
679 endif
680
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000681 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000682 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000683 break
684 endif
685 endif
686 endif
687 endwhile
688
689 if indent(last_match) != ind
690 let ind = indent(last_match)
691 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
692
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200693 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000694 endif
695 endif
696
697 let plinnum = GetLastRealCodeLNum(lnum - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200698 let AntepenultimateLine = getline(plinnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000699
700 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
701
702
703 if ind == b:PHP_default_indenting
704 if last_line =~ terminated
705 let LastLineClosed = 1
706 endif
707 endif
708
709 if !LastLineClosed
710
Bram Moolenaar5c736222010-01-06 20:54:52 +0100711
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200712 if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(]'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000713
714 if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{'
715 let ind = ind + &sw
716 endif
717
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200718 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000719 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaarc236c162008-07-13 17:41:49 +0000720
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200721 return ind + addSpecial
Bram Moolenaar1e015462005-09-25 22:16:38 +0000722 endif
723
724 elseif last_line =~ '\S\+\s*),'.endline
725 call cursor(lnum, 1)
726 call search('),'.endline, 'W')
727 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
728 if openedparent != lnum
729 let ind = indent(openedparent)
730 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200731
Bram Moolenaarc236c162008-07-13 17:41:49 +0000732 elseif last_line =~ '^\s*'.s:blockstart
Bram Moolenaar1e015462005-09-25 22:16:38 +0000733 let ind = ind + &sw
734
Bram Moolenaarc236c162008-07-13 17:41:49 +0000735
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200736 elseif AntepenultimateLine =~ '\%(;\%(\s*\%(?>\|}\)\)\=\|<<<''\=\a\w*''\=$\|^\s*}\|{\)'.endline . '\|' . s:defaultORcase
Bram Moolenaarc236c162008-07-13 17:41:49 +0000737 let ind = ind + &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000738 endif
739
Bram Moolenaar1e015462005-09-25 22:16:38 +0000740 endif
741
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200742 if cline =~ '^\s*[)\]];\='
Bram Moolenaar1e015462005-09-25 22:16:38 +0000743 let ind = ind - &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000744 endif
745
746 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200747 return ind + addSpecial
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000748endfunction