Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Any smart Perl editors?

by FreeBeerReekingMonk (Deacon)
on Jun 08, 2019 at 20:42 UTC ( [id://11101142]=note: print w/replies, xml ) Need Help??


in reply to Any smart Perl editors?

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 $_)

Replies are listed 'Best First'.
Re^2: Any smart Perl editors?
by stevieb (Canon) on Jun 08, 2019 at 21:42 UTC

    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).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11101142]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-04-16 17:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found