blob: d73460d07dba8a797be4201d7cee39b28e90581d [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 Moolenaara7241f52008-06-24 20:39:31 +00005" Last Change: 2007 Jun 24
Bram Moolenaar05a7bb32006-01-19 22:09:32 +00006" Newsletter: http://www.2072productions.com/?to=php-indent-for-vim-newsletter.php
Bram Moolenaard5ab34b2007-05-05 17:15:44 +00007" Version: 1.24
Bram Moolenaar071d4272004-06-13 20:20:40 +00008"
Bram Moolenaara5792f52005-11-23 21:25:05 +00009" The change log and all the comments have been removed from this file.
Bram Moolenaar1e015462005-09-25 22:16:38 +000010"
Bram Moolenaara5792f52005-11-23 21:25:05 +000011" For a complete change log and fully commented code, download the script on
12" 2072productions.com at the URI provided above.
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000013"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000014" If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr
Bram Moolenaar05a7bb32006-01-19 22:09:32 +000015" with an example of code that breaks the algorithm.
Bram Moolenaara5792f52005-11-23 21:25:05 +000016"
17"
18" Thanks a lot for using this script.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000019"
20"
21" NOTE: This script must be used with PHP syntax ON and with the php syntax
Bram Moolenaar05a7bb32006-01-19 22:09:32 +000022" script by Lutz Eymers ( http://www.isp.de/data/php.vim ) that's the script bundled with Vim.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000023"
24"
25" In the case you have syntax errors in your script such as end of HereDoc
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000026" tags not at col 1 you'll have to indent your file 2 times (This script
Bram Moolenaar9ff70112005-07-11 22:29:03 +000027" will automatically put HereDoc end tags at col 1).
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000028"
Bram Moolenaara5792f52005-11-23 21:25:05 +000029"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000030" NOTE: If you are editing file 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:
35"
36" :%s /\r$//g
37"
38" 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 Moolenaar071d4272004-06-13 20:20:40 +000040
Bram Moolenaara5792f52005-11-23 21:25:05 +000041
42" Options: PHP_autoformatcomment = 0 to not enable autoformating of comment by
43" default, if set to 0, this script will let the 'formatoptions' setting intact.
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000044"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000045" Options: PHP_default_indenting = # of sw (default is 0), # of sw will be
Bram Moolenaara5792f52005-11-23 21:25:05 +000046" added to the indent of each line of PHP code.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000047"
48" Options: PHP_removeCRwhenUnix = 1 to make the script automatically remove CR
Bram Moolenaara5792f52005-11-23 21:25:05 +000049" at end of lines (by default this option is unset), NOTE that you
50" MUST remove CR when the fileformat is UNIX else the indentation
51" won't be correct...
Bram Moolenaar9ff70112005-07-11 22:29:03 +000052"
53" Options: PHP_BracesAtCodeLevel = 1 to indent the '{' and '}' at the same
Bram Moolenaara5792f52005-11-23 21:25:05 +000054" level than the code they contain.
55" Exemple:
56" Instead of:
57" if ($foo)
Bram Moolenaar9ff70112005-07-11 22:29:03 +000058" {
Bram Moolenaara5792f52005-11-23 21:25:05 +000059" foo();
Bram Moolenaar9ff70112005-07-11 22:29:03 +000060" }
61"
Bram Moolenaara5792f52005-11-23 21:25:05 +000062" You will write:
63" if ($foo)
64" {
65" foo();
66" }
67"
68" NOTE: The script will be a bit slower if you use this option because
69" some optimizations won't be available.
70
Bram Moolenaar071d4272004-06-13 20:20:40 +000071if exists("b:did_indent")
Bram Moolenaar1e015462005-09-25 22:16:38 +000072 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +000073endif
74let b:did_indent = 1
75
Bram Moolenaar9ff70112005-07-11 22:29:03 +000076
77let php_sync_method = 0
78
79
80if exists("PHP_default_indenting")
Bram Moolenaar1e015462005-09-25 22:16:38 +000081 let b:PHP_default_indenting = PHP_default_indenting * &sw
Bram Moolenaar9ff70112005-07-11 22:29:03 +000082else
Bram Moolenaar1e015462005-09-25 22:16:38 +000083 let b:PHP_default_indenting = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000084endif
85
86if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000087 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000088else
Bram Moolenaar1e015462005-09-25 22:16:38 +000089 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000090endif
91
Bram Moolenaara5792f52005-11-23 21:25:05 +000092if exists("PHP_autoformatcomment")
93 let b:PHP_autoformatcomment = PHP_autoformatcomment
94else
95 let b:PHP_autoformatcomment = 1
96endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000097
98let b:PHP_lastindented = 0
99let b:PHP_indentbeforelast = 0
100let b:PHP_indentinghuge = 0
101let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
102let b:PHP_LastIndentedWasComment = 0
103let b:PHP_InsideMultilineComment = 0
104let b:InPHPcode = 0
105let b:InPHPcode_checked = 0
106let b:InPHPcode_and_script = 0
107let b:InPHPcode_tofind = ""
108let b:PHP_oldchangetick = b:changedtick
109let b:UserIsTypingComment = 0
110let b:optionsset = 0
111
112setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000113setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000114setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +0000115setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000116
Bram Moolenaar071d4272004-06-13 20:20:40 +0000117setlocal indentexpr=GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000118setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000119
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000120
Bram Moolenaar1e015462005-09-25 22:16:38 +0000121
122let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000123
124if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000125 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000126endif
127
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128if exists("*GetPhpIndent")
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000129 finish " XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000130endif
131
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000132let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
133let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000134"setlocal debug=msg " XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000135
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000136
137function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000138
Bram Moolenaar1e015462005-09-25 22:16:38 +0000139 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000140
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000141 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
142 let lnum = b:GetLastRealCodeLNum_ADD
143 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000144
Bram Moolenaar1e015462005-09-25 22:16:38 +0000145 let old_lnum = lnum
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000146
Bram Moolenaar1e015462005-09-25 22:16:38 +0000147 while lnum > 1
148 let lnum = prevnonblank(lnum)
149 let lastline = getline(lnum)
150
151 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
152 let lnum = lnum - 1
153 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
154 let lnum = lnum - 1
155 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
156 let lnum = lnum - 1
157 elseif lastline =~ '\*/\s*$'
158 call cursor(lnum, 1)
159 if lastline !~ '^\*/'
160 call search('\*/', 'W')
161 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000162 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000163
164 let lastline = getline(lnum)
165 if lastline =~ '^\s*/\*'
166 let lnum = lnum - 1
167 else
168 break
169 endif
170
171
172 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
173
174 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
175 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000176 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000177 endwhile
178 if lastline =~ '^\s*?>'
179 let lnum = lnum - 1
180 else
181 break
182 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000183
184
Bram Moolenaar1e015462005-09-25 22:16:38 +0000185 elseif lastline =~? '^\a\w*;$' && lastline !~? s:notPhpHereDoc
186 let tofind=substitute( lastline, '\([^;]\+\);', '<<<\1$', '')
187 while getline(lnum) !~? tofind && lnum > 1
188 let lnum = lnum - 1
189 endwhile
190 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000191 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000192 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000193 endwhile
194
195 if lnum==1 && getline(lnum)!~ '<?'
196 let lnum=0
197 endif
198
199 if b:InPHPcode_and_script && !b:InPHPcode
200 let b:InPHPcode_and_script = 0
201 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000202
203
204
Bram Moolenaar1e015462005-09-25 22:16:38 +0000205 return lnum
206endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000207
Bram Moolenaara5792f52005-11-23 21:25:05 +0000208function! Skippmatch2()
209
210 let line = getline(".")
211
212 if line =~ '\%(".*\)\@<=/\*\%(.*"\)\@=' || line =~ '\%(//.*\)\@<=/\*'
213 return 1
214 else
215 return 0
216 endif
217endfun
218
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000219function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000220 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000221 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 +0000222 return 0
223 else
224 return 1
225 endif
226endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000227
228function! FindOpenBracket(lnum) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000229 call cursor(a:lnum, 1)
230 return searchpair('{', '', '}', 'bW', 'Skippmatch()')
231endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000232
233function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000234
235 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
236 let beforeelse = a:lnum
237 else
238 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
239 endif
240
241 if !s:level
242 let s:iftoskip = 0
243 endif
244
245 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
246 let s:iftoskip = s:iftoskip + 1
247 endif
248
249 if getline(beforeelse) =~ '^\s*}'
250 let beforeelse = FindOpenBracket(beforeelse)
251
252 if getline(beforeelse) =~ '^\s*{'
253 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000254 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000255 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000256
257
Bram Moolenaar1e015462005-09-25 22:16:38 +0000258 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000259 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000260 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000261
Bram Moolenaar1e015462005-09-25 22:16:38 +0000262 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
263
264 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
265 let s:iftoskip = s:iftoskip - 1
266 endif
267
268 let s:level = s:level + 1
269 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
270 endif
271
272 return beforeelse
273
274endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000275
276function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000277 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000278
Bram Moolenaar1e015462005-09-25 22:16:38 +0000279 if a:tofind==""
Bram Moolenaara5792f52005-11-23 21:25:05 +0000280 let tofind = "^\\s*[\"']*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000281 else
282 let tofind = a:tofind
283 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000284
Bram Moolenaar1e015462005-09-25 22:16:38 +0000285 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000286
Bram Moolenaar1e015462005-09-25 22:16:38 +0000287 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000288
Bram Moolenaar1e015462005-09-25 22:16:38 +0000289 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
290
291 if synname =~ '^php' || synname=="Delimiter" || synname =~? '^javaScript'
292 return synname
293 else
294 return ""
295 endif
296endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000297
298let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\);'
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000299let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|else\>\|while\>\|switch\>\|for\%(each\)\=\>\|declare\>\|class\>\|interface\>\|abstract\>\|try\>\|catch\>\|[|&]\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000300
301let s:autorestoptions = 0
302if ! s:autorestoptions
Bram Moolenaara5792f52005-11-23 21:25:05 +0000303 au BufWinEnter,Syntax *.php,*.php3,*.php4,*.php5 call ResetOptions()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000304 let s:autorestoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000305endif
306
307function! ResetOptions()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000308 if ! b:optionsset
Bram Moolenaara5792f52005-11-23 21:25:05 +0000309 if b:PHP_autoformatcomment
310
311 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000312
Bram Moolenaara7241f52008-06-24 20:39:31 +0000313 " setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000314 setlocal formatoptions+=q
315 setlocal formatoptions+=r
316 setlocal formatoptions+=o
Bram Moolenaara7241f52008-06-24 20:39:31 +0000317 " setlocal formatoptions+=w
Bram Moolenaara5792f52005-11-23 21:25:05 +0000318 setlocal formatoptions+=c
319 setlocal formatoptions+=b
320 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000321 let b:optionsset = 1
322 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000323endfunc
324
325function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000326
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000327 let b:GetLastRealCodeLNum_ADD = 0
328
Bram Moolenaar1e015462005-09-25 22:16:38 +0000329 let UserIsEditing=0
330 if b:PHP_oldchangetick != b:changedtick
331 let b:PHP_oldchangetick = b:changedtick
332 let UserIsEditing=1
333 endif
334
335 if b:PHP_default_indenting
336 let b:PHP_default_indenting = g:PHP_default_indenting * &sw
337 endif
338
339 let cline = getline(v:lnum)
340
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000341 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000342 if b:PHP_indentbeforelast
343 let b:PHP_indentinghuge = 1
344 echom 'Large indenting detected, speed optimizations engaged'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000345 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000346 let b:PHP_indentbeforelast = b:PHP_lastindented
347 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000348
Bram Moolenaar1e015462005-09-25 22:16:38 +0000349 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
350 if b:PHP_indentinghuge
351 echom 'Large indenting deactivated'
352 let b:PHP_indentinghuge = 0
353 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000354 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000355 let b:PHP_lastindented = v:lnum
356 let b:PHP_LastIndentedWasComment=0
357 let b:PHP_InsideMultilineComment=0
358 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000359
Bram Moolenaar1e015462005-09-25 22:16:38 +0000360 let b:InPHPcode = 0
361 let b:InPHPcode_checked = 0
362 let b:InPHPcode_and_script = 0
363 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000364
Bram Moolenaar1e015462005-09-25 22:16:38 +0000365 elseif v:lnum > b:PHP_lastindented
366 let real_PHP_lastindented = b:PHP_lastindented
367 let b:PHP_lastindented = v:lnum
368 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000369
Bram Moolenaar1e015462005-09-25 22:16:38 +0000370
371 if !b:InPHPcode_checked " {{{ One time check
372 let b:InPHPcode_checked = 1
373
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000374 let synname = ""
375 if cline !~ '<?.*?>'
376 let synname = IslinePHP (prevnonblank(v:lnum), "")
377 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000378
379 if synname!=""
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000380 if synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000381 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000382 let b:InPHPcode_tofind = ""
383
Bram Moolenaar1e015462005-09-25 22:16:38 +0000384 if synname == "phpComment"
385 let b:UserIsTypingComment = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000386 else
Bram Moolenaar1e015462005-09-25 22:16:38 +0000387 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000388 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000389
Bram Moolenaar1e015462005-09-25 22:16:38 +0000390 if synname =~? '^javaScript'
391 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000392 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000393
Bram Moolenaar1e015462005-09-25 22:16:38 +0000394 else
395 let b:InPHPcode = 0
396 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000397
Bram Moolenaar1e015462005-09-25 22:16:38 +0000398 let lnum = v:lnum - 1
399 while getline(lnum) !~? '<<<\a\w*$' && lnum > 1
400 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000401 endwhile
402
Bram Moolenaar1e015462005-09-25 22:16:38 +0000403 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\(\a\w*\)\c', '^\\s*\1;$', '')
404 endif
405 else
406 let b:InPHPcode = 0
407 let b:UserIsTypingComment = 0
408 let b:InPHPcode_tofind = '<?\%(.*?>\)\@!\|<script.*>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000409 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000410 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000411
412
Bram Moolenaar1e015462005-09-25 22:16:38 +0000413 " Test if we are indenting PHP code {{{
414 let lnum = prevnonblank(v:lnum - 1)
415 let last_line = getline(lnum)
416
417 if b:InPHPcode_tofind!=""
418 if cline =~? b:InPHPcode_tofind
419 let b:InPHPcode = 1
420 let b:InPHPcode_tofind = ""
421 let b:UserIsTypingComment = 0
422 if cline =~ '\*/'
423 call cursor(v:lnum, 1)
424 if cline !~ '^\*/'
425 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000426 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000427 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000428
Bram Moolenaar1e015462005-09-25 22:16:38 +0000429 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000430
Bram Moolenaar1e015462005-09-25 22:16:38 +0000431 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000432
Bram Moolenaar1e015462005-09-25 22:16:38 +0000433 if cline =~ '^\s*\*/'
434 return indent(lnum) + 1
435 else
436 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000437 endif
438
Bram Moolenaar1e015462005-09-25 22:16:38 +0000439 elseif cline =~? '<script\>'
440 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000441 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000442 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000443 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000444 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000445
Bram Moolenaar1e015462005-09-25 22:16:38 +0000446 if b:InPHPcode
447
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000448 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000449 if cline !~? s:PHP_startindenttag
450 let b:InPHPcode = 0
451 let b:InPHPcode_tofind = s:PHP_startindenttag
452 elseif cline =~? '<script\>'
453 let b:InPHPcode_and_script = 1
454 endif
455
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000456 elseif last_line =~? '<<<\a\w*$'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000457 let b:InPHPcode = 0
458 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\(\a\w*\)\c', '^\\s*\1;$', '')
459
460 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
461 let b:InPHPcode = 0
462 let b:InPHPcode_tofind = '\*/'
463
464 elseif cline =~? '^\s*</script>'
465 let b:InPHPcode = 0
466 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000467 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000468 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000469
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000470
Bram Moolenaar1e015462005-09-25 22:16:38 +0000471 if !b:InPHPcode && !b:InPHPcode_and_script
472 return -1
473 endif
474
Bram Moolenaar1e015462005-09-25 22:16:38 +0000475 " Indent successive // or # comment the same way the first is {{{
476 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
477 if b:PHP_LastIndentedWasComment == 1
478 return indent(real_PHP_lastindented)
479 endif
480 let b:PHP_LastIndentedWasComment = 1
481 else
482 let b:PHP_LastIndentedWasComment = 0
483 endif " }}}
484
485 " Indent multiline /* comments correctly {{{
486
487 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
488 if cline =~ '^\s*\*\%(\/\)\@!'
489 if last_line =~ '^\s*/\*'
490 return indent(lnum) + 1
491 else
492 return indent(lnum)
493 endif
494 else
495 let b:PHP_InsideMultilineComment = 0
496 endif
497 endif
498
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000499 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$'
500 if getline(v:lnum + 1) !~ '^\s*\*'
501 return -1
502 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000503 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000504 endif " }}}
505
506
507 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
508 if cline =~# '^\s*<?' && cline !~ '?>'
509 return 0
510 endif
511
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000512 if cline =~ '^\s*?>' && cline !~# '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000513 return 0
514 endif
515
516 if cline =~? '^\s*\a\w*;$' && cline !~? s:notPhpHereDoc
517 return 0
518 endif " }}}
519
520 let s:level = 0
521
522 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000523
Bram Moolenaar1e015462005-09-25 22:16:38 +0000524 let last_line = getline(lnum)
525 let ind = indent(lnum)
526 let endline= s:endline
527
528 if ind==0 && b:PHP_default_indenting
529 let ind = b:PHP_default_indenting
530 endif
531
532 if lnum == 0
533 return b:PHP_default_indenting
534 endif
535
536
537 if cline =~ '^\s*}\%(}}\)\@!'
538 let ind = indent(FindOpenBracket(v:lnum))
539 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000540 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000541 endif
542
543 if cline =~ '^\s*\*/'
544 call cursor(v:lnum, 1)
545 if cline !~ '^\*/'
546 call search('\*/', 'W')
547 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000548 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000549
550 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
551
552 if cline =~ '^\s*\*/'
553 return indent(lnum) + 1
554 else
555 return indent(lnum)
556 endif
557 endif
558
559 let defaultORcase = '^\s*\%(default\|case\).*:'
560
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000561 if last_line =~ '[;}]'.endline && last_line !~# defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000562 if ind==b:PHP_default_indenting
563 return b:PHP_default_indenting
564 elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline
565 return b:PHP_CurrentIndentLevel
566 endif
567 endif
568
569 let LastLineClosed = 0
570
571 let terminated = '\%(;\%(\s*?>\)\=\|<<<\a\w*\|}\)'.endline
572
573 let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline
574
575 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
576 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
577 return indent(FindTheIfOfAnElse(v:lnum, 1))
578 elseif cline =~ '^\s*{'
579 let previous_line = last_line
580 let last_line_num = lnum
581
582 while last_line_num > 1
583
584 if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)' && previous_line !~ '^\s*[|&]'
585
586 let ind = indent(last_line_num)
587
588 if b:PHP_BracesAtCodeLevel
589 let ind = ind + &sw
590 endif
591
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000592 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000593 endif
594
595 let last_line_num = last_line_num - 1
596 let previous_line = getline(last_line_num)
597 endwhile
598
599 elseif last_line =~# unstated && cline !~ '^\s*{\|^\s*);\='.endline
600 let ind = ind + &sw
601 return ind
602
603 elseif ind != b:PHP_default_indenting && last_line =~ terminated
604 let previous_line = last_line
605 let last_line_num = lnum
606 let LastLineClosed = 1
607
608 while 1
609 if previous_line =~ '^\s*}'
610 let last_line_num = FindOpenBracket(last_line_num)
611
612 if getline(last_line_num) =~ '^\s*{'
613 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
614 endif
615
616 let previous_line = getline(last_line_num)
617
618 continue
619 else
620
621 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
622 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
623 continue
624 endif
625
626
627 let last_match = last_line_num
628
629 let one_ahead_indent = indent(last_line_num)
630 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
631 let two_ahead_indent = indent(last_line_num)
632 let after_previous_line = previous_line
633 let previous_line = getline(last_line_num)
634
635
636 if previous_line =~# defaultORcase.'\|{'.endline
637 break
638 endif
639
640 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
641 break
642 endif
643
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000644 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000645 if previous_line =~# '[;}]'.endline || last_line_num < 1
646 break
647 endif
648 endif
649 endif
650 endwhile
651
652 if indent(last_match) != ind
653 let ind = indent(last_match)
654 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
655
656 if cline =~# defaultORcase
657 let ind = ind - &sw
658 endif
659 return ind
660 endif
661 endif
662
663 let plinnum = GetLastRealCodeLNum(lnum - 1)
664 let pline = getline(plinnum)
665
666 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
667
668
669 if ind == b:PHP_default_indenting
670 if last_line =~ terminated
671 let LastLineClosed = 1
672 endif
673 endif
674
675 if !LastLineClosed
676
677 if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && pline !~ '[,(]'.endline
678
679 if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{'
680 let ind = ind + &sw
681 endif
682
683 if b:PHP_BracesAtCodeLevel || cline !~# defaultORcase
684 let b:PHP_CurrentIndentLevel = ind
685 return ind
686 endif
687
688 elseif last_line =~ '\S\+\s*),'.endline
689 call cursor(lnum, 1)
690 call search('),'.endline, 'W')
691 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
692 if openedparent != lnum
693 let ind = indent(openedparent)
694 endif
695
696
697 elseif cline !~ '^\s*{' && pline =~ '\%(;\%(\s*?>\)\=\|<<<\a\w*\|{\|^\s*'.s:blockstart.'\s*(.*)\)'.endline.'\|^\s*}\|'.defaultORcase
698
699 let ind = ind + &sw
700
701 endif
702
703 elseif last_line =~# defaultORcase
704 let ind = ind + &sw
705 endif
706
707 if cline =~ '^\s*);\='
708 let ind = ind - &sw
709 elseif cline =~# defaultORcase
710 let ind = ind - &sw
711
712 endif
713
714 let b:PHP_CurrentIndentLevel = ind
715 return ind
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000716endfunction