NAME

    Term::TermKey - perl wrapper around libtermkey

SYNOPSIS

     use Term::TermKey;
    
     my $tk = Term::TermKey->new( \*STDIN );
    
     print "Press any key\n";
    
     $tk->waitkey( my $key );
    
     print "You pressed: " . $tk->format_key( $key, 0 );

DESCRIPTION

      Note that libtermkey itself is deprecated in favour of its eventual
      merge into libtickit. As a result, uses of this module should also be
      considered deprecated. Consider rewriting code to use Tickit instead;
      either by creating a Tickit::Term to receive key input events, or
      perform a more wholescale rewrite into using Tickit generally for all
      screen interaction purposes.

    This module provides a light perl wrapper around the libtermkey
    library. This library attempts to provide an abstract way to read
    keypress events in terminal-based programs by providing structures that
    describe keys, rather than simply returning raw bytes as read from the
    TTY device.

    This version of Term::TermKey requires libtermkey version at least
    0.16.

 Multi-byte keys, ambiguous keys, and waittime

    Some keypresses generate multiple bytes from the terminal. There is
    also the ambiguity between multi-byte CSI or SS3 sequences, and the
    Escape key itself. The waittime timer is used to distinguish them.

    When some bytes arrive that could be the start of possibly multiple
    different keypress events, the library will attempt to wait for more
    bytes to arrive that would finish it. If no more bytes arrive after
    this time, then the bytes will be reported as events as they stand,
    even if this results in interpreting a partially-complete Escape
    sequence as a literal Escape key followed by some normal letters or
    other symbols.

    Similarly, if the start of an incomplete UTF-8 sequence arrives when
    the library is in UTF-8 mode, this will be reported as the UTF-8
    replacement character (U+FFFD) if it is incomplete after this time.

CONSTRUCTOR

 new

       $tk = Term::TermKey->new( $fh, $flags )

    Construct a new Term::TermKey object that wraps the given term handle.
    $fh should be either an IO handle reference, an integer referring to a
    plain POSIX file descriptor, of undef. $flags is optional, but if given
    should contain the flags to pass to libtermkey's constructor. Assumes a
    default of 0 if not supplied. See the FLAG_* constants.

 new_abstract

       $tk = Term::TermKey->new_abstract( $termtype, $flags )

    Construct a new abstract Term::TermKey object not associated with a
    filehandle. Input may be fed to it using the push_bytes() method rather
    than waitkey() or advisereadable(). The name of the termtype should be
    given in the $termtype string.

METHODS

 start

 stop

       $success = $tk->start
    
       $success = $tk->stop

    Start or stop IO interactions from the instance. Starting will send the
    terminal initialisation sequence and set up termios(5) settings,
    stopping will send the terminal shutdown sequence and restore
    termios(5) back to the initial values. After construction, a
    Term::TermKey instance is already started, but these methods may be
    used to suspend and resume, for example, on receipt of a SIGTSTP signal
    requesting that the application background itself.

    Returns false if it fails; $! will contain an error code.

 is_started

       $started = $tk->is_started

    Returns true if the instance has been started, or false if it is
    stopped.

 get_flags

 set_flags

       $flags = $tk->get_flags
    
       $tk->set_flags( $newflags )

    Accessor and mutator for the flags. One of the FLAG_UTF8 or FLAG_RAW
    flags will be set, even if neither was present in the constructor, as
    in this case the library will attempt to detect if the current locale
    is UTF-8 aware or not.

 get_canonflags

 set_canonflags

       $canonflags = $tk->get_canonflags
    
       $tk->set_canonflags( $newcanonflags )

    Accessor and mutator for the canonicalisation flags.

 get_waittime

 set_waittime

       $msec = $tk->get_waittime
    
       $tk->set_waittime( $msec )

    Accessor and mutator for the maximum wait time in miliseconds. The
    underlying libtermkey library will have specified a default value when
    the object was constructed.

 get_buffer_remaining

       $bytes = $tk->get_buffer_remaining

    Accessor returning the number of bytes of buffer space remaining in the
    buffer; the space in which push_bytes can write.

 get_buffer_size

 set_buffer_size

       $bytes = $tk->get_buffer_size
    
       $tk->set_buffer_size( $size )

    Accessor and mutator to for the total buffer size to store pending
    bytes. If the underlying termkey_set_buffer_size(3) call fails, the
    set_buffer_size method will throw an exception.

 getkey

       $res = $tk->getkey( $key )

    Attempt to retrieve a single keypress event from the buffer, and put it
    in $key. If successful, will return RES_KEY to indicate that the $key
    structure now contains a new keypress event. If $key is an undefined
    lvalue (such as a new scalar variable) it will be initialised to
    contain a new key structure.

    If nothing is in the buffer it will return RES_NONE. If the buffer
    contains a partial keypress event which does not yet contain all the
    bytes required, it will return RES_AGAIN (see above section about
    multibyte events). If no events are ready and the input stream is now
    closed, will return RES_EOF.

    This method will not block, nor will it perform any IO on the
    underlying file descriptor. For a normal blocking read, see waitkey().

 getkey_force

       $res = $tk->getkey_force( $key )

    Similar to getkey(), but will not return RES_AGAIN if a partial match
    was found. Instead, it will force an interpretation of the bytes, even
    if this means interpreting the start of an <Esc>-prefixed multibyte
    sequence as a literal Escape key followed by normal letters. If $key is
    an undefined lvalue (such as a new scalar variable) it will be
    initialised to contain a new key structure.

    This method will not block, nor will it perform any IO on the
    underlying file descriptor. For a normal blocking read, see waitkey().

 waitkey

       $res = $tk->waitkey( $key )

    Attempt to retrieve a single keypress event from the buffer, or block
    until one is available. If successful, will return RES_KEY to indicate
    that the $key structure now contains a new keypress event. If an IO
    error occurs it will return RES_ERROR, and if the input stream is now
    closed it will return RES_EOF.

    If $key is an undefined lvalue (such as a new scalar variable) it will
    be initialised to contain a new key structure.

 advisereadable

       $res = $tk->advisereadable

    Inform the underlying library that new input may be available on the
    underlying file descriptor and so it should call read() to obtain it.
    Will return RES_AGAIN if it read at least one more byte, RES_NONE if no
    more input was found, or RES_ERROR if an IO error occurs.

    Normally this method would only be used in programs that want to use
    Term::TermKey asynchronously; see the EXAMPLES section. This method
    gracefully handles an EAGAIN error from the underlying read() syscall.

 push_bytes

       $len = $tk->push_bytes( $bytes )

    Feed more bytes into the input buffer. This is primarily useful for
    feeding input into filehandle-less instances, constructed by passing
    undef or -1 as the filehandle to the constructor. After calling this
    method, these bytes will be available to read as keypresses by the
    getkey method.

 get_keyname

       $str = $tk->get_keyname( $sym )

    Returns the name of a key sym, such as returned by
    Term::TermKey::Key->sym().

 keyname2sym

       $sym = $tk->keyname2sym( $keyname )

    Look up the sym for a named key. The result of this method call can be
    compared directly against the value returned by
    Term::TermKey::Key->sym(). Because this method has to perform a linear
    search of key names, it is best called rarely, perhaps during program
    initialisation, and the result stored for easier comparisons during
    runtime.

 interpret_unknown_csi

       ( $cmd, @args ) = $tk->interpret_unknown_csi( $key )

    If $key contains an unknown CSI event then its command and arguments
    are returned in a list. $cmd will be a string of 1 to 3 characters
    long, containing the initial and intermediate characters if present,
    followed by the main command character. @args will contain the
    numerical arguments, where missing arguments are replaced by -1. If
    $key does not contain an unknown CSI event then an empty list is
    returned.

    Note that this method needs to be called immediately after getkey or
    waitkey, or at least, before calling either of those methods again. The
    actual CSI sequence is retained in the libtermkey buffer, and only
    retrieved by this method call. Calling getkey or waitkey again may
    overwrite that buffer.

 format_key

       $str = $tk->format_key( $key, $format )

    Return a string representation of the keypress event in $key, following
    the flags given. See the descriptions of the flags, below, for more
    detail.

    This may be useful for matching keypress events against keybindings
    stored in a hash. See EXAMPLES section for more detail.

 parse_key

       $key = $tk->parse_key( $str, $format )

    Return a keypress event by parsing the string representation in $str,
    following the flags given. This method is an inverse of format_key.

    This may be useful for parsing entries from a configuration file or
    similar.

 parse_key_at_pos

       $key = $tk->parse_key_at_pos( $str, $format )

    Return a keypress event by parsing the string representation in a
    region of $str, following the flags given.

    Where parse_key will start at the beginning of the string and requires
    the entire input to be consumed, this method will start at the current
    pos() position in $str (or at the beginning of the string if none is
    yet set), and after a successful parse, will update it to the end of
    the matched section. This position does not have to be at the end of
    the string. $str must therefore be a real scalar variable, and not a
    string literal.

    This may be useful for incremental parsing of configuration or other
    data, out of a larger string.

 keycmp

       $cmp = $tk->keycmp( $key1, $key2 )

    Compares the two given keypress events, returning a number less than,
    equal to, or greater than zero, depending on the ordering. Keys are
    ordered first by type (unicode, keysym, function, mouse), then by value
    within that type, then finally by modifier bits.

    This may be useful in sort expressions:

     my @sorted_keys = sort { $tk->keycmp( $a, $b ) } @keys;

KEY OBJECTS

    The Term::TermKey::Key subclass is used to store a single keypress
    event. Objects in this class cannot be changed by perl code. getkey(),
    getkey_force() or waitkey() will overwrite the contents of the
    structure with a new value.

    Keys cannot be constructed, but getkey(), getkey_force() or waitkey()
    will place a new key structure in the $key variable if it is undefined
    when they are called. parse_key() and parse_key_at_pos() will return
    new keys.

 type

       $key->type

    The type of event. One of TYPE_UNICODE, TYPE_FUNCTION, TYPE_KEYSYM,
    TYPE_MOUSE, TYPE_POSITION, TYPE_MODEREPORT, TYPE_UNKNOWN_CSI.

 type_is_...

       $key->type_is_unicode
    
       $key->type_is_function
    
       $key->type_is_keysym
    
       $key->type_is_mouse
    
       $key->type_is_position
    
       $key->type_is_modereport
    
       $key->type_is_unknown_csi

    Shortcuts which return a boolean.

 codepoint

       $key->codepoint

    The Unicode codepoint number for TYPE_UNICODE, or 0 otherwise.

 number

       $key->number

    The function key number for TYPE_FUNCTION, or 0 otherwise.

 sym

       $key->sym

    The key symbol number for TYPE_KEYSYM, or 0 otherwise. This can be
    passed to Term::TermKey->get_keyname(), or compared to a result earlier
    obtained from Term::TermKey->keyname2sym().

 modifiers

       $key->modifiers

    The modifier bitmask. Can be compared against the KEYMOD_* constants.

 modifier_...

       $key->modifier_shift
    
       $key->modifier_alt
    
       $key->modifier_ctrl

    Shortcuts which return a boolean if the appropriate modifier is
    present.

 utf8

       $key->utf8

    A string representation of the given Unicode codepoint. If the
    underlying termkey library is in UTF-8 mode then this will be a UTF-8
    string. If it is in raw mode, then this will be a single raw byte.

 mouseev

 button

       $key->mouseev
    
       $key->button

    The details of a mouse event for TYPE_MOUSE, or undef for other types
    of event.

 line

 col

       $key->line
    
       $key->col

    The details of a mouse or position event, or undef for other types of
    event.

 termkey

       $key->termkey

    Return the underlying Term::TermKey object this key was retrieved from.

 format

       $str = $key->format( $format )

    Returns a string representation of the keypress event, identically to
    calling format_key on the underlying Term::TermKey object.

EXPORTED CONSTANTS

    The following constant names are all derived from the underlying
    libtermkey library. For more detail see the documentation on the
    library.

    These constants are possible values of $key->type

    TYPE_UNICODE

      a Unicode codepoint

    TYPE_FUNCTION

      a numbered function key

    TYPE_KEYSYM

      a symbolic key

    TYPE_MOUSE

      a mouse movement or button press or release

    TYPE_POSITION

      a cursor position report

    TYPE_MODEREPORT

      an ANSI or DEC mode report

    TYPE_UNKNOWN_CSI

      an unrecognised CSI sequence

    These constants are result values from getkey(), getkey_force(),
    waitkey() or advisereadable()

    RES_NONE

      No key event is ready.

    RES_KEY

      A key event has been provided.

    RES_EOF

      No key events are ready and the terminal has been closed, so no more
      will arrive.

    RES_AGAIN

      No key event is ready yet, but a partial one has been found. This is
      only returned by getkey(). To obtain the partial result even if it
      never completes, call getkey_force().

    RES_ERROR

      Returned by waitkey or advisereadable if an IO error occurs while
      trying to read another key event.

    These constants are key modifier masks for $key->modifiers

    KEYMOD_SHIFT

    KEYMOD_ALT

    KEYMOD_CTRL

      Should be obvious ;)

    These constants are types of mouse event which may be returned by
    $key->mouseev or interpret_mouse:

    MOUSE_UNKNOWN

      The type of mouse event was not recognised

    MOUSE_PRESS

      The event reports a mouse button being pressed

    MOUSE_DRAG

      The event reports the mouse being moved while a button is held down

    MOUSE_RELEASE

      The event reports the mouse buttons being released, or the mouse
      moved without a button held.

    These constants are flags for the constructor, Term::TermKey->new

    FLAG_NOINTERPRET

      Do not attempt to interpret C0 codes into keysyms (ie. Backspace,
      Tab, Enter, Escape). Instead report them as plain Ctrl-letter events.

    FLAG_CONVERTKP

      Convert xterm's alternate keypad symbols into the plain ASCII codes
      they would represent.

    FLAG_RAW

      Ignore locale settings; do not attempt to recombine UTF-8 sequences.
      Instead report only raw values.

    FLAG_UTF8

      Ignore locale settings; force UTF-8 recombining on.

    FLAG_NOTERMIOS

      Even if the terminal file descriptor represents a TTY device, do not
      call the tcsetattr() termios function on it to set in canonical input
      mode.

    FLAG_SPACESYMBOL

      Sets the CANON_SPACESYMBOL canonicalisation flag. See below.

    FLAG_CTRLC

      Disable the SIGINT behaviour of the Ctrl-C key, allowing it to be
      read as a modified Unicode keypress.

    FLAG_EINTR

      Disable retry on signal interrupt; instead report it as an error with
      RES_ERROR and $! set to EINTR. Without this flag, IO operations will
      be retried if interrupted.

    These constants are canonicalisation flags for set_canonflags and
    get_canonflags

    CANON_SPACESYMBOL

      With this flag set, the Space key will appear as a TYPE_KEYSYM key
      event whose symname is "Space". Without this flag, it appears as a
      normal TYPE_UNICODE character.

    CANON_DELBS

      With this flag set, the ASCII DEL byte is interpreted as the
      "Backspace" keysym, rather than "DEL". This flag does not affect the
      interpretation of ASCII BS, which is always represented as
      "Backspace".

    These constants are flags to format_key

    FORMAT_LONGMOD

      Print full modifier names e.g. Shift- instead of abbreviating to S-.

    FORMAT_CARETCTRL

      If the only modifier is Ctrl on a plain character, render it as ^X.

    FORMAT_ALTISMETA

      Use the name Meta or the letter M instead of Alt or A.

    FORMAT_WRAPBRACKET

      If the key event is a special key instead of unmodified Unicode, wrap
      it in <brackets>.

    FORMAT_MOUSE_POS

      If the event is a mouse event, also include the cursor position;
      rendered as @ ($col,$line)

    FORMAT_VIM

      Shortcut to FORMAT_ALTISMETA|FORMAT_WRAPBRACKET; which gives an
      output close to the format the vim editor uses.

EXAMPLES

 A simple print-until-Ctrl-C loop

    This program just prints every keypress until the user presses Ctrl-C.

     use Term::TermKey qw( FLAG_UTF8 RES_EOF FORMAT_VIM );
     
     my $tk = Term::TermKey->new(\*STDIN);
     
     # ensure perl and libtermkey agree on Unicode handling
     binmode( STDOUT, ":encoding(UTF-8)" ) if $tk->get_flags & FLAG_UTF8;
     
     while( ( my $ret = $tk->waitkey( my $key ) ) != RES_EOF ) {
        print "Got key: ".$tk->format_key( $key, FORMAT_VIM )."\n";
     }

 Configuration of custom keypresses

    Because format_key() yields a plain string representation of a keypress
    it can be used as a hash key to look up a "handler" routine for the
    key.

    The following implements a simple line input program, though obviously
    lacking many features in a true line editor like readline.

     use Term::TermKey qw( FLAG_UTF8 RES_EOF FORMAT_LONGMOD );
     
     my $tk = Term::TermKey->new(\*STDIN);
     
     # ensure perl and libtermkey agree on Unicode handling
     binmode( STDOUT, ":encoding(UTF-8)" ) if $tk->get_flags & FLAG_UTF8;
    
     my $line = "";
    
     $| = 1;
    
     my %key_handlers = (
        "Enter"  => sub { 
           print "\nThe line is: $line\n";
           $line = "";
        },
    
        "Backspace" => sub {
           return unless length $line;
           substr( $line, -1, 1 ) = "";
           print "\cH \cH"; # erase it
        },
    
        # other handlers ...
     );
     
     while( ( my $ret = $tk->waitkey( my $key ) ) != RES_EOF ) {
        my $handler = $key_handlers{ $tk->format_key( $key, FORMAT_LONGMOD ) };
        if( $handler ) {
           $handler->( $key );
        }
        elsif( $key->type_is_unicode and !$key->modifiers ) {
           my $char = $key->utf8;
    
           $line .= $char;
           print $char;
        }
     }

 Asynchronous operation

    Because the getkey() method performs no IO itself, it can be combined
    with the advisereadable() method in an asynchronous program.

     use IO::Select;
     use Term::TermKey qw(
        FLAG_UTF8 RES_KEY RES_AGAIN RES_EOF FORMAT_VIM
     );
     
     my $select = IO::Select->new();
     
     my $tk = Term::TermKey->new(\*STDIN);
     $select->add(\*STDIN);
     
     # ensure perl and libtermkey agree on Unicode handling
     binmode( STDOUT, ":encoding(UTF-8)" ) if $tk->get_flags & FLAG_UTF8;
     
     sub on_key
     {
        my ( $tk, $key ) = @_;
     
        print "You pressed " . $tk->format_key( $key, FORMAT_VIM ) . "\n";
     }
     
     my $again = 0;
     
     while(1) {
        my $timeout = $again ? $tk->get_waittime/1000 : undef;
        my @ready = $select->can_read($timeout);
     
        if( !@ready ) {
           my $ret;
           while( ( $ret = $tk->getkey_force( my $key ) ) == RES_KEY ) {
              on_key( $tk, $key );
           }
        }
     
        while( my $fh = shift @ready ) {
           if( $fh == \*STDIN ) {
              $tk->advisereadable;
              my $ret;
              while( ( $ret = $tk->getkey( my $key ) ) == RES_KEY ) {
                 on_key( $tk, $key );
              }
     
              $again = ( $ret == RES_AGAIN );
              exit if $ret == RES_EOF;
           }
           # Deal with other filehandles here
        }
     }

    There may also be more appropriate modules on CPAN for particular event
    frameworks; see the SEE ALSO section below.

SEE ALSO

      * http://www.leonerd.org.uk/code/libtermkey/ - libtermkey home page

      * Term::TermKey::Async - terminal key input using libtermkey with
      IO::Async

      * POE::Wheel::TermKey - terminal key input using libtermkey with POE

      * AnyEvent::TermKey - terminal key input using libtermkey with
      AnyEvent

AUTHOR

    Paul Evans <leonerd@leonerd.org.uk>

