]> git.pld-linux.org Git - packages/vim.git/commitdiff
- up to ver 1.17
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Thu, 1 Sep 2005 19:12:06 +0000 (19:12 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    php.vim -> 1.5

php.vim

diff --git a/php.vim b/php.vim
index 06d6af522de6d4f17ece43a1e12ffdc9a50becb5..05e5a55be54ded486c2985145b10d061c52f372a 100644 (file)
--- a/php.vim
+++ b/php.vim
@@ -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
 " 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 @@ let php_sync_method = 0
 "                 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.
 
-if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
-       let myul=&ul
-       silent! %s/\r$//g
-endif
+let php_sync_method = 0
 
+
+" 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_and_script = 0
 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 @@ function! GetLastRealCodeLNum(startline) " {{{
                " 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 @@ function! GetLastRealCodeLNum(startline) " {{{
        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 @@ function! Skippmatch()  " {{{
        " 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 @@ function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
        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 @@ endfunction
 " }}}
 
 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 @@ function! GetPhpIndent()
                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 @@ function! GetPhpIndent()
                        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 @@ function! GetPhpIndent()
 
                        " Skip /* \n+ */ comments execept when the user is currently
                        " writting them
-               elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!'
-                       " \ && IslinePHP(v:lnum, '/\*')=="phpComment"
+               elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*' " XXX indent comments
                        let b:InPHPcode = 0
                        let b:InPHPcode_tofind = '\*/'
 
@@ -509,7 +602,6 @@ function! GetPhpIndent()
                        " 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 @@ function! GetPhpIndent()
        " 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 @@ function! GetPhpIndent()
                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*\*\%(\/\)\@!'   " 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 @@ function! GetPhpIndent()
                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 @@ function! GetPhpIndent()
                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.'\)\@!'
+       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 @@ function! GetPhpIndent()
                "                                       lkhlkh();
                "                                       echo 'infinite loop\n';
                "                               }
-       elseif ind != b:PHP_default_indenting && last_line =~ ';'.endline.'\|^\s*}\%(.*{'. endline.'\)\@!'
+               "
+               "       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 @@ function! GetPhpIndent()
 
                                " 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 @@ function! GetPhpIndent()
 
                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 @@ function! GetPhpIndent()
        " 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
This page took 0.134368 seconds and 4 git commands to generate.