blob: 9f1a1ed9d3993aeb22535bc67cdf530a1fb2d895 [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 Moolenaar5c736222010-01-06 20:54:52 +01005" Last Change: 2008 November 22nd
Bram Moolenaar05a7bb32006-01-19 22:09:32 +00006" Newsletter: http://www.2072productions.com/?to=php-indent-for-vim-newsletter.php
Bram Moolenaar5c736222010-01-06 20:54:52 +01007" Version: 1.30
Bram Moolenaar071d4272004-06-13 20:20:40 +00008"
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00009"
Bram Moolenaar9ff70112005-07-11 22:29:03 +000010" If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr
Bram Moolenaar05a7bb32006-01-19 22:09:32 +000011" with an example of code that breaks the algorithm.
Bram Moolenaara5792f52005-11-23 21:25:05 +000012"
13"
14" Thanks a lot for using this script.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000015"
16"
17" NOTE: This script must be used with PHP syntax ON and with the php syntax
Bram Moolenaarc236c162008-07-13 17:41:49 +000018" script by Lutz Eymers (http://www.isp.de/data/php.vim ) or with the
19" script by Peter Hodge (http://www.vim.org/scripts/script.php?script_id=1571 )
Bram Moolenaar5c736222010-01-06 20:54:52 +010020" the later is bunbdled by default with Vim 7.
Bram Moolenaar9ff70112005-07-11 22:29:03 +000021"
22"
Bram Moolenaarc236c162008-07-13 17:41:49 +000023" In the case you have syntax errors in your script such as HereDoc end
24" identifiers not at col 1 you'll have to indent your file 2 times (This
25" script will automatically put HereDoc end identifiers at col 1 if
26" they are followed by a ';').
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000027"
Bram Moolenaara5792f52005-11-23 21:25:05 +000028"
Bram Moolenaar5c736222010-01-06 20:54:52 +010029" NOTE: If you are editing files in Unix file format and that (by accident)
30" there are '\r' before new lines, this script won't be able to proceed
31" correctly and will make many mistakes because it won't be able to match
32" '\s*$' correctly.
33" So you have to remove those useless characters first with a command like:
Bram Moolenaar9ff70112005-07-11 22:29:03 +000034"
Bram Moolenaar5c736222010-01-06 20:54:52 +010035" :%s /\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +000036"
Bram Moolenaar5c736222010-01-06 20:54:52 +010037" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will
38" silently remove them when VIM load this script (at each bufread).
Bram Moolenaarc236c162008-07-13 17:41:49 +000039"
Bram Moolenaar5c736222010-01-06 20:54:52 +010040" Options: See :help php-indent for available options.
41
Bram Moolenaara5792f52005-11-23 21:25:05 +000042
Bram Moolenaar071d4272004-06-13 20:20:40 +000043if exists("b:did_indent")
Bram Moolenaar1e015462005-09-25 22:16:38 +000044 finish
Bram Moolenaar071d4272004-06-13 20:20:40 +000045endif
46let b:did_indent = 1
47
Bram Moolenaar9ff70112005-07-11 22:29:03 +000048
49let php_sync_method = 0
50
51
52if exists("PHP_default_indenting")
Bram Moolenaar1e015462005-09-25 22:16:38 +000053 let b:PHP_default_indenting = PHP_default_indenting * &sw
Bram Moolenaar9ff70112005-07-11 22:29:03 +000054else
Bram Moolenaar1e015462005-09-25 22:16:38 +000055 let b:PHP_default_indenting = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000056endif
57
58if exists("PHP_BracesAtCodeLevel")
Bram Moolenaar1e015462005-09-25 22:16:38 +000059 let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
Bram Moolenaar9ff70112005-07-11 22:29:03 +000060else
Bram Moolenaar1e015462005-09-25 22:16:38 +000061 let b:PHP_BracesAtCodeLevel = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +000062endif
63
Bram Moolenaarc236c162008-07-13 17:41:49 +000064
Bram Moolenaara5792f52005-11-23 21:25:05 +000065if exists("PHP_autoformatcomment")
66 let b:PHP_autoformatcomment = PHP_autoformatcomment
67else
68 let b:PHP_autoformatcomment = 1
69endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +000070
Bram Moolenaarc236c162008-07-13 17:41:49 +000071if exists("PHP_vintage_case_default_indent")
72 let b:PHP_vintage_case_default_indent = PHP_vintage_case_default_indent
73else
74 let b:PHP_vintage_case_default_indent = 0
75endif
76
77
78
Bram Moolenaar9ff70112005-07-11 22:29:03 +000079let b:PHP_lastindented = 0
80let b:PHP_indentbeforelast = 0
81let b:PHP_indentinghuge = 0
82let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
83let b:PHP_LastIndentedWasComment = 0
84let b:PHP_InsideMultilineComment = 0
85let b:InPHPcode = 0
86let b:InPHPcode_checked = 0
87let b:InPHPcode_and_script = 0
88let b:InPHPcode_tofind = ""
89let b:PHP_oldchangetick = b:changedtick
90let b:UserIsTypingComment = 0
91let b:optionsset = 0
92
93setlocal nosmartindent
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000094setlocal noautoindent
Bram Moolenaar9ff70112005-07-11 22:29:03 +000095setlocal nocindent
Bram Moolenaar1e015462005-09-25 22:16:38 +000096setlocal nolisp
Bram Moolenaar9ff70112005-07-11 22:29:03 +000097
Bram Moolenaar071d4272004-06-13 20:20:40 +000098setlocal indentexpr=GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +000099setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
Bram Moolenaar071d4272004-06-13 20:20:40 +0000100
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000101
Bram Moolenaar1e015462005-09-25 22:16:38 +0000102
103let s:searchpairflags = 'bWr'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000104
105if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
Bram Moolenaar1e015462005-09-25 22:16:38 +0000106 silent! %s/\r$//g
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000107endif
108
Bram Moolenaar071d4272004-06-13 20:20:40 +0000109if exists("*GetPhpIndent")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100110 call ResetPhpOptions()
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000111 finish " XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000112endif
113
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000114let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
115let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000116"setlocal debug=msg " XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000117
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000118
119function! GetLastRealCodeLNum(startline) " {{{
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000120
Bram Moolenaar1e015462005-09-25 22:16:38 +0000121 let lnum = a:startline
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000122
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000123 if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
124 let lnum = b:GetLastRealCodeLNum_ADD
125 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000126
Bram Moolenaar1e015462005-09-25 22:16:38 +0000127 let old_lnum = lnum
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000128
Bram Moolenaar1e015462005-09-25 22:16:38 +0000129 while lnum > 1
130 let lnum = prevnonblank(lnum)
131 let lastline = getline(lnum)
132
133 if b:InPHPcode_and_script && lastline =~ '?>\s*$'
134 let lnum = lnum - 1
135 elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
136 let lnum = lnum - 1
137 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
138 let lnum = lnum - 1
139 elseif lastline =~ '\*/\s*$'
140 call cursor(lnum, 1)
141 if lastline !~ '^\*/'
142 call search('\*/', 'W')
143 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000144 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000145
146 let lastline = getline(lnum)
147 if lastline =~ '^\s*/\*'
148 let lnum = lnum - 1
149 else
150 break
151 endif
152
153
154 elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
155
156 while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
157 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000158 let lastline = getline(lnum)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000159 endwhile
160 if lastline =~ '^\s*?>'
161 let lnum = lnum - 1
162 else
163 break
164 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000165
166
Bram Moolenaarc236c162008-07-13 17:41:49 +0000167 elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc " XXX 0607
168 let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<''\\=\1''\\=$', '') " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000169 while getline(lnum) !~? tofind && lnum > 1
170 let lnum = lnum - 1
171 endwhile
172 else
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000173 break
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000174 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000175 endwhile
176
177 if lnum==1 && getline(lnum)!~ '<?'
178 let lnum=0
179 endif
180
181 if b:InPHPcode_and_script && !b:InPHPcode
182 let b:InPHPcode_and_script = 0
183 endif
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000184
185
186
Bram Moolenaar1e015462005-09-25 22:16:38 +0000187 return lnum
188endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000189
Bram Moolenaara5792f52005-11-23 21:25:05 +0000190function! Skippmatch2()
191
192 let line = getline(".")
193
Bram Moolenaarc236c162008-07-13 17:41:49 +0000194 if line =~ '\%(".*\)\@<=/\*\%(.*"\)\@=' || line =~ '\%(\%(//\|#\).*\)\@<=/\*'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000195 return 1
196 else
197 return 0
198 endif
199endfun
200
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000201function! Skippmatch() " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000202 let synname = synIDattr(synID(line("."), col("."), 0), "name")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000203 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 +0000204 return 0
205 else
206 return 1
207 endif
208endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000209
210function! FindOpenBracket(lnum) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000211 call cursor(a:lnum, 1)
212 return searchpair('{', '', '}', 'bW', 'Skippmatch()')
213endfun " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000214
215function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000216
217 if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
218 let beforeelse = a:lnum
219 else
220 let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
221 endif
222
223 if !s:level
224 let s:iftoskip = 0
225 endif
226
227 if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
228 let s:iftoskip = s:iftoskip + 1
229 endif
230
231 if getline(beforeelse) =~ '^\s*}'
232 let beforeelse = FindOpenBracket(beforeelse)
233
234 if getline(beforeelse) =~ '^\s*{'
235 let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000236 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000237 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000238
239
Bram Moolenaar1e015462005-09-25 22:16:38 +0000240 if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000241 return beforeelse
Bram Moolenaar1e015462005-09-25 22:16:38 +0000242 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000243
Bram Moolenaar1e015462005-09-25 22:16:38 +0000244 if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
245
246 if s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
247 let s:iftoskip = s:iftoskip - 1
248 endif
249
250 let s:level = s:level + 1
251 let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
252 endif
253
254 return beforeelse
255
256endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000257
258function! IslinePHP (lnum, tofind) " {{{
Bram Moolenaar1e015462005-09-25 22:16:38 +0000259 let cline = getline(a:lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000260
Bram Moolenaar1e015462005-09-25 22:16:38 +0000261 if a:tofind==""
Bram Moolenaara5792f52005-11-23 21:25:05 +0000262 let tofind = "^\\s*[\"']*\\s*\\zs\\S"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000263 else
264 let tofind = a:tofind
265 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000266
Bram Moolenaar1e015462005-09-25 22:16:38 +0000267 let tofind = tofind . '\c'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000268
Bram Moolenaar1e015462005-09-25 22:16:38 +0000269 let coltotest = match (cline, tofind) + 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000270
Bram Moolenaar1e015462005-09-25 22:16:38 +0000271 let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
272
273 if synname =~ '^php' || synname=="Delimiter" || synname =~? '^javaScript'
274 return synname
275 else
276 return ""
277 endif
278endfunction " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000279
Bram Moolenaarc236c162008-07-13 17:41:49 +0000280let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|else\)'
281let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|else\>\|while\>\|switch\>\|for\%(each\)\=\>\|declare\>\|class\>\|interface\>\|abstract\>\|try\>\|catch\>\)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000282
Bram Moolenaar5c736222010-01-06 20:54:52 +0100283let s:autoresetoptions = 0
284if ! s:autoresetoptions
285 let s:autoresetoptions = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000286endif
287
Bram Moolenaar5c736222010-01-06 20:54:52 +0100288function! ResetPhpOptions()
289 if ! b:optionsset && &filetype == "php"
Bram Moolenaara5792f52005-11-23 21:25:05 +0000290 if b:PHP_autoformatcomment
291
292 setlocal comments=s1:/*,mb:*,ex:*/,://,:#
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000293
Bram Moolenaarc236c162008-07-13 17:41:49 +0000294 setlocal formatoptions-=t
Bram Moolenaara5792f52005-11-23 21:25:05 +0000295 setlocal formatoptions+=q
296 setlocal formatoptions+=r
297 setlocal formatoptions+=o
Bram Moolenaarc236c162008-07-13 17:41:49 +0000298 setlocal formatoptions+=w
Bram Moolenaara5792f52005-11-23 21:25:05 +0000299 setlocal formatoptions+=c
300 setlocal formatoptions+=b
301 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000302 let b:optionsset = 1
303 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000304endfunc
305
Bram Moolenaar5c736222010-01-06 20:54:52 +0100306call ResetPhpOptions()
307
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000308function! GetPhpIndent()
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000309
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000310 let b:GetLastRealCodeLNum_ADD = 0
311
Bram Moolenaar1e015462005-09-25 22:16:38 +0000312 let UserIsEditing=0
313 if b:PHP_oldchangetick != b:changedtick
314 let b:PHP_oldchangetick = b:changedtick
315 let UserIsEditing=1
316 endif
317
318 if b:PHP_default_indenting
319 let b:PHP_default_indenting = g:PHP_default_indenting * &sw
320 endif
321
322 let cline = getline(v:lnum)
323
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000324 if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
Bram Moolenaar1e015462005-09-25 22:16:38 +0000325 if b:PHP_indentbeforelast
326 let b:PHP_indentinghuge = 1
Bram Moolenaar5c736222010-01-06 20:54:52 +0100327 echom 'Large indenting detected, speed optimizations engaged (v1.30)'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000328 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000329 let b:PHP_indentbeforelast = b:PHP_lastindented
330 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000331
Bram Moolenaar1e015462005-09-25 22:16:38 +0000332 if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
333 if b:PHP_indentinghuge
334 echom 'Large indenting deactivated'
335 let b:PHP_indentinghuge = 0
336 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000337 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000338 let b:PHP_lastindented = v:lnum
339 let b:PHP_LastIndentedWasComment=0
340 let b:PHP_InsideMultilineComment=0
341 let b:PHP_indentbeforelast = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000342
Bram Moolenaar1e015462005-09-25 22:16:38 +0000343 let b:InPHPcode = 0
344 let b:InPHPcode_checked = 0
345 let b:InPHPcode_and_script = 0
346 let b:InPHPcode_tofind = ""
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000347
Bram Moolenaar1e015462005-09-25 22:16:38 +0000348 elseif v:lnum > b:PHP_lastindented
349 let real_PHP_lastindented = b:PHP_lastindented
350 let b:PHP_lastindented = v:lnum
351 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000352
Bram Moolenaar1e015462005-09-25 22:16:38 +0000353
354 if !b:InPHPcode_checked " {{{ One time check
355 let b:InPHPcode_checked = 1
356
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000357 let synname = ""
358 if cline !~ '<?.*?>'
359 let synname = IslinePHP (prevnonblank(v:lnum), "")
360 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000361
362 if synname!=""
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000363 if synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000364 let b:InPHPcode = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000365 let b:InPHPcode_tofind = ""
366
Bram Moolenaarc236c162008-07-13 17:41:49 +0000367 if synname =~# "^phpComment"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000368 let b:UserIsTypingComment = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000369 else
Bram Moolenaar1e015462005-09-25 22:16:38 +0000370 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000371 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000372
Bram Moolenaar1e015462005-09-25 22:16:38 +0000373 if synname =~? '^javaScript'
374 let b:InPHPcode_and_script = 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000375 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000376
Bram Moolenaar1e015462005-09-25 22:16:38 +0000377 else
378 let b:InPHPcode = 0
379 let b:UserIsTypingComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000380
Bram Moolenaar1e015462005-09-25 22:16:38 +0000381 let lnum = v:lnum - 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000382 while getline(lnum) !~? '<<<''\=\a\w*''\=$' && lnum > 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000383 let lnum = lnum - 1
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000384 endwhile
385
Bram Moolenaarc236c162008-07-13 17:41:49 +0000386 let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '') " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000387 endif
388 else
389 let b:InPHPcode = 0
390 let b:UserIsTypingComment = 0
391 let b:InPHPcode_tofind = '<?\%(.*?>\)\@!\|<script.*>'
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000392 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000393 endif "!b:InPHPcode_checked }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000394
395
Bram Moolenaar1e015462005-09-25 22:16:38 +0000396 " Test if we are indenting PHP code {{{
397 let lnum = prevnonblank(v:lnum - 1)
398 let last_line = getline(lnum)
399
400 if b:InPHPcode_tofind!=""
401 if cline =~? b:InPHPcode_tofind
402 let b:InPHPcode = 1
403 let b:InPHPcode_tofind = ""
404 let b:UserIsTypingComment = 0
405 if cline =~ '\*/'
406 call cursor(v:lnum, 1)
407 if cline !~ '^\*/'
408 call search('\*/', 'W')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000409 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000410 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000411
Bram Moolenaar1e015462005-09-25 22:16:38 +0000412 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000413
Bram Moolenaar1e015462005-09-25 22:16:38 +0000414 let b:PHP_LastIndentedWasComment = 0
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000415
Bram Moolenaar1e015462005-09-25 22:16:38 +0000416 if cline =~ '^\s*\*/'
417 return indent(lnum) + 1
418 else
419 return indent(lnum)
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000420 endif
421
Bram Moolenaar1e015462005-09-25 22:16:38 +0000422 elseif cline =~? '<script\>'
423 let b:InPHPcode_and_script = 1
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000424 let b:GetLastRealCodeLNum_ADD = v:lnum
Bram Moolenaar1e015462005-09-25 22:16:38 +0000425 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000426 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000427 endif
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000428
Bram Moolenaar1e015462005-09-25 22:16:38 +0000429 if b:InPHPcode
430
Bram Moolenaard5ab34b2007-05-05 17:15:44 +0000431 if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000432 if cline !~? s:PHP_startindenttag
433 let b:InPHPcode = 0
434 let b:InPHPcode_tofind = s:PHP_startindenttag
435 elseif cline =~? '<script\>'
436 let b:InPHPcode_and_script = 1
437 endif
438
Bram Moolenaarc236c162008-07-13 17:41:49 +0000439 elseif last_line =~? '<<<''\=\a\w*''\=$' " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000440 let b:InPHPcode = 0
Bram Moolenaarc236c162008-07-13 17:41:49 +0000441 let b:InPHPcode_tofind = substitute( last_line, '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '') " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000442
443 elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
444 let b:InPHPcode = 0
445 let b:InPHPcode_tofind = '\*/'
446
447 elseif cline =~? '^\s*</script>'
448 let b:InPHPcode = 0
449 let b:InPHPcode_tofind = s:PHP_startindenttag
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000450 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000451 endif " }}}
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000452
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000453
Bram Moolenaar1e015462005-09-25 22:16:38 +0000454 if !b:InPHPcode && !b:InPHPcode_and_script
455 return -1
456 endif
457
Bram Moolenaar1e015462005-09-25 22:16:38 +0000458 " Indent successive // or # comment the same way the first is {{{
459 if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
460 if b:PHP_LastIndentedWasComment == 1
461 return indent(real_PHP_lastindented)
462 endif
463 let b:PHP_LastIndentedWasComment = 1
464 else
465 let b:PHP_LastIndentedWasComment = 0
466 endif " }}}
467
468 " Indent multiline /* comments correctly {{{
469
470 if b:PHP_InsideMultilineComment || b:UserIsTypingComment
471 if cline =~ '^\s*\*\%(\/\)\@!'
472 if last_line =~ '^\s*/\*'
473 return indent(lnum) + 1
474 else
475 return indent(lnum)
476 endif
477 else
478 let b:PHP_InsideMultilineComment = 0
479 endif
480 endif
481
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000482 if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$'
483 if getline(v:lnum + 1) !~ '^\s*\*'
484 return -1
485 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000486 let b:PHP_InsideMultilineComment = 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000487 endif " }}}
488
489
490 " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
491 if cline =~# '^\s*<?' && cline !~ '?>'
492 return 0
493 endif
494
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000495 if cline =~ '^\s*?>' && cline !~# '<?'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000496 return 0
497 endif
498
Bram Moolenaarc236c162008-07-13 17:41:49 +0000499 if cline =~? '^\s*\a\w*;$\|^\a\w*$' && cline !~? s:notPhpHereDoc " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000500 return 0
501 endif " }}}
502
503 let s:level = 0
504
505 let lnum = GetLastRealCodeLNum(v:lnum - 1)
Bram Moolenaar05a7bb32006-01-19 22:09:32 +0000506
Bram Moolenaar1e015462005-09-25 22:16:38 +0000507 let last_line = getline(lnum)
508 let ind = indent(lnum)
509 let endline= s:endline
510
511 if ind==0 && b:PHP_default_indenting
512 let ind = b:PHP_default_indenting
513 endif
514
515 if lnum == 0
516 return b:PHP_default_indenting
517 endif
518
519
520 if cline =~ '^\s*}\%(}}\)\@!'
521 let ind = indent(FindOpenBracket(v:lnum))
522 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000523 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000524 endif
525
526 if cline =~ '^\s*\*/'
527 call cursor(v:lnum, 1)
528 if cline !~ '^\*/'
529 call search('\*/', 'W')
530 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000531 let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
Bram Moolenaar1e015462005-09-25 22:16:38 +0000532
533 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
534
535 if cline =~ '^\s*\*/'
536 return indent(lnum) + 1
537 else
538 return indent(lnum)
539 endif
540 endif
541
542 let defaultORcase = '^\s*\%(default\|case\).*:'
543
Bram Moolenaarc236c162008-07-13 17:41:49 +0000544 if last_line =~ '[;}]'.endline && last_line !~ '^)' && last_line !~# defaultORcase " Added && last_line !~ '^)' on 2007-12-30
Bram Moolenaar1e015462005-09-25 22:16:38 +0000545 if ind==b:PHP_default_indenting
546 return b:PHP_default_indenting
547 elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline
548 return b:PHP_CurrentIndentLevel
549 endif
550 endif
551
552 let LastLineClosed = 0
553
Bram Moolenaarc236c162008-07-13 17:41:49 +0000554 let terminated = '\%(;\%(\s*?>\)\=\|<<<''\=\a\w*''\=$\|^\s*}\)'.endline " XXX 0607
Bram Moolenaar1e015462005-09-25 22:16:38 +0000555
556 let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline
557
558 if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
559 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
560 return indent(FindTheIfOfAnElse(v:lnum, 1))
Bram Moolenaarc236c162008-07-13 17:41:49 +0000561 elseif cline =~ '^\s*)\=\s*{'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000562 let previous_line = last_line
563 let last_line_num = lnum
564
565 while last_line_num > 1
566
Bram Moolenaarc236c162008-07-13 17:41:49 +0000567 if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000568
569 let ind = indent(last_line_num)
570
571 if b:PHP_BracesAtCodeLevel
572 let ind = ind + &sw
573 endif
574
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000575 return ind
Bram Moolenaar1e015462005-09-25 22:16:38 +0000576 endif
577
578 let last_line_num = last_line_num - 1
579 let previous_line = getline(last_line_num)
580 endwhile
581
Bram Moolenaarc236c162008-07-13 17:41:49 +0000582 elseif last_line =~# unstated && cline !~ '^\s*);\='.endline
583 let ind = ind + &sw " we indent one level further when the preceding line is not stated
Bram Moolenaar1e015462005-09-25 22:16:38 +0000584 return ind
585
Bram Moolenaarc236c162008-07-13 17:41:49 +0000586 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 +0000587 let previous_line = last_line
588 let last_line_num = lnum
589 let LastLineClosed = 1
590
591 while 1
592 if previous_line =~ '^\s*}'
593 let last_line_num = FindOpenBracket(last_line_num)
594
595 if getline(last_line_num) =~ '^\s*{'
596 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
597 endif
598
599 let previous_line = getline(last_line_num)
600
601 continue
602 else
603
604 if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
605 let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
606 continue
607 endif
608
609
610 let last_match = last_line_num
611
612 let one_ahead_indent = indent(last_line_num)
613 let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
614 let two_ahead_indent = indent(last_line_num)
615 let after_previous_line = previous_line
616 let previous_line = getline(last_line_num)
617
618
619 if previous_line =~# defaultORcase.'\|{'.endline
620 break
621 endif
622
623 if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
624 break
625 endif
626
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000627 if one_ahead_indent == two_ahead_indent || last_line_num < 1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000628 if previous_line =~# '\%(;\|^\s*}\)'.endline || last_line_num < 1
Bram Moolenaar1e015462005-09-25 22:16:38 +0000629 break
630 endif
631 endif
632 endif
633 endwhile
634
635 if indent(last_match) != ind
636 let ind = indent(last_match)
637 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
638
639 if cline =~# defaultORcase
640 let ind = ind - &sw
641 endif
642 return ind
643 endif
644 endif
645
646 let plinnum = GetLastRealCodeLNum(lnum - 1)
647 let pline = getline(plinnum)
648
649 let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
650
651
652 if ind == b:PHP_default_indenting
653 if last_line =~ terminated
654 let LastLineClosed = 1
655 endif
656 endif
657
658 if !LastLineClosed
659
Bram Moolenaar5c736222010-01-06 20:54:52 +0100660
Bram Moolenaar1e015462005-09-25 22:16:38 +0000661 if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && pline !~ '[,(]'.endline
662
663 if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{'
664 let ind = ind + &sw
665 endif
666
Bram Moolenaarc236c162008-07-13 17:41:49 +0000667 if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1 || cline !~# defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000668 let b:PHP_CurrentIndentLevel = ind
Bram Moolenaarc236c162008-07-13 17:41:49 +0000669
Bram Moolenaar1e015462005-09-25 22:16:38 +0000670 return ind
671 endif
672
673 elseif last_line =~ '\S\+\s*),'.endline
674 call cursor(lnum, 1)
675 call search('),'.endline, 'W')
676 let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
677 if openedparent != lnum
678 let ind = indent(openedparent)
679 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +0000680 elseif last_line =~ '^\s*'.s:blockstart
Bram Moolenaar1e015462005-09-25 22:16:38 +0000681 let ind = ind + &sw
682
Bram Moolenaar5c736222010-01-06 20:54:52 +0100683 elseif last_line =~# defaultORcase && cline !~# defaultORcase
Bram Moolenaarc236c162008-07-13 17:41:49 +0000684 let ind = ind + &sw
685
686
Bram Moolenaar5c736222010-01-06 20:54:52 +0100687 elseif pline =~ '\%(;\%(\s*?>\)\=\|<<<''\=\a\w*''\=$\|^\s*}\|{\)'.endline . '\|' . defaultORcase && cline !~# defaultORcase
Bram Moolenaarc236c162008-07-13 17:41:49 +0000688
689 let ind = ind + &sw
Bram Moolenaar1e015462005-09-25 22:16:38 +0000690 endif
691
Bram Moolenaar1e015462005-09-25 22:16:38 +0000692 endif
693
694 if cline =~ '^\s*);\='
695 let ind = ind - &sw
Bram Moolenaarc236c162008-07-13 17:41:49 +0000696 elseif cline =~# defaultORcase && last_line !~# defaultORcase
Bram Moolenaar1e015462005-09-25 22:16:38 +0000697 let ind = ind - &sw
698
699 endif
700
701 let b:PHP_CurrentIndentLevel = ind
702 return ind
Bram Moolenaar9ff70112005-07-11 22:29:03 +0000703endfunction