Tip: #419 - Auto-fold Perl subs
Created: February 3, 2003 20:43 Complexity: intermediate Author: Mina Naguib Version: 6.0 Karma: 90/33 Imported from: Tip#419
Add this to your .vimrc file and it'll automatically fold perl functions (and possibly other languages that define a subroutine with "sub ...")
Once you open a perl file, you'll see all functions are folded. You can then move to a function and (space) or "zo" to open it, "zc" to close it, "zR" to open all folds (normal file) and "zM" to re-fold all folds. It makes skimming over a file a breeze. See ":help folding" for more info on folding in general.
function GetPerlFold()
if getline(v:lnum) =~ '^\s*sub'
return ">1"
elseif getline(v:lnum + 2) =~ '^\s*sub' && getline(v:lnum + 1) =~ '^\s*$'
return "<1"
else
return "="
endif
endfunction
setlocal foldexpr=GetPerlFold()
setlocal foldmethod=expr
Comments
Regarding VimTip419 , I modified it to: 1. Correctly recognize subs beginning, as well as disregard "substr" 2. Correctly recognize end of sub, as well as disregard any following comments (commonly belonging to NEXT SUB) and not include it in fold
Here's the new code:
function GetPerlFold()
if getline(v:lnum) =~ '^\s*sub\s'
return ">1"
elseif getline(v:lnum) =~ '\}\s*$'
let my_perloffset = 1
while (1)
let my_perldata = getline(v:lnum + my_perloffset)
if my_perldata == ""
return "<1"
elseif my_perldata =~ '^\s*sub\s'
return "<1"
elseif my_perldata =~ '^\s*\(\#.*\)\?$'
" do nothing
else
return "="
endif
let my_perloffset = my_perloffset + 1
endwhile
else
return "="
endif
endfunction
setlocal foldexpr=GetPerlFold()
setlocal foldmethod=expr
webmaster--AT--topfx.com
, February 3, 2003 21:49
Yet another bugfix. This one fixes a bug where if a sub has inside it a } followed by an empty line, the fold would end there instead of at the real end of the sub
function GetPerlFold()
if getline(v:lnum) =~ '^\s*sub\s'
return ">1"
elseif getline(v:lnum) =~ '\}\s*$'
let my_perlnum = v:lnum
let my_perlmax = line("$")
while (1)
let my_perlnum = my_perlnum + 1
if my_perlnum > my_perlmax
return "<1"
endif
let my_perldata = getline(my_perlnum)
if my_perldata =~ '^\s*\(\#.*\)\?$'
" do nothing
elseif my_perldata =~ '^\s*sub\s'
return "<1"
else
return "="
endif
endwhile
else
return "="
endif
endfunction
setlocal foldexpr=GetPerlFold()
setlocal foldmethod=expr
webmaster--AT--topfx.com
, February 3, 2003 23:00
The perl syntax file already has this functionality.
To enable it, just put the line:
let perl_fold=1
in your .vimrc, _vimrc or ftplugin/perl.vim.
zak at pobox.com , February 4, 2003 0:42
Aww man ! Why wasn't I told about this before !
Well, at least I learnt a little bit of vim-scripting. The let perl_fold=1 seems to do it more gracefully than my code.
Thanks for the tip.
webmaster--AT--topfx.com , February 4, 2003 8:47
In most cases one should look into the $VIMRUNTIME/syntax/*.vim files. There is additional 'documentation' about extra options for folding and syntax highlighting.
Anonymous , February 7, 2003 0:05
Better yet - try ":help perl.vim" (or "help html.vim", ...)
anonymous , February 10, 2003 16:44
if u put let perl_fold = 1 in your .vimrc fold on marker doesnt work anymore
cnf--AT--antwerpen.be , July 4, 2003 12:15
I remember seeing komodo code folding if,elsif,else clauses as well as functions which was rather cool.
roberth--AT--hydrix.com , July 14, 2003 10:05
i found let perl_fold = 1 works unreliably-depends on indentation etc. The function above works better.
However, that function does not recognize .cgi files as perl(.pl OK) perl_fold recognizes both.
what to do?
Anonymous , January 26, 2004 14:26
Is it possible to modify the function so that the folding occurs after the sub name? The folding is very useful but I think it would be make it more useful if you can see the function name being folded instead of having to unfold the function to see the 'sub name'
cramirez--AT--gte.net , December 13, 2004 21:06
I also found that using perl_fold = 1 the package is folded by default which for most files is not necessary. Also didn't recognise the end of a sub in some cases.
Anonymous , January 21, 2005 1:01