From 8fffc4768b5ab969158f0a452810e0d8673db457 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Tue, 28 Dec 2004 15:18:37 +0000 Subject: [PATCH] - new, ver 1.07 Changed files: php.vim -> 1.1 --- php.vim | 712 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 712 insertions(+) create mode 100644 php.vim diff --git a/php.vim b/php.vim new file mode 100644 index 0000000..479c021 --- /dev/null +++ b/php.vim @@ -0,0 +1,712 @@ +" Vim indent file +" Language: PHP +" Author: John Wellesz +" URL: http://www.2072productions.com/vim/indent/php.vim +" Last Change: 2004 December 27th +" Version: 1.07 +" +" Changes: 1.07 - Added support for "Here document" tags: +" - HereDoc end tags are indented properly. +" - HereDoc content remains unchanged. +" - All the code that is outside PHP delimiters remains +" unchanged. +" - New feature: The content of html tags is considered as PHP +" and indented according to the surrounding PHP code. +" - "else if" are detected as "elseif". +" - Multiline /**/ are indented when the user types it but +" remain unchanged when indenting from their beginning. +" - Fixed indenting of // and # comments. +" - php_sync_method option is set to 0 (fromstart). +" This is required for complex PHP scripts else the indent +" may fail. +" - Files with non PHP code at the beginning could alter the indent +" of the following PHP code. +" - Other minor improvements and corrections. +" +" +" Changes: 1.06: - Switch block were no longer indented correctly... +" - Added an option to use a default indenting instead of 0. +" (whereas I still can't find any good reason to use it!) +" - A problem with ^\s*);\= lines where ending a non '{}' +" structure. +" - Changed script local variable to be buffer local +" variable instead. +" +" Changes: 1.05: - Lines containing "" and "?> +" the last version couldn't work. +" - Folds can be used without problem +" - multilevel non bracked structures are indented (like +" in C) +" Exemple: +" if (!isset($History_lst_sel)) +" if (!isset($blabla)) +" if (!isset($bloum)) { +" $History_lst_sel=0; +" } else +" $foo="truc"; +" else $bla= "foo"; +" $command_hist = TRUE; +" +" - "array( 'blabla'," lines no longer break the indent of the +" following lines +" - the options php_noindent_switch and php_indent_shortopentags have been removed +" (couldn't find any reason why one would want to use them) +" - PHP open and close tags are always set to col 1 as for the +" immediate following php code +" +" If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr +" with an example of code that break the algorithm. +" +" +" Thanks a lot for using this script. +" + +" 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 ) . Else it won't be able to +" work correctly. +" +" This script set the option php_sync_method of PHP syntax script to 0 +" (fromstart indenting method) in order to have an accurate syntax. +" +" 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 +" will automatically put HereDoc end tags at col 1). +" + +" Options: PHP_default_indenting = # of sw (default is 0). + +" This script uses the syntax to test matching {}, comments, validity +" and to know if the line it is ask to indent is php code or not... +" Unfortunately for complex files the search syntax method isn't accurate so +" we must use the fromstart sync method. +let php_sync_method = 0 + +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 needed + +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 +" PHP code detect variables +let b:InPHPcode = 0 +let b:InPHPcode_checked = 0 +let b:InPHPcode_and_script = 0 +let b:InPHPcode_tofind = "" +let b:PHP_oldchangetick = b:changedtick + +if exists("b:did_indent") + finish +endif + +let b:did_indent = 1 +setlocal nosmartindent + +setlocal nolisp +setlocal indentexpr=GetPhpIndent() +"setlocal indentkeys+=0=,0),=EO +setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*,=?>,=\)\@!\|]*>\%(.*<\/script>\)\@!' +" setlocal debug=msg + + +function! GetLastRealCodeLNum(startline) " {{{ + "Inspired from the function SkipJavaBlanksAndComments by Toby Allsopp for indent/java.vim + let lnum = a:startline + let old_lnum = lnum + + while lnum > 1 + let lnum = prevnonblank(lnum) + let lastline = getline(lnum) + + " if we are inside an html ' + let b:InPHPcode = 0 + " let b:InPHPcode_and_script = 0 + let b:InPHPcode_tofind = s:PHP_startindenttag + endif + endif " }}} + + " 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 + endif + + " Align correctly multi // or # lines + + " Indent successive // or # comment the same way the first is {{{ + if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)' + if b:PHP_LastIndentedWasComment == 1 + return indent(real_PHP_lastindented) " line replaced in 1.02 + endif + let b:PHP_LastIndentedWasComment = 1 + else + let b:PHP_LastIndentedWasComment = 0 + endif + " }}} + + " Some tags are always indented to col 1 + + " Things always indented at col 1 (PHP delimiter: , Heredoc end) {{{ + " PHP start tags are always at col 1, useless to indent unless the end tag + " is on the same line + if cline =~# '^\s*' " Added the ^\s* part in version 1.03 + return 0 + endif + + " PHP end tags are always at col 1, useless to indent unless if it's + " followed by a start tag on the same line + if cline =~ '^\s*?>' && cline !~# '\)'.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 + " the end of line + + " if the current line is an 'else' starting line + " (to match an 'else' preceded by a '}' is irrelevant and futile - see + " code above) + if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>' + let b:PHP_CurrentIndentLevel = b:PHP_default_indenting " prevent optimized to work at next call + return indent(FindTheIfOfAnElse(v:lnum, 1)) + elseif last_line =~# unstated && cline !~ '^\s*{\|^\s*);\='.endline + let ind = ind + &sw + return ind + + " If the last line is terminated by ';' or if it's a closing '}' + " We need to check if this isn't the end of a multilevel non '{}' + " structure such as: + " Exemple: + " if ($truc) + " echo 'truc'; + " + " OR + " + " if ($truc) + " while ($truc) { + " lkhlkh(); + " echo 'infinite loop\n'; + " } + elseif ind != b:PHP_default_indenting && last_line =~ ';'.endline.'\|^\s*}\%(.*{'. endline.'\)\@!' + " If we are here it means that the previous line is: + " - a *;$ line + " - a [beginning-blanck] } followed by anything but a { $ + let previous_line = last_line + let last_line_num = lnum + let LastLineClosed = 1 + " The idea here is to check if the current line is after a non '{}' + " structure so we can indent it like the top of that structure. + " The top of that structure is caracterized by a if (ff)$ style line + " preceded by a stated line. If there is no such structure then we + " just have to find two 'normal' lines following each other with the + " same indentation and with the first of these two lines terminated by + " a ; or by a }... + + while 1 + " let's skip '{}' blocks + if previous_line =~ '^\s*}' + " find the openning '{' + let last_line_num = FindOpenBracket(last_line_num) + + " if the '{' is alone on the line get the line before + if getline(last_line_num) =~ '^\s*{' + let last_line_num = GetLastRealCodeLNum(last_line_num - 1) + endif + + let previous_line = getline(last_line_num) + + continue + else + " At this point we know that the previous_line isn't a closing + " '}' so we can check if we really are in such a structure. + + " it's not a '}' but it could be an else alone... + if getline(last_line_num) =~# '^\s*else\%(if\)\=\>' + let last_line_num = FindTheIfOfAnElse(last_line_num, 0) + continue " re-run the loop (we could find a '}' again) + endif + + " So now it's ok we can check :-) + " A good quality is to have confidence in oneself so to know + " if yes or no we are in that struct lets test the indent of + " last_line_num and of last_line_num - 1! + " If those are == then we are almost done. + " + " That isn't sufficient, we need to test how the first of the + " 2 lines is ended... + + " Note the indenting of the line we are checking + + let last_match = last_line_num " remember the 'topest' line we found so far + + let one_ahead_indent = indent(last_line_num) + let last_line_num = GetLastRealCodeLNum(last_line_num - 1) + let two_ahead_indent = indent(last_line_num) + let after_previous_line = previous_line + let previous_line = getline(last_line_num) + + + " 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 + break + endif + + " The 3 lines below are not necessary for the script to work + " but it makes it work a little more faster in some (rare) cases. + " We verify if we are at the top of a non '{}' struct. + if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline + break + endif + + if one_ahead_indent == two_ahead_indent || last_line_num < 1 + " So the previous line and the line before are at the same + " col. Now we just have to check if the line before is a ;$ or [}]$ ended line + " we always check the most ahead line of the 2 lines so + " it's useless to match ')$' since the lines couldn't have + " the same indent... + if previous_line =~# '[;}]'.endline || last_line_num < 1 + break + endif + endif + endif + endwhile + + 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 + " from acting in some special cases + return ind + endif + endif + + + let plinnum = GetLastRealCodeLNum(lnum - 1) + let pline = getline(plinnum) " previous to last line + + " REMOVE comments at end of line before treatment + " the first par of the regex removes // from the end of line when they are + " followed by a number of '"' which is a multiple of 2. The second part + " removes // that are not followed by any '"' + " Sorry for this unreadable thing... + let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','') + + " Indent blocks enclosed by {} or () (default indenting) + if !LastLineClosed " the last line isn't a .*; or a }$ line + " 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 + let b:PHP_CurrentIndentLevel = ind + return ind + endif + endif + endif + + " If the current line closes a multiline function call or array def + if cline =~ '^\s*);\=' + let ind = ind - &sw + elseif cline =~# '^\s*\%(default\|case\).*:' + let ind = ind - &sw + endif + + if last_line =~# '^\s*\%(default\|case\).*:' + let ind = ind + &sw + endif + + let b:PHP_CurrentIndentLevel = ind + return ind +endfunction + +" vim: set ts=4 sw=4: -- 2.44.0