#!perl -w # # $Id: ptktrl 1.9 Mon, 06 Jul 1998 20:44:48 +0200 ach $ # # POD documentation after __END__ require 5.004; $| = 1; use strict; use vars '$VERSION'; $VERSION = substr q$Revision: 1.9 $, 10; use Tk; use Term::ReadLine; use vars qw($mw); my $name = 'ptktrl'; $mw = MainWindow->new; $mw->geometry('+20+20'); print "\n $name V$VERSION"; my $prj = $0; $prj =~ s|[^/]+$|tkach.prj|; # in my devel area? print "(devel) " if -e $prj; print " perl V$] Tk V$Tk::VERSION MainWindow -> \$mw\n"; print "\n\t\@INC:\n"; foreach (@INC) { print "\t $_\n" }; print "\n"; if ( -r ".${name}_init") { print "Reading .${name}_init ...\n"; do ".${name}_init"; } if (defined($ARGV[0]) && -r $ARGV[0]) { print "Reading $ARGV[0] ...\n"; do $ARGV[0]; } my $term = new Term::ReadLine $name; die $term->ReadLine() . " does not support Tk loop\n" unless ${$term->Features}{tkRunning}; $term->tkRunning(1); if (${$term->Features}{ornaments}) { local $^W=0; $term->ornaments('md,me,,'); } ## test if Tk is not blocked. #sub ptksh_test { # print STDERR "I'm working behing the scene\n"; # $mw->after(1500,\&ptksh_test); #} #$mw->after(1500,\&ptksh_test); ### ### Loading history ### my $histfile = "$ENV{HOME}/.${name}_history"; if ( -r $histfile and open(HIST, "<$histfile") ) { while () { chomp $_; $term->addhistory($_); } close HIST; } ### ### Utility function ### sub ptksh::_o { my $w = shift; my $what = shift; $what =~ s/^\s+//; $what =~ s/\s+$//; my (@opt) = split " ", $what; require Tk::Pretty; # check for regexp if ($opt[0] =~ s|^/(.*)/$|$1|) { print "options matching /$opt[0]/:\n"; foreach ($w->configure()) { print Tk::Pretty::Pretty($_),"\n" if $_->[0] =~ /\Q$opt[0]\E/; } return; } # list of options (allow as bar words) foreach (@opt) { s/^['"]//; s/,$//; s/['"]$//; s/^([^-])/-$1/; } if (length $what) { foreach (@opt) { print Tk::Pretty::Pretty($w->configure($_)),"\n"; } } else { foreach ($w->configure()) { print Tk::Pretty::Pretty($_),"\n" } } } sub ptksh::_p { foreach (@_) { print $_, "|\n"; } } my $u_init = 0; my %u_last = (); my $u_cnt; sub ptksh::_u { my $module = shift; if (defined($module) and $module ne '') { $module = "Tk/".ucfirst($module).".pm" unless $module =~ /^Tk/; print " --- Loading $module ---\n"; require "$module"; print $@ if $@; } else { %u_last = () if defined $module; $u_cnt = 0; foreach (sort keys %INC) { next if exists $u_last{$_}; $u_cnt++; $u_last{$_} = 1; #next if m,^/, and m,\.ix$,; # Ignore autoloader files #next if m,\.ix$,; # Ignore autoloader files if (length($_) < 20 ) { printf "%-20s -> %s\n", $_, $INC{$_}; } else { print "$_ -> $INC{$_}\n"; } } print STDERR "No modules loaded since last 'u' command (or startup)\n" unless $u_cnt; } } sub ptksh::_d { require Data::Dumper; print Data::Dumper::Dumper(@_); } sub ptksh::_h { print <<'EOT'; ? print this message d arg,... calls Data::Dumper::Dumper p arg,... print args, each on a line and "|\n" o $w /regexp/ print options of widget matching regexp o $w [option ...] print (all) options of widget u xxx xxx = string : load Tk::Xxx = '' : list all modules loaded = undef : list modules loaded since last u call (or after ptktrl startup) EOT } ### ### Read and evaluate line from terminal ### my ($line, $last) = ('', ''); LINE: while ( defined($line = $term->readline("$name> ")) ) { foreach ($line) { last LINE if /^s*(exit)\b/; last LINE if /^\s.*$/; #$term->add_history($_) if $last ne $_; #$last = $_; last if s/^\?\s*$/ptksh::_h /; last if s/^u(\s+|$)/ptksh::_u /; last if s/^d\s+/ptksh::_d /; last if s/^u\s+(\S+)/ptksh::_u('$1')/; last if s/^p\s+(.*)$/ptksh::_p $1;/; last if s/^o\s+(\S+)\s*?$/ptksh::_o $1;/; last if s/^o\s+(\S+)\s*,?\s+(.*)?$/ptksh::_o $1, '$2';/; } #print "Line: ($line)\n"; use strict; # so 'strict is loaded %u_last = %INC unless $u_init++; eval "{no strict; local \$^W=0; $line;}"; print "$@\n" if $@; } print "\n" unless defined $line; ### ### Save History ### END { my $features = $term->Features; if (exists $features->{getHistory} && $features->{getHistory}) { my @a= $term->GetHistory(); $#a-- if $a[-1] =~ /^(q$|x$|\s*exit\b)/; # chop off the exit command @a= @a[($#a-50)..($#a)] if $#a > 50 ; if( open HIST, ">$histfile" ) { print HIST join("\n",@a), "\n"; close HIST; } else { print "Error: Unable to open history to '$histfile'\n"; } } else { print $term->ReadLine, " does not support a history records :-(\n"; } } __END__ =head1 NAME ptktrl - Simple perl/Tk shell with cmd line editing and a persistent history =head1 SYNOPSIS % ptktrl ?I? ... version informations ... ptktrl> $b=$mw->Button(-text=>'Hi',-command=>sub{print 'Hi'}) ptktrl> $b->grid ptktrl> o $b ... list of options ... ptktrl> ... ptktrl> ^D % =head1 DESCRIPTION ptktrl is a simple perl/Tk shell to enter perl commands interactively. When one starts ptktrl a L is automaticly created. One can access it with I<$mw> on the command line. ptktrl supports command line editing and history via ReadLine interface (see L). The last 50 commands entered are saved on exit to F<~/.ptktrl_history>. The history file is loaded into history cache the next time you start ptktrl. To exit ptktrl use: C<^D, exit,> or C. The primary target of ptktrl is to experiment with perl/Tk widgets. To debug perl/Tk programs use the more powerful the L. Just enter ``O tk'' on debuggers command line to start the Tk eventloop. The only advantage ptktrl has is that history file support and that a MainWindow is automaticly created. =head1 DEBUGGING SUPPORT ptktrl provides some convenience function to make browsing in perl/Tk widgets easier: =over 4 =item B displays a short help summary. =item B ?I, ...? Dumps recursicely arguments to stdout. (see L). =item B

?I, ...? appends "|\n" to each of it's arguments and prints it. If value is B, '(undef)' is printed to stdout. =item B I<$widget> ?I<-option> ...? prints the option(s) of I<$widget> one on each line. If no options are given all options of the widget are listed. See L for more details on the format and contents of the returned list. =item B I<$widget> BIB Lists options of I<$widget> matching the L I. =item B ?I? If no argument is given it lists the modules loaded by the commands you executed or since the last time you called C. If argument is the empty string lists all modules that are loaded by ptktrl. If argument is a string, ``text'' it tried does a ``use Tk::Text''. =back =head1 ENVIRONMENT Same as for Term::ReadLine and perl. See L and L for further details. =head1 FILES =over 4 =item F<.ptktrl_init> If found in current directory it is read in an evaluated after the mainwindow I<$mw> is created. F<.ptktrl_init> can contain any valid perl code. =item F<~/.ptktrl_history> Contains the last 50 lines entered in ptktrl session(s). =back =head1 BUGS Work only on Unix systems. Term::Readline::Perl command line history is broken when used in conjunction with perl/Tk. Term::ReadLine::Gnu has no problems. B function interactively entered or sourced in a init or script file will block ptktrl. =head1 SEE ALSO L L L =head1 AUTHOR Achim Bohnet > Copyright (c) 1996-1998 Achim Bohnet. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut