blob: 6124eb2f6637d7886be4804b9640288b8c2c03e6 [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 Moolenaarc236c162008-07-13 17:41:49 +00005" Last Change: 2008 June 7th
Bram Moolenaar05a7bb32006-01-19 22:09:32 +00006" Newsletter: http://www.2072productions.com/?to=php-indent-for-vim-newsletter.php
Bram Moolenaarc236c162008-07-13 17:41:49 +00007" Version: 1.28
Bram Moolenaar071d4272004-06-13 20:20:40 +00008"
Bram Moolenaarc236c162008-07-13 17:41:49 +00009" If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr
10" with an example of code that breaks the algorithm.
11"
12" ---> The change log and all the comments have been removed from this file.
Bram Moolenaar1e015462005-09-25 22:16:38 +000013"
Bram Moolenaara5792f52005-11-23 21:25:05 +000014" For a complete change log and fully commented code, download the script on
15" 2072productions.com at the URI provided above.
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000016"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000017" If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr
Bram Moolenaar05a7bb32006-01-19 22:09:32 +000018" with an example of code that breaks the algorithm.
Bram Moolenaara5792f52005-11-23 21:25:05 +000019"
20"
21" Thanks a lot for using this script.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000022"
23"
24" NOTE: This script must be used with PHP syntax ON and with the php syntax
Bram Moolenaarc236c162008-07-13 17:41:49 +000025" script by Lutz Eymers (http://www.isp.de/data/php.vim ) or with the
26" script by Peter Hodge (http://www.vim.org/scripts/script.php?script_id=1571 )
27" the later is bunbdled by default with vim 7.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000028"
29"
Bram Moolenaarc236c162008-07-13 17:41:49 +000030" In the case you have syntax errors in your script such as HereDoc end
31" identifiers not at col 1 you'll have to indent your file 2 times (This
32" script will automatically put HereDoc end identifiers at col 1 if
33" they are followed by a ';').
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000034"
Bram Moolenaara5792f52005-11-23 21:25:05 +000035"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000036" NOTE: If you are editing file in Unix file format and that (by accident)
37" there are '\r' before new lines, this script won't be able to proceed
38" correctly and will make many mistakes because it won't be able to match
39" '\s*$' correctly.
40" So you have to remove those useless characters first with a command like:
41"
42" :%s /\r$//g
43"
44" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will
45" silently remove them when VIM load this script (at each bufread).
Bram Moolenaarc236c162008-07-13 17:41:49 +000046"
47"
Bram Moolenaara5792f52005-11-23 21:25:05 +000048" Options: PHP_autoformatcomment = 0 to not enable autoformating of comment by
49" default, if set to 0, this script will let the 'formatoptions' setting intact.
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000050"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000051" Options: PHP_default_indenting = # of sw (default is 0), # of sw will be
Bram Moolenaara5792f52005-11-23 21:25:05 +000052" added to the indent of each line of PHP code.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000053"
54" Options: PHP_removeCRwhenUnix = 1 to make the script automatically remove CR
Bram Moolenaara5792f52005-11-23 21:25:05 +000055" at end of lines (by default this option is unset), NOTE that you
56" MUST remove CR when the fileformat is UNIX else the indentation
Bram Moolenaarc236c162008-07-13 17:41:49 +000057" won't be correct!
Bram Moolenaar9ff70112005-07-11 22:29:03 +000058"
59" Options: PHP_BracesAtCodeLevel = 1 to indent the '{' and '}' at the same
Bram Moolenaara5792f52005-11-23 21:25:05 +000060" level than the code they contain.
61" Exemple:
62" Instead of:
63" if ($foo)
Bram Moolenaar9ff70112005-07-11 22:29:03 +000064" {
Bram Moolenaara5792f52005-11-23 21:25:05 +000065" foo();
Bram Moolenaar9ff70112005-07-11 22:29:03 +000066" }
67"
Bram Moolenaara5792f52005-11-23 21:25:05 +000068" You will write:
69" if ($foo)
70" {
71" foo();
72" }
73"
74" NOTE: The script will be a bit slower if you use this option because
75" some optimizations won't be available.
Bram Moolenaarc236c162008-07-13 17:41:49 +000076"
77" Options: PHP_vintage_case_default_indent = 1 (defaults to 0) to add a meaningless indent
78" befaore 'case:' and 'default":' statement in switch block
79"
Bram Moolenaara5792f52005-11-23 21:25:05 +000080
Bram Moolenaar071d4272004-06-13 20:20:40 +000081if exists("b:did_indent")
Bram Moolenaar1e015462005-09-25 22:16:38 +000082 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +000083endif
84let b:did_indent = 1
85
Bram Moolenaar9ff70112005-07-11 22:29:03 +000086
87let php_sync_method = 0
88
89
90if exists("PHP_default_indenting")
Bram Moolenaar1e015462005-09-25 22:16:38 +000091 let b:PHP_default_indenting = PHP_default_indenting * &sw
Bram Moolenaar9ff70112005-07-11 22:29:03 +000092else
Bram Moolenaar1e015462005-09-25 22:16:38 +000093 let b:PHP_default_indenting = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000094endif
95
96if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000097 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000098else
Bram Moolenaar1e015462005-09-25 22:16:38 +000099 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000100endif
101
Bram Moolenaarc236c162008-07-13 17:41:49 +0000102
Bram Moolenaara5792f52005-11-23 21:25:05 +0000103if exists("PHP_autoformatcomment")
104 let b:PHP_autoformatcomment = PHP_autoformatcomment
105else
106 let b:PHP_autoformatcomment = 1
107endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000108
Bram Moolenaarc236c162008-07-13 17:41:49 +0000109if exists("PHP_vintage_case_default_indent")
110 let b:PHP_vintage_case_default_indent = PHP_vintage_case_default_indent
111else
112 let b:PHP_vintage_case_default_indent = 0
113endif
114
115
116
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000117let b:PHP_lastindented = 0
118let b:PHP_indentbeforelast = 0
119let b:PHP_indentinghuge = 0
120let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
121let b:PHP_LastIndentedWasComment = 0
122let b:PHP_InsideMultilineComment = 0
123let b:InPHPcode = 0
124let b:InPHPcode_checked = 0
125let b:InPHPcode_and_script = 0
126let b:InPHPcode_tofind = ""
127let b:PHP_oldchangetick = b:changedtick
128let b:UserIsTypingComment = 0
129let b:optionsset = 0
130
131setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000132setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000133setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +0000134setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000135
Bram Moolenaar071d4272004-06-13 20:20:40 +0000136setlocal indentexpr=GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000137setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000138
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000139
Bram Moolenaar1e015462005-09-25 22:16:38 +0000140
141let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000142
143if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000144 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000145endif
146
Bram Moolenaar071d4272004-06-13 20:20:40 +0000147if exists("*GetPhpIndent")
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000148 finish " XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000149endif
150
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000151let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
152let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000153"setlocal debug=msg " XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000154
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000155
156function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000157
Bram Moolenaar1e015462005-09-25 22:16:38 +0000158 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000159
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000160 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
161 let lnum = b:GetLastRealCodeLNum_ADD
162 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000163
Bram Moolenaar1e015462005-09-25 22:16:38 +0000164 let old_lnum = lnum
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000165
Bram Moolenaar1e015462005-09-25 22:16:38 +0000166 while lnum > 1
167 let lnum = prevnonblank(lnum)
168 let lastline = getline(lnum)
169
170 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
171 let lnum = lnum - 1
172 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
173 let lnum = lnum - 1
174 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
175 let lnum = lnum - 1
176 elseif lastline =~ '\*/\s*$'
177 call cursor(lnum, 1)
178 if lastline !~ '^\*/'
179 call search('\*/', 'W')
180 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000181 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000182
183 let lastline = getline(lnum)
184 if lastline =~ '^\s*/\*'
185 let lnum = lnum - 1
186 else
187 break
188 endif
189
190
191 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
192
193 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
194 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000195 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000196 endwhile
197 if lastline =~ '^\s*?>'
198 let lnum = lnum - 1
199 else
200 break
201 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000202
203
Bram Moolenaarc236c162008-07-13 17:41:49 +0000204 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc " XXX 0607
205 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<''\\=\1''\\=$', '') " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000206 while getline(lnum) !~? tofind && lnum > 1
207 let lnum = lnum - 1
208 endwhile
209 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000210 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000211 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000212 endwhile
213
214 if lnum==1 && getline(lnum)!~ '<?'
215 let lnum=0
216 endif
217
218 if b:InPHPcode_and_script && !b:InPHPcode
219 let b:InPHPcode_and_script = 0
220 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000221
222
223
Bram Moolenaar1e015462005-09-25 22:16:38 +0000224 return lnum
225endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000226
Bram Moolenaara5792f52005-11-23 21:25:05 +0000227function! Skippmatch2()
228
229 let line = getline(".")
230
Bram Moolenaarc236c162008-07-13 17:41:49 +0000231 if line =~ '\%(".*\)\@<=/\*\%(.*"\)\@=' || line =~ '\%(\%(//\|#\).*\)\@<=/\*'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000232 return 1
233 else
234 return 0
235 endif
236endfun
237
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000238function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000239 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000240 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 +0000241 return 0
242 else
243 return 1
244 endif
245endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000246
247function! FindOpenBracket(lnum) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000248 call cursor(a:lnum, 1)
249 return searchpair('{', '', '}', 'bW', 'Skippmatch()')
250endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000251
252function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000253
254 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
255 let beforeelse = a:lnum
256 else
257 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
258 endif
259
260 if !s:level
261 let s:iftoskip = 0
262 endif
263
264 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
265 let s:iftoskip = s:iftoskip + 1
266 endif
267
268 if getline(beforeelse) =~ '^\s*}'
269 let beforeelse = FindOpenBracket(beforeelse)
270
271 if getline(beforeelse) =~ '^\s*{'
272 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000273 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000274 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000275
276
Bram Moolenaar1e015462005-09-25 22:16:38 +0000277 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000278 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000279 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000280
Bram Moolenaar1e015462005-09-25 22:16:38 +0000281 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
282
283 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
284 let s:iftoskip = s:iftoskip - 1
285 endif
286
287 let s:level = s:level + 1
288 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
289 endif
290
291 return beforeelse
292
293endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000294
295function! 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\)'
318let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|else\>\|while\>\|switch\>\|for\%(each\)\=\>\|declare\>\|class\>\|interface\>\|abstract\>\|try\>\|catch\>\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000319
320let s:autorestoptions = 0
321if ! s:autorestoptions
Bram Moolenaara5792f52005-11-23 21:25:05 +0000322 au BufWinEnter,Syntax *.php,*.php3,*.php4,*.php5 call ResetOptions()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000323 let s:autorestoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000324endif
325
326function! ResetOptions()
Bram Moolenaar1e015462005-09-25 22:16:38 +0000327 if ! b:optionsset
Bram Moolenaara5792f52005-11-23 21:25:05 +0000328 if b:PHP_autoformatcomment
329
330 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000331
Bram Moolenaarc236c162008-07-13 17:41:49 +0000332 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000333 setlocal formatoptions+=q
334 setlocal formatoptions+=r
335 setlocal formatoptions+=o
Bram Moolenaarc236c162008-07-13 17:41:49 +0000336 setlocal formatoptions+=w
Bram Moolenaara5792f52005-11-23 21:25:05 +0000337 setlocal formatoptions+=c
338 setlocal formatoptions+=b
339 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000340 let b:optionsset = 1
341 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000342endfunc
343
344function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000345
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000346 let b:GetLastRealCodeLNum_ADD = 0
347
Bram Moolenaar1e015462005-09-25 22:16:38 +0000348 let UserIsEditing=0
349 if b:PHP_oldchangetick != b:changedtick
350 let b:PHP_oldchangetick = b:changedtick
351 let UserIsEditing=1
352 endif
353
354 if b:PHP_default_indenting
355 let b:PHP_default_indenting = g:PHP_default_indenting * &sw
356 endif
357
358 let cline = getline(v:lnum)
359
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000360 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000361 if b:PHP_indentbeforelast
362 let b:PHP_indentinghuge = 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000363 echom 'Large indenting detected, speed optimizations engaged (v1.28)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000364 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000365 let b:PHP_indentbeforelast = b:PHP_lastindented
366 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000367
Bram Moolenaar1e015462005-09-25 22:16:38 +0000368 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
369 if b:PHP_indentinghuge
370 echom 'Large indenting deactivated'
371 let b:PHP_indentinghuge = 0
372 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000373 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000374 let b:PHP_lastindented = v:lnum
375 let b:PHP_LastIndentedWasComment=0
376 let b:PHP_InsideMultilineComment=0
377 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000378
Bram Moolenaar1e015462005-09-25 22:16:38 +0000379 let b:InPHPcode = 0
380 let b:InPHPcode_checked = 0
381 let b:InPHPcode_and_script = 0
382 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000383
Bram Moolenaar1e015462005-09-25 22:16:38 +0000384 elseif v:lnum > b:PHP_lastindented
385 let real_PHP_lastindented = b:PHP_lastindented
386 let b:PHP_lastindented = v:lnum
387 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000388
Bram Moolenaar1e015462005-09-25 22:16:38 +0000389
390 if !b:InPHPcode_checked " {{{ One time check
391 let b:InPHPcode_checked = 1
392
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000393 let synname = ""
394 if cline !~ '<?.*?>'
395 let synname = IslinePHP (prevnonblank(v:lnum), "")
396 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000397
398 if synname!=""
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000399 if synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000400 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000401 let b:InPHPcode_tofind = ""
402
Bram Moolenaarc236c162008-07-13 17:41:49 +0000403 if synname =~# "^phpComment"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000404 let b:UserIsTypingComment = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000405 else
Bram Moolenaar1e015462005-09-25 22:16:38 +0000406 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000407 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000408
Bram Moolenaar1e015462005-09-25 22:16:38 +0000409 if synname =~? '^javaScript'
410 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000411 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000412
Bram Moolenaar1e015462005-09-25 22:16:38 +0000413 else
414 let b:InPHPcode = 0
415 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000416
Bram Moolenaar1e015462005-09-25 22:16:38 +0000417 let lnum = v:lnum - 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000418 while getline(lnum) !~? '<<<''\=\a\w*''\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000419 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000420 endwhile
421
Bram Moolenaarc236c162008-07-13 17:41:49 +0000422 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '') " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000423 endif
424 else
425 let b:InPHPcode = 0
426 let b:UserIsTypingComment = 0
427 let b:InPHPcode_tofind = '<?\%(.*?>\)\@!\|<script.*>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000428 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000429 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000430
431
Bram Moolenaar1e015462005-09-25 22:16:38 +0000432 " Test if we are indenting PHP code {{{
433 let lnum = prevnonblank(v:lnum - 1)
434 let last_line = getline(lnum)
435
436 if b:InPHPcode_tofind!=""
437 if cline =~? b:InPHPcode_tofind
438 let b:InPHPcode = 1
439 let b:InPHPcode_tofind = ""
440 let b:UserIsTypingComment = 0
441 if cline =~ '\*/'
442 call cursor(v:lnum, 1)
443 if cline !~ '^\*/'
444 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000445 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000446 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000447
Bram Moolenaar1e015462005-09-25 22:16:38 +0000448 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000449
Bram Moolenaar1e015462005-09-25 22:16:38 +0000450 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000451
Bram Moolenaar1e015462005-09-25 22:16:38 +0000452 if cline =~ '^\s*\*/'
453 return indent(lnum) + 1
454 else
455 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000456 endif
457
Bram Moolenaar1e015462005-09-25 22:16:38 +0000458 elseif cline =~? '<script\>'
459 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000460 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000461 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000462 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000463 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000464
Bram Moolenaar1e015462005-09-25 22:16:38 +0000465 if b:InPHPcode
466
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000467 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000468 if cline !~? s:PHP_startindenttag
469 let b:InPHPcode = 0
470 let b:InPHPcode_tofind = s:PHP_startindenttag
471 elseif cline =~? '<script\>'
472 let b:InPHPcode_and_script = 1
473 endif
474
Bram Moolenaarc236c162008-07-13 17:41:49 +0000475 elseif last_line =~? '<<<''\=\a\w*''\=$' " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000476 let b:InPHPcode = 0
Bram Moolenaarc236c162008-07-13 17:41:49 +0000477 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '') " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000478
479 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
480 let b:InPHPcode = 0
481 let b:InPHPcode_tofind = '\*/'
482
483 elseif cline =~? '^\s*</script>'
484 let b:InPHPcode = 0
485 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000486 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000487 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000488
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000489
Bram Moolenaar1e015462005-09-25 22:16:38 +0000490 if !b:InPHPcode && !b:InPHPcode_and_script
491 return -1
492 endif
493
Bram Moolenaar1e015462005-09-25 22:16:38 +0000494 " Indent successive // or # comment the same way the first is {{{
495 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
496 if b:PHP_LastIndentedWasComment == 1
497 return indent(real_PHP_lastindented)
498 endif
499 let b:PHP_LastIndentedWasComment = 1
500 else
501 let b:PHP_LastIndentedWasComment = 0
502 endif " }}}
503
504 " Indent multiline /* comments correctly {{{
505
506 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
507 if cline =~ '^\s*\*\%(\/\)\@!'
508 if last_line =~ '^\s*/\*'
509 return indent(lnum) + 1
510 else
511 return indent(lnum)
512 endif
513 else
514 let b:PHP_InsideMultilineComment = 0
515 endif
516 endif
517
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000518 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$'
519 if getline(v:lnum + 1) !~ '^\s*\*'
520 return -1
521 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000522 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000523 endif " }}}
524
525
526 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
527 if cline =~# '^\s*<?' && cline !~ '?>'
528 return 0
529 endif
530
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000531 if cline =~ '^\s*?>' && cline !~# '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000532 return 0
533 endif
534
Bram Moolenaarc236c162008-07-13 17:41:49 +0000535 if cline =~? '^\s*\a\w*;$\|^\a\w*$' && cline !~? s:notPhpHereDoc " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000536 return 0
537 endif " }}}
538
539 let s:level = 0
540
541 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000542
Bram Moolenaar1e015462005-09-25 22:16:38 +0000543 let last_line = getline(lnum)
544 let ind = indent(lnum)
545 let endline= s:endline
546
547 if ind==0 && b:PHP_default_indenting
548 let ind = b:PHP_default_indenting
549 endif
550
551 if lnum == 0
552 return b:PHP_default_indenting
553 endif
554
555
556 if cline =~ '^\s*}\%(}}\)\@!'
557 let ind = indent(FindOpenBracket(v:lnum))
558 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000559 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000560 endif
561
562 if cline =~ '^\s*\*/'
563 call cursor(v:lnum, 1)
564 if cline !~ '^\*/'
565 call search('\*/', 'W')
566 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000567 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000568
569 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
570
571 if cline =~ '^\s*\*/'
572 return indent(lnum) + 1
573 else
574 return indent(lnum)
575 endif
576 endif
577
578 let defaultORcase = '^\s*\%(default\|case\).*:'
579
Bram Moolenaarc236c162008-07-13 17:41:49 +0000580 if last_line =~ '[;}]'.endline && last_line !~ '^)' && last_line !~# defaultORcase " Added && last_line !~ '^)' on 2007-12-30
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 Moolenaarc236c162008-07-13 17:41:49 +0000590 let terminated = '\%(;\%(\s*?>\)\=\|<<<''\=\a\w*''\=$\|^\s*}\)'.endline " XXX 0607
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 Moolenaarc236c162008-07-13 17:41:49 +0000597 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000598 let previous_line = last_line
599 let last_line_num = lnum
600
601 while last_line_num > 1
602
Bram Moolenaarc236c162008-07-13 17:41:49 +0000603 if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000604
605 let ind = indent(last_line_num)
606
607 if b:PHP_BracesAtCodeLevel
608 let ind = ind + &sw
609 endif
610
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000611 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000612 endif
613
614 let last_line_num = last_line_num - 1
615 let previous_line = getline(last_line_num)
616 endwhile
617
Bram Moolenaarc236c162008-07-13 17:41:49 +0000618 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
619 let ind = ind + &sw " we indent one level further when the preceding line is not stated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000620 return ind
621
Bram Moolenaarc236c162008-07-13 17:41:49 +0000622 elseif (ind != b:PHP_default_indenting || last_line =~ '^)' ) && last_line =~ terminated " Added || last_line =~ '^)' on 2007-12-30 (array indenting [rpblem broke other things)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000623 let previous_line = last_line
624 let last_line_num = lnum
625 let LastLineClosed = 1
626
627 while 1
628 if previous_line =~ '^\s*}'
629 let last_line_num = FindOpenBracket(last_line_num)
630
631 if getline(last_line_num) =~ '^\s*{'
632 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
633 endif
634
635 let previous_line = getline(last_line_num)
636
637 continue
638 else
639
640 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
641 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
642 continue
643 endif
644
645
646 let last_match = last_line_num
647
648 let one_ahead_indent = indent(last_line_num)
649 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
650 let two_ahead_indent = indent(last_line_num)
651 let after_previous_line = previous_line
652 let previous_line = getline(last_line_num)
653
654
655 if previous_line =~# defaultORcase.'\|{'.endline
656 break
657 endif
658
659 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
660 break
661 endif
662
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000663 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000664 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000665 break
666 endif
667 endif
668 endif
669 endwhile
670
671 if indent(last_match) != ind
672 let ind = indent(last_match)
673 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
674
675 if cline =~# defaultORcase
676 let ind = ind - &sw
677 endif
678 return ind
679 endif
680 endif
681
682 let plinnum = GetLastRealCodeLNum(lnum - 1)
683 let pline = getline(plinnum)
684
685 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
686
687
688 if ind == b:PHP_default_indenting
689 if last_line =~ terminated
690 let LastLineClosed = 1
691 endif
692 endif
693
694 if !LastLineClosed
695
696 if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && pline !~ '[,(]'.endline
697
698 if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{'
699 let ind = ind + &sw
700 endif
701
Bram Moolenaarc236c162008-07-13 17:41:49 +0000702 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1 || cline !~# defaultORcase
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 Moolenaarc236c162008-07-13 17:41:49 +0000715 elseif last_line =~ '^\s*'.s:blockstart
Bram Moolenaar1e015462005-09-25 22:16:38 +0000716 let ind = ind + &sw
717
Bram Moolenaarc236c162008-07-13 17:41:49 +0000718 elseif last_line =~# defaultORcase
719 let ind = ind + &sw
720
721
722 elseif pline =~ '\%(;\%(\s*?>\)\=\|<<<''\=\a\w*''\=$\|^\s*}\|{\)'.endline . '\|' . defaultORcase
723
724 let ind = ind + &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000725 endif
726
Bram Moolenaar1e015462005-09-25 22:16:38 +0000727 endif
728
729 if cline =~ '^\s*);\='
730 let ind = ind - &sw
Bram Moolenaarc236c162008-07-13 17:41:49 +0000731 elseif cline =~# defaultORcase && last_line !~# defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000732 let ind = ind - &sw
733
734 endif
735
736 let b:PHP_CurrentIndentLevel = ind
737 return ind
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000738endfunction