Vim Tips Wiki
Advertisement

Previous TipNext Tip

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


Advertisement