1 |
8 |
hellwig |
<HTML><HEAD>
|
2 |
|
|
<TITLE>Index of /usr/skunk/src/Tools/getline</TITLE>
|
3 |
|
|
</HEAD><BODY>
|
4 |
|
|
<H1>Index of /usr/skunk/src/Tools/getline</H1>
|
5 |
|
|
<PRE><IMG SRC="/icons/blank.xbm" ALT=" "> Name Last modified Size Description
|
6 |
|
|
<HR>
|
7 |
|
|
<IMG SRC="/icons/back.xbm" ALT="[DIR]"> <A HREF="/usr/skunk/src/Tools/">Parent Directory</A> 01-Aug-95 06:43 -
|
8 |
|
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="CHANGES">CHANGES</A> 03-May-95 10:08 3k
|
9 |
|
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="Makefile">Makefile</A> 21-Jun-95 05:42 1k
|
10 |
|
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.3">getline.3</A> 03-May-95 10:08 9k
|
11 |
|
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.c">getline.c</A> 03-May-95 10:08 28k
|
12 |
|
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="getline.h">getline.h</A> 03-May-95 10:08 1k
|
13 |
|
|
<IMG SRC="/icons/unknown.xbm" ALT="[ ]"> <A HREF="testgl.c">testgl.c</A> 03-May-95 10:08 1k
|
14 |
|
|
</PRE><HR>
|
15 |
|
|
<PRE>
|
16 |
|
|
*************************** Motivation **********************************
|
17 |
|
|
|
18 |
|
|
Many interactive programs read input line by line, but would like to
|
19 |
|
|
provide line editing and history functionality to the end-user that
|
20 |
|
|
runs the program.
|
21 |
|
|
|
22 |
|
|
The input-edit package provides that functionality. As far as the
|
23 |
|
|
programmer is concerned, the program only asks for the next line
|
24 |
|
|
of input. However, until the user presses the RETURN key they can use
|
25 |
|
|
emacs-style line editing commands and can traverse the history of lines
|
26 |
|
|
previously typed.
|
27 |
|
|
|
28 |
|
|
Other packages, such as GNU's readline, have greater capability but are
|
29 |
|
|
also substantially larger. Input-edit is small, since it uses neither
|
30 |
|
|
stdio nor any termcap features, and is also quite portable. It only uses
|
31 |
|
|
\b to backspace and \007 to ring the bell on errors. Since it cannot
|
32 |
|
|
edit multiple lines it scrolls long lines left and right on the same line.
|
33 |
|
|
|
34 |
|
|
Input edit uses classic (not ANSI) C, and should run on any Unix
|
35 |
|
|
system (BSD, SYSV or POSIX), PC's under DOS with MSC, TurboC or djgpp,
|
36 |
|
|
PC's under OS/2 with gcc (EMX), or Vax/VMS. Porting the package to new
|
37 |
|
|
systems basicaly requires code to read a character when it is typed without
|
38 |
|
|
echoing it, everything else should be OK.
|
39 |
|
|
|
40 |
|
|
I have run the package on:
|
41 |
|
|
|
42 |
|
|
DECstation 5000, Ultrix 4.3 with cc 2.1 and gcc 2.3.3
|
43 |
|
|
Sun Sparc 2, SunOS 4.1.1, with cc
|
44 |
|
|
SGI Iris, IRIX System V.3, with cc
|
45 |
|
|
PC using DOS with MSC
|
46 |
|
|
|
47 |
|
|
The description below is broken into two parts, the end-user (editing)
|
48 |
|
|
interface and the programmer interface. Send bug reports, fixes and
|
49 |
|
|
enhancements to:
|
50 |
|
|
|
51 |
|
|
Chris Thewalt (thewalt@ce.berkeley.edu)
|
52 |
|
|
5/3/93
|
53 |
|
|
|
54 |
|
|
Thanks to the following people who have provided enhancements and fixes:
|
55 |
|
|
Ron Ueberschaer, Christoph Keller, Scott Schwartz, Steven List,
|
56 |
|
|
DaviD W. Sanderson, Goran Bostrom, Michael Gleason, Glenn Kasten,
|
57 |
|
|
Edin Hodzic, Eric J Bivona, Kai Uwe Rommel, Danny Quah, Ulrich Betzler
|
58 |
|
|
|
59 |
|
|
PS: I don't have, and don't want to add, a vi mode, sorry.
|
60 |
|
|
|
61 |
|
|
************************** End-User Interface ***************************
|
62 |
|
|
|
63 |
|
|
Entering printable keys generally inserts new text into the buffer (unless
|
64 |
|
|
in overwrite mode, see below). Other special keys can be used to modify
|
65 |
|
|
the text in the buffer. In the description of the keys below, ^n means
|
66 |
|
|
Control-n, or holding the CONTROL key down while pressing "n". Errors
|
67 |
|
|
will ring the terminal bell.
|
68 |
|
|
|
69 |
|
|
^A/^E : Move cursor to beginning/end of the line.
|
70 |
|
|
^F/^B : Move cursor forward/backward one character.
|
71 |
|
|
ESC-F : Move cursor forward one word.
|
72 |
|
|
ESC-B : Move cursor backward one word.
|
73 |
|
|
^D : Delete the character under the cursor.
|
74 |
|
|
^H, DEL : Delete the character to the left of the cursor.
|
75 |
|
|
^K : Kill from the cursor to the end of line.
|
76 |
|
|
^L : Redraw current line.
|
77 |
|
|
^O : Toggle overwrite/insert mode. Initially in insert mode. Text
|
78 |
|
|
added in overwrite mode (including yanks) overwrite
|
79 |
|
|
existing text, while insert mode does not overwrite.
|
80 |
|
|
^P/^N : Move to previous/next item on history list.
|
81 |
|
|
^R/^S : Perform incremental reverse/forward search for string on
|
82 |
|
|
the history list. Typing normal characters adds to the current
|
83 |
|
|
search string and searches for a match. Typing ^R/^S marks
|
84 |
|
|
the start of a new search, and moves on to the next match.
|
85 |
|
|
Typing ^H or DEL deletes the last character from the search
|
86 |
|
|
string, and searches from the starting location of the last search.
|
87 |
|
|
Therefore, repeated DEL's appear to unwind to the match nearest
|
88 |
|
|
the point at which the last ^R or ^S was typed. If DEL is
|
89 |
|
|
repeated until the search string is empty the search location
|
90 |
|
|
begins from the start of the history list. Typing ESC or
|
91 |
|
|
any other editing character accepts the current match and
|
92 |
|
|
loads it into the buffer, terminating the search.
|
93 |
|
|
^T : Toggle the characters under and to the left of the cursor.
|
94 |
|
|
^U : Deletes the entire line
|
95 |
|
|
^Y : Yank previously killed text back at current location. Note that
|
96 |
|
|
this will overwrite or insert, depending on the current mode.
|
97 |
|
|
TAB : By default adds spaces to buffer to get to next TAB stop
|
98 |
|
|
(just after every 8th column), although this may be rebound by the
|
99 |
|
|
programmer, as described below.
|
100 |
|
|
NL, CR : returns current buffer to the program.
|
101 |
|
|
|
102 |
|
|
DOS and ANSI terminal arrow key sequences are recognized, and act like:
|
103 |
|
|
|
104 |
|
|
up : same as ^P
|
105 |
|
|
down : same as ^N
|
106 |
|
|
left : same as ^B
|
107 |
|
|
right : same as ^F
|
108 |
|
|
|
109 |
|
|
************************** Programmer Interface ***************************
|
110 |
|
|
|
111 |
|
|
The programmer accesses input-edit through these functions, and optionally
|
112 |
|
|
through three additional function pointer hooks. The four functions are:
|
113 |
|
|
|
114 |
|
|
char *gl_getline(char *prompt)
|
115 |
|
|
|
116 |
|
|
Prints the prompt and allows the user to edit the current line. A
|
117 |
|
|
pointer to the line is returned when the user finishes by
|
118 |
|
|
typing a newline or a return. Unlike GNU readline, the returned
|
119 |
|
|
pointer points to a static buffer, so it should not be free'd, and
|
120 |
|
|
the buffer contains the newline character. The user enters an
|
121 |
|
|
end-of-file by typing ^D on an empty line, in which case the
|
122 |
|
|
first character of the returned buffer is '\0'. Getline never
|
123 |
|
|
returns a NULL pointer. The getline functions sets terminal modes
|
124 |
|
|
needed to make it work, and resets them before returning to the
|
125 |
|
|
caller. The getline function also looks for characters that would
|
126 |
|
|
generate a signal, and resets the terminal modes before raising the
|
127 |
|
|
signal condition. If the signal handler returns to getline,
|
128 |
|
|
the screen is automatically redrawn and editing can continue.
|
129 |
|
|
Getline now requires both the input and output stream be connected
|
130 |
|
|
to the terminal (not redirected) so the main program should check
|
131 |
|
|
to make sure this is true. If input or output have been redirected
|
132 |
|
|
the main program should use buffered IO (stdio) rather than
|
133 |
|
|
the slow 1 character read()s that getline uses.
|
134 |
|
|
|
135 |
|
|
void gl_setwidth(int width)
|
136 |
|
|
|
137 |
|
|
Set the width of the terminal to the specified width. The default
|
138 |
|
|
width is 80 characters, so this function need only be called if the
|
139 |
|
|
width of the terminal is not 80. Since horizontal scrolling is
|
140 |
|
|
controlled by this parameter it is important to get it right.
|
141 |
|
|
|
142 |
|
|
void gl_histadd(char *buf)
|
143 |
|
|
|
144 |
|
|
The gl_histadd function checks to see if the buf is not empty or
|
145 |
|
|
whitespace, and also checks to make sure it is different than
|
146 |
|
|
the last saved buffer to avoid repeats on the history list.
|
147 |
|
|
If the buf is a new non-blank string a copy is made and saved on
|
148 |
|
|
the history list, so the caller can re-use the specified buf.
|
149 |
|
|
|
150 |
|
|
void gl_strwidth(size_t (*func)())
|
151 |
|
|
The gl_strwidth function allows the caller to supply a pointer to
|
152 |
|
|
a prompt width calculation function (strlen by default). This
|
153 |
|
|
allows the caller to embed escape sequences in the prompt and then
|
154 |
|
|
tell getline how many screen spaces the prompt will take up.
|
155 |
|
|
|
156 |
|
|
The main loop in testgl.c, included in this directory, shows how the
|
157 |
|
|
input-edit package can be used:
|
158 |
|
|
|
159 |
|
|
extern char *getline();
|
160 |
|
|
extern void gl_histadd();
|
161 |
|
|
main()
|
162 |
|
|
{
|
163 |
|
|
char *p;
|
164 |
|
|
do {
|
165 |
|
|
p = getline("PROMPT>>>> ");
|
166 |
|
|
gl_histadd(p);
|
167 |
|
|
fputs(p, stdout);
|
168 |
|
|
} while (*p != 0);
|
169 |
|
|
}
|
170 |
|
|
|
171 |
|
|
In order to allow the main program to have additional access to the buffer,
|
172 |
|
|
to implement things such as completion or auto-indent modes, three
|
173 |
|
|
function pointers can be bound to user functions to modify the buffer as
|
174 |
|
|
described below. By default gl_in_hook and gl_out_hook are set to NULL,
|
175 |
|
|
and gl_tab_hook is bound to a function that inserts spaces until the next
|
176 |
|
|
logical tab stop is reached. The user can reassign any of these pointers
|
177 |
|
|
to other functions. Each of the functions bound to these hooks receives
|
178 |
|
|
the current buffer as the first argument, and must return the location of
|
179 |
|
|
the leftmost change made in the buffer. If the buffer isn't modified the
|
180 |
|
|
functions should return -1. When the hook function returns the screen is
|
181 |
|
|
updated to reflect any changes made by the user function.
|
182 |
|
|
|
183 |
|
|
int (*gl_in_hook)(char *buf)
|
184 |
|
|
|
185 |
|
|
If gl_in_hook is non-NULL the function is called each time a new
|
186 |
|
|
buffer is loaded. It is called when getline is entered, with an
|
187 |
|
|
empty buffer, it is called each time a new buffer is loaded from
|
188 |
|
|
the history with ^P or ^N, and it is called when an incremental
|
189 |
|
|
search string is accepted (when the search is terminated). The
|
190 |
|
|
buffer can be modified and will be redrawn upon return to getline().
|
191 |
|
|
|
192 |
|
|
int (*gl_out_hook)(char *buf)
|
193 |
|
|
|
194 |
|
|
If gl_out_hook is non-NULL it is called when a line has been
|
195 |
|
|
completed by the user entering a newline or return. The buffer
|
196 |
|
|
handed to the hook does not yet have the newline appended. If the
|
197 |
|
|
buffer is modified the screen is redrawn before getline returns the
|
198 |
|
|
buffer to the caller.
|
199 |
|
|
|
200 |
|
|
int (*gl_tab_hook)(char *buf, int prompt_width, int *cursor_loc)
|
201 |
|
|
|
202 |
|
|
If gl_tab_hook is non-NULL, it is called whenever a tab is typed.
|
203 |
|
|
In addition to receiving the buffer, the current prompt width is
|
204 |
|
|
given (needed to do tabbing right) and a pointer to the cursor
|
205 |
|
|
offset is given, where a 0 offset means the first character in the
|
206 |
|
|
line. Not only does the cursor_loc tell the programmer where the
|
207 |
|
|
TAB was received, but it can be reset so that the cursor will end
|
208 |
|
|
up at the specified location after the screen is redrawn.
|
209 |
|
|
</PRE>
|
210 |
|
|
</BODY></HTML>
|