http://qs1969.pair.com?node_id=671388
Category: miscellaneous
Author/Contact Info halfcountplus@intergate.com
Description: I have seen a few people wanting to use the F-keys, PgUp, End, (etc) in non-GUI apps. I once did too. Unfortunately this requires changing terminal modes with the poorly documented Term::ReadKey, but if you still want to go ahead, my short script will read the multicharacter KEYS and remember them with names you give them (eg, F7). These keys are identified by reducing the number of unique elements in 3,4, or 5 byte KEYS (remember, 1 character = 1 byte!) according to the chart at the beginning. You can hex these raw character values and use them in regex with \x.

So it can be done, but most people really won't want to ;) IMPORTANT: if you don't exit cleanly (w/ ENTER) the terminal probably won't return to normal mode, and your command line will now be unresponsive...

Update: I noticed recently there is a "Curses" module for perl on CPAN which probably makes this a lot simpler -- ie. i'm wrong, Term::ReadKey is neither the only nor the best option. However, Term::ReadLine::Gnu recognizes these multi-character escape sequences in "bind_keyseq".
#!/usr/bin/perl
# will register multicharacter keys (eg F3, End, PgUp, <-) and allow y
+ou
# to name them, then return those names when pressed again.

# ReadKey in cbreak returns key values like this:
#byte:  1       2       3       4       5
#1char          X       X       X       X       normal
#3char  \e      0               X       X       F1-4, home, end
#3char  \e      [               X       X       arrows
#4char  \e      [               ~       X       PgUp, PgDn
#5char  \e      [                       ~       F5-12
#       eg. a is "a", PgUp is "\e[5~"
#       \e is ESC

use warnings;
use Term::ReadKey;

sub idkey {
        my @key = (); $C="@_";
        if ($C =~ /^\e/) {
                $C = ReadKey();
                if ($C =~ /^\[/) {
                        until ($C eq "~" || $C =~ /[A-D]/) {
                                $C = ReadKey(); if ($C ne "~") {push @
+key,$C;}
                        }   
                } else {push @key,$C;$C = ReadKey(); push @key,$C;}
                my $x = "@key";
                foreach (%mcks) {
                        if (exists($mcks{$_}) && $mcks{$_} eq "$x") {r
+eturn "$_";}
                }   
                ReadMode('normal');
                print "name? "; $nm = <>; chomp $nm;
                $mcks{$nm} = "$x";
                return @key;
        } else {return "@_";}
}    

%mcks=();    

while (1) {
        ReadMode('cbreak');
        print "Press a key. (ENTER quits)\n";
        $C = ReadKey();
        if ($C eq "\n") {ReadMode('normal');exit;}
        @key = idkey("$C");
        print "key:@key\n";
}