1 The Command-Line User Interface Term::Clui
2
3 NEW ! Now with mouse !
4 NEW ! Now with speech !
5
6Term::Clui offers a high-level user interface, with subroutines &choose
7&ask &edit &view &confirm and &sorry. It works at a higher level than
8widgets; it gives command-line applications a consistent "look and feel".
9Its metaphor for the computer is a human-like conversation-partner,
10and as each answer/response is completed it is summarised onto one line,
11and remains on screen, so that the history of the dialogue gradually
12accumulates on the screen and is available for review, or for cut/paste.
13Also included is the file-selector module Term::Clui::FileSelect,
14with its main subroutine &select_file. Term::Clui doesn't yet work
15under Windows.
16
17To install just:
18 perl Makefile.PL ; make ; make install
19
20For up-to-date source, see http://search.cpan.org/~pjb
21
22
23&edit and &view use the default EDITOR and PAGER from the user's
24environment, except that if &view is called with a very short text
25a builtin viewer is used, allowing the user to choose whether the
26text remains on-screen or is cleared.
27
28&confirm expects Y,y,N or n. &ask respects left and right arrows
29and backspace, ctrl-B moves to the beginning, ctrl-E to the end,
30and ctrl-D or ctrl-X clear the current string.
31
32&choose maintains a DBM database of what the user chose last time in
33response to the same question, and if it's still in the list this
34time then &choose highlights it as the default. Thus &choose manages
35its own defaults, and menus using Term::Clui autoconfigure themselves
36to the user's preferences. When &choose is called in an array context,
37it offers the user a multiple choice; mouse-button3 or the Spacebar
38mark items in a multiple choice. If the choices won't fit on the
39screen the user is asked for a substring clue.
40
41The programmer can pass &ask a default string, as an optional second
42argument. &select_file obeys options modelled after those of
43Tk::FileDialog.pm and Tk::SimpleFileSelect.pm
44
45Term::Clui is fast, very easy for both programmer and user, and has
46few external dependencies. It doesn't use curses which is a whole-of
47-screen interface; it uses a portable subset of vt100 sequences (up
48left right normal reverse clrtoeol and mouse-reporting). It handles
49window size changes, using Term::ReadKey or Term::Size if available;
50if not, it tries `tput`.
51
52For the user, Version 1.50 introduced a significant upgrade: mouse-
53-handling. The user can now select an item in &choose using the mouse
54and left-click, as well as by using the arrowkeys and return as before
55(or q or ctrl-X to quit); button3 or the spacebar mark items in a
56multiple choice. Since version 1.62, mouse-handling can be disabled
57by setting CLUI_MOUSE=OFF; by default, it is on.
58
59Since version 1.60, a speaking interface is provided for the visually
60impaired user. It employs either eflite or espeak. Speech is turned
61on if the CLUI_SPEAK environment variable is set to a non-empty string;
62by default, it is off. If speakup is running, then it is silenced
63while Term::Clui runs, and then restored. Because Term::Clui's
64metaphor for the computer is a human-like conversation-partner, this
65works very naturally, and the application needs no modification.
66
67A calling-interface-compatible Python3-module is included.
68
69Peter Billam http://www.pjb.com.au/comp/contact.html
70
README.md
1# NAME
2
3Term::Clui.pm - Perl module offering a Command-Line User Interface
4
5# SYNOPSIS
6
7```perl
8use Term::Clui;
9$chosen = choose("A Title", @a_list); # single choice
10@chosen = choose("A Title", @a_list); # multiple choice
11# multi-line question-texts are possible...
12$x = choose("Which ?\n(Mouse, or Arrow-keys and Return)", @w);
13$x = choose("Which ?\n".help_text(), @w);
14
15if (confirm($text)) { do_something(); };
16
17$answer = ask($question);
18$answer = ask($question,$suggestion);
19$password = ask_password("Enter password:");
20$filename = ask_filename("Which file ?"); # with Tab-completion
21
22$newtext = edit($title, $oldtext);
23edit($filename);
24
25view($title, $text) # if $title is not a filename
26view($textfile) # if $textfile _is_ a filename
27
28edit(choose("Edit which file ?", grep(-T, readdir D)));
29```
30
31# DESCRIPTION
32
33Term::Clui
34offers a high-level user interface to give the user of
35command-line applications a consistent "look and feel".
36Its metaphor for the computer is as a human-like conversation-partner,
37and as each question/response is completed it is summarised onto one line,
38and remains on screen, so that the history of the session gradually
39accumulates on the screen and is available for review, or for cut/paste.
40This user interface can therefore be intermixed with
41standard applications which write to STDOUT or STDERR,
42such as _make_, _pgp_, _rcs_ etc.
43
44For the user, _choose()_ uses either
45(since 1.50) the mouse;
46or arrow keys (or hjkl) and Return;
47also **q** to quit, and SpaceBar or Button3 to highlight multiple choices.
48_confirm()_ expects y, Y, n or N.
49In general, ctrl-L redraws the (currently active bit of the) screen.
50_edit()_ and _view()_ use the default EDITOR and PAGER if possible.
51
52It's fast, simple, and has few external dependencies.
53It doesn't use _curses_ (which is a whole-of-screen interface);
54it uses a small subset of vt100 sequences (up down left right normal
55and reverse) which are very portable,
56and also (since 1.50) the _SET\_ANY\_EVENT\_MOUSE_ and _kmous_ (terminfo)
57sequences,
58which are supported by all _xterm_, _rxvt_, _konsole_, _screen_,
59_linux_, _gnome_ and _putty_ terminals.
60
61There is an associated file selector, Term::Clui::FileSelect
62
63Since version 1.60, a speaking interface is provided
64for the visually-impaired user;
65it employs _eflite_ or _espeak_.
66Speech is turned on if the _CLUI\_SPEAK_ environment variable
67is set to any non-empty string.
68Since version 1.62, if _speakup_ is running,
69it is silenced while Term::Clui runs, and then restored.
70Because Term::Clui's metaphor for the computer
71is a human-like conversation-partner, this works very naturally.
72The application needs no modification.
73
74There is an equivalent Python3 module,
75with (as far as possible) the same calling interface, at
76http://cpansearch.perl.org/src/PJB/Term-Clui-1.71/py/TermClui.py
77
78This is Term::Clui.pm version 1.71
79
80# WINDOW-SIZE
81
82Term::Clui attempts to handle the WINCH signal.
83If the window size is changed,
84then as soon as the user enters the next keystroke (such as ctrl-L)
85the current question/response will be redisplayed to fit the new size.
86
87The first line of the question, the one which will remain on-screen, is
88not re-formatted, but is left to be dealt with by the width of the window.
89Subsequent lines are split into blank-separated words which are
90filled into the available width; lines beginning with white-space
91are treated as the beginning of a new indented paragraph,
92individual words which will not fit onto one line are truncated,
93and successive blank lines are collapsed into one.
94If the question will not fit within the available rows, it is truncated.
95
96If the available choice items in a _choose()_ overflow the screen,
97the user is asked to enter "clue" letters,
98and as soon as the items matching them will fit onto the screen
99they are displayed as a choice.
100
101# SUBROUTINES
102
103- _ask_( $question ); OR _ask_( $question, $default );
104
105 Asks the user the question and returns a string answer,
106 with no newline character at the end.
107 If the optional second argument is present,
108 it is offered to the user as a default.
109 If the _$question_ is multi-line,
110 the entry-field is at the top to the right of the first line,
111 and the subsequent lines are formatted within the
112 screen width and displayed beneath, as with _choose_.
113
114 For the user, left and right arrow keys move backward and forward
115 through the string, delete and backspace erase the previous character,
116 ctrl-A moves to the beginning, ctrl-E to the end,
117 and ctrl-D or ctrl-X clear the current string.
118
119- _ask\_password_( $question );
120
121 Does the same with no echo, as used for password entry.
122
123- _ask\_filename_( $question );
124
125 Uses _Term::ReadLine::Gnu_ to provide filename-completion with
126 the _Tab_ key, but also displays multi-line questions in the
127 same way as _ask_ and _choose_ do.
128 This function was introduced in version 1.65.
129
130- _choose_( $question, @list );
131
132 Displays the question, and formats the list items onto the lines beneath it.
133
134 If _choose_ is called in a scalar context,
135 the user can choose an item using arrow keys (or hjkl) and Return,
136 or cancel the choice with a "q".
137 _choose_ then returns the chosen item,
138 or _undefined_ if the choice was cancelled.
139
140 If _choose_ is called in an array context,
141 the user can also mark an item with the SpaceBar.
142 _choose_ then returns the list of marked items,
143 (including the item highlit when Return was pressed),
144 or an empty array if the choice was cancelled.
145
146 A DBM database is maintained of the question and its chosen response.
147 The next time the user is offered a choice with the same question,
148 if that response is still in the list it is highlighted
149 as the default; otherwise the first item is highlighted.
150 Different parts of the code, or different applications using _Term::Clui.pm_
151 can therefore exchange defaults simply by using the same question words,
152 such as "Which printer ?".
153 Multiple choices are not remembered, as the danger exists
154 that the user might fail to notice some of the highlit items
155 (for example, all the items might not fit onto one screen).
156
157 The database _~/.clui\_dir/choices_ or _$ENV{CLUI\_DIR}/choices_
158 is available to be read or written if lower-level manipulation is needed,
159 and the _EXPORT\_OK_ routines _get\_default_($question) and
160 _set\_default_($question, $choice) should be used for this purpose,
161 as they handle DBM's problem with concurrent accesses.
162 The whole default database mechanism can be disabled by
163 _CLUI\_DIR=OFF_ if you really want to :-(
164
165 If the items won't fit on the screen, the user is asked to enter
166 a substring as a clue. As soon as the matching items will fit,
167 they are displayed to be chosen as normal. If the user pressed "q"
168 at this choice, they are asked if they wish to change their substring
169 clue; if they reply "n" to this, choose quits and returns _undefined_.
170
171 If the $question is multi-line,
172 The first line is put at the top as usual with the choices
173 arranged beneath it; the subsequent lines are formatted within the
174 screen width and displayed at the bottom.
175 After the choice is made all but the first line is erased,
176 and the first line remains on-screen with the choice appended after it.
177 You should therefore try to arrange multi-line questions
178 so that the first line is the question in short form,
179 and subsequent lines are explanation and elaboration.
180
181- _confirm_( $question );
182
183 Asks the question, takes "y", "n", "Y" or "N" as a response.
184 If the $question is multi-line, after the response, all but the first
185 line is erased, and the first line remains on-screen with _Yes_ or _No_
186 appended after it; you should therefore try to arrange multi-line
187 questions so that the first line is the question in short form,
188 and subsequent lines are explanation and elaboration.
189 Returns true or false.
190
191- _edit_( $title, $text ); OR _edit_( $filename );
192
193 Uses the environment variable EDITOR ( or _vi_ :-)
194 Uses RCS if directory RCS/ exists
195
196- _sorry_( $message );
197
198 Similar to _warn "Sorry, $message\\n";_
199
200- _inform_( $message );
201
202 Similar to _warn "$message\\n";_ except that it doesn't add the
203 newline at the end if there already is one,
204 and it uses _/dev/tty_ rather than _STDERR_ if it can.
205
206- _view_( $title, $text ); OR _view_( $filename );
207
208 If the _$text_ is longer than a screenful, uses the environment
209 variable PAGER ( or _less_ ) to display it.
210 If it is one or two lines it just omits the title and displays it.
211 Otherwise it uses a simple built-in routine which expects either "q"
212 or _Return_ from the user; if the user presses _Return_
213 the displayed text remains on the screen and the dialogue continues
214 after it, if the user presses "q" the text is erased.
215
216 If there is only one argument and it's a filename,
217 then the user's PAGER displays it,
218 except (since 1.65) if it's a _.doc_ file, when either
219 _wvText_, _antiword_ or _catdoc_ is used to extract its contents first.
220
221- _help\_text_( $mode );
222
223 This returns a short help message for the user.
224 If _mode_ is "ask" then the text describes the keys the user has available
225 when responding to an _&ask_ question;
226 If _mode_ is "multi" then the text describes the keys
227 and mouse actions the user has available
228 when responding to a multiple-choice _&choose_ question;
229 otherwise, the text describes the keys
230 and mouse actions the user has available
231 when responding to a single-choice _&choose_.
232
233# EXPORT\_OK SUBROUTINES
234
235The following routines are not exported by default, but are
236exported under the _ALL_ tag, so if you need them you should:
237
238```
239import Term::Clui qw(:ALL);
240```
241
242- _beep_()
243
244 Beeps.
245
246- _timestamp_()
247
248 Returns a sortable timestamp string in "YYYYMMDD hhmmss" form.
249
250- _get\_default_( $question )
251
252 Consults the database _~/.clui\_dir/choices_ or
253 _$ENV{CLUI\_DIR}/choices_ and returns the choice that
254 the user made the last time this question was asked.
255 This is better than opening the database directly
256 as it handles DBM's problem with concurrent accesses.
257
258- _set\_default_( $question, $new\_default )
259
260 Opens the database _~/.clui\_dir/choices_ or
261 _$ENV{CLUI\_DIR}/choices_ and sets the default response which will
262 be offered to the user made the next time this question is asked.
263 This is better than opening the database directly
264 as it handles DBM's problem with concurrent accesses.
265
266# DEPENDENCIES
267
268It requires Exporter, which is core Perl.
269It uses Term::ReadKey if it's available;
270and uses Term::Size if it's available;
271if not, it tries _tput_ before guessing 80x24.
272
273# ENVIRONMENT
274
275The environment variable _CLUI\_DIR_ can be used (by programmer or user)
276to override _~/.clui\_dir_ as the directory in which _choose()_ keeps
277its database of previous choices.
278The whole default database mechanism can be disabled by
279_CLUI\_DIR = OFF_ if you really want to :-(
280
281If either the LANG or the LC\_TYPE environment variables
282contain the string _utf8_ or _utf-8_ (case insensitive),
283then _choose()_ and _inform()_ open _/dev/tty_ with a _utf8_ encoding.
284
285If the environment variable _CLUI\_SPEAK_ is set
286or if _EDITOR_ is set to _emacspeak_,
287and if _flite_ is installed,
288then _Term::Clui_ will use _flite_
289to speak its questions and choices out loud.
290
291If the environment variable _CLUI\_MOUSE_ is set to _OFF_
292then _choose()_ will not interpret mouse-clicks as making a choice.
293The advantage of this is that the mouse can then be used
294to highlight and paste text from this window as usual.
295
296_Term::Clui_ also consults the environment variables
297HOME, LOGDIR, EDITOR and PAGER, if they are set.
298
299# EXAMPLES
300
301These scripts using Term::Clui and Term::Clui::FileSelect are to
302be found in the _examples_ subdirectory of the build directory.
303
304- _linux\_admin_
305
306 I use this script a lot at work, for routine system administration of
307 linux boxes, particularly Fedora and Debian. It includes crontab,
308 chkconfig, update-rc.d, visudo, vipw, starting and stopping daemons,
309 reconfiguring squid samba or apache, editing sysconfig or running
310 any of the system-config-\* utilities, and much else.
311
312- _audio\_stuff_
313
314 This script offers an arrow-key-and-return interface integrating
315 aplaymidi, cdrecord, cdda2wav, icedax, lame, mkisofs, muscript,
316 normalize, normalize-audio,
317 mpg123, sndfile-play, timidity, wodim and so on,
318 allowing audio files to be ripped,
319 burned, played, or converted between Muscript, MIDI, WAV and MP3 formats.
320
321- _login\_shell_
322
323 This script offers the naive user arrow-key-and-return access
324 to a text-based browser, a mail client, a news client, ssh and ftp
325 and various other stuff.
326
327- _test\_script_
328
329 This is the test script, as used during development.
330
331- _choose_
332
333 This is a script which wraps Term::Clui::choose for use at the shell-script
334 level. It can either choose between command-line arguments,
335 or, with the **-f** (filter) option, between lines of STDIN, like grep.
336 A **-m** (multiple) option allows multiple-choice.
337 This can be a very useful script, and you may want to copy it into
338 _/usr/local/bin/_ or elsewhere in your PATH.
339
340# AUTHOR
341
342Original author:
343
344Peter J Billam www.pjb.com.au/comp/contact.html
345
346Current maintainer:
347
348Graham Ollis
349
350Contributors:
351
352Peter Scott
353
354# CREDITS
355
356Based on some old perl 4 libraries, _ask.pl_, _choose.pl_,
357_confirm.pl_, _edit.pl_, _sorry.pl_, _inform.pl_ and _view.pl_,
358which were in turn based on some even older curses-based programs in _C_.
359
360# SEE ALSO
361
362```
363Term::Clui::FileSelect
364Term::ReadKey
365Term::Size
366http://www.pjb.com.au/
367http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
368http://search.cpan.org/~pjb
369festival(1)
370eflite(1)
371espeak(1)
372espeakup(1)
373edbrowse(1)
374emacspeak(1)
375perl(1)
376```
377
378There is an equivalent Python3 module,
379with (as far as possible) the same calling interface, at
380https://fastapi.metacpan.org/source/PJB/Term-Clui-1.71/py/TermClui.py
381