diff options
Diffstat (limited to 'runtime/indent/perl.vim')
-rw-r--r-- | runtime/indent/perl.vim | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/runtime/indent/perl.vim b/runtime/indent/perl.vim new file mode 100644 index 000000000..1af058043 --- /dev/null +++ b/runtime/indent/perl.vim @@ -0,0 +1,180 @@ +" Vim indent file +" Language: Perl +" Author: Rafael Garcia-Suarez <rgarciasuarez@free.fr> +" URL: http://rgarciasuarez.free.fr/vim/indent/perl.vim +" Last Change: 2003 Apr 25 + +" Suggestions and improvements by : +" Aaron J. Sherman (use syntax for hints) +" Artem Chuprina (play nice with folding) + +" TODO things that are not or not properly indented (yet) : +" - Continued statements +" print "foo", +" "bar"; +" print "foo" +" if bar(); +" - Multiline regular expressions (m//x) +" (The following probably needs modifying the perl syntax file) +" - qw() lists +" - Heredocs with terminators that don't match \I\i* + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" Is syntax highlighting active ? +let b:indent_use_syntax = has("syntax") && &syntax == "perl" + +let s:cpo_save = &cpo +set cpo-=C + +setlocal indentexpr=GetPerlIndent() +setlocal indentkeys+=0=,0),0=or,0=and +if !b:indent_use_syntax + setlocal indentkeys+=0=EO +endif + +" Only define the function once. +if exists("*GetPerlIndent") + finish +endif + +function GetPerlIndent() + + " Get the line to be indented + let cline = getline(v:lnum) + + " Indent POD markers to column 0 + if cline =~ '^\s*=\L\@!' + return 0 + endif + + " Don't reindent coments on first column + if cline =~ '^#.' + return 0 + endif + + " Get current syntax item at the line's first char + let csynid = '' + if b:indent_use_syntax + let csynid = synIDattr(synID(v:lnum,1,0),"name") + endif + + " Don't reindent POD and heredocs + if csynid == "perlPOD" || csynid == "perlHereDoc" || csynid =~ "^pod" + return indent(v:lnum) + endif + + " Indent end-of-heredocs markers to column 0 + if b:indent_use_syntax + " Assumes that an end-of-heredoc marker matches \I\i* to avoid + " confusion with other types of strings + if csynid == "perlStringStartEnd" && cline =~ '^\I\i*$' + return 0 + endif + else + " Without syntax hints, assume that end-of-heredocs markers begin with EO + if cline =~ '^\s*EO' + return 0 + endif + endif + + " Now get the indent of the previous perl line. + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + let line = getline(lnum) + let ind = indent(lnum) + " Skip heredocs, POD, and comments on 1st column + if b:indent_use_syntax + let skippin = 2 + while skippin + let synid = synIDattr(synID(lnum,1,0),"name") + if (synid == "perlStringStartEnd" && line =~ '^\I\i*$') + \ || (skippin != 2 && synid == "perlPOD") + \ || (skippin != 2 && synid == "perlHereDoc") + \ || synid == "perlComment" + \ || synid =~ "^pod" + let lnum = prevnonblank(lnum - 1) + if lnum == 0 + return 0 + endif + let line = getline(lnum) + let ind = indent(lnum) + let skippin = 1 + else + let skippin = 0 + endif + endwhile + else + if line =~ "^EO" + let lnum = search("<<[\"']\\=EO", "bW") + let line = getline(lnum) + let ind = indent(lnum) + endif + endif + + " Indent blocks enclosed by {} or () + if b:indent_use_syntax + " Find a real opening brace + let bracepos = match(line, '[(){}]', matchend(line, '^\s*[)}]')) + while bracepos != -1 + let synid = synIDattr(synID(lnum, bracepos + 1, 0), "name") + " If the brace is highlighted in one of those groups, indent it. + " 'perlHereDoc' is here only to handle the case '&foo(<<EOF)'. + if synid == "" + \ || synid == "perlMatchStartEnd" + \ || synid == "perlHereDoc" + \ || synid =~ "^perlFiledescStatement" + \ || synid =~ '^perl\(Sub\|BEGINEND\|If\)Fold' + let brace = strpart(line, bracepos, 1) + if brace == '(' || brace == '{' + let ind = ind + &sw + else + let ind = ind - &sw + endif + endif + let bracepos = match(line, '[(){}]', bracepos + 1) + endwhile + let bracepos = matchend(cline, '^\s*[)}]') + if bracepos != -1 + let synid = synIDattr(synID(v:lnum, bracepos, 0), "name") + if synid == "" + \ || synid == "perlMatchStartEnd" + \ || synid =~ '^perl\(Sub\|BEGINEND\|If\)Fold' + let ind = ind - &sw + endif + endif + else + if line =~ '[{(]\s*\(#[^)}]*\)\=$' + let ind = ind + &sw + endif + if cline =~ '^\s*[)}]' + let ind = ind - &sw + endif + endif + + " Indent lines that begin with 'or' or 'and' + if cline =~ '^\s*\(or\|and\)\>' + if line !~ '^\s*\(or\|and\)\>' + let ind = ind + &sw + endif + elseif line =~ '^\s*\(or\|and\)\>' + let ind = ind - &sw + endif + + return ind + +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:ts=8:sts=2:sw=2 |