blob: bc196ed3c48c8e07e2408c580f44a55e4378ba03 [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 Moolenaar8408a9a2010-07-30 22:41:22 +02005" Last Change: 2010 Jully 26th
6" Newsletter: http://www.2072productions.com/?to=php-indent-for-vim-newsletter.php
7" Version: 1.33
Bram Moolenaar071d4272004-06-13 20:20:40 +00008"
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00009"
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020010" If you find a bug, please report it on GitHub:
11" http://github.com/2072/PHP-Indenting-for-VIm/issues
Bram Moolenaar05a7bb32006-01-19 22:09:32 +000012" with an example of code that breaks the algorithm.
Bram Moolenaara5792f52005-11-23 21:25:05 +000013"
14"
15" Thanks a lot for using this script.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000016"
17"
18" NOTE: This script must be used with PHP syntax ON and with the php syntax
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020019" script by Lutz Eymers (http://www.ipdienste.net/data/php.vim ) or with the
Bram Moolenaarc236c162008-07-13 17:41:49 +000020" script by Peter Hodge (http://www.vim.org/scripts/script.php?script_id=1571 )
Bram Moolenaar5c736222010-01-06 20:54:52 +010021" the later is bunbdled by default with Vim 7.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000022"
23"
Bram Moolenaarc236c162008-07-13 17:41:49 +000024" In the case you have syntax errors in your script such as HereDoc end
25" identifiers not at col 1 you'll have to indent your file 2 times (This
26" script will automatically put HereDoc end identifiers at col 1 if
27" they are followed by a ';').
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000028"
Bram Moolenaara5792f52005-11-23 21:25:05 +000029"
Bram Moolenaar5c736222010-01-06 20:54:52 +010030" NOTE: If you are editing files in Unix file format and that (by accident)
31" there are '\r' before new lines, this script won't be able to proceed
32" correctly and will make many mistakes because it won't be able to match
33" '\s*$' correctly.
34" So you have to remove those useless characters first with a command like:
Bram Moolenaar9ff70112005-07-11 22:29:03 +000035"
Bram Moolenaar5c736222010-01-06 20:54:52 +010036" :%s /\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +000037"
Bram Moolenaar5c736222010-01-06 20:54:52 +010038" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will
39" silently remove them when VIM load this script (at each bufread).
Bram Moolenaarc236c162008-07-13 17:41:49 +000040"
Bram Moolenaar5c736222010-01-06 20:54:52 +010041" Options: See :help php-indent for available options.
42
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
53if exists("PHP_default_indenting")
Bram Moolenaar1e015462005-09-25 22:16:38 +000054 let b:PHP_default_indenting = PHP_default_indenting * &sw
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
59if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000060 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000061else
Bram Moolenaar1e015462005-09-25 22:16:38 +000062 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000063endif
64
Bram Moolenaarc236c162008-07-13 17:41:49 +000065
Bram Moolenaara5792f52005-11-23 21:25:05 +000066if exists("PHP_autoformatcomment")
67 let b:PHP_autoformatcomment = PHP_autoformatcomment
68else
69 let b:PHP_autoformatcomment = 1
70endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000071
Bram Moolenaar8408a9a2010-07-30 22:41:22 +020072if exists("PHP_outdentphpescape")
73 let b:PHP_outdentphpescape = PHP_outdentphpescape
74else
75 let b:PHP_outdentphpescape = 1
76endif
77
78
79if exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent
80 let b:PHP_vintage_case_default_indent = 1
Bram Moolenaarc236c162008-07-13 17:41:49 +000081else
82 let b:PHP_vintage_case_default_indent = 0
83endif
84
85
86
Bram Moolenaar9ff70112005-07-11 22:29:03 +000087let b:PHP_lastindented = 0
88let b:PHP_indentbeforelast = 0
89let b:PHP_indentinghuge = 0
90let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
91let b:PHP_LastIndentedWasComment = 0
92let b:PHP_InsideMultilineComment = 0
93let b:InPHPcode = 0
94let b:InPHPcode_checked = 0
95let b:InPHPcode_and_script = 0
96let b:InPHPcode_tofind = ""
97let b:PHP_oldchangetick = b:changedtick
98let b:UserIsTypingComment = 0
99let b:optionsset = 0
100
101setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000102setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000103setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +0000104setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000105
Bram Moolenaar071d4272004-06-13 20:20:40 +0000106setlocal indentexpr=GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000107setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000108
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000109
Bram Moolenaar1e015462005-09-25 22:16:38 +0000110
111let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000112
113if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000114 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000115endif
116
Bram Moolenaar071d4272004-06-13 20:20:40 +0000117if exists("*GetPhpIndent")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100118 call ResetPhpOptions()
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200119 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120endif
121
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000122let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
123let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000124
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000125
126function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000127
Bram Moolenaar1e015462005-09-25 22:16:38 +0000128 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000129
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000130 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
131 let lnum = b:GetLastRealCodeLNum_ADD
132 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000133
Bram Moolenaar1e015462005-09-25 22:16:38 +0000134 let old_lnum = lnum
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000135
Bram Moolenaar1e015462005-09-25 22:16:38 +0000136 while lnum > 1
137 let lnum = prevnonblank(lnum)
138 let lastline = getline(lnum)
139
140 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
141 let lnum = lnum - 1
142 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
143 let lnum = lnum - 1
144 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
145 let lnum = lnum - 1
146 elseif lastline =~ '\*/\s*$'
147 call cursor(lnum, 1)
148 if lastline !~ '^\*/'
149 call search('\*/', 'W')
150 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000151 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000152
153 let lastline = getline(lnum)
154 if lastline =~ '^\s*/\*'
155 let lnum = lnum - 1
156 else
157 break
158 endif
159
160
161 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
162
163 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
164 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000165 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000166 endwhile
167 if lastline =~ '^\s*?>'
168 let lnum = lnum - 1
169 else
170 break
171 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000172
173
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200174 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc
175 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<''\\=\1''\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000176 while getline(lnum) !~? tofind && lnum > 1
177 let lnum = lnum - 1
178 endwhile
179 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000180 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000181 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000182 endwhile
183
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200184 if lnum==1 && getline(lnum) !~ '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000185 let lnum=0
186 endif
187
188 if b:InPHPcode_and_script && !b:InPHPcode
189 let b:InPHPcode_and_script = 0
190 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000191
192
193
Bram Moolenaar1e015462005-09-25 22:16:38 +0000194 return lnum
195endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000196
Bram Moolenaara5792f52005-11-23 21:25:05 +0000197function! Skippmatch2()
198
199 let line = getline(".")
200
Bram Moolenaarc236c162008-07-13 17:41:49 +0000201 if line =~ '\%(".*\)\@<=/\*\%(.*"\)\@=' || line =~ '\%(\%(//\|#\).*\)\@<=/\*'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000202 return 1
203 else
204 return 0
205 endif
206endfun
207
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200208function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000209 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000210 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 +0000211 return 0
212 else
213 return 1
214 endif
215endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000216
217function! FindOpenBracket(lnum) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000218 call cursor(a:lnum, 1)
219 return searchpair('{', '', '}', 'bW', 'Skippmatch()')
220endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000221
222function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000223
224 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
225 let beforeelse = a:lnum
226 else
227 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
228 endif
229
230 if !s:level
231 let s:iftoskip = 0
232 endif
233
234 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
235 let s:iftoskip = s:iftoskip + 1
236 endif
237
238 if getline(beforeelse) =~ '^\s*}'
239 let beforeelse = FindOpenBracket(beforeelse)
240
241 if getline(beforeelse) =~ '^\s*{'
242 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000243 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000244 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000245
246
Bram Moolenaar1e015462005-09-25 22:16:38 +0000247 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000248 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000249 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000250
Bram Moolenaar1e015462005-09-25 22:16:38 +0000251 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
252
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200253 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000254 let s:iftoskip = s:iftoskip - 1
255 endif
256
257 let s:level = s:level + 1
258 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
259 endif
260
261 return beforeelse
262
263endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000264
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200265let s:defaultORcase = '^\s*\%(default\|case\).*:'
266
267function! FindTheSwitchIndent (lnum) " {{{
268
269
270 let test = GetLastRealCodeLNum(a:lnum - 1)
271
272 if test <= 1
273 return indent(1) - &sw * b:PHP_vintage_case_default_indent
274 end
275
276 if getline(test) =~ '^\s*}'
277 let test = FindOpenBracket(test)
278
279 if getline(test) =~ '^\s*{'
280 let test = GetLastRealCodeLNum(GetLastRealCodeLNum(test - 1) - 1)
281 endif
282 endif
283
284 if getline(test) =~# '^\s*switch\>'
285 return indent(test)
286 elseif getline(test) =~# s:defaultORcase
287 return indent(test) - &sw * b:PHP_vintage_case_default_indent
288 else
289 return FindTheSwitchIndent(test)
290 endif
291
292endfunction "}}}
293
294
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000295function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000296 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000297
Bram Moolenaar1e015462005-09-25 22:16:38 +0000298 if a:tofind==""
Bram Moolenaara5792f52005-11-23 21:25:05 +0000299 let tofind = "^\\s*[\"']*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000300 else
301 let tofind = a:tofind
302 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000303
Bram Moolenaar1e015462005-09-25 22:16:38 +0000304 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000305
Bram Moolenaar1e015462005-09-25 22:16:38 +0000306 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000307
Bram Moolenaar1e015462005-09-25 22:16:38 +0000308 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
309
310 if synname =~ '^php' || synname=="Delimiter" || synname =~? '^javaScript'
311 return synname
312 else
313 return ""
314 endif
315endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000316
Bram Moolenaarc236c162008-07-13 17:41:49 +0000317let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|else\)'
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200318let 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 +0000319
Bram Moolenaar5c736222010-01-06 20:54:52 +0100320let s:autoresetoptions = 0
321if ! s:autoresetoptions
322 let s:autoresetoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000323endif
324
Bram Moolenaar5c736222010-01-06 20:54:52 +0100325function! ResetPhpOptions()
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200326 if ! b:optionsset && &filetype == "php"
Bram Moolenaara5792f52005-11-23 21:25:05 +0000327 if b:PHP_autoformatcomment
328
329 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000330
Bram Moolenaarc236c162008-07-13 17:41:49 +0000331 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000332 setlocal formatoptions+=q
333 setlocal formatoptions+=r
334 setlocal formatoptions+=o
Bram Moolenaarc236c162008-07-13 17:41:49 +0000335 setlocal formatoptions+=w
Bram Moolenaara5792f52005-11-23 21:25:05 +0000336 setlocal formatoptions+=c
337 setlocal formatoptions+=b
338 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000339 let b:optionsset = 1
340 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000341endfunc
342
Bram Moolenaar5c736222010-01-06 20:54:52 +0100343call ResetPhpOptions()
344
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000345function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000346
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000347 let b:GetLastRealCodeLNum_ADD = 0
348
Bram Moolenaar1e015462005-09-25 22:16:38 +0000349 let UserIsEditing=0
350 if b:PHP_oldchangetick != b:changedtick
351 let b:PHP_oldchangetick = b:changedtick
352 let UserIsEditing=1
353 endif
354
355 if b:PHP_default_indenting
356 let b:PHP_default_indenting = g:PHP_default_indenting * &sw
357 endif
358
359 let cline = getline(v:lnum)
360
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000361 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000362 if b:PHP_indentbeforelast
363 let b:PHP_indentinghuge = 1
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200364 echom 'Large indenting detected, speed optimizations engaged (v1.33)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000365 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000366 let b:PHP_indentbeforelast = b:PHP_lastindented
367 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000368
Bram Moolenaar1e015462005-09-25 22:16:38 +0000369 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
370 if b:PHP_indentinghuge
371 echom 'Large indenting deactivated'
372 let b:PHP_indentinghuge = 0
373 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000374 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000375 let b:PHP_lastindented = v:lnum
376 let b:PHP_LastIndentedWasComment=0
377 let b:PHP_InsideMultilineComment=0
378 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000379
Bram Moolenaar1e015462005-09-25 22:16:38 +0000380 let b:InPHPcode = 0
381 let b:InPHPcode_checked = 0
382 let b:InPHPcode_and_script = 0
383 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000384
Bram Moolenaar1e015462005-09-25 22:16:38 +0000385 elseif v:lnum > b:PHP_lastindented
386 let real_PHP_lastindented = b:PHP_lastindented
387 let b:PHP_lastindented = v:lnum
388 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000389
Bram Moolenaar1e015462005-09-25 22:16:38 +0000390
391 if !b:InPHPcode_checked " {{{ One time check
392 let b:InPHPcode_checked = 1
393
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000394 let synname = ""
395 if cline !~ '<?.*?>'
396 let synname = IslinePHP (prevnonblank(v:lnum), "")
397 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000398
399 if synname!=""
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000400 if synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000401 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000402 let b:InPHPcode_tofind = ""
403
Bram Moolenaarc236c162008-07-13 17:41:49 +0000404 if synname =~# "^phpComment"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000405 let b:UserIsTypingComment = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000406 else
Bram Moolenaar1e015462005-09-25 22:16:38 +0000407 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000408 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000409
Bram Moolenaar1e015462005-09-25 22:16:38 +0000410 if synname =~? '^javaScript'
411 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000412 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000413
Bram Moolenaar1e015462005-09-25 22:16:38 +0000414 else
415 let b:InPHPcode = 0
416 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000417
Bram Moolenaar1e015462005-09-25 22:16:38 +0000418 let lnum = v:lnum - 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000419 while getline(lnum) !~? '<<<''\=\a\w*''\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000420 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000421 endwhile
422
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200423 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000424 endif
425 else
426 let b:InPHPcode = 0
427 let b:UserIsTypingComment = 0
428 let b:InPHPcode_tofind = '<?\%(.*?>\)\@!\|<script.*>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000429 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000430 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000431
432
Bram Moolenaar1e015462005-09-25 22:16:38 +0000433 " Test if we are indenting PHP code {{{
434 let lnum = prevnonblank(v:lnum - 1)
435 let last_line = getline(lnum)
436
437 if b:InPHPcode_tofind!=""
438 if cline =~? b:InPHPcode_tofind
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200439 let b:InPHPcode = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000440 let b:InPHPcode_tofind = ""
441 let b:UserIsTypingComment = 0
442 if cline =~ '\*/'
443 call cursor(v:lnum, 1)
444 if cline !~ '^\*/'
445 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000446 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000447 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000448
Bram Moolenaar1e015462005-09-25 22:16:38 +0000449 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000450
Bram Moolenaar1e015462005-09-25 22:16:38 +0000451 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000452
Bram Moolenaar1e015462005-09-25 22:16:38 +0000453 if cline =~ '^\s*\*/'
454 return indent(lnum) + 1
455 else
456 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000457 endif
458
Bram Moolenaar1e015462005-09-25 22:16:38 +0000459 elseif cline =~? '<script\>'
460 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000461 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000462 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000463 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000464 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000465
Bram Moolenaar1e015462005-09-25 22:16:38 +0000466 if b:InPHPcode
467
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000468 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000469 if cline !~? s:PHP_startindenttag
470 let b:InPHPcode = 0
471 let b:InPHPcode_tofind = s:PHP_startindenttag
472 elseif cline =~? '<script\>'
473 let b:InPHPcode_and_script = 1
474 endif
475
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200476 elseif last_line =~? '<<<''\=\a\w*''\=$'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000477 let b:InPHPcode = 0
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200478 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000479
480 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
481 let b:InPHPcode = 0
482 let b:InPHPcode_tofind = '\*/'
483
484 elseif cline =~? '^\s*</script>'
485 let b:InPHPcode = 0
486 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000487 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000488 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000489
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000490
Bram Moolenaar1e015462005-09-25 22:16:38 +0000491 if !b:InPHPcode && !b:InPHPcode_and_script
492 return -1
493 endif
494
Bram Moolenaar1e015462005-09-25 22:16:38 +0000495 " Indent successive // or # comment the same way the first is {{{
496 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
497 if b:PHP_LastIndentedWasComment == 1
498 return indent(real_PHP_lastindented)
499 endif
500 let b:PHP_LastIndentedWasComment = 1
501 else
502 let b:PHP_LastIndentedWasComment = 0
503 endif " }}}
504
505 " Indent multiline /* comments correctly {{{
506
507 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
508 if cline =~ '^\s*\*\%(\/\)\@!'
509 if last_line =~ '^\s*/\*'
510 return indent(lnum) + 1
511 else
512 return indent(lnum)
513 endif
514 else
515 let b:PHP_InsideMultilineComment = 0
516 endif
517 endif
518
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000519 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$'
520 if getline(v:lnum + 1) !~ '^\s*\*'
521 return -1
522 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000523 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000524 endif " }}}
525
526
527 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200528 if cline =~# '^\s*<?' && cline !~ '?>' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000529 return 0
530 endif
531
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200532 if cline =~ '^\s*?>' && cline !~# '<?' && b:PHP_outdentphpescape
Bram Moolenaar1e015462005-09-25 22:16:38 +0000533 return 0
534 endif
535
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200536 if cline =~? '^\s*\a\w*;$\|^\a\w*$' && cline !~? s:notPhpHereDoc
Bram Moolenaar1e015462005-09-25 22:16:38 +0000537 return 0
538 endif " }}}
539
540 let s:level = 0
541
542 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000543
Bram Moolenaar1e015462005-09-25 22:16:38 +0000544 let last_line = getline(lnum)
545 let ind = indent(lnum)
546 let endline= s:endline
547
548 if ind==0 && b:PHP_default_indenting
549 let ind = b:PHP_default_indenting
550 endif
551
552 if lnum == 0
553 return b:PHP_default_indenting
554 endif
555
556
557 if cline =~ '^\s*}\%(}}\)\@!'
558 let ind = indent(FindOpenBracket(v:lnum))
559 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000560 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000561 endif
562
563 if cline =~ '^\s*\*/'
564 call cursor(v:lnum, 1)
565 if cline !~ '^\*/'
566 call search('\*/', 'W')
567 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000568 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000569
570 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
571
572 if cline =~ '^\s*\*/'
573 return indent(lnum) + 1
574 else
575 return indent(lnum)
576 endif
577 endif
578
Bram Moolenaar1e015462005-09-25 22:16:38 +0000579
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200580 if last_line =~ '[;}]'.endline && last_line !~ '^)' && last_line !~# s:defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000581 if ind==b:PHP_default_indenting
582 return b:PHP_default_indenting
583 elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline
584 return b:PHP_CurrentIndentLevel
585 endif
586 endif
587
588 let LastLineClosed = 0
589
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200590 let terminated = '\%(;\%(\s*?>\)\=\|<<<''\=\a\w*''\=$\|^\s*}\)'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000591
592 let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline
593
594 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
595 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
596 return indent(FindTheIfOfAnElse(v:lnum, 1))
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200597 elseif cline =~# s:defaultORcase
598 return FindTheSwitchIndent(v:lnum) + &sw * b:PHP_vintage_case_default_indent
Bram Moolenaarc236c162008-07-13 17:41:49 +0000599 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000600 let previous_line = last_line
601 let last_line_num = lnum
602
603 while last_line_num > 1
604
Bram Moolenaarc236c162008-07-13 17:41:49 +0000605 if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000606
607 let ind = indent(last_line_num)
608
609 if b:PHP_BracesAtCodeLevel
610 let ind = ind + &sw
611 endif
612
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000613 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000614 endif
615
616 let last_line_num = last_line_num - 1
617 let previous_line = getline(last_line_num)
618 endwhile
619
Bram Moolenaarc236c162008-07-13 17:41:49 +0000620 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200621 let ind = ind + &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000622 return ind
623
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200624 elseif (ind != b:PHP_default_indenting || last_line =~ '^)' ) && last_line =~ terminated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000625 let previous_line = last_line
626 let last_line_num = lnum
627 let LastLineClosed = 1
628
629 while 1
630 if previous_line =~ '^\s*}'
631 let last_line_num = FindOpenBracket(last_line_num)
632
633 if getline(last_line_num) =~ '^\s*{'
634 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
635 endif
636
637 let previous_line = getline(last_line_num)
638
639 continue
640 else
641
642 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
643 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
644 continue
645 endif
646
647
648 let last_match = last_line_num
649
650 let one_ahead_indent = indent(last_line_num)
651 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
652 let two_ahead_indent = indent(last_line_num)
653 let after_previous_line = previous_line
654 let previous_line = getline(last_line_num)
655
656
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200657 if previous_line =~# s:defaultORcase.'\|{'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000658 break
659 endif
660
661 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
662 break
663 endif
664
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000665 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000666 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000667 break
668 endif
669 endif
670 endif
671 endwhile
672
673 if indent(last_match) != ind
674 let ind = indent(last_match)
675 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
676
Bram Moolenaar1e015462005-09-25 22:16:38 +0000677 return ind
678 endif
679 endif
680
681 let plinnum = GetLastRealCodeLNum(lnum - 1)
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200682 let AntepenultimateLine = getline(plinnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000683
684 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
685
686
687 if ind == b:PHP_default_indenting
688 if last_line =~ terminated
689 let LastLineClosed = 1
690 endif
691 endif
692
693 if !LastLineClosed
694
Bram Moolenaar5c736222010-01-06 20:54:52 +0100695
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200696 if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(]'.endline
Bram Moolenaar1e015462005-09-25 22:16:38 +0000697
698 if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{'
699 let ind = ind + &sw
700 endif
701
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200702 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000703 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaarc236c162008-07-13 17:41:49 +0000704
Bram Moolenaar1e015462005-09-25 22:16:38 +0000705 return ind
706 endif
707
708 elseif last_line =~ '\S\+\s*),'.endline
709 call cursor(lnum, 1)
710 call search('),'.endline, 'W')
711 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
712 if openedparent != lnum
713 let ind = indent(openedparent)
714 endif
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200715
Bram Moolenaarc236c162008-07-13 17:41:49 +0000716 elseif last_line =~ '^\s*'.s:blockstart
Bram Moolenaar1e015462005-09-25 22:16:38 +0000717 let ind = ind + &sw
718
Bram Moolenaarc236c162008-07-13 17:41:49 +0000719
720
Bram Moolenaar8408a9a2010-07-30 22:41:22 +0200721 elseif AntepenultimateLine =~ '\%(;\%(\s*?>\)\=\|<<<''\=\a\w*''\=$\|^\s*}\|{\)'.endline . '\|' . s:defaultORcase
Bram Moolenaarc236c162008-07-13 17:41:49 +0000722 let ind = ind + &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000723 endif
724
Bram Moolenaar1e015462005-09-25 22:16:38 +0000725 endif
726
727 if cline =~ '^\s*);\='
728 let ind = ind - &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000729 endif
730
731 let b:PHP_CurrentIndentLevel = ind
732 return ind
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000733endfunction