• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

CHANGESH A D03-May-20223 KiB6857

MakefileH A D03-May-20221.3 KiB4432

READMEH A D19-Oct-19938.8 KiB194160

getline.3H A D15-May-19939.4 KiB377328

getline.cH A D15-Jan-199828.2 KiB1,117970

getline.hH A D15-Jan-1998872 3622

testgl.cH A D15-Jan-1998275 1912

README

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