NAME

     gl_get_line,            new_GetLine,            del_GetLine,
     gl_customize_completion, gl_change_terminal - allow the user
     to compose an input line

SYNOPSIS

     #include <stdio.h>
     #include <libtecla.h>

     GetLine *new_GetLine(size_t linelen, size_t histlen);

     GetLine *del_GetLine(GetLine *gl);

     char *gl_get_line(GetLine *gl, const char *prompt,
                      const char *start_line, int start_pos);

     int gl_customize_completion(GetLine *gl, void *data,
                                 CplMatchFn *match_fn);

     int gl_change_terminal(GetLine *gl, FILE *input_fp,
                            FILE *output_fp, const char *term);



DESCRIPTION

     The gl_get_line() function is part of the tecla library (see
     the libtecla(3) man page). If the user is typing at a termi-
     nal, it prompts them for an line  of  input,  then  provides
     interactive editing facilities, similar to those of the unix
     tcsh shell. In addition to simple command-line  editing,  it
     supports  recall  of  previously  entered command lines, TAB
     completion of file names, and in-line wild-card expansion of
     filenames.


AN EXAMPLE

     The following shows a complete example of  how  to  use  the
     gl_get_line() function to get input from the user:

       #include <stdio.h>
       #include <libtecla.h>

       int main(int argc, char *argv[])
       {
         char *line;    /* The line that the user typed */
         Getline *gl;   /* The gl_get_line() resource object */

         gl = new_GetLine(1024, 2048);
         if(!gl)
           return 1;

         while((line=gl_get_line(gl, "$ ", NULL, -1)) != NULL &&
                strcmp(line, "exit\n") != 0)
           printf("You typed: %s\n", line);

         gl = del_GetLine(gl);
         return 0;
       }

     In  the  example,  first  the  resources   needed   by   the
     gl_get_line() function are created by calling new_GetLine().
     This allocates the memory used in subsequent  calls  to  the
     gl_get_line()  function,  including  the  history buffer for
     recording previously entered lines. Then one or  more  lines
     are read from the user, until either an error occurs, or the
     user types exit. Then finally the resources that were  allo-
     cated  by  new_GetLine(), are returned to the system by cal-
     ling del_GetLine(). Note the use of the NULL return value of
     del_GetLine()  to make gl NULL. This is a safety precaution.
     If  the  program  subsequently  attempts  to  pass   gl   to
     gl_get_line(),  said  function  will complain, and return an
     error, instead of attempting to  use  the  deleted  resource
     object.



THE FUNCTIONS USED IN THE EXAMPLE

     The descriptions of the functions used in the example are as
     follows:

       GetLine *new_GetLine(size_t linelen, size_t histlen)

     This  function   creates   the   resources   used   by   the
     gl_get_line()  function and returns an opaque pointer to the
     object that contains them.  The maximum length of  an  input
     line  is  specified via the linelen argument, and the number
     of bytes to allocate for storing history lines is set by the
     histlen argument. History lines are stored back-to-back in a
     single buffer of this size.  On error, a message is  printed
     to stderr and NULL is returned.

       GetLine *del_GetLine(GetLine *gl)

     This function deletes the resources that were returned by  a
     previous call to new_GetLine(). It always returns NULL (ie a
     deleted object). It does nothing if the gl argument is NULL.

       char *gl_get_line(GetLine *gl, const char *prompt,
                        const char *start_line, int start_pos);

     The gl_get_line() function can be called any number of times
     to  read input from the user. The gl argument must have been
     previously returned by a call to new_GetLine().  The  prompt
     argument   should   be   a  normal  NUL  terminated  string,
     specifying the prompt to present the user with. If you  want
     to specify the initial contents of the line, for the user to
     edit, pass the desired string via the  start_line  argument.
     You can then specify which character of this line the cursor
     is initially positioned over, using the start_pos  argument.
     This  should be -1 if you want the cursor to follow the last
     character of the start line. If you don't  want  to  preload
     the  line  in  this manner, send start_line as NULL, and set
     start_pos to -1.

     The gl_get_line() function returns a  pointer  to  the  line
     entered  by  the user, or NULL on error or at the end of the
     input. The returned pointer is  part  of  the  specified  gl
     resource  object,  and  thus  should  not  be  free'd by the
     caller, or assumed to be unchanging from  one  call  to  the
     next.  When  reading  from  a user at a terminal, there will
     always be a newline character at the  end  of  the  returned
     line.   When  standard input is being taken from a pipe or a
     file, there will similarly be a  newline  unless  the  input
     line  was  too  long to store in the internal buffer. In the
     latter case you should call gl_get_line() again to read  the
     rest   of   the   line.   Note   that  this  behavior  makes
     gl_get_line() similar to fgets().  In fact when stdin  isn't
     connected to a terminal,gl_get_line() just calls fgets().


THE AVAILABLE KEY BINDING FUNCTIONS

     The gl_get_line() function provides a  number  of  functions
     which  can  be  bound  to  key sequences. The names of these
     functions, and what they do, are given below.

       user-interrupt           -  Send a SIGINT signal to the
                                   parent process.
       abort                    -  Send a SIGABRT signal to the
                                   parent process.
       suspend                  -  Suspend the parent process.
       stop-output              -  Pause terminal output.
       start-output             -  Resume paused terminal output.
       literal-next             -  Arrange for the next character
                                   to be treated as a normal
                                   character. This allows control
                                   characters to be entered.
       cursor-right             -  Move the cursor one character
                                   right.
       cursor-left              -  Move the cursor one character
                                   left.
       insert-mode              -  Toggle between insert mode and
                                   overwrite mode.
       beginning-of-line        -  Move the cursor to the
                                   beginning of the line.
       end-of-line              -  Move the cursor to the end of
                                   the line.
       delete-line              -  Delete the contents of the
                                   current line.
       kill-line                -  Delete everything that follows
                                   the cursor.
       backward-kill-line       -  Delete all characters between
                                   the cursor and the start of the
                                   line.
       forward-word             -  Move to the end of the word
                                   which follows the cursor.
       forward-to-word          -  Move the cursor to the start of
                                   the word that follows the
                                   cursor.
       backward-word            -  Move to the start of the word
                                   which precedes the cursor.
       goto-column              -  Move the cursor to the
                                   1-relative column in the line
                                   specified by any preceding
                                   digit-argument sequences (see
                                   ENTERING REPEAT COUNTS below).
       find-parenthesis         -  If the cursor is currently
                                   over a parenthesis character,
                                   move it to the matching
                                   parenthesis character. If not
                                   over a parenthesis character
                                   move right to the next close
                                   parenthesis.
       forward-delete-char      -  Delete the character under the
                                   cursor.
       backward-delete-char     -  Delete the character which
                                   precedes the cursor.
       list-or-eof              -  This is intended for binding
                                   to ^D. When invoked when the
                                   cursor is within the line it
                                   displays all possible
                                   completions then redisplays
                                   the line unchanged. When
                                   invoked on an empty line, it
                                   signals end-of-input (EOF) to
                                   the caller of gl_get_line().
       del-char-or-list-or-eof  -  This is intended for binding
                                   to ^D. When invoked when the
                                   cursor is within the line it
                                   invokes forward-delete-char.
                                   When invoked at the end of the
                                   line it displays all possible
                                   completions then redisplays
                                   the line unchanged. When
                                   invoked on an empty line, it
                                   signals end-of-input (EOF) to
                                   the caller of gl_get_line().
       forward-delete-word      -  Delete the word which follows
                                   the cursor.
       backward-delete-word     -  Delete the word which precedes
                                   the cursor.
       upcase-word              -  Convert all of the characters
                                   of the word which follows the
                                   cursor, to upper case.
       downcase-word            -  Convert all of the characters
                                   of the word which follows the
                                   cursor, to lower case.
       capitalize-word          -  Capitalize the word which
                                   follows the cursor.
       change-case              -  If the next character is upper
                                   case, toggle it to lower case
                                   and vice versa.
       redisplay                -  Redisplay the line.
       clear-screen             -  Clear the terminal, then
                                   redisplay the current line.
       transpose-chars          -  Swap the character under the
                                   cursor with the character just
                                   before the cursor.
       set-mark                 -  Set a mark at the position of
                                   the cursor.
       exchange-point-and-mark  -  Move the cursor to the last
                                   mark that was set, and move
                                   the mark to where the cursor
                                   used to be.
       kill-region              -  Delete the characters that lie
                                   between the last mark that was
                                   set, and the cursor.
       copy-region-as-kill      -  Copy the text between the mark
                                   and the cursor to the cut
                                   buffer, without deleting the
                                   original text.
       yank                     -  Insert the text that was last
                                   deleted, just before the
                                   current position of the cursor.
       append-yank              -  Paste the current contents of
                                   the cut buffer, after the
                                   cursor.
       up-history               -  Recall the next oldest line
                                   that was entered. Note that
                                   in vi mode you are left in
                                   command mode.
       down-history             -  Recall the next most recent
                                   line that was entered. If no
                                   history recall session is
                                   currently active, the next
                                   line from a previous recall
                                   session is recalled. Note that
                                   in vi mode you are left in
                                   command mode.
       history-search-backward  -  Recall the next oldest line
                                   who's prefix matches the string
                                   which currently precedes the
                                   cursor (in vi command-mode the
                                   character under the cursor is
                                   also included in the search
                                   string).  Note that in vi mode
                                   you are left in command mode.
       history-search-forward   -  Recall the next newest line
                                   who's prefix matches the string
                                   which currently precedes the
                                   cursor (in vi command-mode the
                                   character under the cursor is
                                   also included in the search
                                   string).  Note that in vi mode
                                   you are left in command mode.
       history-re-search-backward -Recall the next oldest line
                                   who's prefix matches that
                                   established by the last
                                   invocation of either
                                   history-search-forward or
                                   history-search-backward.
       history-re-search-forward - Recall the next newest line
                                   who's prefix matches that
                                   established by the last
                                   invocation of either
                                   history-search-forward or
                                   history-search-backward.
       complete-word            -  Attempt to complete the
                                   incomplete word which
                                   precedes the cursor. Unless
                                   the host program has customized
                                   word completion, filename
                                   completion is attempted. In vi
                                   commmand mode the character
                                   under the cursor is also
                                   included in the word being
                                   completed, and you are left in
                                   vi insert mode.
       expand-filename          -  Within the command line, expand
                                   wild cards, tilde expressions
                                   and dollar expressions in the
                                   filename which immediately
                                   precedes the cursor. In vi
                                   commmand mode the character
                                   under the cursor is also
                                   included in the filename being
                                   expanded, and you are left in
                                   vi insert mode.
       list-glob                -  List any filenames which match
                                   the wild-card, tilde and dollar
                                   expressions in the filename
                                   which immediately precedes the
                                   cursor, then redraw the input
                                   line unchanged.
       read-from-file           -  Temporarily switch to reading
                                   input from the file who's
                                   name precedes the cursor.
       beginning-of-history     -  Move to the oldest line in the
                                   history list. Note that in vi
                                   mode you are left in command
                                   mode.
       end-of-history           -  Move to the newest line in the
                                   history list (ie. the current
                                   line). Note that in vi mode
                                   this leaves you in command
                                   mode.
       digit-argument           -  Enter a repeat count for the
                                   next key-binding function.
                                   For details, see the ENTERING
                                   REPEAT COUNTS section.
       newline                  -  Terminate and return the
                                   current contents of the line.
       repeat-history           -  Return the line that is being
                                   edited, then arrange for the
                                   next most recent entry in the
                                   history buffer to be recalled
                                   when gl_get_line() is
                                   next called. Repeatedly
                                   invoking this action causes
                                   successive historical input
                                   lines to be re-executed. Note
                                   that this action is equivalent
                                   to the 'Operate' action in
                                   ksh.
       ring-bell                -  Ring the terminal bell, unless
                                   the bell has been silenced via
                                   the nobeep configuration
                                   option (see the THE TECLA
                                   CONFIGURATION FILE section).
       forward-copy-char        -  Copy the next character into
                                   the cut buffer (NB. use repeat
                                   counts to copy more than one).
       backward-copy-char       -  Copy the previous character
                                   into the cut buffer.
       forward-copy-word        -  Copy the next word into the cut
                                   buffer.
       backward-copy-word       -  Copy the previous word into the
                                   cut buffer.
       forward-find-char        -  Move the cursor to the next
                                   occurrence of the next
                                   character that you type.
       backward-find-char       -  Move the cursor to the last
                                   occurrence of the next
                                   character that you type.
       forward-to-char          -  Move the cursor to the
                                   character just before the next
                                   occurrence of the next
                                   character that the user types.
       backward-to-char         -  Move the cursor to the
                                   character just after the last
                                   occurrence before the cursor
                                   of the next character that the
                                   user types.
       repeat-find-char         -  Repeat the last
                                   backward-find-char,
                                   forward-find-char,
                                   backward-to-char or
                                   forward-to-char.
       invert-refind-char       -  Repeat the last
                                   backward-find-char,
                                   forward-find-char,
                                   backward-to-char, or
                                   forward-to-char in the
                                   opposite direction.
       delete-to-column         -  Delete the characters from the
                                   cursor up to the column that
                                   is specified by the repeat
                                   count.
       delete-to-parenthesis    -  Delete the characters from the
                                   cursor up to and including
                                   the matching parenthesis, or
                                   next close parenthesis.
       forward-delete-find      -  Delete the characters from the
                                   cursor up to and including the
                                   following occurence of the
                                   next character typed.
       backward-delete-find     -  Delete the characters from the
                                   cursor up to and including the
                                   preceding occurence of the
                                   next character typed.
       forward-delete-to        -  Delete the characters from the
                                   cursor up to, but not
                                   including, the following
                                   occurence of the next
                                   character typed.
       backward-delete-to       -  Delete the characters from the
                                   cursor up to, but not
                                   including, the preceding
                                   occurence of the next
                                   character typed.
       delete-refind            -  Repeat the last *-delete-find
                                   or *-delete-to action.
       delete-invert-refind     -  Repeat the last *-delete-find
                                   or *-delete-to action, in the
                                   opposite direction.
       copy-to-column           -  Copy the characters from the
                                   cursor up to the column that
                                   is specified by the repeat
                                   count, into the cut buffer.
       copy-to-parenthesis      -  Copy the characters from the
                                   cursor up to and including
                                   the matching parenthesis, or
                                   next close parenthesis, into
                                   the cut buffer.
       forward-copy-find        -  Copy the characters from the
                                   cursor up to and including the
                                   following occurence of the
                                   next character typed, into the
                                   cut buffer.
       backward-copy-find       -  Copy the characters from the
                                   cursor up to and including the
                                   preceding occurence of the
                                   next character typed, into the
                                   cut buffer.
       forward-copy-to          -  Copy the characters from the
                                   cursor up to, but not
                                   including, the following
                                   occurence of the next
                                   character typed, into the cut
                                   buffer.
       backward-copy-to         -  Copy the characters from the
                                   cursor up to, but not
                                   including, the preceding
                                   occurence of the next
                                   character typed, into the cut
                                   buffer.
       copy-refind              -  Repeat the last *-copy-find
                                   or *-copy-to action.
       copy-invert-refind       -  Repeat the last *-copy-find
                                   or *-copy-to action, in the
                                   opposite direction.
       vi-mode                  -  Switch to vi mode from emacs
                                   mode.
       emacs-mode               -  Switch to emacs mode from vi
                                   mode.
       vi-insert                -  From vi command mode, switch to
                                   insert mode.
       vi-overwrite             -  From vi command mode, switch to
                                   overwrite mode.
       vi-insert-at-bol         -  From vi command mode, move the
                                   cursor to the start of the line
                                   and switch to insert mode.
       vi-append-at-eol         -  From vi command mode, move the
                                   cursor to the end of the line
                                   and switch to append mode.
       vi-append                -  From vi command mode, move the
                                   cursor one position right, and
                                   switch to insert mode.
       vi-replace-char          -  From vi command mode, replace
                                   the character under the cursor
                                   with the the next character
                                   entered.
       vi-forward-change-char   -  From vi command mode, delete
                                   the next character then enter
                                   insert mode.
       vi-backward-change-char  -  From vi command mode, delete
                                   the preceding character then
                                   enter insert mode.
       vi-forward-change-word   -  From vi command mode, delete
                                   the next word then enter
                                   insert mode.
       vi-backward-change-word  -  From vi command mode, delete
                                   the preceding word then
                                   enter insert mode.
       vi-change-rest-of-line   -  From vi command mode, delete
                                   from the cursor to the end of
                                   the line, then enter insert
                                   mode.
       vi-change-line           -  From vi command mode, delete
                                   the current line, then enter
                                   insert mode.
       vi-change-to-bol         -  From vi command mode, delete
                                   all characters between the
                                   cursor and the beginning of
                                   the line, then enter insert
                                   mode.
       vi-change-to-column      -  From vi command mode, delete
                                   the characters from the cursor
                                   up to the column that is
                                   specified by the repeat count,
                                   then enter insert mode.
       vi-change-to-parenthesis -  Delete the characters from the
                                   cursor up to and including
                                   the matching parenthesis, or
                                   next close parenthesis, then
                                   enter vi insert mode.
       vi-forward-change-find   -  From vi command mode, delete
                                   the characters from the
                                   cursor up to and including the
                                   following occurence of the
                                   next character typed, then
                                   enter insert mode.
       vi-backward-change-find  -  From vi command mode, delete
                                   the characters from the
                                   cursor up to and including the
                                   preceding occurence of the
                                   next character typed, then
                                   enter insert mode.
       vi-forward-change-to     -  From vi command mode, delete
                                   the characters from the
                                   cursor up to, but not
                                   including, the following
                                   occurence of the next
                                   character typed, then enter
                                   insert mode.
       vi-backward-change-to    -  From vi command mode, delete
                                   the characters from the
                                   cursor up to, but not
                                   including, the preceding
                                   occurence of the next
                                   character typed, then enter
                                   insert mode.
       vi-change-refind         -  Repeat the last
                                   vi-*-change-find or
                                   vi-*-change-to action.
       vi-change-invert-refind  -  Repeat the last
                                   vi-*-change-find or
                                   vi-*-change-to action, in the
                                   opposite direction.
       vi-undo                  -  In vi mode, undo the last
                                   editing operation.
       vi-repeat-change         -  In vi command mode, repeat the
                                   last command that modified the
                                   line.


DEFAULT KEY BINDINGS IN EMACS MODE

     The following default key bindings, which can  be  overriden
     by  the tecla configuration file, are designed to mimic most
     of the bindings of the unix tcsh shell, when it is in  emacs
     editing mode.

     This is the default editing mode of the tecla library.

     Note that a key sequence like  ^A  or  C-a  means  hold  the
     control-key down while pressing the letter A, and that where
     you see \E or M- in a binding, this  represents  the  escape
     key   or   the   Meta   modifier  key.  Also  note  that  to
     gl_get_line(), pressing the  escape  key  before  a  key  is
     equivalent to pressing the meta key at the same time as that
     key. Thus the key sequence M-p can be typed in two ways,  by
     pressing  the  escape  key,  followed  by  pressing p, or by
     pressing the Meta key at the same time as p.

     Under UNIX the terminal driver sets a number of special keys
     for certain functions. The tecla library attempts to use the
     same keybindings to maintain consistency. The key  sequences
     shown for the following 6 bindings are thus just examples of
     what they will probably be set to. If you have used the stty
     command  to  change  these  keys,  then the default bindings
     should match.

       ^C     ->   user-interrupt
       ^\     ->   abort
       ^Z     ->   suspend
       ^Q     ->   start-output
       ^S     ->   stop-output
       ^V     ->   literal-next

     The cursor keys are refered to by name, as follows. This  is
     necessary because different types of terminals generate dif-
     ferent key sequences when their cursor keys are pressed.

       right  ->   cursor-right
       left   ->   cursor-left
       up     ->   up-history
       down   ->   down-history

     The remaining bindings don't depend on  the  terminal  sett-
     tings.

       ^F     ->   cursor-right
       ^B     ->   cursor-left
       M-i    ->   insert-mode
       ^A     ->   beginning-of-line
       ^E     ->   end-of-line
       ^U     ->   delete-line
       ^K     ->   kill-line
       M-f    ->   forward-word
       M-b    ->   backward-word
       ^D     ->   del-char-or-list-or-eof
       ^H     ->   backward-delete-char
       ^?     ->   backward-delete-char
       M-d    ->   forward-delete-word
       M-^H   ->   backward-delete-word
       M-^?   ->   backward-delete-word
       M-u    ->   upcase-word
       M-l    ->   downcase-word
       M-c    ->   capitalize-word
       ^R     ->   redisplay
       ^L     ->   clear-screen
       ^T     ->   transpose-chars
       ^@     ->   set-mark
       ^X^X   ->   exchange-point-and-mark
       ^W     ->   kill-region
       M-w    ->   copy-region-as-kill
       ^Y     ->   yank
       ^P     ->   up-history
       ^N     ->   down-history
       M-p    ->   history-search-backward
       M-n    ->   history-search-forward
       ^I     ->   complete-word
       ^X*    ->   expand-filename
       ^X^F   ->   read-from-file
       M-<    ->   beginning-of-history
       M->    ->   end-of-history
       \n     ->   newline
       \r     ->   newline
       M-o    ->   repeat-history
       M-^V   ->   vi-mode

       M-0, M-1, ... M-9  ->  digit-argument  (see below)

     Note that ^I is what the TAB key generates, and that ^@  can
     be  generated not only by pressing the control key and the @
     key simultaneously, but also by pressing the control key and
     the space bar at the same time.


DEFAULT KEY BINDINGS IN VI MODE

     The following default key bindings are designed to mimic the
     vi  style of editing as closely as possible. This means that
     very few editing functions are provided in the initial char-
     acter  input  mode, editing functions instead being provided
     by the vi command mode. Vi command mode is entered  whenever
     the  escape character is pressed, or whenever a key-sequence
     that starts with a meta character is entered. In addition to
     mimicing  vi, libtecla provides bindings for tab completion,
     wild-card expansion  of  file  names,  and  historical  line
     recall.

     To learn how to tell  the  tecla  library  to  use  vi  mode
     instead  of  the default emacs editing mode, see the section
     entitled THE TECLA CONFIGURATION FILE.

     As already mentioned above in the emacs section, Note that a
     key  sequence like ^A or C-a means hold the control-key down
     while pressing the letter A, and that where you see \E or M-
     in  a  binding,  this  represents the escape key or the Meta
     modifier key. Also note that to gl_get_line(), pressing  the
     escape  key  before a key is equivalent to pressing the meta
     key at the same time as that key. Thus the key sequence  M-p
     can  be  typed in two ways, by pressing the escape key, fol-
     lowed by pressing p, or by pressing the Meta key at the same
     time as p.

     Under UNIX the terminal driver sets a number of special keys
     for certain functions. The tecla library attempts to use the
     same keybindings to maintain consistency, binding them  both
     in  input  mode and in command mode. The key sequences shown
     for the following 6 bindings are thus just examples of  what
     they will probably be set to. If you have used the stty com-
     mand to change these keys, then the default bindings  should
     match.

       ^C     ->   user-interrupt
       ^\     ->   abort
       ^Z     ->   suspend
       ^Q     ->   start-output
       ^S     ->   stop-output
       ^V     ->   literal-next
       M-^C   ->   user-interrupt
       M-^\   ->   abort
       M-^Z   ->   suspend
       M-^Q   ->   start-output
       M-^S   ->   stop-output

     Note that above, most of the  bindings  are  defined  twice,
     once as a raw control code like ^C and then a second time as
     a meta character like M-^C. The former is the binding for vi
     input mode, whereas the latter is the binding for vi command
     mode. Once in command mode all key-sequences that  the  user
     types  that  they don't explicitly start with an escape or a
     meta key, have their first key secretly converted to a  meta
     character  before  the  key sequence is looked up in the key
     binding table. Thus, once in command mode, when you type the
     letter  i,  for example, the tecla library actually looks up
     the binding for M-i.

     The cursor keys are refered to by name, as follows. This  is
     necessary because different types of terminals generate dif-
     ferent key sequences when their cursor keys are pressed.

       right  ->   cursor-right
       left   ->   cursor-left
       up     ->   up-history
       down   ->   down-history

     The cursor keys normally generate a keysequence  that  start
     with  an  escape  character,  so beware that using the arrow
     keys will put you into command mode (if you  aren't  already
     in command mode).

     The following are the terminal-independent key bindings  for
     vi input mode.

       ^D     ->   list-or-eof
       ^G     ->   list-glob
       ^H     ->   backward-delete-char
       ^I     ->   complete-word
       \r     ->   newline
       \n     ->   newline
       ^L     ->   clear-screen
       ^N     ->   down-history
       ^P     ->   up-history
       ^R     ->   redisplay
       ^U     ->   backward-kill-line
       ^W     ->   backward-delete-word
       ^X*    ->   expand-filename
       ^X^F   ->   read-from-file
       ^?     ->   backward-delete-char

     The following are the key bindings that are  defined  in  vi
     command mode, this being specified by them all starting with
     a meta character. As mentioned above, once in  command  mode
     the  initial  meta  character  is optional. For example, you
     might enter command mode by typing Esc,  and  then  press  h
     twice  to  move the cursor two positions to the left. Both h
     characters get quietly converted to M-h  before  being  com-
     pared to the key-binding table, the first one because Escape
     followed  by  a  character  is  always  converted   to   the
     equivalent  meta  character,  and the second because command
     mode was already active.

       M-\     ->   cursor-right     (Meta-space)
       M-$     ->   end-of-line
       M-*     ->   expand-filename
       M-+     ->   down-history
       M--     ->   up-history
       M-<     ->   beginning-of-history
       M->     ->   end-of-history
       M-^     ->   beginning-of-line
       M-;     ->   repeat-find-char
       M-,     ->   invert-refind-char
       M-|     ->   goto-column
       M-~     ->   change-case
       M-.     ->   vi-repeat-change
       M-%     ->   find-parenthesis
       M-a     ->   vi-append
       M-A     ->   vi-append-at-eol
       M-b     ->   backward-word
       M-B     ->   backward-word
       M-C     ->   vi-change-rest-of-line
       M-cb    ->   vi-backward-change-word
       M-cB    ->   vi-backward-change-word
       M-cc    ->   vi-change-line
       M-ce    ->   vi-forward-change-word
       M-cE    ->   vi-forward-change-word
       M-cw    ->   vi-forward-change-word
       M-cW    ->   vi-forward-change-word
       M-cF    ->   vi-backward-change-find
       M-cf    ->   vi-forward-change-find
       M-cT    ->   vi-backward-change-to
       M-ct    ->   vi-forward-change-to
       M-c;    ->   vi-change-refind
       M-c,    ->   vi-change-invert-refind
       M-ch    ->   vi-backward-change-char
       M-c^H   ->   vi-backward-change-char
       M-c^?   ->   vi-backward-change-char
       M-cl    ->   vi-forward-change-char
       M-c\    ->   vi-forward-change-char  (Meta-c-space)
       M-c^    ->   vi-change-to-bol
       M-c0    ->   vi-change-to-bol
       M-c$    ->   vi-change-rest-of-line
       M-c|    ->   vi-change-to-column
       M-c%    ->   vi-change-to-parenthesis
       M-dh    ->   backward-delete-char
       M-d^H   ->   backward-delete-char
       M-d^?   ->   backward-delete-char
       M-dl    ->   forward-delete-char
       M-d     ->   forward-delete-char    (Meta-d-space)
       M-dd    ->   delete-line
       M-db    ->   backward-delete-word
       M-dB    ->   backward-delete-word
       M-de    ->   forward-delete-word
       M-dE    ->   forward-delete-word
       M-dw    ->   forward-delete-word
       M-dW    ->   forward-delete-word
       M-dF    ->   backward-delete-find
       M-df    ->   forward-delete-find
       M-dT    ->   backward-delete-to
       M-dt    ->   forward-delete-to
       M-d;    ->   delete-refind
       M-d,    ->   delete-invert-refind
       M-d^    ->   backward-kill-line
       M-d0    ->   backward-kill-line
       M-d$    ->   kill-line
       M-D     ->   kill-line
       M-d|    ->   delete-to-column
       M-d%    ->   delete-to-parenthesis
       M-e     ->   forward-word
       M-E     ->   forward-word
       M-f     ->   forward-find-char
       M-F     ->   backward-find-char
       M--     ->   up-history
       M-h     ->   cursor-left
       M-H     ->   beginning-of-history
       M-i     ->   vi-insert
       M-I     ->   vi-insert-at-bol
       M-j     ->   down-history
       M-J     ->   history-search-forward
       M-k     ->   up-history
       M-K     ->   history-search-backward
       M-l     ->   cursor-right
       M-L     ->   end-of-history
       M-n     ->   history-re-search-forward
       M-N     ->   history-re-search-backward
       M-p     ->   append-yank
       M-P     ->   yank
       M-r     ->   vi-replace-char
       M-R     ->   vi-overwrite
       M-s     ->   vi-forward-change-char
       M-S     ->   vi-change-line
       M-t     ->   forward-to-char
       M-T     ->   backward-to-char
       M-u     ->   vi-undo
       M-w     ->   forward-to-word
       M-W     ->   forward-to-word
       M-x     ->   forward-delete-char
       M-X     ->   backward-delete-char
       M-yh    ->   backward-copy-char
       M-y^H   ->   backward-copy-char
       M-y^?   ->   backward-copy-char
       M-yl    ->   forward-copy-char
       M-y\    ->   forward-copy-char  (Meta-y-space)
       M-ye    ->   forward-copy-word
       M-yE    ->   forward-copy-word
       M-yw    ->   forward-copy-word
       M-yW    ->   forward-copy-word
       M-yb    ->   backward-copy-word
       M-yB    ->   backward-copy-word
       M-yf    ->   forward-copy-find
       M-yF    ->   backward-copy-find
       M-yt    ->   forward-copy-to
       M-yT    ->   backward-copy-to
       M-y;    ->   copy-refind
       M-y,    ->   copy-invert-refind
       M-y^    ->   copy-to-bol
       M-y0    ->   copy-to-bol
       M-y$    ->   copy-rest-of-line
       M-yy    ->   copy-line
       M-Y     ->   copy-line
       M-y|    ->   copy-to-column
       M-y%    ->   copy-to-parenthesis
       M-^E    ->   emacs-mode
       M-^H    ->   cursor-left
       M-^?    ->   cursor-left
       M-^L    ->   clear-screen
       M-^N    ->   down-history
       M-^P    ->   up-history
       M-^R    ->   redisplay
       M-^D    ->   list-or-eof
       M-^I    ->   complete-word
       M-\r    ->   newline
       M-\n    ->   newline

       M-0, M-1, ... M-9  ->  digit-argument  (see below)

     Note that ^I is what the TAB key generates.


ENTERING REPEAT COUNTS

     Many of the key binding functions described previously, take
     an  optional  count, typed in before the target keysequence.
     This is interpretted as a repeat count by most  bindings.  A
     notable  exception  is the goto-column binding, which inter-
     prets the count as a column number.

     By default you can specify this count argument  by  pressing
     the  meta key while typing in the numeric count. This relies
     on the digit-argument action being bound to  Meta-0,  Meta-1
     etc.  Once any one of these bindings has been activated, you
     can optionally take your finger off the meta key to type  in
     the rest of the number, since every numeric digit thereafter
     is treated as part of the number, unless it is  preceded  by
     the literal-next binding. As soon as a non-digit, or literal
     digit key is pressed the  repeat  count  is  terminated  and
     either  causes  the  just typed character to be added to the
     line that many times, or causes the next  key-binding  func-
     tion to be given that argument.

     For example, in emacs mode, typing:

       M-12a

     causes the letter 'a' to be added  to  the  line  12  times,
     whereas

       M-4M-c

     Capitalizes the next 4 words.

     In vi command mode the Meta modifier is automatically  added
     to  all  characters  typed  in,  so  to  enter a count in vi
     command-mode, just involves typing in the number, just as at
     it  does in the vi editor itself. So for example, in vi com-
     mand mode, typing:

       4w2x

     moves the cursor four words to the right, then  deletes  two
     characters.

     You can also bind digit-argument to other key sequences.  If
     these  end  in  a numeric digit, that digit gets appended to
     the current repeat count. If it doesn't  end  in  a  numeric
     digit,  a  new repeat count is started with a value of zero,
     and can be completed by typing in the number, after  letting
     go of the key which triggered the digit-argument action.


THE TECLA CONFIGURATION FILE

     When new_GetLine() is called, it first defines  the  default
     emacs  key  bindings, as listed above, then looks for a file
     called .teclarc in your home directory (ie. ~/.teclarc).  If
     it  finds  this file, it reads it, interpreting each line as
     defining a new  key  binding  or  an  editing  configuration
     option.  For those wanting to use the non-default vi editing
     mode, the most important item to go in this file is the fol-
     lowing line:

       edit-mode vi

     This will re-configure the default bindings for vi-mode.

     To prevent the terminal bell from being rung, such  as  when
     an unrecognized control-sequence is typed, place the follow-
     ing line in the configuration file:

       nobeep

     An example of a key binding line in the  configuration  file
     is the following.

       bind M-[2~ insert-mode

     On a Sun keyboard, the above key sequence is generated  when
     one presses the insert key, so with this keybinding, one can
     toggle between emacs insert and overwrite  mode  by  hitting
     one  key.  One  could  also  do  it  by typing out the above
     sequence of characters one by one. As explained  above,  the
     M- part of this sequence can be typed either by pressing the
     escape key before the following key, or by pressing the Meta
     key  at  the same time as the following key. Thus if you had
     set the above key binding, and the insert key on  your  key-
     board  didn't  generate  the  above  key sequence, you could
     still type it in either of the following 2 ways.

       1. Hit the escape key momentarily, then press '[', then '2', then
          finally '~'.

       2. Press the meta key at the same time as pressing the '[' key,
          then press '2', then '~'.

     If you set a keybinding for a key-sequence that  is  already
     bound  to a function, the new binding overrides the old one.
     If in the new binding you omit the name of the new  function
     to  bind  to  the key-sequence, the original binding becomes
     undefined.

     Note that all key-sequences are required  to  start  with  a
     control  or  meta character. The only exception to this rule
     is for symbolically named characters such as the arrow keys.
     For example, to rebind the up and down arrow keys to use the
     history  search  mechanism  instead  of  the  simple  recall
     method, you would need to place the following in your confi-
     guration file:

       bind up history-search-backwards
       bind down history-search-backwards


FILENAME AND TILDE COMPLETION

     With the default key bindings, pressing the  TAB  key  (aka.
     ^I)  results  in  gl_get_line()  attempting  to complete the
     incomplete filename that precedes the cursor.  gl_get_line()
     searches backwards from the cursor, looking for the start of
     the filename, stopping when it hits either a  space  or  the
     start  of  the line. If more than one file has the specified
     prefix, gl_get_line() completes the filename up to the point
     at  which  the ambiguous matches start to differ, then lists
     the possible matches.

     In addition to literally  written  filenames,  gl_get_line()
     can complete files that start with ~/ and ~user/ expressions
     and that contain $envvar expressions. In particular, if  you
     hit    TAB   within   an   incomplete   ~user,   expression,
     gl_get_line() will attempt to complete the username, listing
     any ambiguous matches.

     The   completion   binding   is   implemented   using    the
     cpl_word_completions()  function,  which  is  also available
     separately   to   users   of   this   library.    See    the
     cpl_word_completions(3) man page for more details.


CUSTOMIZED WORD COMPLETION

     If in your application, you would like to have  TAB  comple-
     tion  complete  other  things  in  addition  or  instead  of
     filenames, you can arrange this by registering an  alternate
     completion   callback   function,   via   a   call   to  the
     gl_customize_completion() function.

       int gl_customize_completion(GetLine *gl, void *data,
                                   CplMatchFn *match_fn);

     The data argument provides a way  for  your  application  to
     pass  arbitrary,  application-specific  information  to  the
     callback function. This is passed to the callback every time
     that it is called. It might for example, point to the symbol
     table from which possible completions are to be sought.  The
     match_fn  argument  specifies  the  callback  function to be
     called.  The  CplMatchFn  function  type   is   defined   in
     libtecla.h, as is a CPL_MATCH_FN() macro that you can use to
     declare and prototype callback  functions.  The  declaration
     and  responsibilities of callback functions are described in
     depth in the cpl_complete_word(3) man page.

     In brief, the callback function is responsible  for  looking
     backwards  in  the  input line, back from the point at which
     the user pressed TAB, to find the start of  the  word  being
     completed.  It then must lookup possible completions of this
     word, and record them  one  by  one  in  the  WordCompletion
     object  that  is passed to it as an argument, by calling the
     cpl_add_completion()  function.  If  the  callback  function
     wishes to provide filename completion in addition to its own
     specific completions, it has the option  of  itself  calling
     the  builtin  file-name  completion  callback. This also, is
     documented in the cpl_complete_word(3) man page.


FILENAME EXPANSION

     With  the  default  key  bindings,   pressing   ^X*   causes
     gl_get_line()  to expand the filename that precedes the cur-
     sor,  replacing  ~/  and   ~user/   expressions   with   the
     corresponding   home   directories,  and  replacing  $envvar
     expressions with the  value  of  the  specified  environment
     variable,  then if there are any wildcards, replacing the so
     far expanded filename with a  space-separated  list  of  the
     files which match the wild cards.

     The   expansion   binding   is   implemented    using    the
     ef_expand_file()  function.   See  the ef_expand_file(3) man
     page for more details.


RECALLING PREVIOUSLY TYPED LINES

     Every time that a new line is entered by  the  user,  it  is
     appended  to  a  list  of  historical input lines maintained
     within the GetLine resource object. You can traverse up  and
     down  this  list  using the up and down arrow keys. Alterna-
     tively, you can do the same with the ^P, and ^N keys, and in
     vi  command mode you can alternatively use the k and j char-
     acters. Thus pressing up-arrow once,  replaces  the  current
     input  line  with  the previously entered line. Pressing up-
     arrow again, replaces this with the line  that  was  entered
     before it, etc.. Having gone back one or more lines into the
     history list, one can return  to  newer  lines  by  pressing
     down-arrow  one  or  more  times.  If you do this sufficient
     times, you will return to the original line  that  you  were
     entering when you first hit up-arrow.

     Note that in vi mode, all of the  history  recall  functions
     switch the library into command mode.

     In emacs mode the M-p and M-n keys work just like the ^P and
     ^N  keys,  except  that  they  skip all but those historical
     lines which share the prefix that precedes the cursor. In vi
     command  mode  the upper case K and J characters do the same
     thing, except that the string that they search for  includes
     the character under the cursor as well as what precedes it.

     Thus for example, suppose that you were in emacs  mode,  and
     you  had  just entered the following list of commands in the
     order shown:

       ls ~/tecla/
       cd ~/tecla
       ls -l getline.c
       emacs ~/tecla/getline.c

     If you next typed:

       ls

     and then hit M-p, then rather than returning the  previously
     typed   emacs   line,   which   doesn't   start  with  "ls",
     gl_get_line() would  recall  the  "ls  -l  getline.c"  line.
     Pressing M-p again would recall the "ls ~/tecla/" line.


CHANGING TERMINALS

     The new_GetLine() constructor function assumes that input is
     to  be  read  from  stdin, and output written to stdout. The
     following function allows you to switch to  different  input
     and output streams.

       int gl_change_terminal(GetLine *gl, FILE *input_fp,
                              FILE *output_fp, const char *term);

     The  gl  argument  is  the  object  that  was  returned   by
     new_GetLine().   The  input_fp argument specifies the stream
     to read from, and output_fp specifies the stream to be writ-
     ten  to.  Only  if  both  of these refer to a terminal, will
     interactive   terminal   input   be   enabled.     Otherwise
     gl_get_line()  will  simply  call  fgets()  to  read command
     input. If both streams refer to a terminal, then  they  must
     refer  to  the  same terminal, and the type of this terminal
     must be specified via the term argument. The  value  of  the
     term argument is looked up in the terminal information data-
     base (terminfo or termcap), in order to determine which spe-
     cial control sequences are needed to control various aspects
     of the  terminal.  new_GetLine()  for  example,  passes  the
     return  value  of getenv("TERM") in this argument. Note that
     if one or both of input_fp and output_fp don't  refer  to  a
     terminal,  then it is legal to pass NULL instead of a termi-
     nal type.

     Note  that  if  you  want  to  pass  file   descriptors   to
     gl_change_terminal(),  you  can  do  this  by creating stdio
     stream wrappers using the POSIX fdopen() function.


THREAD SAFETY

     In a multi-threaded program, you should use the libtecla_r.a
     version of the library. This uses reentrant versions of sys-
     tem functions, where available. Unfortunately  neither  ter-
     minfo  nor  termcap  were  designed  to be reentrant, so you
     can't safely use the functions of the getline module in mul-
     tiple  threads  (you can use the separate file-expansion and
     word-completion  modules  in  multiple  threads,   see   the
     corresponding man pages for details). However due to the use
     of POSIX reentrant functions for looking up home directories
     etc, it is safe to use this module from a single thread of a
     multi-threaded program, provided  that  your  other  threads
     don't use any termcap or terminfo functions.


FILES

     libtecla.a      -    The tecla library
     libtecla.h      -    The tecla header file.
     ~/.teclarc      -    The personal tecla customization file.


SEE ALSO

     libtecla(3),    ef_expand_file(3),     cpl_complete_word(3),
     pca_lookup_file(3)


AUTHOR

     Martin Shepherd  (mcs@astro.caltech.edu)