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.
23 Sepia is a set of features to make Emacs a better tool for Perl
24 development. This package contains the Perl side of the
25 implementation, including all user-serviceable parts (for the
26 cross-referencing facility see L<Sepia::Xref>). This document is
27 aimed as Sepia developers; for user documentation, see
28 L<Sepia.html> or L<sepia.info>.
30 Though not intended to be used independent of the Emacs interface, the
31 Sepia module's functionality can be used through a rough procedural
39 use Sepia
::Debug
; # THIS TURNS ON DEBUGGING INFORMATION!
41 use Scalar
::Util
'looks_like_number';
44 use Storable
qw(store retrieve);
46 use vars
qw($PS1 %REPL %RK %REPL_DOC %REPL_SHORT %PRINTER
47 @REPL_RESULT @res $REPL_LEVEL $REPL_QUIT $PACKAGE
48 $WANTARRAY $PRINTER $STRICT $PRINT_PRETTY $ISEVAL
49 $LAST_INPUT @PRE_EVAL @POST_EVAL @PRE_PROMPT);
52 eval { use List::Util 'max' };
57 $ret = $_ if $_ > $ret;
66 Like Emacs, Sepia's behavior can be modified by placing functions on
67 various hooks (arrays). Hooks can be manipulated by the following
72 =item C<add_hook(@hook, @functions)> -- Add C<@functions> to C<@hook>.
74 =item C<remove_hook(@hook, @functions)> -- Remove named C<@functions> from C<@hook>.
76 =item C<run_hook(@hook)> -- Run the functions on the named hook.
78 Each function is called with no arguments in an eval {} block, and
79 its return value is ignored.
83 Sepia currently defines the following hooks:
87 =item C<@PRE_PROMPT> -- Called immediately before the prompt is printed.
89 =item C<@PRE_EVAL> -- Called immediately before evaluating user input.
91 =item C<@POST_EVAL> -- Called immediately after evaluating user input.
110 push @$hook, $h unless grep $h eq $_, @$hook;
117 @$hook = grep { my $x = $_; !grep $_ eq $x, @$hook } @$hook;
122 Sepia tries hard to come up with a list of completions.
126 =item C<$re = _apropos_re($pat)>
128 Create a completion expression from user input.
134 # Do that crazy multi-word identifier completion thing:
136 return qr/.*/ if $re eq '';
139 s/(?:^|(?<=[A-Za-z\d]))(([^A-Za-z\d])\2*)/[A-Za-z\\d]*$2+/g;
141 } split /:+/, $re, -1;
143 if ($re !~ /[^\w\d_^:]/) {
144 $re =~ s/(?<=[A-Za-z\d])(([^A-Za-z\d])\2*)/[A-Za-z\\d]*$2+/g;
152 %sigil = qw(ARRAY @ SCALAR $ HASH %);
155 =item C<$val = filter_untyped>
157 Return true if C<$_> is the name of a sub, file handle, or package.
159 =item C<$val = filter_typed $type>
161 Return true if C<$_> is the name of something of C<$type>, which
162 should be either a glob slot name (e.g. SCALAR) or the special value
163 "VARIABLE", meaning an array, hash, or scalar.
171 local $_ = /^::/ ?
$_ : "::$_";
172 defined *{$_}{CODE
} || defined *{$_}{IO
} || (/::$/ && %$_);
175 ## XXX: Careful about autovivification here! Specifically:
176 ## defined *FOO{HASH} # => ''
177 ## defined %FOO # => ''
178 ## defined *FOO{HASH} # => 1
183 local $_ = /^::/ ?
$_ : "::$_";
184 if ($type eq 'SCALAR') {
186 } elsif ($type eq 'VARIABLE') {
187 defined $$_ || defined *{$_}{HASH
} || defined *{$_}{ARRAY
};
193 =item C<$re_out = maybe_icase $re_in>
195 Make C<$re_in> case-insensitive if it looks like it should be.
202 return '' if $ch eq '';
203 $ch =~ /[A-Z]/ ?
$ch : '['.uc($ch).$ch.']';
206 =item C<@res = all_abbrev_completions $pattern>
208 Find all "abbreviated completions" for $pattern.
212 sub all_abbrev_completions
214 use vars
'&_completions';
215 local *_completions
= sub {
217 my ($stash, @e) = @_;
218 my $ch = '[A-Za-z0-9]*';
219 my $re1 = "^".maybe_icase
($e[0]).$ch.join('', map {
220 '_'.maybe_icase
($_).$ch
223 my $re2 = maybe_icase
$e[0];
224 $re2 = qr/^$re2.*::$/;
225 my @ret = grep !/::$/ && /$re1/, keys %{$stash};
226 my @pkgs = grep /$re2/, keys %{$stash};
227 (map("$stash$_", @ret),
228 @e > 1 ?
map { _completions
"$stash$_", @e[1..$#e] } @pkgs :
229 map { "$stash$_" } @pkgs)
231 map { s/^:://; $_ } _completions
('::', split //, shift);
236 my ($icase, $re) = @_;
238 $icase ?
qr/^$re.*$/i : qr/^$re.*$/;
243 my $icase = $_[0] !~ /[A-Z]/;
244 my @parts = split /:+/, shift, -1;
245 my $re = apropos_re
$icase, pop @parts;
246 use vars
'&_completions';
247 local *_completions
= sub {
251 map { "$stash$_" } grep /$re/, keys %{$stash};
253 my $re2 = $icase ?
qr/^$_[0].*::$/i : qr/^$_[0].*::$/;
254 my @pkgs = grep /$re2/, keys %{$stash};
255 map { _completions
"$stash$_", @_[1..$#_] } @pkgs
258 map { s/^:://; $_ } _completions
('::', @parts);
261 =item C<@res = filter_exact_prefix @names>
263 Filter exact matches so that e.g. "A::x" completes to "A::xx" when
264 both "Ay::xx" and "A::xx" exist.
268 sub filter_exact_prefix
270 my @parts = split /:+/, shift, -1;
273 my $pre = shift @parts;
274 while (@parts && (@tmp = grep /^\Q$pre\E(?:::|$)/, @res)) {
276 $pre .= '::'.shift @parts;
281 =item C<@res = lexical_completions $type, $str, $sub>
283 Find lexicals of C<$sub> (or a parent lexical environment) of type
284 C<$type> matching C<$str>.
288 sub lexical_completions
290 eval { require PadWalker
; import PadWalker
'peek_sub' };
291 # "internal" function, so don't warn on failure
293 *lexical_completions
= sub {
294 my ($type, $str, $sub) = @_;
295 $sub = "$PACKAGE\::$sub" unless $sub =~ /::/;
296 # warn "Completing $str of type $type in $sub\n";
298 return unless defined *{$sub}{CODE
};
299 my $pad = peek_sub
(\
&$sub);
301 map { s/^[\$\@&\%]//;$_ } grep /^\Q$type$str\E/, keys %$pad;
303 map { s/^[\$\@&\%]//;$_ } grep /^.\Q$str\E/, keys %$pad;
306 goto &lexical_completions
;
309 =item C<@compls = completions($string [, $type])>
311 Find a list of completions for C<$string> with glob type C<$type>,
312 which may be "SCALAR", "HASH", "ARRAY", "CODE", "IO", or the special
313 value "VARIABLE", which means either scalar, hash, or array.
314 Completion operates on word subparts separated by [:_], so
315 e.g. "S:m_w" completes to "Sepia::my_walksymtable".
317 =item C<@compls = method_completions($expr, $string [,$eval])>
319 Complete among methods on the object returned by C<$expr>. The
320 C<$eval> argument, if present, is a function used to do the
321 evaluation; the default is C<eval>, but for example the Sepia REPL
322 uses C<Sepia::repl_eval>. B<Warning>: Since it has to evaluate
323 C<$expr>, method completion can be extremely problematic. Use with
330 my ($type, $str, $sub) = @_;
332 my %h = qw(@ ARRAY % HASH & CODE * IO $ SCALAR);
334 @rh{values %h} = keys %h;
336 $t = $type ?
$rh{$type} : '';
338 if ($sub && $type ne '') {
339 @ret = lexical_completions
$t, $str, $sub;
343 $type ? filter_typed
$type : filter_untyped
344 } all_completions
$str;
346 if (!@ret && $str !~ /:/) {
348 $type ? filter_typed
$type : filter_untyped
349 } all_abbrev_completions
$str;
351 @ret = map { s/^:://; "$t$_" } filter_exact_prefix
$str, @ret;
352 # ## XXX: Control characters, $", and $1, etc. confuse Emacs, so
355 length $_ > 0 && !/^\d+$/ && !/^[^\w\d_]$/ && !/^_</ && !/^[[:cntrl:]]/
359 sub method_completions
361 my ($x, $fn, $eval) = @_;
364 $eval ||= 'CORE::eval';
366 return unless ($x =~ /^\$/ && ($x = $eval->("ref($x)")))
367 || $eval->('%'.$x.'::');
369 my $re = _apropos_re
$fn;
370 ## Filter out overload methods "(..."
371 return sort { $a cmp $b } map { s/.*:://; $_ }
372 grep { defined *{$_}{CODE
} && /::$re/ && !/\(/ }
377 =item C<@matches = apropos($name [, $is_regex])>
379 Search for function C<$name>, either in all packages or, if C<$name>
380 is qualified, only in one package. If C<$is_regex> is true, the
381 non-package part of C<$name> is a regular expression.
385 sub my_walksymtable
(&*)
391 &$f for keys %$stash;
392 _walk
("$stash$_") for grep /(?<!main)::$/, keys %$stash;
399 my ($it, $re, @types) = @_;
402 $stashp = grep /STASH/, @types;
403 @types = grep !/STASH/, @types;
408 if ($it =~ /^(.*::)([^:]+)$/) {
409 my ($stash, $name) = ($1, $2);
414 my $name = qr/^$name/;
419 my $stashnm = "$stash$_";
423 defined($_ eq 'SCALAR' ?
$$stashnm : *{$stashnm}{$_})
427 defined &$it ?
$it : ();
431 my $findre = $re ?
qr/$it/ : qr/^\Q$it\E$/;
433 push @ret, "$stash$_" if /$findre/;
435 map { s/^:*(?:main:+)*//;$_ } @ret;
441 =head2 Module information
445 =item C<@names = mod_subs($pack)>
447 Find subs in package C<$pack>.
455 my $stash = \
%{"$p\::"};
457 grep { defined &{"$p\::$_"} } keys %$stash;
461 =item C<@decls = mod_decls($pack)>
463 Generate a list of declarations for all subroutines in package
474 my $proto = prototype(\
&{"$pack\::$sn"});
475 $proto = defined($proto) ?
"($proto)" : '';
478 return wantarray ?
@ret : join '', @ret;
481 =item C<$info = module_info($module, $type)>
483 Emacs-called function to get module information.
489 eval { require Module
::Info
; import Module
::Info
};
497 $info = Module
::Info
->new_from_file($m);
499 (my $file = $m) =~ s
|::|/|g
;
501 if (exists $INC{$file}) {
502 $info = Module
::Info
->new_from_loaded($m);
504 $info = Module
::Info
->new_from_module($m);
515 =item C<$file = mod_file($mod)>
517 Find the likely file owner for module C<$mod>.
525 while ($m && !exists $INC{"$m.pm"}) {
526 $m =~ s
#(?:^|/)[^/]+$##;
528 $m ?
$INC{"$m.pm"} : undef;
531 =item C<@mods = package_list>
533 Gather a list of all distributions on the system.
541 eval 'require ExtUtils::Installed';
542 $INST = new ExtUtils
::Installed
;
549 sort { $a cmp $b } inst
()->modules;
552 =item C<@mods = module_list>
554 Gather a list of all packages (.pm files, really) installed on the
555 system, grouped by distribution. XXX UNUSED
561 @_ = package_list
unless @_;
562 my $incre = join '|', map quotemeta, @INC;
563 $incre = qr
|(?
:$incre)/|;
567 s/$incre//; s
|/|::|g
;$_
568 } grep /\.pm$/, $inst->files($_)]
572 =item C<@mods = doc_list>
574 Gather a list of all documented packages (.?pm files, really)
575 installed on the system, grouped by distribution. XXX UNUSED
583 @_ = package_list
unless @_;
587 s/.*man.\///; s|/|::|g
;s/\..?pm//; $_
588 } grep /\..pm$/, $inst->files($_)]
592 =head2 Miscellaneous functions
596 =item C<$v = core_version($module)>
602 eval { require Module
::CoreList
};
606 *core_version
= sub { Module
::CoreList
->first_release(@_) };
611 =item C<[$file, $line, $name] = location($name)>
613 Return a [file, line, name] triple for function C<$name>.
621 if (my ($pfx, $name) = /^([\%\$\@]?)(.+)/) {
623 warn "Sorry -- can't lookup variables.";
625 # XXX: svref_2object only seems to work with a package
626 # tacked on, but that should probably be done elsewhere...
627 $name = 'main::'.$name unless $name =~ /::/;
628 my $cv = B
::svref_2object
(\
&{$name});
629 if ($cv && defined($cv = $cv->START) && !$cv->isa('B::NULL')) {
630 my ($file, $line) = ($cv->file, $cv->line);
631 if ($file !~ /^\//) {
633 if (!ref $_ && -f
"$_/$file") {
639 my ($shortname) = $name =~ /^(?:.*::)([^:]+)$/;
640 return [Cwd
::abs_path
($file), $line, $shortname || $name]
648 =item C<lexicals($subname)>
650 Return a list of C<$subname>'s lexical variables. Note that this
651 includes all nested scopes -- I don't know if or how Perl
652 distinguishes inner blocks.
658 my $cv = B
::svref_2object
(\
&{+shift});
659 return unless $cv && ($cv = $cv->PADLIST);
660 my ($names, $vals) = $cv->ARRAY;
662 my $name = $_->PV; $name =~ s/\0.*$//; $name
663 } grep B
::class($_) ne 'SPECIAL', $names->ARRAY;
666 =item C<$lisp = tolisp($perl)>
668 Convert a Perl scalar to some ELisp equivalent.
674 my $thing = @_ == 1 ?
shift : \
@_;
677 if (!defined $thing) {
679 } elsif (looks_like_number
$thing) {
682 ## XXX Elisp and perl have slightly different
683 ## escaping conventions, so we do this crap instead.
684 $thing =~ s/["\\]/\\$1/g;
687 } elsif ($t eq 'GLOB') {
688 (my $name = $$thing) =~ s/\*main:://;
690 } elsif ($t eq 'ARRAY') {
691 '(' . join(' ', map { tolisp
($_) } @
$thing).')'
692 } elsif ($t eq 'HASH') {
693 '(' . join(' ', map {
694 '(' . tolisp
($_) . " . " . tolisp
($thing->{$_}) . ')'
696 } elsif ($t eq 'Regexp') {
697 "'(regexp . \"" . quotemeta($thing) . '")';
698 # } elsif ($t eq 'IO') {
704 =item C<printer(\@res, $wantarray)>
706 Print C<@res> appropriately on the current filehandle. If C<$ISEVAL>
707 is true, use terse format. Otherwise, use human-readable format,
708 which can use either L<Data::Dumper>, L<YAML>, or L<Data::Dump>.
714 eval { require Data
::Dumper
};
715 local $Data::Dumper
::Deparse
= 1;
716 local $Data::Dumper
::Indent
= 0;
718 my $thing = @res > 1 ? \
@res : $res[0];
720 $_ = Data
::Dumper
::Dumper
($thing);
724 if (length $_ > ($ENV{COLUMNS
} || 80)) {
725 $Data::Dumper
::Indent
= 1;
727 $_ = Data
::Dumper
::Dumper
($thing);
740 eval { require YAML
};
742 $PRINTER{dumper
}->();
748 eval { require Data
::Dump
};
750 $PRINTER{dumper
}->();
752 Data
::Dump
::dump(\
@res);
761 $PRINTER{dumper
}->();
763 my $ret = new IO
::Scalar
;
764 my $out = select $ret;
765 Devel
::Peek
::Dump
(@res == 1 ?
$res[0] : \
@res);
775 my ($wantarray) = @_;
778 $::__
= @res == 1 ?
$res[0] : [@res];
782 } elsif (@res == 1 && UNIVERSAL
::can
($res[0], '()')) {
785 } elsif (!$ISEVAL && $PRINT_PRETTY && @res > 1 && !grep ref, @res) {
786 $res = columnate
(@res);
790 $res = $PRINTER{$PRINTER}->();
793 print ';;;', length $res, "\n$res\n";
807 =item C<prompt()> -- Print the REPL prompt.
813 run_hook
@PRE_PROMPT;
814 "$PACKAGE ".($WANTARRAY ?
'@' : '$').$PS1
820 Data
::Dumper
->Dump([$_[0]], [$_[1]]);
824 =item C<$flowed = flow($width, $text)> -- Flow C<$text> to at most C<$width> columns.
831 my $n1 = int(2*$n/3);
833 s/(.{$n1,$n}) /$1\n/g;
843 =item C<load \@keyvals> -- Load persisted data in C<@keyvals>.
845 =item C<$ok = saveable $name> -- Return whether C<$name> is saveable.
847 Saving certain magic variables leads to badness, so we avoid them.
849 =item C<\@kvs = save $re> -- Return a list of name/value pairs to save.
860 *{$_->[0]} = $_->[1];
865 undef @BADVARS{qw(%INC @INC %SIG @ISA %ENV @ARGV)};
871 return !/^.[^c-zA-Z]$/ # single-letter stuff (match vars, $_, etc.)
872 && !/^.[\0-\060]/ # magic weirdness.
873 && !/^._</ # debugger info
874 && !exists $BADVARS{$_}; # others.
881 $re = qr/(?:^|::)$re/;
882 no strict; # no kidding...
885 || $stash =~ /^(?:::)?(?:warnings|Config|strict|B)\b/;
887 my $name = "$stash$_";
888 if (defined ${$name} and saveable '$'.$_) {
889 push @save, [$name, \$$name];
891 if (defined *{$name}{HASH} and saveable '%'.$_) {
892 push @save, [$name, \%{$name}];
894 if (defined *{$name}{ARRAY} and saveable '@'.$_) {
895 push @save, [$name, \@{$name}];
899 print STDERR "$_->[0] " for @save;
904 =head2 REPL shortcuts
906 The function implementing built-in REPL shortcut ",X" is named C<repl_X>.
910 =item C<define_shortcut $name, $sub [, $doc [, $shortdoc]]>
912 Define $name as a shortcut for function $sub.
918 my ($name, $doc, $short, $fn);
924 ($name, $fn, $doc) = @_;
927 ($name, $fn, $short, $doc) = @_;
930 $REPL_DOC{$name} = $doc;
931 $REPL_SHORT{$name} = $short;
934 =item C<define_shortcuts()>
936 Define the default REPL shortcuts.
942 define_shortcut 'help', \&Sepia::repl_help,
944 'Display help on all commands, or just CMD.';
945 define_shortcut 'cd', \&Sepia::repl_chdir,
946 'cd DIR', 'Change directory to DIR';
947 define_shortcut 'pwd', \&Sepia::repl_pwd,
948 'Show current working directory';
949 define_shortcut 'methods', \&Sepia::repl_methods,
951 'List methods for reference or package X, matching optional pattern RE';
952 define_shortcut 'package', \&Sepia::repl_package,
953 'package PKG', 'Set evaluation package to PKG';
954 define_shortcut 'who', \&Sepia::repl_who,
956 'List variables and subs in PKG matching optional pattern RE.';
957 define_shortcut 'wantarray', \&Sepia::repl_wantarray,
958 'wantarray [0|1]', 'Set or toggle evaluation context';
959 define_shortcut 'format', \&Sepia::repl_format,
960 'format [TYPE]', "Set output formatter to TYPE (one of 'dumper', 'dump', 'yaml', 'plain'; default: 'dumper'), or show current type.";
961 define_shortcut 'strict', \&Sepia::repl_strict,
962 'strict [0|1]', 'Turn \'use strict\' mode on or off';
963 define_shortcut 'quit', \&Sepia::repl_quit,
965 define_shortcut 'restart', \&Sepia::repl_restart,
966 'Reload Sepia.pm and relaunch the REPL.';
967 define_shortcut 'shell', \&Sepia::repl_shell,
968 'shell CMD ...', 'Run CMD in the shell';
969 define_shortcut 'eval', \&Sepia::repl_eval,
970 'eval EXP', '(internal)';
971 define_shortcut 'size', \&Sepia::repl_size,
973 'List total sizes of objects in PKG matching optional pattern RE.';
974 define_shortcut define => \&Sepia::repl_define,
975 'define NAME [\'DOC\'] BODY',
976 'Define NAME as a shortcut executing BODY';
977 define_shortcut undef => \&Sepia::repl_undef,
978 'undef NAME', 'Undefine shortcut NAME';
979 define_shortcut test => \&Sepia::repl_test,
980 'test FILE...', 'Run tests interactively.';
981 define_shortcut load => \&Sepia::repl_load,
982 'load [FILE]', 'Load state from FILE.';
983 define_shortcut save => \&Sepia::repl_save,
984 'save [PATTERN [FILE]]', 'Save variables matching PATTERN to FILE.';
985 define_shortcut reload => \&Sepia::repl_reload,
986 'reload [MODULE | /RE/]', 'Reload MODULE, or all modules matching RE.';
987 define_shortcut freload => \&Sepia::repl_full_reload,
988 'freload MODULE', 'Reload MODULE and all its dependencies.';
989 define_shortcut time => \&Sepia::repl_time,
990 'time [0|1]', 'Print timing information for each command.';
993 =item C<repl_strict([$value])>
995 Toggle strict mode. Requires L<Lexical::Persistence>.
1001 eval { require Lexical::Persistence; import Lexical::Persistence };
1003 print "Strict mode requires Lexical::Persistence.\n";
1005 *repl_strict = sub {
1006 my $x = as_boolean(shift, $STRICT);
1007 if ($x && !$STRICT) {
1008 $STRICT = new Lexical::Persistence;
1019 eval { require Devel::Size };
1021 print "Size requires Devel::Size.\n";
1023 *Sepia::repl_size = sub {
1025 ## XXX: C&P from repl_who:
1026 my ($pkg, $re) = split ' ', shift || '';
1027 if ($pkg =~ /^\/(.*)\/?$/) {
1033 } elsif (!$re && !%{$pkg.'::'}) {
1037 my @who = who($pkg, $re);
1038 my $len = max(3, map { length } @who) + 4;
1039 my $fmt = '%-'.$len."s%10d\n";
1040 # print "$pkg\::/$re/\n";
1041 print 'Var', ' ' x ($len + 2), "Bytes\n";
1042 print '-' x ($len-4), ' ' x 9, '-' x 5, "\n";
1045 next unless /^[\$\@\%\&]/; # skip subs.
1046 next if $_ eq '%SIG';
1047 $res{$_} = eval "no strict; package $pkg; Devel::Size::total_size \\$_;";
1049 for (sort { $res{$b} <=> $res{$a} } keys %res) {
1050 printf $fmt, $_, $res{$_};
1057 =item C<repl_time([$value])>
1059 Toggle command timing.
1063 my ($time_res, $TIME);
1064 sub time_pre_prompt_bsd
1066 printf "(%.2gr, %.2gu, %.2gs) ", @{$time_res} if defined $time_res;
1069 sub time_pre_prompt_plain
1071 printf "(%.2gs) ", $time_res if defined $time_res;
1076 $TIME = as_boolean(shift, $TIME);
1078 print STDERR "Removing time hook.\n";
1079 remove_hook @PRE_PROMPT, 'Sepia::time_pre_prompt';
1080 remove_hook @PRE_EVAL, 'Sepia::time_pre_eval';
1081 remove_hook @POST_EVAL, 'Sepia::time_post_eval';
1084 print STDERR "Adding time hook.\n";
1085 add_hook @PRE_PROMPT, 'Sepia::time_pre_prompt';
1086 add_hook @PRE_EVAL, 'Sepia::time_pre_eval';
1087 add_hook @POST_EVAL, 'Sepia::time_post_eval';
1088 my $has_bsd = eval { use BSD::Resource 'getrusage';1 };
1089 my $has_hires = eval { use Time::HiRes qw(gettimeofday tv_interval);1 };
1091 if ($has_bsd) { # sweet! getrusage!
1092 my ($user, $sys, $real);
1093 *time_pre_eval
= sub {
1095 ($user, $sys) = getrusage
;
1096 $real = $has_hires ?
[gettimeofday
] : $user+$sys;
1098 *time_post_eval
= sub {
1099 my ($u2, $s2) = getrusage
;
1100 $time_res = [$has_hires ?
(tv_interval
$real, [gettimeofday
])
1101 : $s2 + $u2 - $real,
1102 ($u2 - $user), ($s2 - $sys)];
1104 *time_pre_prompt
= *time_pre_prompt_bsd
;
1105 } elsif ($has_hires) { # at least we have msec...
1106 *time_pre_eval
= sub {
1108 $t0 = [gettimeofday
];
1110 *time_post_eval
= sub {
1111 $time_res = tv_interval
($t0, [gettimeofday
]);
1113 *time_pre_prompt
= *time_pre_prompt_plain
;
1115 *time_pre_eval
= sub {
1119 *time_post_eval
= sub {
1120 $time_res = (time - $t0);
1122 *time_pre_prompt
= *time_pre_prompt_plain
;
1128 my $width = $ENV{COLUMNS
} || 80;
1130 if ($args =~ /\S/) {
1133 my $full = $RK{$args};
1135 my $short = $REPL_SHORT{$full};
1136 my $flow = flow
($width - length $short - 4, $REPL_DOC{$full});
1137 $flow =~ s/(.)\n/"$1\n".(' 'x (4 + length $short))/eg;
1138 print "$short $flow\n";
1140 print "$args: no such command\n";
1143 my $left = 1 + max
map length, values %REPL_SHORT;
1144 print "REPL commands (prefixed with ','):\n";
1146 for (sort keys %REPL) {
1147 my $flow = flow
($width - $left, $REPL_DOC{$_});
1148 $flow =~ s/(.)\n/"$1\n".(' ' x $left)/eg;
1149 printf "%-${left}s%s\n", $REPL_SHORT{$_}, $flow;
1157 my ($name, $doc, $body);
1158 if (/^\s*(\S+)\s+'((?:[^'\\]|\\.)*)'\s+(.+)/) {
1159 ($name, $doc, $body) = ($1, $2, $3);
1160 } elsif (/^\s*(\S+)\s+(\S.*)/) {
1161 ($name, $doc, $body) = ($1, $2, $2);
1163 print "usage: define NAME ['doc'] BODY...\n";
1166 my $sub = eval "sub { do { $body } }";
1168 print "usage: define NAME ['doc'] BODY...\n\t$@\n";
1171 define_shortcut
$name, $sub, $doc;
1172 %RK = abbrev
keys %REPL;
1180 my $full = $RK{$name};
1182 delete $REPL{$full};
1183 delete $REPL_SHORT{$full};
1184 delete $REPL_DOC{$full};
1185 %RK = abbrev
keys %REPL;
1187 print "$name: no such shortcut.\n";
1196 print "printer = $PRINTER, pretty = @{[$PRINT_PRETTY ? 1 : 0]}\n";
1198 my %formats = abbrev
keys %PRINTER;
1199 if (exists $formats{$t}) {
1200 $PRINTER = $formats{$t};
1202 warn "No such format '$t' (dumper, dump, yaml, plain).\n";
1209 chomp(my $dir = shift);
1210 $dir =~ s/^~\//$ENV{HOME
}\
//;
1211 $dir =~ s/\$HOME/$ENV{HOME}/;
1214 my $ecmd = '(cd "'.Cwd
::getcwd
().'")';
1215 print ";;;###".length($ecmd)."\n$ecmd\n";
1217 warn "Can't chdir\n";
1223 print Cwd
::getcwd
(), "\n";
1226 =item C<who($package [, $re])>
1228 List variables and functions in C<$package> matching C<$re>, or all
1229 variables if C<$re> is absent.
1235 my ($pack, $re_str) = @_;
1237 my $re = qr/$re_str/;
1239 if ($re_str =~ /^[\$\@\%\&]/) {
1240 ## sigil given -- match it
1241 sort grep /$re/, map {
1242 my $name = $pack.'::'.$_;
1243 (defined *{$name}{HASH
} ?
'%'.$_ : (),
1244 defined *{$name}{ARRAY
} ?
'@'.$_ : (),
1245 defined *{$name}{CODE
} ?
$_ : (),
1246 defined ${$name} ?
'$'.$_ : (), # ?
1248 } grep !/::$/ && !/^(?:_<|[^\w])/ && /$re/, keys %{$pack.'::'};
1250 ## no sigil -- don't match it
1252 my $name = $pack.'::'.$_;
1253 (defined *{$name}{HASH
} ?
'%'.$_ : (),
1254 defined *{$name}{ARRAY
} ?
'@'.$_ : (),
1255 defined *{$name}{CODE
} ?
$_ : (),
1256 defined ${$name} ?
'$'.$_ : (), # ?
1258 } grep !/::$/ && !/^(?:_<|[^\w])/ && /$re/, keys %{$pack.'::'};
1262 =item C<$text = columnate(@items)>
1264 Format C<@items> in columns such that they fit within C<$ENV{COLUMNS}>
1272 my $width = $ENV{COLUMNS
} || 80;
1274 $len = length if $len < length;
1276 my $nc = int($width / ($len+1)) || 1;
1277 my $nr = int(@_ / $nc) + (@_ % $nc ?
1 : 0);
1278 my $fmt = ('%-'.($len+1).'s') x
($nc-1) . "%s\n";
1279 my @incs = map { $_ * $nr } 0..$nc-1;
1281 for my $r (0..$nr-1) {
1282 $str .= sprintf $fmt, map { defined($_) ?
$_ : '' }
1283 @_[map { $r + $_ } @incs];
1291 my ($pkg, $re) = split ' ', shift;
1293 if ($pkg && $pkg =~ /^\/(.*)\
/?$/) {
1296 } elsif (!$re && !%{$pkg.'::'}) {
1300 print columnate who
($pkg || $PACKAGE, $re);
1303 =item C<@m = methods($package [, $qualified])>
1305 List method names in C<$package> and its parents. If C<$qualified>,
1306 return full "CLASS::NAME" rather than just "NAME."
1312 my ($pack, $qualified) = @_;
1314 my @own = $qualified ?
grep {
1316 } map { "$pack\::$_" } keys %{$pack.'::'}
1318 defined *{"$pack\::$_"}{CODE
}
1319 } keys %{$pack.'::'};
1320 (@own, defined *{$pack.'::ISA'}{ARRAY
}
1321 ?
(map methods
($_, $qualified), @
{$pack.'::ISA'}) : ());
1326 my ($x, $re) = split ' ', shift;
1330 $x = $REPL{eval}->("ref $x");
1335 print columnate
sort { $a cmp $b } grep /$re/, methods
$x;
1340 my ($val, $cur) = @_;
1342 length($val) ?
$val : !$cur;
1347 $WANTARRAY = as_boolean
shift, $WANTARRAY;
1352 chomp(my $p = shift);
1356 # my $ecmd = '(setq sepia-eval-package "'.$p.'")';
1357 # print ";;;###".length($ecmd)."\n$ecmd\n";
1359 warn "Can't go to package $p -- doesn't exist!\n";
1371 do $INC{'Sepia.pm'};
1373 print "Restart failed:\n$@\n";
1375 $REPL_LEVEL = 0; # ok?
1390 # local $PACKAGE = $pkg || $PACKAGE;
1393 $buf = 'scalar($buf)';
1395 my $ctx = join(',', keys %{$STRICT->get_context('_')});
1396 $ctx = $ctx ?
"my ($ctx);" : '';
1397 $buf = eval "sub { package $PACKAGE; use strict; $ctx $buf }";
1399 print "ERROR\n$@\n";
1402 $STRICT->call($buf);
1404 $buf = "do { package $PACKAGE; no strict; $buf }";
1422 } elsif (-f
"t/$buf") {
1426 find
({ no_chdir
=> 1,
1428 push @files, $_ if /\.t$/;
1429 }}, Cwd
::getcwd
() =~ /t\/?
$/ ? '.' : './t
');
1432 # XXX: this is cribbed from an EU::MM-generated Makefile.
1433 system $^X, qw(-MExtUtils::Command::MM -e),
1434 "test_harness(0, 'blib/lib', 'blib/arch')", @files;
1436 print "No test files for '$buf' in ", Cwd
::getcwd
, "\n";
1442 my ($file) = split ' ', shift;
1443 $file ||= "$ENV{HOME}/.sepia-save";
1444 load
(retrieve
$file);
1449 my ($re, $file) = split ' ', shift;
1451 $file ||= "$ENV{HOME}/.sepia-save";
1452 store save
($re), $file;
1457 (my $name = shift) =~ s!::!/!g;
1459 print STDERR
"full reload $name\n";
1460 my %save_inc = %INC;
1463 my @ret = keys %INC;
1464 while (my ($k, $v) = each %save_inc) {
1470 sub repl_full_reload
1472 chomp (my $pat = shift);
1473 my @x = full_reload
$pat;
1474 print "Reloaded: @x\n";
1479 chomp (my $pat = shift);
1480 if ($pat =~ /^\/(.*)\
/?$/) {
1498 if (exists $INC{$pat}) {
1500 eval 'require $mod';
1502 print "Reloaded $mod.\n"
1504 print "$mod not loaded.\n"
1509 =item C<sig_warn($warning)>
1511 Collect C<$warning> for later printing.
1513 =item C<print_warnings()>
1515 Print and clear accumulated warnings.
1531 print ';;;'.length($tmp)."\n$tmp\n";
1535 print "warning: $_\n";
1544 I need user feedback! Please send questions or comments to seano\@cpan.org.
1545 Sepia version $Sepia::VERSION.
1546 Type ",h" for help, or ",q" to quit.
1552 Execute a command interpreter on standard input and standard output.
1553 If you want to use different descriptors, localize them before
1554 calling C<repl()>. The prompt has a few bells and whistles, including:
1558 =item Obviously-incomplete lines are treated as multiline input (press
1559 'return' twice or 'C-c' to discard).
1561 =item C<die> is overridden to enter a debugging repl at the point
1566 Behavior is controlled in part through the following package-globals:
1570 =item C<$PACKAGE> -- evaluation package
1572 =item C<$PRINTER> -- result printer (default: dumper)
1574 =item C<$PS1> -- the default prompt
1576 =item C<$STRICT> -- whether 'use strict' is applied to input
1578 =item C<$WANTARRAY> -- evaluation context
1580 =item C<$PRINT_PRETTY> -- format some output nicely (default = 1)
1582 Format some values nicely, independent of $PRINTER. Currently, this
1583 displays arrays of scalars as columns.
1585 =item C<$REPL_LEVEL> -- level of recursive repl() calls
1587 If zero, then initialization takes place.
1589 =item C<%REPL> -- maps shortcut names to handlers
1591 =item C<%REPL_DOC> -- maps shortcut names to documentation
1593 =item C<%REPL_SHORT> -- maps shortcut names to brief usage
1604 if ($REPL_LEVEL == 0) {
1606 -f
"$ENV{HOME}/.sepiarc" and do "$ENV{HOME}/.sepiarc";
1607 warn ".sepiarc: $@\n" if $@
;
1609 Sepia
::Debug
::add_repl_commands
;
1610 repl_banner
if $REPL_LEVEL == 0;
1617 local $REPL_LEVEL = $REPL_LEVEL + 1;
1623 my $nextrepl = sub { $sigged = 1; };
1626 local *CORE
::GLOBAL
::die = \
&Sepia
::Debug
::die;
1627 local *CORE
::GLOBAL
::warn = \
&Sepia
::Debug
::warn;
1629 my @sigs = qw(INT TERM PIPE ALRM);
1631 $SIG{$_} = $nextrepl for @sigs;
1632 repl
: while (defined(my $in = <STDIN
>)) {
1642 if ($buf =~ /^<<(\d+)\n(.*)/) {
1647 while ($len && defined($tmp = read STDIN
, $buf, $len, length $buf)) {
1652 ## Only install a magic handler if no one else is playing.
1653 local $SIG{__WARN__
} = $SIG{__WARN__
};
1655 unless ($SIG{__WARN__
}) {
1656 $SIG{__WARN__
} = 'Sepia::sig_warn';
1660 # repeat last interactive command
1666 if ($buf =~ /^,(\S+)\s*(.*)/s) {
1667 ## Inspector shortcuts
1669 if (exists $Sepia::RK
{$short}) {
1673 $Sepia::REPL
{$Sepia::RK
{$short}}->($arg, wantarray);
1675 if (grep /^$short/, keys %Sepia::REPL
) {
1676 print "Ambiguous shortcut '$short': ",
1677 join(', ', sort grep /^$short/, keys %Sepia::REPL
),
1680 print "Unrecognized shortcut '$short'\n";
1689 @res = $REPL{eval}->($buf);
1690 run_hook
@POST_EVAL;
1693 ## Always return results for an eval request
1694 Sepia
::printer \
@res, wantarray;
1695 Sepia
::printer
[$@
], wantarray;
1696 # print_warnings $ISEVAL;
1699 } elsif ($@
=~ /(?:at|before) EOF(?:$| at)/m) {
1700 ## Possibly-incomplete line
1702 print "Error:\n$@\n*** cancel ***\n", prompt
;
1709 # $@ =~ s/(.*) at eval .*/$1/;
1710 # don't complain if we're abandoning execution
1711 # from the debugger.
1712 unless (ref $@
eq 'Sepia::Debug') {
1714 print "\n" unless $@
=~ /\n\z/;
1722 if ($buf !~ /;\s*$/ && $buf !~ /^,/) {
1723 ## Be quiet if it ends with a semicolon, or if we
1724 ## executed a shortcut.
1725 Sepia
::printer \
@res, wantarray;
1732 wantarray ?
@REPL_RESULT : $REPL_RESULT[0]
1737 tolisp
($REPL{eval}->(shift));
1740 =head2 Module browsing
1744 =item C<$status = html_module_list([$file [, $prefix]])>
1746 Generate an HTML list of installed modules, looking inside of
1747 packages. If C<$prefix> is missing, uses "about://perldoc/". If
1748 $file is given, write the result to $file; otherwise, return it as a
1751 =item C<$status = html_package_list([$file [, $prefix]])>
1753 Generate an HTML list of installed top-level modules, without looking
1754 inside of packages. If C<$prefix> is missing, uses
1755 "about://perldoc/". $file is the same as for C<html_module_list>.
1761 sub html_module_list
1763 my ($file, $base) = @_;
1764 $base ||= 'about://perldoc/';
1766 return unless $inst;
1768 open OUT
, ">", $file || \
$out or return;
1769 print OUT
"<html><body>";
1772 for (package_list
) {
1773 push @
{$ns{$1}}, $_ if /^([^:]+)/;
1775 # Handle core modules.
1777 undef $fs{$_} for map {
1778 s/.*man.\///; s|/|::|g
; s/\.\d(?:pm)?$//; $_
1780 /\.\d(?:pm)?$/ && !/man1/ && !/usr\/bin
/ # && !/^(?
:\
/|perl)/
1781 } $inst->files('Perl');
1782 my @fs = sort keys %fs;
1783 print OUT
qq{<h2
>Core Modules
</h2
><ul
>};
1785 print OUT
qq{<li
><a href
="$base$_">$_</a
>};
1787 print OUT
'</ul><h2>Installed Modules</h2><ul>';
1790 for (sort keys %ns) {
1791 next if $_ eq 'Perl'; # skip Perl core.
1792 print OUT
qq{<li
><b
>$_</b
><ul
>} if @
{$ns{$_}} > 1;
1793 for (sort @
{$ns{$_}}) {
1795 undef $fs{$_} for map {
1796 s/.*man.\///; s|/|::|g
; s/\.\d(?:pm)?$//; $_
1798 /\.\d(?:pm)?$/ && !/man1/
1800 my @fs = sort keys %fs;
1801 next unless @fs > 0;
1803 print OUT
qq{<li
><a href
="$base$fs[0]">$fs[0]</a
>};
1805 print OUT
qq{<li
>$_<ul
>};
1807 print OUT
qq{<li
><a href
="$base$_">$_</a
>};
1812 print OUT
qq{</ul
>} if @
{$ns{$_}} > 1;
1815 print OUT
"</ul></body></html>\n";
1820 sub html_package_list
1822 my ($file, $base) = @_;
1823 return unless inst
();
1824 $base ||= 'about://perldoc/';
1826 open OUT
, ">", $file || \
$out or return;
1827 print OUT
"<html><body><ul>";
1830 for (package_list
) {
1831 push @
{$ns{$1}}, $_ if /^([^:]+)/;
1833 for (sort keys %ns) {
1834 if (@
{$ns{$_}} == 1) {
1836 qq{<li
><a href
="$base$ns{$_}[0]">$ns{$_}[0]</a
>};
1838 print OUT
qq{<li
><b
>$_</b
><ul
>};
1839 print OUT
qq{<li
><a href
="$base$_">$_</a
>}
1840 for sort @
{$ns{$_}};
1841 print OUT
qq{</ul
>};
1844 print OUT
"</ul></body></html>\n";
1854 for (package_list
) {
1855 undef $ret{$_} if /$re/;
1857 undef $ret{$_} for map {
1858 s/.*man.\///; s|/|::|g
; s/\.\d(?:pm)?$//; $_
1860 /\.\d(?:pm)?$/ && !/man1/ && !/usr\/bin
/ && /$re/
1861 } $inst->files('Perl');
1870 See the README file included with the distribution.
1874 Sepia's public GIT repository is located at L<http://repo.or.cz/w/sepia.git>.
1876 There are several modules for Perl development in Emacs on CPAN,
1877 including L<Devel::PerlySense> and L<PDE>. For a complete list, see
1878 L<http://emacswiki.org/cgi-bin/wiki/PerlLanguage>.
1882 Sean O'Rourke, E<lt>seano@cpan.orgE<gt>
1884 Bug reports welcome, patches even more welcome.
1888 Copyright (C) 2005-2009 Sean O'Rourke. All rights reserved, some
1889 wrongs reversed. This module is distributed under the same terms as