5 Sepia - Simple Emacs-Perl Interface
11 M-x load-library RET sepia RET
14 At the prompt in the C<*sepia-repl*> buffer:
18 For more information, please see F<Sepia.html> or F<sepia.info>, which
19 come with the distribution.
26 use Sepia
::Debug
; # THIS TURNS ON DEBUGGING INFORMATION!
28 use Scalar
::Util
'looks_like_number';
31 use Storable
qw(store retrieve);
33 use vars
qw($PS1 %REPL %RK %REPL_DOC %REPL_SHORT %PRINTER
35 $REPL_LEVEL $PACKAGE $WANTARRAY $PRINTER $STRICT $PRINT_PRETTY
40 eval { require Lexical::Persistence; import Lexical::Persistence };
42 print "Strict mode requires Lexical::Persistence.\n";
45 my $x = as_boolean(shift, $STRICT);
47 $STRICT = new Lexical::Persistence;
58 eval { require Module::CoreList };
62 *core_version = sub { Module::CoreList->first_release(@_) };
68 eval { use List::Util 'max' };
73 $ret = $_ if $_ > $ret;
82 eval { require Devel::Size };
84 print "Size requires Devel::Size.\n";
86 *Sepia::repl_size = sub {
88 ## XXX: C&P from repl_who:
89 my ($pkg, $re) = split ' ', shift || '';
90 if ($pkg =~ /^\/(.*)\/?$/) {
93 } elsif (!$re && !%{$pkg.'::'}) {
97 my @who = who($pkg, $re);
98 my $len = max(3, map { length } @who) + 4;
99 my $fmt = '%-'.$len."s%10d\n";
100 # print "$pkg\::/$re/\n";
101 print 'Var', ' ' x ($len + 2), "Bytes\n";
102 print '-' x ($len-4), ' ' x 9, '-' x 5, "\n";
105 next unless /^[\$\@\%\&]/; # skip subs.
106 next if $_ eq '%SIG';
107 $res{$_} = eval "no strict; package $pkg; Devel::Size::total_size \\$_;";
109 for (sort { $res{$b} <=> $res{$a} } keys %res) {
110 printf $fmt, $_, $res{$_};
119 Sepia is a set of features to make Emacs a better tool for Perl
120 development. This package contains the Perl side of the
121 implementation, including all user-serviceable parts (for the
122 cross-referencing facility see L<Sepia::Xref>). This document is
123 aimed as Sepia developers; for user documentation, see
124 L<Sepia.html> or L<sepia.info>.
126 Though not intended to be used independent of the Emacs interface, the
127 Sepia module's functionality can be used through a rough procedural
130 =head2 C<@compls = completions($string [, $type])>
132 Find a list of completions for C<$string> with glob type C<$type>,
133 which may be "SCALAR", "HASH", "ARRAY", "CODE", "IO", or the special
134 value "VARIABLE", which means either scalar, hash, or array.
135 Completion operates on word subparts separated by [:_], so
136 e.g. "S:m_w" completes to "Sepia::my_walksymtable".
138 =head2 C<@compls = method_completions($expr, $string [,$eval])>
140 Complete among methods on the object returned by C<$expr>. The
141 C<$eval> argument, if present, is a function used to do the
142 evaluation; the default is C<eval>, but for example the Sepia REPL
143 uses C<Sepia::repl_eval>. B<Warning>: Since it has to evaluate
144 C<$expr>, method completion can be extremely problematic. Use with
151 # Do that crazy multi-word identifier completion thing:
153 return qr/.*/ if $re eq '';
156 s/(?:^|(?<=[A-Za-z\d]))(([^A-Za-z\d])\2*)/[A-Za-z\\d]*$2+/g;
158 } split /:+/, $re, -1;
160 if ($re !~ /[^\w\d_^:]/) {
161 $re =~ s/(?<=[A-Za-z\d])(([^A-Za-z\d])\2*)/[A-Za-z\\d]*$2+/g;
169 %sigil = qw(ARRAY @ SCALAR $ HASH %);
175 local $_ = /^::/ ?
$_ : "::$_";
176 defined *{$_}{CODE
} || defined *{$_}{IO
} || (/::$/ && %$_);
179 ## XXX: Careful about autovivification here! Specifically:
180 ## defined *FOO{HASH} # => ''
181 ## defined %FOO # => ''
182 ## defined *FOO{HASH} # => 1
187 local $_ = /^::/ ?
$_ : "::$_";
188 if ($type eq 'SCALAR') {
190 } elsif ($type eq 'VARIABLE') {
191 defined $$_ || defined *{$_}{HASH
} || defined *{$_}{ARRAY
};
200 return '' if $ch eq '';
201 $ch =~ /[A-Z]/ ?
$ch : '['.uc($ch).$ch.']';
204 sub all_abbrev_completions
206 use vars
'&_completions';
207 local *_completions
= sub {
209 my ($stash, @e) = @_;
210 my $ch = '[A-Za-z0-9]*';
211 my $re1 = "^".maybe_icase
($e[0]).$ch.join('', map {
212 '_'.maybe_icase
($_).$ch
215 my $re2 = maybe_icase
$e[0];
216 $re2 = qr/^$re2.*::$/;
217 my @ret = grep !/::$/ && /$re1/, keys %{$stash};
218 my @pkgs = grep /$re2/, keys %{$stash};
219 (map("$stash$_", @ret),
220 @e > 1 ?
map { _completions
"$stash$_", @e[1..$#e] } @pkgs :
221 map { "$stash$_" } @pkgs)
223 map { s/^:://; $_ } _completions
('::', split //, shift);
228 my ($icase, $re) = @_;
230 $icase ?
qr/^$re.*$/i : qr/^$re.*$/;
235 my $icase = $_[0] !~ /[A-Z]/;
236 my @parts = split /:+/, shift, -1;
237 my $re = apropos_re
$icase, pop @parts;
238 use vars
'&_completions';
239 local *_completions
= sub {
243 map { "$stash$_" } grep /$re/, keys %{$stash};
245 my $re2 = $icase ?
qr/^$_[0].*::$/i : qr/^$_[0].*::$/;
246 my @pkgs = grep /$re2/, keys %{$stash};
247 map { _completions
"$stash$_", @_[1..$#_] } @pkgs
250 map { s/^:://; $_ } _completions
('::', @parts);
253 # Filter exact matches so that e.g. "A::x" completes to "A::xx" when
254 # both "Ay::xx" and "A::xx" exist.
255 sub filter_exact_prefix
257 my @parts = split /:+/, shift, -1;
260 my $pre = shift @parts;
261 while (@parts && (@tmp = grep /^\Q$pre\E(?:::|$)/, @res)) {
263 $pre .= '::'.shift @parts;
268 sub lexical_completions
270 eval { require PadWalker
; import PadWalker
'peek_sub' };
271 # "internal" function, so don't warn on failure
273 *lexical_completions
= sub {
274 my ($type, $str, $sub) = @_;
275 $sub = "$PACKAGE\::$sub" unless $sub =~ /::/;
276 # warn "Completing $str of type $type in $sub\n";
278 return unless defined *{$sub}{CODE
};
279 my $pad = peek_sub
(\
&$sub);
281 map { s/^[\$\@&\%]//;$_ } grep /^\Q$type$str\E/, keys %$pad;
283 map { s/^[\$\@&\%]//;$_ } grep /^.\Q$str\E/, keys %$pad;
286 goto &lexical_completions
;
291 my ($type, $str, $sub) = @_;
293 my %h = qw(@ ARRAY % HASH & CODE * IO $ SCALAR);
295 @rh{values %h} = keys %h;
297 $t = $type ?
$rh{$type} : '';
299 if ($sub && $type ne '') {
300 @ret = lexical_completions
$t, $str, $sub;
304 $type ? filter_typed
$type : filter_untyped
305 } all_completions
$str;
307 if (!@ret && $str !~ /:/) {
309 $type ? filter_typed
$type : filter_untyped
310 } all_abbrev_completions
$str;
312 @ret = map { s/^:://; "$t$_" } filter_exact_prefix
$str, @ret;
313 # ## XXX: Control characters, $", and $1, etc. confuse Emacs, so
316 length $_ > 0 && !looks_like_number
($_) && !/^[^\w\d_]$/ && !/^_</ && !/^[[:cntrl:]]/
320 sub method_completions
322 my ($x, $fn, $eval) = @_;
325 $eval ||= 'CORE::eval';
327 return unless ($x =~ /^\$/ && ($x = $eval->("ref($x)")))
328 || $eval->('%'.$x.'::');
330 my $re = _apropos_re
$fn;
331 ## Filter out overload methods "(..."
332 return sort { $a cmp $b } map { s/.*:://; $_ }
333 grep { defined *{$_}{CODE
} && /::$re/ && !/\(/ }
338 =head2 C<@locs = location(@names)>
340 Return a list of [file, line, name] triples, one for each function
350 if (my ($pfx, $name) = $str =~ /^([\%\$\@]?)(.+)/) {
352 warn "Sorry -- can't lookup variables.";
355 # XXX: svref_2object only seems to work with a package
356 # tacked on, but that should probably be done
358 $name = 'main::'.$name unless $name =~ /::/;
359 my $cv = B
::svref_2object
(\
&{$name});
360 if ($cv && defined($cv = $cv->START) && !$cv->isa('B::NULL')) {
361 my ($file, $line) = ($cv->file, $cv->line);
362 if ($file !~ /^\//) {
370 my ($shortname) = $name =~ /^(?:.*::)([^:]+)$/;
371 [Cwd
::abs_path
($file), $line, $shortname || $name]
373 # warn "Bad CV for $name: $cv";
384 =head2 C<@matches = apropos($name [, $is_regex])>
386 Search for function C<$name>, either in all packages or, if C<$name>
387 is qualified, only in one package. If C<$is_regex> is true, the
388 non-package part of C<$name> is a regular expression.
392 sub my_walksymtable
(&*)
398 &$f for keys %$stash;
399 _walk
("$stash$_") for grep /(?<!main)::$/, keys %$stash;
406 my ($it, $re, @types) = @_;
409 $stashp = grep /STASH/, @types;
410 @types = grep !/STASH/, @types;
415 if ($it =~ /^(.*::)([^:]+)$/) {
416 my ($stash, $name) = ($1, $2);
421 my $name = qr/^$name/;
426 my $stashnm = "$stash$_";
430 defined($_ eq 'SCALAR' ?
$$stashnm : *{$stashnm}{$_})
434 defined &$it ?
$it : ();
438 my $findre = $re ?
qr/$it/ : qr/^\Q$it\E$/;
440 push @ret, "$stash$_" if /$findre/;
442 map { s/^:*(?:main:+)*//;$_ } @ret;
446 =head2 C<@names = mod_subs($pack)>
448 Find subs in package C<$pack>.
456 my $stash = \
%{"$p\::"};
458 grep { defined &{"$p\::$_"} } keys %$stash;
462 =head2 C<@decls = mod_decls($pack)>
464 Generate a list of declarations for all subroutines in package
475 my $proto = prototype(\
&{"$pack\::$sn"});
476 $proto = defined($proto) ?
"($proto)" : '';
479 return wantarray ?
@ret : join '', @ret;
482 =head2 C<$info = module_info($module, $type)>
484 Emacs-called function to get module information.
490 eval { require Module
::Info
; import Module
::Info
};
498 $info = Module
::Info
->new_from_file($m);
500 (my $file = $m) =~ s
|::|/|g
;
502 if (exists $INC{$file}) {
503 $info = Module
::Info
->new_from_loaded($m);
505 $info = Module
::Info
->new_from_module($m);
516 =head2 C<$file = mod_file($mod)>
518 Find the likely file owner for module C<$mod>.
526 while ($m && !exists $INC{"$m.pm"}) {
527 $m =~ s
#(?:^|/)[^/]+$##;
529 $m ?
$INC{"$m.pm"} : undef;
532 =head2 C<@mods = package_list>
534 Gather a list of all distributions on the system. XXX UNUSED
542 eval 'require ExtUtils::Installed';
543 $INST = new ExtUtils
::Installed
;
550 sort { $a cmp $b } inst
()->modules;
553 =head2 C<@mods = module_list>
555 Gather a list of all packages (.pm files, really) installed on the
556 system, grouped by distribution. XXX UNUSED
562 @_ = package_list
unless @_;
563 my $incre = join '|', map quotemeta, @INC;
564 $incre = qr
|(?
:$incre)/|;
568 s/$incre//; s
|/|::|g
;$_
569 } grep /\.pm$/, $inst->files($_)]
573 =head2 C<@mods = doc_list>
575 Gather a list of all documented packages (.?pm files, really)
576 installed on the system, grouped by distribution. XXX UNUSED
582 @_ = package_list
unless @_;
586 s/.*man.\///; s|/|::|g
;s/\..?pm//; $_
587 } grep /\..pm$/, $inst->files($_)]
591 =head2 C<lexicals($subname)>
593 Return a list of C<$subname>'s lexical variables. Note that this
594 includes all nested scopes -- I don't know if or how Perl
595 distinguishes inner blocks.
601 my $cv = B
::svref_2object
(\
&{+shift});
602 return unless $cv && ($cv = $cv->PADLIST);
603 my ($names, $vals) = $cv->ARRAY;
605 my $name = $_->PV; $name =~ s/\0.*$//; $name
606 } grep B
::class($_) ne 'SPECIAL', $names->ARRAY;
609 =head2 C<$lisp = tolisp($perl)>
611 Convert a Perl scalar to some ELisp equivalent.
617 my $thing = @_ == 1 ?
shift : \
@_;
620 if (!defined $thing) {
622 } elsif (looks_like_number
$thing) {
625 ## XXX Elisp and perl have slightly different
626 ## escaping conventions, so we do this crap instead.
627 $thing =~ s/["\\]/\\$1/g;
630 } elsif ($t eq 'GLOB') {
631 (my $name = $$thing) =~ s/\*main:://;
633 } elsif ($t eq 'ARRAY') {
634 '(' . join(' ', map { tolisp
($_) } @
$thing).')'
635 } elsif ($t eq 'HASH') {
636 '(' . join(' ', map {
637 '(' . tolisp
($_) . " . " . tolisp
($thing->{$_}) . ')'
639 } elsif ($t eq 'Regexp') {
640 "'(regexp . \"" . quotemeta($thing) . '")';
641 # } elsif ($t eq 'IO') {
647 =head2 C<printer(\@res, $wantarray)>
649 Print C<@res> appropriately on the current filehandle. If C<$ISEVAL>
650 is true, use terse format. Otherwise, use human-readable format,
651 which can use either L<Data::Dumper>, L<YAML>, or L<Data::Dump>.
657 eval { require Data
::Dumper
};
658 local $Data::Dumper
::Deparse
= 1;
659 local $Data::Dumper
::Indent
= 0;
661 my $thing = @res > 1 ? \
@res : $res[0];
663 $_ = Data
::Dumper
::Dumper
($thing);
667 if (length $_ > ($ENV{COLUMNS
} || 80)) {
668 $Data::Dumper
::Indent
= 1;
670 $_ = Data
::Dumper
::Dumper
($thing);
683 eval { require YAML
};
685 $PRINTER{dumper
}->();
691 eval { require Data
::Dump
};
693 $PRINTER{dumper
}->();
695 Data
::Dump
::dump(\
@res);
703 my ($wantarray) = @_;
706 $::__
= @res == 1 ?
$res[0] : [@res];
710 } elsif (@res == 1 && UNIVERSAL
::can
($res[0], '()')) {
713 } elsif (!$ISEVAL && $PRINT_PRETTY && @res > 1 && !grep ref, @res) {
714 $res = columnate
(@res);
718 $res = $PRINTER{$PRINTER}->();
721 print ';;;', length $res, "\n$res\n";
737 "$PACKAGE ".($WANTARRAY ?
'@' : '$').$PS1
743 Data
::Dumper
->Dump([$_[0]], [$_[1]]);
750 my $n1 = int(2*$n/3);
752 s/(.{$n1,$n}) /$1\n/g;
761 *{$_->[0]} = $_->[1];
766 undef @BADVARS{qw(%INC @INC %SIG @ISA %ENV @ARGV)};
772 return !/^.[^c-zA-Z]$/ # single-letter stuff (match vars, $_, etc.)
773 && !/^.[\0-\060]/ # magic weirdness.
774 && !/^._</ # debugger info
775 && !exists $BADVARS{$_}; # others.
782 $re = qr/(?:^|::)$re/;
783 no strict; # no kidding...
786 || $stash =~ /^(?:::)?(?:warnings|Config|strict|B)\b/;
788 my $name = "$stash$_";
789 if (defined ${$name} and saveable '$'.$_) {
790 push @save, [$name, \$$name];
792 if (defined *{$name}{HASH} and saveable '%'.$_) {
793 push @save, [$name, \%{$name}];
795 if (defined *{$name}{ARRAY} and saveable '@'.$_) {
796 push @save, [$name, \@{$name}];
800 print STDERR "$_->[0] " for @save;
805 =head2 C<define_shortcut $name, $sub [, $doc [, $shortdoc]]>
807 Define $name as a shortcut for function $sub.
813 my ($name, $doc, $short, $fn);
819 ($name, $fn, $doc) = @_;
822 ($name, $fn, $short, $doc) = @_;
825 $REPL_DOC{$name} = $doc;
826 $REPL_SHORT{$name} = $short;
831 define_shortcut 'help', \&Sepia::repl_help,
833 'Display help on all commands, or just CMD.';
834 define_shortcut 'cd', \&Sepia::repl_chdir,
835 'cd DIR', 'Change directory to DIR';
836 define_shortcut 'pwd', \&Sepia::repl_pwd,
837 'Show current working directory';
838 define_shortcut 'methods', \&Sepia::repl_methods,
840 'List methods for reference or package X, matching optional pattern RE';
841 define_shortcut 'package', \&Sepia::repl_package,
842 'package PKG', 'Set evaluation package to PKG';
843 define_shortcut 'who', \&Sepia::repl_who,
845 'List variables and subs in PKG matching optional pattern RE.';
846 define_shortcut 'wantarray', \&Sepia::repl_wantarray,
847 'wantarray [0|1]', 'Set or toggle evaluation context';
848 define_shortcut 'format', \&Sepia::repl_format,
849 'format [TYPE]', "Set output formatter to TYPE (one of 'dumper', 'dump', 'yaml', 'plain'; default: 'dumper'), or show current type.";
850 define_shortcut 'strict', \&Sepia::repl_strict,
851 'strict [0|1]', 'Turn \'use strict\' mode on or off';
852 define_shortcut 'quit', \&Sepia::repl_quit,
854 define_shortcut 'restart', \&Sepia::repl_restart,
855 'Reload Sepia.pm and relaunch the REPL.';
856 define_shortcut 'shell', \&Sepia::repl_shell,
857 'shell CMD ...', 'Run CMD in the shell';
858 define_shortcut 'eval', \&Sepia::repl_eval,
859 'eval EXP', '(internal)';
860 define_shortcut 'size', \&Sepia::repl_size,
862 'List total sizes of objects in PKG matching optional pattern RE.';
863 define_shortcut define => \&Sepia::repl_define,
864 'define NAME [\'doc\'] BODY',
865 'Define NAME as a shortcut executing BODY';
866 define_shortcut undef => \&Sepia::repl_undef,
867 'undef NAME', 'Undefine shortcut NAME';
868 define_shortcut test => \&Sepia::repl_test,
869 'test FILE...', 'Run tests interactively.';
870 define_shortcut load => \&Sepia::repl_load,
871 'load [FILE]', 'Load state from FILE.';
872 define_shortcut save => \&Sepia::repl_save,
873 'save [PATTERN [FILE]]', 'Save variables matching PATTERN to FILE.';
874 define_shortcut reload => \&Sepia::repl_reload,
875 'reload [MODULE | /RE/]', 'Reload MODULE, or all modules matching RE.';
876 define_shortcut freload => \&Sepia::repl_full_reload,
877 'freload MODULE', 'Reload MODULE and all its dependencies.';
882 my $width = $ENV{COLUMNS} || 80;
887 my $full = $RK{$args};
889 my $short = $REPL_SHORT{$full};
890 my $flow = flow($width - length $short - 4, $REPL_DOC{$full});
891 $flow =~ s/(.)\n/"$1\n".(' 'x (4 + length $short))/eg;
892 print "$short $flow\n";
894 print "$args: no such command\n";
897 my $left = 1 + max map length, values %REPL_SHORT;
898 print "REPL commands (prefixed with ','):\n";
900 for (sort keys %REPL) {
901 my $flow = flow($width - $left, $REPL_DOC{$_});
902 $flow =~ s/(.)\n/"$1\n".(' ' x $left)/eg;
903 printf "%-${left}s%s\n", $REPL_SHORT{$_}, $flow;
911 my ($name, $doc, $body);
912 if (/^\s*(\S+)\s+'((?:[^'\\]|\\.)*)'\s+(.+)/) {
913 ($name, $doc, $body) = ($1, $2, $3);
914 } elsif (/^\s*(\S+)\s+(\S.*)/) {
915 ($name, $doc, $body) = ($1, $2, $2);
917 print "usage: define NAME ['doc'] BODY...\n";
920 my $sub = eval "sub { do { $body } }";
922 print "usage: define NAME ['doc'] BODY...\n\t$@\n";
925 define_shortcut $name, $sub, $doc;
926 %RK = abbrev keys %REPL;
934 my $full = $RK{$name};
937 delete $REPL_SHORT{$full};
938 delete $REPL_DOC{$full};
939 %RK = abbrev keys %REPL;
941 print "$name: no such shortcut.\n";
950 print "printer = $PRINTER, pretty = @{[$PRINT_PRETTY ? 1 : 0]}\n";
952 my %formats = abbrev keys %PRINTER;
953 if (exists $formats{$t}) {
954 $PRINTER = $formats{$t};
956 warn "No such format '$t' (dumper, dump, yaml, plain).\n";
963 chomp(my $dir = shift);
964 $dir =~ s/^~\//$ENV{HOME}\//;
965 $dir =~ s/\$HOME/$ENV{HOME}/;
968 my $ecmd = '(cd "'.Cwd::getcwd().'")';
969 print ";;;###".length($ecmd)."\n$ecmd\n";
971 warn "Can't chdir\n";
977 print Cwd::getcwd(), "\n";
982 my ($pack, $re_str) = @_;
984 my $re = qr/$re_str/;
986 if ($re_str =~ /^[\$\@\%\&]/) {
987 ## sigil given -- match it
988 sort grep /$re/, map {
989 my $name = $pack.'::'.$_;
990 (defined *{$name}{HASH} ? '%'.$_ : (),
991 defined *{$name}{ARRAY} ? '@'.$_ : (),
992 defined *{$name}{CODE} ? $_ : (),
993 defined ${$name} ? '$'.$_ : (), # ?
995 } grep !/::$/ && !/^(?:_<|[^\w])/ && /$re/, keys %{$pack.'::'};
997 ## no sigil -- don't match it
999 my $name = $pack.'::'.$_;
1000 (defined *{$name}{HASH} ? '%'.$_ : (),
1001 defined *{$name}{ARRAY} ? '@'.$_ : (),
1002 defined *{$name}{CODE} ? $_ : (),
1003 defined ${$name} ? '$'.$_ : (), # ?
1005 } grep !/::$/ && !/^(?:_<|[^\w])/ && /$re/, keys %{$pack.'::'};
1013 my $width = $ENV{COLUMNS} || 80;
1015 $len = length if $len < length;
1017 my $nc = int($width / ($len+1)) || 1;
1018 my $nr = int(@_ / $nc) + (@_ % $nc ? 1 : 0);
1019 my $fmt = ('%-'.($len+1).'s') x ($nc-1) . "%s\n";
1020 my @incs = map { $_ * $nr } 0..$nc-1;
1022 for my $r (0..$nr-1) {
1023 $str .= sprintf $fmt, map { defined($_) ? $_ : '' }
1024 @_[map { $r + $_ } @incs];
1032 my ($pkg, $re) = split ' ', shift;
1034 if ($pkg && $pkg =~ /^\/(.*)\/?$/) {
1037 } elsif (!$re && !%{$pkg.'::'}) {
1041 print columnate who($pkg || $PACKAGE, $re);
1046 my ($pack, $qualified) = @_;
1048 my @own = $qualified ? grep {
1050 } map { "$pack\::$_" } keys %{$pack.'::'}
1052 defined *{"$pack\::$_"}{CODE}
1053 } keys %{$pack.'::'};
1054 (@own, defined *{$pack.'::ISA'}{ARRAY}
1055 ? (map methods($_, $qualified), @{$pack.'::ISA'}) : ());
1060 my ($x, $re) = split ' ', shift;
1064 $x = $REPL{eval}->("ref $x");
1069 print columnate sort { $a cmp $b } grep /$re/, methods $x;
1074 my ($val, $cur) = @_;
1076 length($val) ? $val : !$cur;
1081 $WANTARRAY = as_boolean shift, $WANTARRAY;
1086 chomp(my $p = shift);
1090 # my $ecmd = '(setq sepia-eval-package "'.$p.'")';
1091 # print ";;;###".length($ecmd)."\n$ecmd\n";
1093 warn "Can't go to package $p -- doesn't exist!\n";
1104 do $INC{'Sepia.pm'};
1106 print "Restart failed:\n$@\n";
1108 $REPL_LEVEL = 0; # ok?
1123 # local $PACKAGE = $pkg || $PACKAGE;
1126 $buf = 'scalar($buf)';
1128 my $ctx = join(',', keys %{$STRICT->get_context('_')});
1129 $ctx = $ctx ? "my ($ctx);" : '';
1130 $buf = eval "sub { package $PACKAGE; use strict; $ctx $buf }";
1132 print "ERROR\n$@\n";
1135 $STRICT->call($buf);
1137 $buf = "do { package $PACKAGE; no strict; $buf }";
1155 } elsif (-f "t/$buf") {
1159 find({ no_chdir => 1,
1161 push @files, $_ if /\.t$/;
1162 }}, Cwd::getcwd() =~ /t\/?$/ ? '.' : './t');
1165 # XXX: this is cribbed from an EU::MM-generated Makefile.
1166 system $^X, qw(-MExtUtils::Command::MM -e),
1167 "test_harness(0, 'blib/lib', 'blib/arch')", @files;
1169 print "No test files for '$buf' in ", Cwd
::getcwd
, "\n";
1175 my ($file) = split ' ', shift;
1176 $file ||= "$ENV{HOME}/.sepia-save";
1177 load
(retrieve
$file);
1182 my ($re, $file) = split ' ', shift;
1184 $file ||= "$ENV{HOME}/.sepia-save";
1185 store save
($re), $file;
1190 (my $name = shift) =~ s!::!/!g;
1192 print STDERR
"full reload $name\n";
1193 my %save_inc = %INC;
1196 my @ret = keys %INC;
1197 while (my ($k, $v) = each %save_inc) {
1203 sub repl_full_reload
1205 chomp (my $pat = shift);
1206 my @x = full_reload
$pat;
1207 print "Reloaded: @x\n";
1212 chomp (my $pat = shift);
1213 if ($pat =~ /^\/(.*)\
/?$/) {
1231 if (exists $INC{$pat}) {
1233 eval 'require $mod';
1235 print "Reloaded $mod.\n"
1237 print "$mod not loaded.\n"
1242 ## Collects warnings for REPL
1255 print ';;;'.length($tmp)."\n$tmp\n";
1259 print "warning: $_\n";
1268 I need user feedback! Please send questions or comments to seano\@cpan.org.
1269 Sepia version $Sepia::VERSION.
1270 Type ",h" for help, or ",q" to quit.
1276 Execute a command interpreter on standard input and standard output.
1277 If you want to use different descriptors, localize them before
1278 calling C<repl()>. The prompt has a few bells and whistles, including:
1282 =item Obviously-incomplete lines are treated as multiline input (press
1283 'return' twice or 'C-c' to discard).
1285 =item C<die> is overridden to enter a debugging repl at the point
1290 Behavior is controlled in part through the following package-globals:
1294 =item C<$PACKAGE> -- evaluation package
1296 =item C<$PRINTER> -- result printer (default: dumper)
1298 =item C<$PS1> -- the default prompt
1300 =item C<$STRICT> -- whether 'use strict' is applied to input
1302 =item C<$WANTARRAY> -- evaluation context
1304 =item C<$PRINT_PRETTY> -- format some output nicely (default = 1)
1306 Format some values nicely, independent of $PRINTER. Currently, this
1307 displays arrays of scalars as columns.
1309 =item C<$REPL_LEVEL> -- level of recursive repl() calls
1311 If zero, then initialization takes place.
1313 =item C<%REPL> -- maps shortcut names to handlers
1315 =item C<%REPL_DOC> -- maps shortcut names to documentation
1317 =item C<%REPL_SHORT> -- maps shortcut names to brief usage
1326 if ($REPL_LEVEL == 0) {
1328 -f
"$ENV{HOME}/.sepiarc" and do "$ENV{HOME}/.sepiarc";
1329 warn ".sepiarc: $@\n" if $@
;
1331 local $REPL_LEVEL = $REPL_LEVEL + 1;
1337 my $nextrepl = sub { $sigged = 1; };
1340 local *CORE
::GLOBAL
::die = \
&Sepia
::Debug
::die;
1341 local *CORE
::GLOBAL
::warn = \
&Sepia
::Debug
::warn;
1343 Sepia
::Debug
::add_repl_commands
;
1344 repl_banner
if $REPL_LEVEL == 1;
1346 my @sigs = qw(INT TERM PIPE ALRM);
1348 $SIG{$_} = $nextrepl for @sigs;
1349 repl
: while (defined(my $in = <STDIN
>)) {
1359 if ($buf =~ /^<<(\d+)\n(.*)/) {
1364 while ($len && defined($tmp = read STDIN
, $buf, $len, length $buf)) {
1369 ## Only install a magic handler if no one else is playing.
1370 local $SIG{__WARN__
} = $SIG{__WARN__
};
1372 unless ($SIG{__WARN__
}) {
1373 $SIG{__WARN__
} = 'Sepia::sig_warn';
1377 # repeat last interactive command
1383 if ($buf =~ /^,(\S+)\s*(.*)/s) {
1384 ## Inspector shortcuts
1386 if (exists $Sepia::RK
{$short}) {
1390 $Sepia::REPL
{$Sepia::RK
{$short}}->($arg, wantarray);
1392 if (grep /^$short/, keys %Sepia::REPL
) {
1393 print "Ambiguous shortcut '$short': ",
1394 join(', ', sort grep /^$short/, keys %Sepia::REPL
),
1397 print "Unrecognized shortcut '$short'\n";
1405 @res = $REPL{eval}->($buf);
1408 ## Always return results for an eval request
1409 Sepia
::printer \
@res, wantarray;
1410 Sepia
::printer
[$@
], wantarray;
1411 # print_warnings $ISEVAL;
1414 } elsif ($@
=~ /(?:at|before) EOF(?:$| at)/m) {
1415 ## Possibly-incomplete line
1417 print "Error:\n$@\n*** cancel ***\n", prompt
;
1424 # $@ =~ s/(.*) at eval .*/$1/;
1425 # don't complain if we're abandoning execution
1426 # from the debugger.
1427 unless (ref $@
eq 'Sepia::Debug') {
1429 print "\n" unless $@
=~ /\n\z/;
1437 if ($buf !~ /;\s*$/ && $buf !~ /^,/) {
1438 ## Be quiet if it ends with a semicolon, or if we
1439 ## executed a shortcut.
1440 Sepia
::printer \
@res, wantarray;
1446 wantarray ?
@REPL_RESULT : $REPL_RESULT[0]
1451 tolisp
($REPL{eval}->(shift));
1454 =head2 C<$status = html_module_list([$file [, $prefix]])>
1456 Generate an HTML list of installed modules, looking inside of
1457 packages. If C<$prefix> is missing, uses "about://perldoc/". If
1458 $file is given, write the result to $file; otherwise, return it as a
1461 =head2 C<$status = html_package_list([$file [, $prefix]])>
1463 Generate an HTML list of installed top-level modules, without looking
1464 inside of packages. If C<$prefix> is missing, uses
1465 "about://perldoc/". $file is the same as for C<html_module_list>.
1469 sub html_module_list
1471 my ($file, $base) = @_;
1472 $base ||= 'about://perldoc/';
1474 return unless $inst;
1476 open OUT
, ">", $file || \
$out or return;
1477 print OUT
"<html><body>";
1480 for (package_list
) {
1481 push @
{$ns{$1}}, $_ if /^([^:]+)/;
1483 # Handle core modules.
1485 undef $fs{$_} for map {
1486 s/.*man.\///; s|/|::|g
; s/\.\d(?:pm)?$//; $_
1488 /\.\d(?:pm)?$/ && !/man1/ && !/usr\/bin
/ # && !/^(?
:\
/|perl)/
1489 } $inst->files('Perl');
1490 my @fs = sort keys %fs;
1491 print OUT
qq{<h2
>Core Modules
</h2
><ul
>};
1493 print OUT
qq{<li
><a href
="$base$_">$_</a
>};
1495 print OUT
'</ul><h2>Installed Modules</h2><ul>';
1498 for (sort keys %ns) {
1499 next if $_ eq 'Perl'; # skip Perl core.
1500 print OUT
qq{<li
><b
>$_</b
><ul
>} if @
{$ns{$_}} > 1;
1501 for (sort @
{$ns{$_}}) {
1503 undef $fs{$_} for map {
1504 s/.*man.\///; s|/|::|g
; s/\.\d(?:pm)?$//; $_
1506 /\.\d(?:pm)?$/ && !/man1/
1508 my @fs = sort keys %fs;
1509 next unless @fs > 0;
1511 print OUT
qq{<li
><a href
="$base$fs[0]">$fs[0]</a
>};
1513 print OUT
qq{<li
>$_<ul
>};
1515 print OUT
qq{<li
><a href
="$base$_">$_</a
>};
1520 print OUT
qq{</ul
>} if @
{$ns{$_}} > 1;
1523 print OUT
"</ul></body></html>\n";
1528 sub html_package_list
1530 my ($file, $base) = @_;
1531 return unless inst
();
1532 $base ||= 'about://perldoc/';
1534 open OUT
, ">", $file || \
$out or return;
1535 print OUT
"<html><body><ul>";
1538 for (package_list
) {
1539 push @
{$ns{$1}}, $_ if /^([^:]+)/;
1541 for (sort keys %ns) {
1542 if (@
{$ns{$_}} == 1) {
1544 qq{<li
><a href
="$base$ns{$_}[0]">$ns{$_}[0]</a
>};
1546 print OUT
qq{<li
><b
>$_</b
><ul
>};
1547 print OUT
qq{<li
><a href
="$base$_">$_</a
>}
1548 for sort @
{$ns{$_}};
1549 print OUT
qq{</ul
>};
1552 print OUT
"</ul></body></html>\n";
1562 for (package_list
) {
1563 undef $ret{$_} if /$re/;
1565 undef $ret{$_} for map {
1566 s/.*man.\///; s|/|::|g
; s/\.\d(?:pm)?$//; $_
1568 /\.\d(?:pm)?$/ && !/man1/ && !/usr\/bin
/ && /$re/
1569 } $inst->files('Perl');
1578 See the README file included with the distribution.
1582 Sepia's public GIT repository is located at L<http://repo.or.cz/w/sepia.git>.
1584 There are several modules for Perl development in Emacs on CPAN,
1585 including L<Devel::PerlySense> and L<PDE>. For a complete list, see
1586 L<http://emacswiki.org/cgi-bin/wiki/PerlLanguage>.
1590 Sean O'Rourke, E<lt>seano@cpan.orgE<gt>
1592 Bug reports welcome, patches even more welcome.
1596 Copyright (C) 2005-2009 Sean O'Rourke. All rights reserved, some
1597 wrongs reversed. This module is distributed under the same terms as