Author: arekm Date: Thu Sep 1 19:12:11 2005 GMT Module: SOURCES Tag: HEAD ---- Log message: - up to ver 1.17
---- Files affected: SOURCES: php.vim (1.4 -> 1.5) ---- Diffs: ================================================================ Index: SOURCES/php.vim diff -u SOURCES/php.vim:1.4 SOURCES/php.vim:1.5 --- SOURCES/php.vim:1.4 Sat Jun 18 11:42:53 2005 +++ SOURCES/php.vim Thu Sep 1 21:12:06 2005 @@ -2,8 +2,41 @@ " Language: PHP " Author: John Wellesz <John.wellesz (AT) teaser (DOT) fr> " URL: http://www.2072productions.com/vim/indent/php.vim -" Last Change: 2005 May 31th -" Version: 1.12 +" Last Change: 2005 June 30th +" Version: 1.17 +" +" +" Changes: 1.17 - Now following parts of split lines are indented: +" Instead of: +" $foo= +" "foo" +" ."foo"; +" +" You have: +" $foo= +" "foo" +" ."foo"; +" +" - If a "case : break;" was declared on a single line, the +" following "case" was not indented correctly. +" - If a </script> html tag was preceded by a "?>" it wasn't indented. +" - Some other minor corrections and improvements. +" +" +" Changes: 1.16 - Now starting and ending '*' of multiline '/* */' comments are aligned +" on the '*' of the '/*' comment starter. +" - Some code improvements that make indentation faster. +" +" Changes: 1.15 - Corrected some problems with the indentation of +" multiline "array()" declarations. +" +" Changes: 1.14 - Added auto-formatting for comments (using the Vim option formatoptions=qroc). +" - Added the script option PHP_BracesAtCodeLevel to +" indent the '{' and '}' at the same level than the +" code they contain. +" +" Changes: 1.13 - Some code cleaning and typo corrections (Thanks to +" Emanuele Giaquinta for his patches) " " Changes: 1.12 - The bug involving searchpair() and utf-8 encoding in Vim 6.3 will " not make this script to hang but you'll have to be @@ -97,14 +130,6 @@ " NOTE: This script must be used with PHP syntax ON and with the php syntax " script by Lutz Eymers (http://www.isp.de/data/php.vim ) that's the script bundled with Gvim. " -" This script set the option php_sync_method of PHP syntax script to 0 -" (fromstart indenting method) in order to have an accurate syntax. -" If you are using very big PHP files (which is a bad idea) you will -" experience slowings down while editing, if your code contains only PHP -" code you can comment the line below. - -let php_sync_method = 0 - " " In the case you have syntax errors in your script such as end of HereDoc " tags not at col 1 you'll have to indent your file 2 times (This script @@ -129,37 +154,62 @@ " at end of lines (by default this option is unset), NOTE that you " MUST remove CR when the fileformat is UNIX else the indentation " won't be correct... +" +" Options: PHP_BracesAtCodeLevel = 1 to indent the '{' and '}' at the same +" level than the code they contain. +" Exemple: +" Instead of: +" if ($foo) +" { +" foo(); +" } +" +" You will write: +" if ($foo) +" { +" foo(); +" } +" +" NOTE: The script will be a bit slower if you use this option because +" some optimizations won't be available. -setlocal nosmartindent -setlocal nolisp -"This will prevent a bug involving searchpair(), its 'r' flag, utf-8 and vim 6.3 -"from occurring but will forbid you to write other '/*' inside a '/* */' comment. -if version <= 603 && &encoding == 'utf-8' - let s:searchpairflags = 'bW' -else - let s:searchpairflags = 'bWr' +" The 4 following lines prevent this script from being loaded several times per buffer. +" They also prevent the load of different indent scripts for PHP at the same time. +if exists("b:did_indent") + finish endif +let b:did_indent = 1 + +" This script set the option php_sync_method of PHP syntax script to 0 +" (fromstart indenting method) in order to have an accurate syntax. +" If you are using very big PHP files (which is a bad idea) you will +" experience slowings down while editing, if your code contains only PHP +" code you can comment the line below. +let php_sync_method = 0 -if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix - let myul=&ul - silent! %s/\r$//g -endif +" Apply PHP_default_indenting option if exists("PHP_default_indenting") let b:PHP_default_indenting = PHP_default_indenting * &sw else let b:PHP_default_indenting = 0 endif -" Only load this indent file when no other was loaded. But reset those state -" variables + +if exists("PHP_BracesAtCodeLevel") + let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel +else + let b:PHP_BracesAtCodeLevel = 0 +endif + let b:PHP_lastindented = 0 let b:PHP_indentbeforelast = 0 let b:PHP_indentinghuge = 0 let b:PHP_CurrentIndentLevel = b:PHP_default_indenting let b:PHP_LastIndentedWasComment = 0 +let b:PHP_InsideMultilineComment = 0 " PHP code detect variables let b:InPHPcode = 0 let b:InPHPcode_checked = 0 @@ -167,22 +217,33 @@ let b:InPHPcode_tofind = "" let b:PHP_oldchangetick = b:changedtick let b:UserIsTypingComment = 0 +let b:optionsset = 0 -if exists("b:did_indent") - finish -endif - -let b:did_indent = 1 - +" The 4 options belows are overriden by indentexpr so they are always off +" anyway... setlocal nosmartindent -setlocal nolisp +setlocal noautoindent setlocal nocindent -setlocal autoindent +setlocal nolisp " autoindent must be on, so this line is also useless... setlocal indentexpr=GetPhpIndent() setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/ -" Only define the function once. + +"This will prevent a bug involving searchpair(), its 'r' flag, utf-8 and vim 6.3 +"from occurring but will forbid you to write other '/*' inside a '/* */' comment. +if version <= 603 && &encoding == 'utf-8' + let s:searchpairflags = 'bW' +else + let s:searchpairflags = 'bWr' +endif + +" Clean CR when the file is in Unix format +if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix + silent! %s/\r$//g +endif + +" Only define the functions once per Vim session. if exists("*GetPhpIndent") finish " XXX endif @@ -205,14 +266,14 @@ " everything as php if b:InPHPcode_and_script && lastline =~ '?>\s*$' let lnum = lnum - 1 - - + elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$' + let lnum = lnum - 1 elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' " if line is under comment let lnum = lnum - 1 elseif lastline =~ '\*/\s*$' " skip multiline comments call cursor(lnum, 1) call search('\*/\zs', 'W') " positition the cursor after the first */ - let lnum = searchpair('/\*', '', '\*/\zs', s:searchpairflags, '') " find the most outside /* + let lnum = searchpair('/\*', '', '\*/\zs', s:searchpairflags) " find the most outside /* "echo 'lnum skipnonphp= ' . lnum "call getchar() @@ -255,6 +316,12 @@ if lnum==1 && getline(lnum)!~ '<?' let lnum=0 endif + + " This is to handle correctly end of script tags; to return the real last php + " code line else a '?>' could be returned has last_line + if b:InPHPcode_and_script && !b:InPHPcode + let b:InPHPcode_and_script = 0 + endif return lnum endfunction " }}} @@ -264,7 +331,7 @@ " times faster but you may have troubles with '{' inside comments or strings " that will break the indent algorithm... let synname = synIDattr(synID(line("."), col("."), 0), "name") - if synname == "phpParent" || synname == "javaScriptBraces" || synname == "phpComment" && b:UserIsTypingComment + if synname == "Delimiter" || synname == "phpParent" || synname == "javaScriptBraces" || synname == "phpComment" && b:UserIsTypingComment return 0 else return 1 @@ -299,7 +366,7 @@ endif " A closing bracket? let skip the whole block to save some recursive calls - if getline(beforeelse) =~ '^\s*}' " .s:endline + if getline(beforeelse) =~ '^\s*}' let beforeelse = FindOpenBracket(beforeelse) " Put us on the block starter @@ -358,7 +425,23 @@ " }}} let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\);' -let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|while\>\|for\%(each\)\=\>\|declare\|||\|&&\>\)' +let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|while\>\|switch\>\|for\%(each\)\=\>\|declare\>\|[|&]\)' + +" make sure the options needed for this script to work correctly are set here +" for the last time. They could have been overriden by any 'onevent' +" associated setting file... +let s:autorestoptions = 0 +if ! s:autorestoptions + au BufWinEnter,Syntax *.php,*.php3,*.php4,*.php5 call ResetOptions() + let s:autorestoptions = 1 +endif + +function! ResetOptions() + if ! b:optionsset + setlocal formatoptions=qroc + let b:optionsset = 1 + endif +endfunc function! GetPhpIndent() "############################################## @@ -399,6 +482,7 @@ endif let b:PHP_lastindented = v:lnum let b:PHP_LastIndentedWasComment=0 + let b:PHP_InsideMultilineComment=0 let b:PHP_indentbeforelast = 0 let b:InPHPcode = 0 @@ -471,8 +555,18 @@ if cline =~ '\*/' " End comment tags must be indented like start comment tags call cursor(v:lnum, 1) call search('\*/\zs', 'W') - let lnum = searchpair('/\*', '', '\*/\zs', s:searchpairflags, '') " find the most outside /* - return indent(lnum) + let lnum = searchpair('/\*', '', '\*/\zs', s:searchpairflags) " find the most outside /* + + let b:PHP_CurrentIndentLevel = b:PHP_default_indenting + let b:PHP_LastIndentedWasComment = 0 " prevent a problem if multiline /**/ comment are surounded by + " other types of comments + + if cline =~ '^\s*\*/' + return indent(lnum) + 1 + else + return indent(lnum) + endif + elseif cline =~? '<script\>' " a more accurate test is useless since there isn't any other possibility let b:InPHPcode_and_script = 1 endif @@ -500,8 +594,7 @@ " Skip /* \n+ */ comments execept when the user is currently " writting them - elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)[EMAIL PROTECTED]' - " \ && IslinePHP(v:lnum, '/\*')=="phpComment" + elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)[EMAIL PROTECTED]' && getline(v:lnum + 1) !~ '^\s*\*' " XXX indent comments let b:InPHPcode = 0 let b:InPHPcode_tofind = '\*/' @@ -509,7 +602,6 @@ " same as php code) elseif cline =~? '^\s*</script>' let b:InPHPcode = 0 - " let b:InPHPcode_and_script = 0 let b:InPHPcode_tofind = s:PHP_startindenttag endif endif " }}} @@ -517,8 +609,8 @@ " Non PHP code is let as it is if !b:InPHPcode && !b:InPHPcode_and_script return -1 - elseif !b:InPHPcode - let b:InPHPcode_and_script = 0 + "elseif !b:InPHPcode + " let b:InPHPcode_and_script = 0 " now it is GetLastRealCodeLNum that resets this variable endif " Align correctly multi // or # lines @@ -533,6 +625,29 @@ let b:PHP_LastIndentedWasComment = 0 endif " }}} + + " Indent multiline /* comments correctly {{{ + + "if we are on the start of a MULTI * beginning comment or if the user is + "currently typing a /* beginning comment. + + if b:PHP_InsideMultilineComment || b:UserIsTypingComment + if cline =~ '^\s*\*\%(\/\)[EMAIL PROTECTED]' " if cline == '*' + if last_line =~ '^\s*/\*' " if last_line == '/*' + return indent(lnum) + 1 + else + return indent(lnum) + endif + else + let b:PHP_InsideMultilineComment = 0 + endif + endif + + if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' " if cline == '/*' + let b:PHP_InsideMultilineComment = 1 + return -1 + endif + " }}} " Some tags are always indented to col 1 @@ -572,18 +687,6 @@ return b:PHP_default_indenting endif - " if the last line is a stated line and it's not indented then why should - " we indent this one?? - " if optimized mode is active and nor current or previous line are an 'else' - " or the end of a possible bracketless thing then indent the same as the previous - " line - if last_line =~ '[;}]'.endline && last_line !~# '^\s*\%(default\|case\).*:' - if ind==b:PHP_default_indenting - return b:PHP_default_indenting - elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline - return b:PHP_CurrentIndentLevel - endif - endif " Search the matching open bracket (with searchpair()) and set the indent of cline " to the indent of the matching line. @@ -593,17 +696,46 @@ return ind endif - " While editing check for end of comment and indent it like its beginning - if UserIsEditing && cline =~ '\*/' " End comment tags must be indented like start comment tags + " Check for end of comment and indent it like its beginning + if cline =~ '^\s*\*/' " End comment tags must be indented like start comment tags call cursor(v:lnum, 1) call search('\*/\zs', 'W') - let lnum = searchpair('/\*', '', '\*/\zs', s:searchpairflags, '') " find the most outside /* - return indent(lnum) + let lnum = searchpair('/\*', '', '\*/\zs', s:searchpairflags) " find the most outside /* + + let b:PHP_CurrentIndentLevel = b:PHP_default_indenting + + if cline =~ '^\s*\*/' + return indent(lnum) + 1 + else + return indent(lnum) + endif + endif + + let defaultORcase = '^\s*\%(default\|case\).*:' + + " if the last line is a stated line and it's not indented then why should + " we indent this one?? + " if optimized mode is active and nor current or previous line are an 'else' + " or the end of a possible bracketless thing then indent the same as the previous + " line + if last_line =~ '[;}]'.endline && last_line !~# defaultORcase + if ind==b:PHP_default_indenting " if no indentation for the previous line + return b:PHP_default_indenting + elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline + return b:PHP_CurrentIndentLevel + endif endif let LastLineClosed = 0 " used to prevent redundant tests in the last part of the script - let unstated='\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline + "let terminated = '\%(;\%(\s*?>\)\=\|<<<\a\w*\)'.endline.'\|}\%(.*{'. endline.'\)[EMAIL PROTECTED]' + let terminated = '\%(;\%(\s*?>\)\=\|<<<\a\w*\|}\)'.endline + " What is a terminated line? + " - a line terminated by a ";" optionaly followed by a "?>" + " - a HEREDOC starter line (the content of such block is never seen by this script) + " - a "}" not followed by a "{" + + let unstated = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline " What is an unstated line? " - an "else" at the end of line " - a s:blockstart (if while etc...) followed by anything and a ")" at @@ -633,7 +765,12 @@ " lkhlkh(); " echo 'infinite loop\n'; " } - elseif ind != b:PHP_default_indenting && last_line =~ ';'.endline.'\|^\s*}\%(.*{'. endline.'\)[EMAIL PROTECTED]' + " + " OR even (ADDED for version 1.17 - no modification required ) + " + " $thing = + " "something"; + elseif ind != b:PHP_default_indenting && last_line =~ terminated " If we are here it means that the previous line is: " - a *;$ line " - a [beginning-blanck] } followed by anything but a { $ @@ -694,7 +831,7 @@ " If we find a '{' or a case/default then we are inside that block so lets " indent properly... Like the line following that block starter - if previous_line =~# '^\s*\%(case\|default\).*:\|{'.endline + if previous_line =~# defaultORcase.'\|{'.endline break endif @@ -720,13 +857,17 @@ if indent(last_match) != ind " if nothing was done lets the old script continue let ind = indent(last_match) " let's use the indent of the last line matched by the alhorithm above - let b:PHP_CurrentIndentLevel = b:PHP_default_indenting "line added in version 1.02 to prevent optimized mode + let b:PHP_CurrentIndentLevel = b:PHP_default_indenting " line added in version 1.02 to prevent optimized mode " from acting in some special cases + + " case and default are indented 1 level below + if cline =~# defaultORcase + let ind = ind - &sw + endif return ind endif endif - let plinnum = GetLastRealCodeLNum(lnum - 1) let pline = getline(plinnum) " previous to last line @@ -737,28 +878,68 @@ " Sorry for this unreadable thing... let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') + + if ind == b:PHP_default_indenting + if last_line =~ terminated + let LastLineClosed = 1 + endif + endif + " Indent blocks enclosed by {} or () (default indenting) if !LastLineClosed " the last line isn't a .*; or a }$ line + " Indent correctly multilevel and multiline '(.*)' things + " if the last line is a [{(]$ or a multiline function call (or array " declaration) with already one parameter on the opening ( line if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && pline !~ '[,(]'.endline - let ind = ind + &sw - if cline !~# '^\s*\%(default\|case\).*:' " case and default are not indented inside blocks + + if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{' " XXX mod { + let ind = ind + &sw + endif + + if b:PHP_BracesAtCodeLevel || cline !~# defaultORcase " XXX mod (2) { + " case and default are not indented inside blocks let b:PHP_CurrentIndentLevel = ind return ind endif + + " If the last line isn't empty and ends with a '),' then check if the + " ')' was oppened on the same line, if not it means it closes a + " multiline '(.*)' thing and that the current line need to be + " de-indented one time. + elseif last_line =~ '\S\+\s*),'.endline + call cursor(lnum, 1) + call search('),'.endline, 'W') + let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()') + if openedparent != lnum + let ind = indent(openedparent) + endif + + " In all other cases if the last line isn't terminated indent 1 + " level higher but only if the line before the last line wasn't + " indented for the same reason. + + elseif cline !~ '^\s*{' && pline =~ '\%(;\%(\s*?>\)\=\|<<<\a\w*\|{\|^\s*'.s:blockstart.'\s*(.*)\)'.endline.'\|^\s*}\|'.defaultORcase + + let ind = ind + &sw + endif + " If the PHP_BracesAtCodeLevel is set then indent the '{' + if b:PHP_BracesAtCodeLevel && cline =~# '^\s*{' " XXX mod { + let ind = ind + &sw + endif + + elseif last_line =~# defaultORcase + let ind = ind + &sw endif - " If the current line closes a multiline function call or array def + " If the current line closes a multiline function call or array def XXX if cline =~ '^\s*);\=' let ind = ind - &sw - elseif cline =~# '^\s*\%(default\|case\).*:' + " CASE and DEFAULT are indented at the same level than the SWITCH + elseif cline =~# defaultORcase let ind = ind - &sw - endif - - if last_line =~# '^\s*\%(default\|case\).*:' - let ind = ind + &sw + endif let b:PHP_CurrentIndentLevel = ind ================================================================ ---- CVS-web: http://cvs.pld-linux.org/SOURCES/php.vim?r1=1.4&r2=1.5&f=u _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
