othar@joliet.berkeley.edu (Othar Hansson) (07/14/90)
The following trivial program demonstrates a quick and dirty way to integrate the GNU Readline library into interactive perl scripts, i.e., by the following kind of perl fragment: $TTY=`tty`; chop $TTY; $USERPROMPT='yeah?> '; open(USERIN,"gnureadline \"$USERPROMPT\" 2>$TTY |"); while (<USERIN>) { chop; printf STDOUT "you typed: (%s)\n", $_; # munch on $_ } Readline allows the user to play with his input in the style of Ksh or Bash: - emacs-style editing commands work (even keyboard macros) - a command history is retained, and the current line is viewed as a one-line window on a command-history (emacs) buffer, i.e., C-s and C-r search through commands, C-n and C-p scroll through them - gobs of other fortuitous features derived from the emacs analogy (user-defined keymaps, completion, etc.) - if you don't want all those features, vi-mode is available This program pleased one of my Ksh-spoiled users to no end. Try it out -- the fragment above should be pretty easy to put into any interactive perl script that doesn't do too much tty ioctl magic of its own. If you like it, read the Readline docs for customization info. Othar Hansson CS Division UC Berkeley ..!ucbvax!ernie!othar othar@ernie.berkeley.edu ---------cut here for gnureadline.c---------- /* * Readline Filter Process (gnureadline.c) * * Reads a line of text (echoed on stderr) and outputs it (on stdout). * Designed for piping between user and a Perl script. * * by Othar Hansson, othar@ernie.berkeley.edu * by simply extending a fragment from the readline documentation * (readline.texinfo) by Brian Fox * * the GNU Readline library is available on major ftp sites * (e.g., in pub/gnu on labrea.stanford.edu or prep.ai.mit.edu) * where it is bundled with the BASH distribution. * This code works with bash-1.05. * * The GNU General Public License applies to the GNU readline library, * and thus to all but the most trivial uses of this program */ #include <stdio.h> #include <readline/readline.h> #include <readline/history.h> /* A static variable for holding the line. */ static char *my_gets_line = (char *)NULL; /* * Read a string, and return a pointer to it. Returns NULL on EOF. */ static char * my_gets (prompt) char* prompt; { /* free the string that readline() alloc'ed last time */ if (my_gets_line != (char *)NULL) free (my_gets_line); my_gets_line = readline (prompt); /* Get a line from the user. */ /* If the line has any text in it, save it. */ if (my_gets_line && *my_gets_line) add_history (my_gets_line); return (my_gets_line); } int main (argc, argv) int argc; char* argv[]; { char *prompt = ""; if (argc >= 2) prompt = argv[1]; rl_outstream = stderr; /* so output doesn't see your typos */ for (;;) { char *nextline = my_gets(prompt); if (nextline == (char*) NULL) return 0; else fprintf(stdout,"%s\n",nextline); fflush(stdout); } } /* compile me with * cc -g -o gnureadline -I$BASHDIR gnureadline.c * -L$BASHDIR/readline -lreadline -ltermcap' */ ---------cut here----------
othar@joliet.berkeley.edu (Othar Hansson) (07/17/90)
A few days ago, I posted a simple C program that lets you bring the GNU readline library into interactive perl scripts. Someone suggested that I try to do so for the debugger. The diff for perldb.pl ends this message. Briefly, this makes the perl debugger's command-line editing act somewhat like GDB. An initial test suggests that it clashes badly with an interactive program that uses the same technique, but perhaps that can be fixed. You can try it out by patching a copy of perldb.pl in, e.g., /tmp, and prefacing a script with: #!/usr/bin/perl -dI/tmp For those who missed the original msg, the Readline library allows users to edit the command line in the style of Ksh and Bash. I can email you gnureadline.c if you can't get the article out of your news feed. Othar Hansson CS Division, UC Berkeley ..!ucbvax!ernie!othar othar@ernie.berkeley.edu Script started on Tue Jul 17 02:18:45 1990 /tmp>diff -c perldb.pl /usr/local/lib/perl/perldb.pl *** perldb.pl Tue Jul 17 02:17:04 1990 --- /usr/local/lib/perl/perldb.pl Fri Dec 30 00:00:00 1988 *************** *** 25,39 **** # # ! $TTY=`tty`; ! chop $TTY; ! # open(IN,"/dev/tty"); # so we don't dingle stdin ! open(IN,"gnureadline ' (perldb) ' 2>$TTY |"); ! open(OUT,">/dev/tty"); # so we don't dongle stdout select(OUT); - printf "<readline debugger running...>\n"; - $| = 1; # for DB'OUT select(STDOUT); $| = 1; # for real STDOUT --- 25,33 ---- # # ! open(IN,"/dev/tty"); # so we don't dingle stdin open(OUT,">/dev/tty"); # so we don't dongle stdout select(OUT); $| = 1; # for DB'OUT select(STDOUT); $| = 1; # for real STDOUT *************** *** 74,81 **** print OUT $#stack . " levels deep in subroutine calls!\n" if $single & 4; $start = $line; ! # while ((print OUT " DB<", $#hist+1, "> "), $cmd=<IN>) { ! while ($cmd=<IN>) { $single = 0; $signal = 0; $cmd eq '' && exit 0; --- 68,74 ---- print OUT $#stack . " levels deep in subroutine calls!\n" if $single & 4; $start = $line; ! while ((print OUT " DB<", $#hist+1, "> "), $cmd=<IN>) { $single = 0; $signal = 0; $cmd eq '' && exit 0; /tmp>exit script done on Tue Jul 17 02:21:21 1990