howl.interact
Overview
The howl.interact module acts as the central registry of interactions in Howl
and lets you register new interactions as well as invoke interactions. An
interaction is a piece of functionality that is invoked as a function call and
it retrieves some information from the user. Interactions use the command line,
and optionally additional widgets, to get information from the user. For
example, consider this call to the read_text
interaction:
name = howl.interact.read_text prompt: 'Enter your name:'
Here the read_text
interaction displays the given prompt in the command line
and lets the user type some text. When the user presses enter
, the command
line is closed and the read_text
function returns the text entered by user. If
the user presses escape
, the function returns nil
.
Interactions are commonly used to read user input when implementing interactive
commands. Howl includes a number of built-in interactions, such
as select_file
, which lets the user choose a file, and select
, which lets
the user choose an item from a list of options - see Built-in
interactions below for details.
An interaction is implemented as simple table that provides the name of the interaction, a description, and either a handler or a factory field. Simple interactions that just customize other interactions can be implemented easily with just a handler function. More complex interactions that need greater control on the command line behavior are implemented as factory based interactions. Details for both handler and factory based interactions are in register below.
Interactions are run by the command line, which maintains a stack of running interactions. While one or more interactions are running, the command line API can be used to display prompts in the command line, read and update the command line text, as well as attach helper widgets above the command line (for example, a ListWidget may show a completion list).
See also:
- The CommandLine module for details about the command line API
- The command module for more information about commands in Howl
Functions
register (def)
Registers a new interaction. Registered interactions are available as fields on
the interact
module itself, using the interaction name.
def
is a table with the following fields:
name
: [required] The name of the interaction.description
: [required] A short description of the interaction.handler
orfactory
: [required] One ofhandler
orfactory
must be specified, but not both.
The handler
function implements the interaction and returns the result of the
interaction. Here is an example definition of a handler:
handler: -> howl.interact.select items: {'red', 'blue', 'green'}
The above handler displays a selection list containing three items and lets the
user select one. Note that it reuses the select
interaction. Handler functions
are blocking - i.e. the function does not return until the result of the
interaction is available.
The handler function may accept arguments. Any arguments passed when calling the interaction are passed through to the handler function.
Interactions can also be implemented as factory based interactions. The
factory
field is a function that returns an interaction instance table. This
table describes how various events should be handled and has the following
fields:
run
: [required] A function that is called when the interaction is invoked. This function is called with afinish
callback function as the first argument, followed by all arguments that were passed in the interaction call. The command line is displayed and holds the cursor while the interaction is active. The interaction must callfinish
whenever the result of the interaction is ready and it must pass the result as the argument tofinish
. The interaction is active untilfinish
is called, so it is important to callfinish
at some point.on_update
: [optional] A function that is called every time the text in the command line is updated. The interaction instance table and the new text are passed as two arguments to the function.If the command line API is used to update the command line text from within the
run
or theon_update
function thenon_update
is not called. However, if the command line text is updated when the user types some text, or from within a keymap function,on_update
is called.keymap
: [optional] A keymap that is used while the interaction is active. This table specifies a mapping from keystroke names to functions. When a key matching the keystroke name is pressed, the function is invoked and the interaction instance table is passed as the first argument.help
: [optional] A table containing one or more help entries, which specify the help text for bound keystrokes. The format of help entries is the same as used byadd_help
.
Here is an example implementation of an interaction using a factory:
factory: -> { run: (@finish) => @command_line = howl.app.window.command_line @command_line.prompt = 'Text:' on_update: (text) => log.info text keymap: enter: => self.finish @command_line.text escape: => self.finish! binding_for: ['view-close']: => self.finish! help: { { key_for: 'view-close' action: 'Cancel this' } { heading: 'Syntax' title: 'Use [some specific syntax]' } } }
The above example displays ‘Text:’ as the command line prompt and lets the user
enter any text in the command line. Whenever the text is updated by the user,
the interaction shows it in an info message. When the user presses enter
, the
interaction finishes, returning the text entered by the user. If the user
presses escape
, the interaction finishes, returning nil
.
Note the special key called binding_for
in the keymap. This demonstrates how a
keystroke can be specified indirectly instead
of by hard-coding. In the above example, the “view-close” key within
“binding-for” refers to the keystroke currently bound to the “view-close”
command. This means if the user presses the keystroke that is bound to the
“view-close” command - which is ctrl_shift_w
by default - the associated
function will be invoked, closing the command line and returning nil
. If the
user has changed the key binding for the “view-close” command, that keystroke
will be bound to the function above instead.
Also note that help text has been specified for the keystroke bound to the
view-close
command. For the default binding, this will display a message like
‘ctrl_shift_w Cancel this’ in the command help.
unregister (name)
Unregister an interaction with the name name
.
Built-in interactions
read_text (opts)
Lets the user enter free form text in the command line. Returns the text entered
by the user when the user presses enter
, or nil
if the user presses
escape
. opts
is a table that contains the following fields:
prompt
: [optional] The prompt displayed in the command line.title
: [optional] The title displayed in the command line title bar.
Example:
name = howl.interact.read_text title:'Name', prompt:'Enter name:' log.info 'Hello '..name if name
select (opts)
Displays a list of options to the user and lets the user select one by using the
up
and down
arrow keys and pressing enter
. Also lets the user narrow down
the options by typing something in the command line - the options list is then
filtered to show only those items that match the entered text.
Allows customization such as multiple columns, column headers, styling, user provided selection etc. These are described below.
If the user presses enter
, returns a table containing two fields - selection
and text
, where:
selection
is the item selected by the user (ornil
ifallow_new_value
was specified and the user specified option was selected - seeallow_new_value
below).text
is the command line text at the timeenter
was pressed.
If the user presses escape
, nil
is returned.
opts
is a table that specifies:
items
ormatcher
: [required] One ofitems
ormatcher
must be specified, but not both.items
is a table containing a list of items, where each item represents one select-able option and can be either a string for a single column list, or a table for a multiple column list. When each item is a table, it contains a list of strings, one each for each column. Instead of a string, a StyledText object can be used as well.matcher
is a function that accepts a string and returns a table of items similar toitems
. When called with the empty string,matcher
should return a list of all options. As the user types text into the command line, thematcher
function is called repeatedly and passed the typed text - it should return a filtered list of items matching the given text.
prompt
: [optional] The prompt displayed in the command line.title
: [optional] The title displayed in the command line title bar.columns
: [optional] A table containing the header text and style for each column. Identical to thecolumns
argument in the StyledText.for_table function.keymap
: [optional] An additional keymap to used for this interaction.on_change
: [optional] A function callback that is called whenever the user changes the currently selected item or updates the text in the command line. The callback function is called with the three arguments(selection, text, items)
, where:selection
is the newly selected itemtext
is the current text in the command lineitems
is the current (possibly filtered) list of items
selection
: [optional] The item that is initially selected by default. This must be an item in theitems
list.hide_until_tab
: [optional, default: false] When set totrue
, the list of items is initially hidden and only displayed when the user pressestab
.allow_new_value
: [optional, default: false] When set totrue
, allows the user to choose an option that is user specified and not available in the list of available items. The user does this by typing some text that does not exactly match any available option. This causes an additional option containing the user’s text to be automatically added to the list of options. The user can then select this new option (identifiable because it shows ‘New’ next to it) and pressenter
.reverse
: [optional, default: false] When set totrue
, the list is displayed reversed, i.e. the first item is displayed at the bottom and subsequent items above it.
Examples:
The following example displays a list of three items with a column header. It also lets the user specify a color that is not in the given list.
color = howl.interact.select items: {'red', 'blue', 'green'} columns: {{header: 'Color'}} allow_new_value: true if color if color.selection log.info 'You selected:'..color.selection else log.info 'You selected a new color:'..color.text
The following example displays a two column list. It also shows how string fields can be used in the items table. Unlike numerically indexed fields, string fields are not displayed, but they can be used to associate additional data with each item.
action = howl.interact.select items: { {'Run', 'Run this file', cmd: 'run'}, {'Compile', 'Compile this file', cmd: 'compile'}, } if action if action.selection.cmd == 'run' log.info 'running...' else log.info 'compiling...'
select_buffer (opts)
Lets the user select a buffer from a list of all buffers. opts
is a table
containing:
prompt
: [optional] The prompt displayed in the command line. Default is no prompt.title
: [optional] The title displayed in the command line title bar. Default is ‘Buffers’.
Returns the Buffer selected by the user, or nil
if the user
presses escape
.
select_directory (opts)
Lets the user select a directory. Displays sub directories in a completion list and allows the user to navigate the file system using either the completion list or typing a path in the command line.
opts
is a table containing:
title
: [optional] The title displayed in the command line title bar. Default is ‘Directory’.allow_new
: [optional, default: false] Whentrue
, allows the user to choose a nonexistent path by typing it in the command line and pressing enter.
Returns the File selected by the user, or nil
if the user presses escape
.
Note that if allow_new
was specified, the returned file object may refer to a
nonexistent path.
select_file (opts)
Lets the user select a file. Displays files in the completion list and allows the user to navigate the file system using the completion list or typing a path in the command line.
opts
is a table containing:
title
: [optional] The title displayed in the command line title bar. Default is ‘File’.allow_new
: [optional, default: false] Whentrue
, allows the user to choose a nonexistent path by typing it in the command line and pressing enter.directory_reader
: [optional] A callback function that is used for getting the list of files in any directory. The function should accept one argument - a File object for a directory - and should return a list of File objects for the contents of the given directory.
Returns the File selected by the user, or nil
if the user presses escape
.
Note that if allow_new
was specified, the returned file object may refer to a
nonexistent path.
select_file_in_project (opts)
Lets the user select a file from a completion list containing all files in the
current project. opts
is a table containing:
title
: [optional] The title displayed in the command line title bar. Default is the project path.
Returns the File selected by the user, or nil
if the user presses escape
.
select_line(opts)
Lets the user select a line from a list of source lines. opts
is a table
similar to the table accepted by select, with the following
differences:
items
,matcher
andon_change
cannot be specified.lines
must be provided and should be a list of Line objects.
If the user presses enter
, returns a table containing:
line
: the Line object selected by the user.text
: the command line text at the timeenter
was pressed.column
: the first position within line that matches the user entered text.
If the user presses escape
, nil
is returned.
select_location(opts)
Very similar to select, lets the user select an item from a list of
options. In addition, it displays a preview of the currently selected option in
the editor. Each item in items
(or returned by matcher
) must also have the
following fields:
file
orbuffer
: One offile
orbuffer
must be provided. This specifies which file or buffer is previewed in the editor when this item is selected:line_nr
: The line number infile
orbuffer
that is centered during the preview.
yes_or_no (opts)
Lets the user select either ‘Yes’ or ‘No’ as an answer to a question. Returns
true
if the user selects ‘Yes’, false
if the user selects ‘No’ and nil
if
the user presses escape
. opts
is table containing:
prompt
: [optional] The prompt displayed in the command line. Default is no prompt.title
: [optional] The title displayed in the command line title bar. Default is no title.