diff options
Diffstat (limited to 'runtime/indent/php.vim')
-rw-r--r-- | runtime/indent/php.vim | 195 |
1 files changed, 140 insertions, 55 deletions
diff --git a/runtime/indent/php.vim b/runtime/indent/php.vim index 07ecd8f141..b0430dea8d 100644 --- a/runtime/indent/php.vim +++ b/runtime/indent/php.vim @@ -3,8 +3,8 @@ " Author: John Wellesz <John.wellesz (AT) teaser (DOT) fr> " URL: http://www.2072productions.com/vim/indent/php.vim " Home: https://github.com/2072/PHP-Indenting-for-VIm -" Last Change: 2015 September 8th -" Version: 1.60 +" Last Change: 2018 May 18th +" Version: 1.66 " " " Type :help php-indent for available options @@ -50,25 +50,15 @@ let b:did_indent = 1 let g:php_sync_method = 0 -if exists('*shiftwidth') - function! s:sw() - return shiftwidth() - endfunction -else - function! s:sw() - return &shiftwidth - endfunction -endif - if exists("PHP_default_indenting") - let b:PHP_default_indenting = PHP_default_indenting * s:sw() + let b:PHP_default_indenting = PHP_default_indenting * shiftwidth() else let b:PHP_default_indenting = 0 endif if exists("PHP_outdentSLComments") - let b:PHP_outdentSLComments = PHP_outdentSLComments * s:sw() + let b:PHP_outdentSLComments = PHP_outdentSLComments * shiftwidth() else let b:PHP_outdentSLComments = 0 endif @@ -92,6 +82,12 @@ else let b:PHP_outdentphpescape = 1 endif +if exists("PHP_noArrowMatching") + let b:PHP_noArrowMatching = PHP_noArrowMatching +else + let b:PHP_noArrowMatching = 0 +endif + if exists("PHP_vintage_case_default_indent") && PHP_vintage_case_default_indent let b:PHP_vintage_case_default_indent = 1 @@ -140,13 +136,14 @@ endif let s:PHP_validVariable = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\|die\|else\)' let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|\%(}\s*\)\?else\>\|do\>\|while\>\|switch\>\|case\>\|default\>\|for\%(each\)\=\>\|declare\>\|class\>\|trait\>\|use\>\|interface\>\|abstract\>\|final\>\|try\>\|\%(}\s*\)\=catch\>\|\%(}\s*\)\=finally\>\)' -let s:functionDecl = '\<function\>\%(\s\+'.s:PHP_validVariable.'\)\=\s*(.*' -let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$' +let s:functionDecl = '\<function\>\%(\s\+&\='.s:PHP_validVariable.'\)\=\s*(.*' +let s:endline = '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$' +let s:unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.s:endline -let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)\|^[^''"`]*[''"`]$' +let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)' let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!' - +let s:structureHead = '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline . '\|\<new\s\+class\>' let s:escapeDebugStops = 0 @@ -214,10 +211,28 @@ function! GetLastRealCodeLNum(startline) " {{{ let lnum = lnum - 1 endwhile elseif lastline =~ '^[^''"`]*[''"`][;,]'.s:endline - let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$', '') - while getline(lnum) !~? tofind && lnum > 1 - let lnum = lnum - 1 + + let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '') + let trylnum = lnum + while getline(trylnum) !~? tofind && trylnum > 1 + let trylnum = trylnum - 1 endwhile + + if trylnum == 1 + break + else + if lastline =~ ';'.s:endline + while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1 + let trylnum = prevnonblank(trylnum - 1) + endwhile + + + if trylnum == 1 + break + end + end + let lnum = trylnum + end else break endif @@ -247,7 +262,7 @@ endfun function! Skippmatch() " {{{ let synname = synIDattr(synID(line("."), col("."), 0), "name") - if synname == "Delimiter" || synname == "phpRegionDelimiter" || synname =~# "^phpParent" || synname == "phpArrayParens" || synname =~# '^php\%(Block\|Brace\)' || synname == "javaScriptBraces" || synname =~# '^php\%(Doc\)\?Comment' && b:UserIsTypingComment + if synname ==? "Delimiter" || synname ==? "phpRegionDelimiter" || synname =~? "^phpParent" || synname ==? "phpArrayParens" || synname =~? '^php\%(Block\|Brace\)' || synname ==? "javaScriptBraces" || synname =~? '^php\%(Doc\)\?Comment' && b:UserIsTypingComment return 0 else return 1 @@ -262,7 +277,7 @@ function! FindOpenBracket(lnum, blockStarter) " {{{ while line > 1 let linec = getline(line) - if linec =~ s:terminated || linec =~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline + if linec =~ s:terminated || linec =~ s:structureHead break endif @@ -273,6 +288,62 @@ function! FindOpenBracket(lnum, blockStarter) " {{{ return line endfun " }}} +let s:blockChars = {'{':1, '[': 1, '(': 1, ')':-1, ']':-1, '}':-1} +function! BalanceDirection (str) + + let balance = 0 + + for c in split(a:str, '\zs') + if has_key(s:blockChars, c) + let balance += s:blockChars[c] + endif + endfor + + return balance +endfun + +function! StripEndlineComments (line) + return substitute(a:line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') +endfun + +function! FindArrowIndent (lnum) " {{{ + + let parrentArrowPos = 0 + let lnum = a:lnum + while lnum > 1 + let last_line = getline(lnum) + if last_line =~ '^\s*->' + let parrentArrowPos = indent(a:lnum) + break + else + call cursor(lnum, 1) + let cleanedLnum = StripEndlineComments(last_line) + if cleanedLnum =~ '->' + if ! b:PHP_noArrowMatching + let parrentArrowPos = searchpos('->', 'W', lnum)[1] - 1 + else + let parrentArrowPos = indent(lnum) + shiftwidth() + endif + break + elseif cleanedLnum =~ ')'.s:endline && BalanceDirection(last_line) < 0 + call searchpos(')'.s:endline, 'cW', lnum) + let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') + if openedparent != lnum + let lnum = openedparent + else + let openedparent = -1 + endif + + else + let parrentArrowPos = indent(lnum) + shiftwidth() + break + endif + endif + endwhile + + return parrentArrowPos +endfun "}}} + function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{ if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>' @@ -323,7 +394,7 @@ function! FindTheSwitchIndent (lnum) " {{{ let test = GetLastRealCodeLNum(a:lnum - 1) if test <= 1 - return indent(1) - s:sw() * b:PHP_vintage_case_default_indent + return indent(1) - shiftwidth() * b:PHP_vintage_case_default_indent end while getline(test) =~ '^\s*}' && test > 1 @@ -337,14 +408,14 @@ function! FindTheSwitchIndent (lnum) " {{{ if getline(test) =~# '^\s*switch\>' return indent(test) elseif getline(test) =~# s:defaultORcase - return indent(test) - s:sw() * b:PHP_vintage_case_default_indent + return indent(test) - shiftwidth() * b:PHP_vintage_case_default_indent else return FindTheSwitchIndent(test) endif endfunction "}}} -let s:SynPHPMatchGroups = {'phpParent':1, 'Delimiter':1, 'Define':1, 'Storageclass':1, 'StorageClass':1, 'Structure':1, 'Exception':1} +let s:SynPHPMatchGroups = {'phpparent':1, 'delimiter':1, 'define':1, 'storageclass':1, 'structure':1, 'exception':1} function! IslinePHP (lnum, tofind) " {{{ let cline = getline(a:lnum) @@ -360,7 +431,7 @@ function! IslinePHP (lnum, tofind) " {{{ let synname = synIDattr(synID(a:lnum, coltotest, 0), "name") - if synname == 'phpStringSingle' || synname == 'phpStringDouble' || synname == 'phpBacktick' + if synname ==? 'phpStringSingle' || synname ==? 'phpStringDouble' || synname ==? 'phpBacktick' if cline !~ '^\s*[''"`]' return "SpecStringEntrails" else @@ -368,7 +439,7 @@ function! IslinePHP (lnum, tofind) " {{{ end end - if get(s:SynPHPMatchGroups, synname) || synname =~ '^php' || synname =~? '^javaScript' + if get(s:SynPHPMatchGroups, tolower(synname)) || synname =~ '^php' || synname =~? '^javaScript' return synname else return "" @@ -399,6 +470,10 @@ endfunc call ResetPhpOptions() +function! GetPhpIndentVersion() + return "1.66-bundle" +endfun + function! GetPhpIndent() let b:GetLastRealCodeLNum_ADD = 0 @@ -410,7 +485,7 @@ function! GetPhpIndent() endif if b:PHP_default_indenting - let b:PHP_default_indenting = g:PHP_default_indenting * s:sw() + let b:PHP_default_indenting = g:PHP_default_indenting * shiftwidth() endif let cline = getline(v:lnum) @@ -456,14 +531,14 @@ function! GetPhpIndent() endif if synname!="" - if synname == "SpecStringEntrails" - let b:InPHPcode = -1 + if synname ==? "SpecStringEntrails" + let b:InPHPcode = -1 " thumb down let b:InPHPcode_tofind = "" - elseif synname != "phpHereDoc" && synname != "phpHereDocDelimiter" + elseif synname !=? "phpHereDoc" && synname !=? "phpHereDocDelimiter" let b:InPHPcode = 1 let b:InPHPcode_tofind = "" - if synname =~# '^php\%(Doc\)\?Comment' + if synname =~? '^php\%(Doc\)\?Comment' let b:UserIsTypingComment = 1 let b:InPHPcode_checked = 0 endif @@ -532,7 +607,7 @@ function! GetPhpIndent() if 1 == b:InPHPcode - if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter" + if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~?"Delimiter" if cline !~? s:PHP_startindenttag let b:InPHPcode = 0 let b:InPHPcode_tofind = s:PHP_startindenttag @@ -540,7 +615,7 @@ function! GetPhpIndent() let b:InPHPcode_and_script = 1 endif - elseif last_line =~ '^[^''"`]\+[''"`]$' + elseif last_line =~ '^[^''"`]\+[''"`]$' " a string identifier with nothing after it and no other string identifier before let b:InPHPcode = -1 let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '') elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$' @@ -660,25 +735,26 @@ function! GetPhpIndent() let terminated = s:terminated - let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline + let unstated = s:unstated + if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>' let b:PHP_CurrentIndentLevel = b:PHP_default_indenting return indent(FindTheIfOfAnElse(v:lnum, 1)) elseif cline =~# s:defaultORcase - return FindTheSwitchIndent(v:lnum) + s:sw() * b:PHP_vintage_case_default_indent + return FindTheSwitchIndent(v:lnum) + shiftwidth() * b:PHP_vintage_case_default_indent elseif cline =~ '^\s*)\=\s*{' let previous_line = last_line let last_line_num = lnum while last_line_num > 1 - if previous_line =~ terminated || previous_line =~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . endline + if previous_line =~ terminated || previous_line =~ s:structureHead let ind = indent(last_line_num) if b:PHP_BracesAtCodeLevel - let ind = ind + s:sw() + let ind = ind + shiftwidth() endif return ind @@ -687,9 +763,10 @@ function! GetPhpIndent() let last_line_num = GetLastRealCodeLNum(last_line_num - 1) let previous_line = getline(last_line_num) endwhile - + elseif cline =~ '^\s*->' + return FindArrowIndent(lnum) elseif last_line =~# unstated && cline !~ '^\s*);\='.endline - let ind = ind + s:sw() + let ind = ind + shiftwidth() " we indent one level further when the preceding line is not stated return ind + addSpecial elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated @@ -768,8 +845,7 @@ function! GetPhpIndent() let AntepenultimateLine = getline(plinnum) - let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') - + let last_line = StripEndlineComments(last_line) if ind == b:PHP_default_indenting if last_line =~ terminated && last_line !~# s:defaultORcase @@ -779,44 +855,53 @@ function! GetPhpIndent() if !LastLineClosed + let openedparent = -1 + - if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline + if last_line =~# '[{(\[]'.endline || last_line =~? '\h\w*\s*(.*,$' && AntepenultimateLine !~ '[,(\[]'.endline && BalanceDirection(last_line) > 0 let dontIndent = 0 - if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*)\s*{'.endline && last_line !~ '^\s*\%(' . s:blockstart . '\)\|'. s:functionDecl . s:endline + if last_line =~ '\S\+\s*{'.endline && last_line !~ '^\s*[)\]]\+\(\s*:\s*'.s:PHP_validVariable.'\)\=\s*{'.endline && last_line !~ s:structureHead let dontIndent = 1 endif if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{') - let ind = ind + s:sw() + let ind = ind + shiftwidth() endif if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1 let b:PHP_CurrentIndentLevel = ind - return ind + addSpecial endif - elseif last_line =~ '\S\+\s*),'.endline + elseif last_line =~ '),'.endline && BalanceDirection(last_line) < 0 call cursor(lnum, 1) - call search('),'.endline, 'W') + call searchpos('),'.endline, 'cW') let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') if openedparent != lnum let ind = indent(openedparent) endif - elseif last_line =~ '^\s*'.s:blockstart - let ind = ind + s:sw() + elseif last_line =~ s:structureHead + let ind = ind + shiftwidth() + + + elseif AntepenultimateLine =~ '{'.endline && AntepenultimateLine !~? '^\s*use\>' || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase + let ind = ind + shiftwidth() + endif - elseif AntepenultimateLine =~ '{'.endline || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase - let ind = ind + s:sw() + if openedparent >= 0 + let last_line = StripEndlineComments(getline(openedparent)) endif + endif + if cline =~ '^\s*[)\]];\=' + let ind = ind - shiftwidth() endif - if cline =~ '^\s*[)\]];\=' - let ind = ind - s:sw() + if last_line =~ '^\s*->' && last_line !~? s:structureHead && BalanceDirection(last_line) <= 0 + let ind = ind - shiftwidth() endif let b:PHP_CurrentIndentLevel = ind |