http://www.perlmonks.org?node_id=11101116

harangzsolt33 has asked for the wisdom of the Perl Monks concerning the following question:

Is there a perl editor that parses the code and shows you a list of sub names that are declared in the code so you can click on the name of the sub routine you want to edit, and then it will show you only that part of the code, nothing else.

I started learning computer programming on QBASIC 1.1 which came with MS-DOS 5. This source editor parsed the BASIC source code and divided the program into sections so that you saw the main code and the individual subs and functions as a different page or different document. When you're editing a large program, it helps to see the subs enumerated, and when you click on one of them, it shows only that portion of code on the screen, nothing else. Is there an editor like that for perl? something I could use in Windows maybe?

Most programming editors just display the entire content of the file like a simple text editor perhaps with syntax highlighting. But I don't really care about highlighting. I just want something that will split my code into a separate page, so each sub will appear separately.

Replies are listed 'Best First'.
Re: Any smart Perl editors?
by soonix (Canon) on Jun 08, 2019 at 07:41 UTC
    There is a comparison of Perl Development Tools. The feature you are looking for, is folding (or at least that's the nearest to your description).
Re: Any smart Perl editors?
by stevieb (Canon) on Jun 08, 2019 at 14:27 UTC

    Here's the platform I've been using for several years now, on every computer I work on. Note that it doesn't "split" code (ie. show only a single sub clicked on), but clicking on a sub within the editor will take you directly to it, and with code folding, you can see in your file only the sub definition lines until you unfold to view the code.

    Here's an screenshot of the above setup. Normally I have two files open side-by-side within the IDE window, but when working on my laptop, the screen's just a tiny bit too small to do that efficiently.

    Although I've only mentioned IDEA, the Perl 5 plugin works on all of intelliJ's IDEs (PyCharm, CLion, Rider etc), which is handy, because if I'm working on one of my XS distributions, I'm using the CLion IDE, but because the plugin is installed in this one as well, I don't have to switch back and forth between two IDEs to work on Perl or C/C++ code.

    There are thousands of various plugins for the IDE in addition to the few I mentioned above, including editors (Vim, for the win!), and comes fully complete with VCS integration (I use Git exclusively nowadays). It also has a built-in terminal, and while the IDE is fully capable of running code, having the terminal built-in is fantastic, particularly because a lot of coding I do is over an SSHFS connection, so I can SSH to the remote system from right within the IDE itself.

    Note that IDEs have a steep learning curve if all one is familiar with is a simple text editor, but it's worth it. A couple of good solid weeks of learning and using, and the time you'll save in the long run will be immense.

    Update: I forgot to mention that the IDE mentioned also allows you to select any item, and it'll follow through to any sub or class in other any other file they're defined in (deep inspection). Exceptionally handy for delving deep.

      Wow! Thank you very much for all these ideas! I will try several of these mentioned here --Sublime, Idea, and Notepad++. Okay. I've already tested Notepad++ and it's not exactly what I am looking for. but it's a powerful editor otherwise.
Re: Any smart Perl editors?
by 1nickt (Canon) on Jun 08, 2019 at 14:50 UTC

    Hi, you might like Sublime. One of the guys at $work uses it and it seems to have lots of features similar to what you are describing. (Disclaimer: I use vim.)

    Hope this helps!


    The way forward always starts with a minimal test.

      If I'm on any computer that I can't get my IDE on, I use Vim as well. Here's a handy little bit of code for one's .vimrc file that allows for folding/unfolding of Perl subs:

      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

      Here's a screenshot of what things look like if the above code snip is added into the config file (all subs are folded by default when opening a Perl file).

      I keep a copy of my most basic vim config file in my Github for easy retrieval while I'm on systems I don't have control over.

      Update: While in Vim's normal mode, zo will open/expand the folded sub, and zc will close it again.

        Very nice! Here is a slightly changed version adapted to my own coding style (using '};' instead of '}' and pod documentation before each 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" elseif my_perldata =~ '^\s*=head.\s*' return "<1" else return "=" endif endwhile else return "=" endif endfunction setlocal foldexpr=GetPerlFold() setlocal foldmethod=expr
        This will let the pod lines between subs out of the folds. The original version will fold the pod lines with the previous sub.
Re: Any smart Perl editors?
by FreeBeerReekingMonk (Deacon) on Jun 08, 2019 at 20:42 UTC
    It's not exactly what you want, but Microsoft CODE has View: Split Editor (Ctrl+\) and in the second view you can fold all, and when you click on "sub", the side scrollbar shows extra markers where that keyword is, effectively showing you the relative position of the subroutines and how many there are.

    A poor man's implementation would be to split up your perlscript on /^sub (\w+)/ and make different files out of those, and have a script that reassembles them back. The problem in Perl is that you can predefine, post-define and embed subroutines, so it has to be a real parser to do that... but you can circumvent this by using perltidy on the source first, so that, once you encounter /^sub.*/ all you need to do is write to a new subroutine file until you reach a solitary /^}$/ and you go back to main. Then open all these files in an editor that can remember a session (like notepad++, Kate, code, sublime, etc). Then, before running you file, you have a cmd/sh file that concats the files and voila...

    Not sure if this splitter works on Windows:

    #!/usr/bin/perl use File::Basename qw(fileparse fileparse_set_fstype); use autodie qw(open close); $fn = shift; my $type = fileparse_set_fstype(); # save old type fileparse_set_fstype("Unix") unless $type eq "Unix"; # set to unix typ +e my @T = fileparse($fn,'\.[^\.]*$'); #base, path, ext fileparse_set_fstype($type) unless $type eq "Unix"; # restore $filebase = $T[1] . $T[0]; $filename = $filebase . '.main'; open(FI,'<', $fn); open(FO,'>', $filename); while(<FI>){ if(/^sub (\w+)/){ close(FO); $filename = $filebase . '.'. $1; open(FO,'>', $filename); print FO "\n" . $_; }elsif(/^}$/ && $filename ne $filebase . '.main'){ print FO $_; close(FO); $filename = $filebase . '.main'; open(FO,'>>', $filename); }else{ print FO $_; } }

    Edit: Oh, forgot: Notepad++ has a Function list that lists all the subroutines. (View -> Function List) So you can combine that with Splitview (rightclick on the tab, then "Clone to other View"). And so, to go to a sub, you click inside the middle pl file, then doubleclick on the right side on any subroutine name, then click on the leftmost pl file that has your edit session. It also has bookmarks on the you can set in every line and rotate through them with (shift) F2

    Edit2: updated code (dumb to print $1 and $2 while whole line is still available in $_)

      I like the idea here, check out Devel::Examine::Subs, which uses PPI to figure out where subs are. Not only that, it fetches the sub code and stuffs each sub into objects where you can spit them out individually. Works on any Perl file type.

      I'm currently working AFK so I can't demo anything at the moment, but I'll see if I can get a chance a little later, but here's a quick and dirty example:

      use strict; use warnings; use 5.10.0; use Devel::Examine::Subs; my $des = Devel::Examine::Subs->new(file => 'test.pl'); my $subs = $des->objects; for my $sub (@$subs){ say $sub->name; say "------"; say $_ for @{ $sub->code }; say "\n"; }

      Input file:

      use warnings; use strict; three(5); sub three { return two(shift); } sub two { return one(_helper(shift)); } sub one { my $num = calc(shift); display($num); } sub calc { my $num = shift; return $num ** 3; } sub display { my $num = shift; print "$num\n"; } sub _helper { my $num = shift; return ++$num; }

      Output:

      spek@scelia ~/scratch $ perl des.pl display ------ sub display { my $num = shift; print "$num\n"; } two ------ sub two { return one(_helper(shift)); } three ------ sub three { return two(shift); } one ------ sub one { my $num = calc(shift); display($num); } calc ------ sub calc { my $num = shift; return $num ** 3; } _helper ------ sub _helper { my $num = shift; return ++$num; }

      Might help facilitate the separation with a bit more reliability :)

        wow... nice module!

        Fiddling with Notepad++ I found that you can run external commands and pass your file (FULL_CURRENT_PATH) and the selected subroutine name (CURRENT_WORD). This external command would use your module to write the subroutine to a file, then call notepad++ again to open that file in the editor...

        http://docs.notepad-plus-plus.org/index.php/External_Programs

        But now a question to the OP: Is this the way to go?

        It will be a temporal file, just for looking at it?

        If not: Saving that file back, you can run another external command that find the name of the subroutine, finds the multiline string in the original file, and replaces it with the updated content of the isolated subroutine. And Notepad++ is intelligent enough to tell you the file has changed and you need to update it. The only problem is that you somehow need to make sure the main pl file is saved before doing this, or you lose your changes to the main body (edit: just checked and NPP does NOT autosave before running external commands).

Re: Any smart Perl editors?
by Anonymous Monk on Jun 08, 2019 at 22:01 UTC
    Emacs in cperl-mode is scanning all subs.

    Calling M-x imenu will allow you jumping to a sub chosen from a menu. You can also easily make imenu a navigation bar entry hence you can jump easily from a call to a subs definition.

    You can also bind it to a key like M-Ret. That's handy cause the menu defaults to the word under the cursor.

    If you want a side pane where you can click with your mouse, you'd have the choice between installing ECB or PDE from elpa. Both draw a side pane using imenu's data.

    the other requirement of only showing the code is a bit unclear. It sounds like narrow-to-defun where the code outside the sub is hidden.

    In case you want folding, try hide-show-minor-mode.

Re: Any smart Perl editors?
by Anonymous Monk on Jun 08, 2019 at 07:48 UTC