<HTML><HEAD>
|
<HTML><HEAD>
|
<TITLE>Index of /usr/skunk/src/Tools/getline</TITLE>
|
<TITLE>Index of /usr/skunk/src/Tools/getline</TITLE>
|
</HEAD><BODY>
|
</HEAD><BODY>
|
<H1>Index of /usr/skunk/src/Tools/getline</H1>
|
<H1>Index of /usr/skunk/src/Tools/getline</H1>
|
<PRE><IMG SRC="/icons/blank.xbm" ALT=" "> Name Last modified Size Description
|
<PRE><IMG SRC="/icons/blank.xbm" ALT=" "> Name Last modified Size Description
|
<HR>
|
<HR>
|
<IMG SRC="/icons/back.xbm" ALT="[DIR]"> <A HREF="/usr/skunk/src/Tools/">Parent Directory</A> 01-Aug-95 06:43 -
|
<IMG SRC="/icons/back.xbm" ALT="[DIR]"> <A HREF="/usr/skunk/src/Tools/">Parent Directory</A> 01-Aug-95 06:43 -
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="CHANGES">CHANGES</A> 03-May-95 10:08 3k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="CHANGES">CHANGES</A> 03-May-95 10:08 3k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="Makefile">Makefile</A> 21-Jun-95 05:42 1k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="Makefile">Makefile</A> 21-Jun-95 05:42 1k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.3">getline.3</A> 03-May-95 10:08 9k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.3">getline.3</A> 03-May-95 10:08 9k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.c">getline.c</A> 03-May-95 10:08 28k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.c">getline.c</A> 03-May-95 10:08 28k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.h">getline.h</A> 03-May-95 10:08 1k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.h">getline.h</A> 03-May-95 10:08 1k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="testgl.c">testgl.c</A> 03-May-95 10:08 1k
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="testgl.c">testgl.c</A> 03-May-95 10:08 1k
|
</PRE><HR>
|
</PRE><HR>
|
<PRE>
|
<PRE>
|
*************************** Motivation **********************************
|
*************************** Motivation **********************************
|
|
|
Many interactive programs read input line by line, but would like to
|
Many interactive programs read input line by line, but would like to
|
provide line editing and history functionality to the end-user that
|
provide line editing and history functionality to the end-user that
|
runs the program.
|
runs the program.
|
|
|
The input-edit package provides that functionality. As far as the
|
The input-edit package provides that functionality. As far as the
|
programmer is concerned, the program only asks for the next line
|
programmer is concerned, the program only asks for the next line
|
of input. However, until the user presses the RETURN key they can use
|
of input. However, until the user presses the RETURN key they can use
|
emacs-style line editing commands and can traverse the history of lines
|
emacs-style line editing commands and can traverse the history of lines
|
previously typed.
|
previously typed.
|
|
|
Other packages, such as GNU's readline, have greater capability but are
|
Other packages, such as GNU's readline, have greater capability but are
|
also substantially larger. Input-edit is small, since it uses neither
|
also substantially larger. Input-edit is small, since it uses neither
|
stdio nor any termcap features, and is also quite portable. It only uses
|
stdio nor any termcap features, and is also quite portable. It only uses
|
\b to backspace and \007 to ring the bell on errors. Since it cannot
|
\b to backspace and \007 to ring the bell on errors. Since it cannot
|
edit multiple lines it scrolls long lines left and right on the same line.
|
edit multiple lines it scrolls long lines left and right on the same line.
|
|
|
Input edit uses classic (not ANSI) C, and should run on any Unix
|
Input edit uses classic (not ANSI) C, and should run on any Unix
|
system (BSD, SYSV or POSIX), PC's under DOS with MSC, TurboC or djgpp,
|
system (BSD, SYSV or POSIX), PC's under DOS with MSC, TurboC or djgpp,
|
PC's under OS/2 with gcc (EMX), or Vax/VMS. Porting the package to new
|
PC's under OS/2 with gcc (EMX), or Vax/VMS. Porting the package to new
|
systems basicaly requires code to read a character when it is typed without
|
systems basicaly requires code to read a character when it is typed without
|
echoing it, everything else should be OK.
|
echoing it, everything else should be OK.
|
|
|
I have run the package on:
|
I have run the package on:
|
|
|
DECstation 5000, Ultrix 4.3 with cc 2.1 and gcc 2.3.3
|
DECstation 5000, Ultrix 4.3 with cc 2.1 and gcc 2.3.3
|
Sun Sparc 2, SunOS 4.1.1, with cc
|
Sun Sparc 2, SunOS 4.1.1, with cc
|
SGI Iris, IRIX System V.3, with cc
|
SGI Iris, IRIX System V.3, with cc
|
PC using DOS with MSC
|
PC using DOS with MSC
|
|
|
The description below is broken into two parts, the end-user (editing)
|
The description below is broken into two parts, the end-user (editing)
|
interface and the programmer interface. Send bug reports, fixes and
|
interface and the programmer interface. Send bug reports, fixes and
|
enhancements to:
|
enhancements to:
|
|
|
Chris Thewalt (thewalt@ce.berkeley.edu)
|
Chris Thewalt (thewalt@ce.berkeley.edu)
|
5/3/93
|
5/3/93
|
|
|
Thanks to the following people who have provided enhancements and fixes:
|
Thanks to the following people who have provided enhancements and fixes:
|
Ron Ueberschaer, Christoph Keller, Scott Schwartz, Steven List,
|
Ron Ueberschaer, Christoph Keller, Scott Schwartz, Steven List,
|
DaviD W. Sanderson, Goran Bostrom, Michael Gleason, Glenn Kasten,
|
DaviD W. Sanderson, Goran Bostrom, Michael Gleason, Glenn Kasten,
|
Edin Hodzic, Eric J Bivona, Kai Uwe Rommel, Danny Quah, Ulrich Betzler
|
Edin Hodzic, Eric J Bivona, Kai Uwe Rommel, Danny Quah, Ulrich Betzler
|
|
|
PS: I don't have, and don't want to add, a vi mode, sorry.
|
PS: I don't have, and don't want to add, a vi mode, sorry.
|
|
|
************************** End-User Interface ***************************
|
************************** End-User Interface ***************************
|
|
|
Entering printable keys generally inserts new text into the buffer (unless
|
Entering printable keys generally inserts new text into the buffer (unless
|
in overwrite mode, see below). Other special keys can be used to modify
|
in overwrite mode, see below). Other special keys can be used to modify
|
the text in the buffer. In the description of the keys below, ^n means
|
the text in the buffer. In the description of the keys below, ^n means
|
Control-n, or holding the CONTROL key down while pressing "n". Errors
|
Control-n, or holding the CONTROL key down while pressing "n". Errors
|
will ring the terminal bell.
|
will ring the terminal bell.
|
|
|
^A/^E : Move cursor to beginning/end of the line.
|
^A/^E : Move cursor to beginning/end of the line.
|
^F/^B : Move cursor forward/backward one character.
|
^F/^B : Move cursor forward/backward one character.
|
ESC-F : Move cursor forward one word.
|
ESC-F : Move cursor forward one word.
|
ESC-B : Move cursor backward one word.
|
ESC-B : Move cursor backward one word.
|
^D : Delete the character under the cursor.
|
^D : Delete the character under the cursor.
|
^H, DEL : Delete the character to the left of the cursor.
|
^H, DEL : Delete the character to the left of the cursor.
|
^K : Kill from the cursor to the end of line.
|
^K : Kill from the cursor to the end of line.
|
^L : Redraw current line.
|
^L : Redraw current line.
|
^O : Toggle overwrite/insert mode. Initially in insert mode. Text
|
^O : Toggle overwrite/insert mode. Initially in insert mode. Text
|
added in overwrite mode (including yanks) overwrite
|
added in overwrite mode (including yanks) overwrite
|
existing text, while insert mode does not overwrite.
|
existing text, while insert mode does not overwrite.
|
^P/^N : Move to previous/next item on history list.
|
^P/^N : Move to previous/next item on history list.
|
^R/^S : Perform incremental reverse/forward search for string on
|
^R/^S : Perform incremental reverse/forward search for string on
|
the history list. Typing normal characters adds to the current
|
the history list. Typing normal characters adds to the current
|
search string and searches for a match. Typing ^R/^S marks
|
search string and searches for a match. Typing ^R/^S marks
|
the start of a new search, and moves on to the next match.
|
the start of a new search, and moves on to the next match.
|
Typing ^H or DEL deletes the last character from the search
|
Typing ^H or DEL deletes the last character from the search
|
string, and searches from the starting location of the last search.
|
string, and searches from the starting location of the last search.
|
Therefore, repeated DEL's appear to unwind to the match nearest
|
Therefore, repeated DEL's appear to unwind to the match nearest
|
the point at which the last ^R or ^S was typed. If DEL is
|
the point at which the last ^R or ^S was typed. If DEL is
|
repeated until the search string is empty the search location
|
repeated until the search string is empty the search location
|
begins from the start of the history list. Typing ESC or
|
begins from the start of the history list. Typing ESC or
|
any other editing character accepts the current match and
|
any other editing character accepts the current match and
|
loads it into the buffer, terminating the search.
|
loads it into the buffer, terminating the search.
|
^T : Toggle the characters under and to the left of the cursor.
|
^T : Toggle the characters under and to the left of the cursor.
|
^U : Deletes the entire line
|
^U : Deletes the entire line
|
^Y : Yank previously killed text back at current location. Note that
|
^Y : Yank previously killed text back at current location. Note that
|
this will overwrite or insert, depending on the current mode.
|
this will overwrite or insert, depending on the current mode.
|
TAB : By default adds spaces to buffer to get to next TAB stop
|
TAB : By default adds spaces to buffer to get to next TAB stop
|
(just after every 8th column), although this may be rebound by the
|
(just after every 8th column), although this may be rebound by the
|
programmer, as described below.
|
programmer, as described below.
|
NL, CR : returns current buffer to the program.
|
NL, CR : returns current buffer to the program.
|
|
|
DOS and ANSI terminal arrow key sequences are recognized, and act like:
|
DOS and ANSI terminal arrow key sequences are recognized, and act like:
|
|
|
up : same as ^P
|
up : same as ^P
|
down : same as ^N
|
down : same as ^N
|
left : same as ^B
|
left : same as ^B
|
right : same as ^F
|
right : same as ^F
|
|
|
************************** Programmer Interface ***************************
|
************************** Programmer Interface ***************************
|
|
|
The programmer accesses input-edit through these functions, and optionally
|
The programmer accesses input-edit through these functions, and optionally
|
through three additional function pointer hooks. The four functions are:
|
through three additional function pointer hooks. The four functions are:
|
|
|
char *gl_getline(char *prompt)
|
char *gl_getline(char *prompt)
|
|
|
Prints the prompt and allows the user to edit the current line. A
|
Prints the prompt and allows the user to edit the current line. A
|
pointer to the line is returned when the user finishes by
|
pointer to the line is returned when the user finishes by
|
typing a newline or a return. Unlike GNU readline, the returned
|
typing a newline or a return. Unlike GNU readline, the returned
|
pointer points to a static buffer, so it should not be free'd, and
|
pointer points to a static buffer, so it should not be free'd, and
|
the buffer contains the newline character. The user enters an
|
the buffer contains the newline character. The user enters an
|
end-of-file by typing ^D on an empty line, in which case the
|
end-of-file by typing ^D on an empty line, in which case the
|
first character of the returned buffer is '\0'. Getline never
|
first character of the returned buffer is '\0'. Getline never
|
returns a NULL pointer. The getline functions sets terminal modes
|
returns a NULL pointer. The getline functions sets terminal modes
|
needed to make it work, and resets them before returning to the
|
needed to make it work, and resets them before returning to the
|
caller. The getline function also looks for characters that would
|
caller. The getline function also looks for characters that would
|
generate a signal, and resets the terminal modes before raising the
|
generate a signal, and resets the terminal modes before raising the
|
signal condition. If the signal handler returns to getline,
|
signal condition. If the signal handler returns to getline,
|
the screen is automatically redrawn and editing can continue.
|
the screen is automatically redrawn and editing can continue.
|
Getline now requires both the input and output stream be connected
|
Getline now requires both the input and output stream be connected
|
to the terminal (not redirected) so the main program should check
|
to the terminal (not redirected) so the main program should check
|
to make sure this is true. If input or output have been redirected
|
to make sure this is true. If input or output have been redirected
|
the main program should use buffered IO (stdio) rather than
|
the main program should use buffered IO (stdio) rather than
|
the slow 1 character read()s that getline uses.
|
the slow 1 character read()s that getline uses.
|
|
|
void gl_setwidth(int width)
|
void gl_setwidth(int width)
|
|
|
Set the width of the terminal to the specified width. The default
|
Set the width of the terminal to the specified width. The default
|
width is 80 characters, so this function need only be called if the
|
width is 80 characters, so this function need only be called if the
|
width of the terminal is not 80. Since horizontal scrolling is
|
width of the terminal is not 80. Since horizontal scrolling is
|
controlled by this parameter it is important to get it right.
|
controlled by this parameter it is important to get it right.
|
|
|
void gl_histadd(char *buf)
|
void gl_histadd(char *buf)
|
|
|
The gl_histadd function checks to see if the buf is not empty or
|
The gl_histadd function checks to see if the buf is not empty or
|
whitespace, and also checks to make sure it is different than
|
whitespace, and also checks to make sure it is different than
|
the last saved buffer to avoid repeats on the history list.
|
the last saved buffer to avoid repeats on the history list.
|
If the buf is a new non-blank string a copy is made and saved on
|
If the buf is a new non-blank string a copy is made and saved on
|
the history list, so the caller can re-use the specified buf.
|
the history list, so the caller can re-use the specified buf.
|
|
|
void gl_strwidth(size_t (*func)())
|
void gl_strwidth(size_t (*func)())
|
The gl_strwidth function allows the caller to supply a pointer to
|
The gl_strwidth function allows the caller to supply a pointer to
|
a prompt width calculation function (strlen by default). This
|
a prompt width calculation function (strlen by default). This
|
allows the caller to embed escape sequences in the prompt and then
|
allows the caller to embed escape sequences in the prompt and then
|
tell getline how many screen spaces the prompt will take up.
|
tell getline how many screen spaces the prompt will take up.
|
|
|
The main loop in testgl.c, included in this directory, shows how the
|
The main loop in testgl.c, included in this directory, shows how the
|
input-edit package can be used:
|
input-edit package can be used:
|
|
|
extern char *getline();
|
extern char *getline();
|
extern void gl_histadd();
|
extern void gl_histadd();
|
main()
|
main()
|
{
|
{
|
char *p;
|
char *p;
|
do {
|
do {
|
p = getline("PROMPT>>>> ");
|
p = getline("PROMPT>>>> ");
|
gl_histadd(p);
|
gl_histadd(p);
|
fputs(p, stdout);
|
fputs(p, stdout);
|
} while (*p != 0);
|
} while (*p != 0);
|
}
|
}
|
|
|
In order to allow the main program to have additional access to the buffer,
|
In order to allow the main program to have additional access to the buffer,
|
to implement things such as completion or auto-indent modes, three
|
to implement things such as completion or auto-indent modes, three
|
function pointers can be bound to user functions to modify the buffer as
|
function pointers can be bound to user functions to modify the buffer as
|
described below. By default gl_in_hook and gl_out_hook are set to NULL,
|
described below. By default gl_in_hook and gl_out_hook are set to NULL,
|
and gl_tab_hook is bound to a function that inserts spaces until the next
|
and gl_tab_hook is bound to a function that inserts spaces until the next
|
logical tab stop is reached. The user can reassign any of these pointers
|
logical tab stop is reached. The user can reassign any of these pointers
|
to other functions. Each of the functions bound to these hooks receives
|
to other functions. Each of the functions bound to these hooks receives
|
the current buffer as the first argument, and must return the location of
|
the current buffer as the first argument, and must return the location of
|
the leftmost change made in the buffer. If the buffer isn't modified the
|
the leftmost change made in the buffer. If the buffer isn't modified the
|
functions should return -1. When the hook function returns the screen is
|
functions should return -1. When the hook function returns the screen is
|
updated to reflect any changes made by the user function.
|
updated to reflect any changes made by the user function.
|
|
|
int (*gl_in_hook)(char *buf)
|
int (*gl_in_hook)(char *buf)
|
|
|
If gl_in_hook is non-NULL the function is called each time a new
|
If gl_in_hook is non-NULL the function is called each time a new
|
buffer is loaded. It is called when getline is entered, with an
|
buffer is loaded. It is called when getline is entered, with an
|
empty buffer, it is called each time a new buffer is loaded from
|
empty buffer, it is called each time a new buffer is loaded from
|
the history with ^P or ^N, and it is called when an incremental
|
the history with ^P or ^N, and it is called when an incremental
|
search string is accepted (when the search is terminated). The
|
search string is accepted (when the search is terminated). The
|
buffer can be modified and will be redrawn upon return to getline().
|
buffer can be modified and will be redrawn upon return to getline().
|
|
|
int (*gl_out_hook)(char *buf)
|
int (*gl_out_hook)(char *buf)
|
|
|
If gl_out_hook is non-NULL it is called when a line has been
|
If gl_out_hook is non-NULL it is called when a line has been
|
completed by the user entering a newline or return. The buffer
|
completed by the user entering a newline or return. The buffer
|
handed to the hook does not yet have the newline appended. If the
|
handed to the hook does not yet have the newline appended. If the
|
buffer is modified the screen is redrawn before getline returns the
|
buffer is modified the screen is redrawn before getline returns the
|
buffer to the caller.
|
buffer to the caller.
|
|
|
int (*gl_tab_hook)(char *buf, int prompt_width, int *cursor_loc)
|
int (*gl_tab_hook)(char *buf, int prompt_width, int *cursor_loc)
|
|
|
If gl_tab_hook is non-NULL, it is called whenever a tab is typed.
|
If gl_tab_hook is non-NULL, it is called whenever a tab is typed.
|
In addition to receiving the buffer, the current prompt width is
|
In addition to receiving the buffer, the current prompt width is
|
given (needed to do tabbing right) and a pointer to the cursor
|
given (needed to do tabbing right) and a pointer to the cursor
|
offset is given, where a 0 offset means the first character in the
|
offset is given, where a 0 offset means the first character in the
|
line. Not only does the cursor_loc tell the programmer where the
|
line. Not only does the cursor_loc tell the programmer where the
|
TAB was received, but it can be reset so that the cursor will end
|
TAB was received, but it can be reset so that the cursor will end
|
up at the specified location after the screen is redrawn.
|
up at the specified location after the screen is redrawn.
|
</PRE>
|
</PRE>
|
</BODY></HTML>
|
</BODY></HTML>
|
|
|