update runtime files
[vim_extended.git] / runtime / indent / perl.vim
blobb3a9fc0214b4925630cae902ee1cd9c0e27a8b00
1 " Vim indent file
2 " Language:     Perl
3 " Author:       Rafael Garcia-Suarez <rgarciasuarez@free.fr>
4 " URL:          http://rgarciasuarez.free.fr/vim/indent/perl.vim
5 " Last Change:  2005 Sep 07
7 " Suggestions and improvements by :
8 "   Aaron J. Sherman (use syntax for hints)
9 "   Artem Chuprina (play nice with folding)
11 " TODO things that are not or not properly indented (yet) :
12 " - Continued statements
13 "     print "foo",
14 "       "bar";
15 "     print "foo"
16 "       if bar();
17 " - Multiline regular expressions (m//x)
18 " (The following probably needs modifying the perl syntax file)
19 " - qw() lists
20 " - Heredocs with terminators that don't match \I\i*
22 " Only load this indent file when no other was loaded.
23 if exists("b:did_indent")
24   finish
25 endif
26 let b:did_indent = 1
28 " Is syntax highlighting active ?
29 let b:indent_use_syntax = has("syntax")
31 setlocal indentexpr=GetPerlIndent()
32 setlocal indentkeys+=0=,0),0=or,0=and
33 if !b:indent_use_syntax
34   setlocal indentkeys+=0=EO
35 endif
37 " Only define the function once.
38 if exists("*GetPerlIndent")
39   finish
40 endif
42 let s:cpo_save = &cpo
43 set cpo-=C
45 function GetPerlIndent()
47   " Get the line to be indented
48   let cline = getline(v:lnum)
50   " Indent POD markers to column 0
51   if cline =~ '^\s*=\L\@!'
52     return 0
53   endif
55   " Don't reindent coments on first column
56   if cline =~ '^#.'
57     return 0
58   endif
60   " Get current syntax item at the line's first char
61   let csynid = ''
62   if b:indent_use_syntax
63     let csynid = synIDattr(synID(v:lnum,1,0),"name")
64   endif
66   " Don't reindent POD and heredocs
67   if csynid == "perlPOD" || csynid == "perlHereDoc" || csynid =~ "^pod"
68     return indent(v:lnum)
69   endif
71   " Indent end-of-heredocs markers to column 0
72   if b:indent_use_syntax
73     " Assumes that an end-of-heredoc marker matches \I\i* to avoid
74     " confusion with other types of strings
75     if csynid == "perlStringStartEnd" && cline =~ '^\I\i*$'
76       return 0
77     endif
78   else
79     " Without syntax hints, assume that end-of-heredocs markers begin with EO
80     if cline =~ '^\s*EO'
81       return 0
82     endif
83   endif
85   " Now get the indent of the previous perl line.
87   " Find a non-blank line above the current line.
88   let lnum = prevnonblank(v:lnum - 1)
89   " Hit the start of the file, use zero indent.
90   if lnum == 0
91     return 0
92   endif
93   let line = getline(lnum)
94   let ind = indent(lnum)
95   " Skip heredocs, POD, and comments on 1st column
96   if b:indent_use_syntax
97     let skippin = 2
98     while skippin
99       let synid = synIDattr(synID(lnum,1,0),"name")
100       if (synid == "perlStringStartEnd" && line =~ '^\I\i*$')
101             \ || (skippin != 2 && synid == "perlPOD")
102             \ || (skippin != 2 && synid == "perlHereDoc")
103             \ || synid == "perlComment"
104             \ || synid =~ "^pod"
105         let lnum = prevnonblank(lnum - 1)
106         if lnum == 0
107           return 0
108         endif
109         let line = getline(lnum)
110         let ind = indent(lnum)
111         let skippin = 1
112       else
113         let skippin = 0
114       endif
115     endwhile
116   else
117     if line =~ "^EO"
118       let lnum = search("<<[\"']\\=EO", "bW")
119       let line = getline(lnum)
120       let ind = indent(lnum)
121     endif
122   endif
124   " Indent blocks enclosed by {} or ()
125   if b:indent_use_syntax
126     " Find a real opening brace
127     let bracepos = match(line, '[(){}]', matchend(line, '^\s*[)}]'))
128     while bracepos != -1
129       let synid = synIDattr(synID(lnum, bracepos + 1, 0), "name")
130       " If the brace is highlighted in one of those groups, indent it.
131       " 'perlHereDoc' is here only to handle the case '&foo(<<EOF)'.
132       if synid == ""
133             \ || synid == "perlMatchStartEnd"
134             \ || synid == "perlHereDoc"
135             \ || synid =~ "^perlFiledescStatement"
136             \ || synid =~ '^perl\(Sub\|BEGINEND\|If\)Fold'
137         let brace = strpart(line, bracepos, 1)
138         if brace == '(' || brace == '{'
139           let ind = ind + &sw
140         else
141           let ind = ind - &sw
142         endif
143       endif
144       let bracepos = match(line, '[(){}]', bracepos + 1)
145     endwhile
146     let bracepos = matchend(cline, '^\s*[)}]')
147     if bracepos != -1
148       let synid = synIDattr(synID(v:lnum, bracepos, 0), "name")
149       if synid == ""
150             \ || synid == "perlMatchStartEnd"
151             \ || synid =~ '^perl\(Sub\|BEGINEND\|If\)Fold'
152         let ind = ind - &sw
153       endif
154     endif
155   else
156     if line =~ '[{(]\s*\(#[^)}]*\)\=$'
157       let ind = ind + &sw
158     endif
159     if cline =~ '^\s*[)}]'
160       let ind = ind - &sw
161     endif
162   endif
164   " Indent lines that begin with 'or' or 'and'
165   if cline =~ '^\s*\(or\|and\)\>'
166     if line !~ '^\s*\(or\|and\)\>'
167       let ind = ind + &sw
168     endif
169   elseif line =~ '^\s*\(or\|and\)\>'
170     let ind = ind - &sw
171   endif
173   return ind
175 endfunction
177 let &cpo = s:cpo_save
178 unlet s:cpo_save
180 " vim:ts=8:sts=2:sw=2