.TH smenu 1 "2015" "beta"
.SH NAME
smenu - filter that allows one to interactively select a word from stdin
and outputs the selection to stdout.
.SH SYNOPSIS
.nf
\f(CRsmenu [\fB-h\fP|\fB-?\fP] [\fB-f\fP \fIconfiguration_file\fP] \\
[\fB-n\fP [\fIlines\fP]] [\fB-t\fP [\fIcols\fP]] [\fB-k\fP] \\
[\fB-s\fP \fIpattern\fP] [\fB-m\fP \fImessage\fP] [\fB-w\fP] \\
[\fB-d\fP] [\fB-M\fP] [\fB-c\fP] [\fB-l\fP] [\fB-r\fP] [\fB-b\fP] \\
[\fB-a\fP \
(i|e|c|b|si|m|t|ct|sf|st|mf|mt|sfe|ste|mfe|mte|da):\fIATTR\fP]... \\
[\fB-i\fP \fIregex\fP] [\fB-e\fP \fIregex\fP] \\
[\fB-C\fP \
[\fIi\fP|\fIe\fP]
] \\
[\fB-R\fP \
[\fIi\fP|\fIe\fP]] \\
[\fB-S\fP \fI/regex/string/\fP[\fIg\fP][\fIv\fP][\fIs\fP][\fIi\fP]] \\
[\fB-I\fP \fI/regex/string/\fP[\fIg\fP][\fIv\fP][\fIs\fP][\fIi\fP]] \\
[\fB-E\fP \fI/regex/string/\fP[\fIg\fP][\fIv\fP][\fIs\fP][\fIi\fP]] \\
[\fB-A\fP \fIregex\fP] [\fB-Z\fP \fIregex\fP] \\
[\fB-N\fP [\fIregex\fP]] [\fB-U\fP [\fIregex\fP]] [\fB-F\fP] \
[\fB-D\fP \fIsub-option\fP...] \\
[\fB-1\fP \fIregex\fP [\fIATTR\fP]] \
[\fB-2\fP \fIregex\fP [\fIATTR\fP]] ... \
[\fB-5\fP \fIregex\fP [\fIATTR\fP]] \\
[\fB-g\fP [\fIstring\fP]] [\fB-q\fP] \
[\fB-W\fP \fIbytes\fP] [\fB-L\fP \fIbytes\fP] \\
[\fB-T\fP [\fIseparator\fP]] [\fB-P\fP [\fIseparator\fP]] [\fB-p\fP] \\
[\fB-V\fP] [\fB-x\fP|\fB-X\fP \fItype\fP [\fIword\fP] \fIdelay\fP] \
[\fB-/\fP \fIprefix\fP|\fIsubstring\fP|\fIfuzzy\fP] \\
[input_file]
::= \fIcol1\fP[-\fIcol2\fP],...|\fI\fP,...
::= \fIcol1\fP[-\fIcol2\fP],...|\fI\fP,...
::= [l|r:]|[a:left|right]|[p:included|all|
[w:]|[f:yes|no]|[o:[+]]|[n:]|
[i:]|[d:]|[s:]|[h:trim|cut|keep]
::= [fg][/bg][,style]
::= \fB\fIregex\fB\fR
and can be freely mixed.
The parameters of -a and -D must be delimited by blanks.
.fi
.SH DESCRIPTION
This small utility acts as a filter when no input file is given
(reads from stdin and writes to stdout) or takes its inputs from that file.
All read words are presented in a scrolling window on the terminal
\fBat\fP the current cursor position without clearing the screen before.
.PP
The selection cursor is initially positioned on the first selectable word
by default.
.PP
Options exists to explicitly or implicitly include or exclude some words by
using extended regular expressions.
Notice that when some words are explicitly excluded they can no more be
re-included after.
.PP
Excluded words are skipped when the selection cursor is moved and cannot
be searched for.
.PP
The \fB-W\fP option can be used to set the characters (or multibyte
sequences) which will be used to delimit the input words.
The default delimiters are: \fISPACE\fP, \fI\\t\fP and \fI\\n\fP.
.PP
The \fB-L\fP has a similar meaning for lines.
Special character sequences formed by a \fI\\\fP followed by one of the
characters \fIa\fP \fIb\fP \fIt\fP \fIn\fP \fIv\fP \fIf\fP \fIr\fP and
\fI\\\fP are understood and have their traditional meanings.
UTF-8 sequences introduced by \fI\\u\fP are also understood.
\fI\\u\fP can be followed by 2,4,6 or 8 hexadecimal characters.
An invalid UTF-8 sequence will be replaced by a dot (\fI.\fP), see
also below.
Example: \fI\\uc3a9\fP means latin small letter e with acute.
.PP
Note that with most shells, the \fI\\\fP before the \fIu\fP need to be
protected or escaped.
.PP
Quotations (single and double) in the input stream can be used to ignore
the word separators so that a group of words are taken as a single entity.
.PP
Non printable characters in words that are not delimiters are
converted to their traditional form (\fI\\n\fP for end-of-line,
\fI\\t\fP for tabulation...) by default.
A single dot (\fI.\fP) is also used as a placeholder otherwise.
.PP
Words containing only spaces, entered directly or resulting from a
substitution, are also rejected unless they are not selectable.
This allows special effects like creating blank lines for example.
These words are also kept in column mode, selectable or not.
.PP
\fBWarning\fP, \fBUTF-8\fP encoded codepoints are quietly converted
into dots (\fI.\fP) when the user locale is not \fBUTF-8\fP aware like
\fBPOSIX\fP or \fBC\fP by example.
.PP
.SS "Moving among words"
The cursor can be moved in every direction by using the
keyboard arrow keys (\fB\(<-\fP,\fB\(da\fP,\fB\(ua\fP,\fB\(->\fP)
or the \fIvi\fP direction keys (\fBh\fP, \fBj\fP, \fBk\fP and \fBl\fP).
\fBHOME\fP, \fBEND\fP, \fBPgDn\fP and \fBPgUp\fP can also be used,
if available, and have the following meanings:
.TS
tab(@);
l l.
\fB\(<-\fP, \fBh\fP@Previous word
\fBCTRL\ \(<-\fP, \fBH\fP@Start of line
\fB\(ua\fP, \fBk\fP@Previous line
\fBPgUp\fP, \fBK\fP@Previous page
\fBHOME\fP@First word of the window
\fBCTRL\ HOME\fP, \fBSHIFT\ HOME\fP, \fBCTRL\ K\fP@First word
\fB\(->\fP, \fBl\fP@Next word
\fBCTRL\ \(->\fP, \fBL\fP@End of line
\fB\(da\fP, \fBj\fP@Next line
\fBPgDn\fP, \fBJ\fP@Next page
\fBEND\fP@Last word of the window
\fBCTRL\ END\fP, \fBSHIFT\ END\fP, \fBCTRL\ J\fP@Last word
.TE
\fBCTRL\ \(<-\fP/\fBH\fP (resp. \fBCTRL\ \(->\fP/\fBL\fP) places the cursor
so that a maximum number of words (selectable or not) are visible to
the left (reps. right) side of the window.
If \fB-N\fP, \fB-U\fP or \fB-F\fP are used, then it becomes possible to
directly access a word by entering its number.
The numbering created using these option is done \fBbefore\fP any words
substitution done using \fB-S\fP, \fB-I\fP or \fB-E\fP.
Using a combination of these options, it is easy to control which words
will be numbered by adding a special symbol in it before using smenu and
removing it (substituted by nothing) afterward using \fB-I\fP by example.
\fB-E\fP gives another way to do that, see below or more.
.SS "Searching for words"
A word can be searched using different algorithms: \fIprefix\fP,
\fIsubstring\fP of \fIfuzzy\fP.
.TP
\fIprefix\fP (keys \fB^\fP or \fB=\fP):
The sequence of characters entered must match the beginning of a word.
.TP
\fIsubstring\fP (keys \fB"\fP or \fB'\fP):
The sequence of characters entered must match a substring in a word.
.TP
\fIfuzzy\fP (keys \fB~\fP or \fB*\fP):
All the characters in the entered sequence must appear in the same order
in a word, but need not be consecutive.
The case is also ignored.
The cursor is placed, if possible, on the first matching word having the
minimum number of gaps between the first and last matching character,
see the difference between the actions of the \fBs\fP/\fBS\fP and
\fBn\fP/\fBN\fP keys below.
This method also tolerates intermediate symbols not appearing in the
words which will be ignored.
If this is the case, the attributes of the approximatively matching
words are changed into an error versions of them to warn the user to
this situation.
The erroneous symbols will \fInot\fP be inserted in the search buffer.
For example: if the word \fBabcdef\fP is present in the standard input,
then entering \f(CBabxcdye\fP puts \fBabcdef\fP in the search buffer
and the word is added to the list of matching words and displayed with
an error attribute (in red by default).
This special state will persist until all the symbols following the first
erroneous one are deleted (using backspace) or if \fBESC\fP is pressed.
.PP
During a search session, the cursor changes and each character entered is
added in (or removed from) the search buffer.
The display is refreshed after each change in this buffer.
.PP
The slash key (fB/\fP) can also be used instead of any of these keys.
By default it is is programmed to do a \fIfuzzy\fP search but this can
be changed by using the command line option (\fB-/\fP) or by tuning
a configuration file, see below.
.PP
All the words matching the current search buffer are enhanced:
The characters present in the current search buffer are highlighted in
one way and the other characters in another way.
Both of these highlighting methods are configurable.
.PP
If the user has entered the search sequence: \fBo\fP, \fBs\fP, then the
matching word "words" will be displayed as \fBw\fP\fIo\fP\fBrd\fP\fIs\fP
when the \fIfuzzy\fP algorithm is in use depending of the display
attributes configured.
.PP
\fBESC\fP can be used anytime to abort the current search session.
\fBENTER\fP and all cursor moves also terminate the search
session but do not clear the list of the matchng words.
.PP
The user can then use the \fBn\fP/\fBs\fP/\fBSPACE\fP keys (forward) and
the \fBN\fP/\fBS\fP keys (backward) to navigate in the list of matching
words,
In \fIfuzzy\fP search mode, the \fBs\fP/\fBS\fP keys attempt to move the
cursor to the next/previous word whose matching part forms a substring
of this word.
If no such matches exist, \fBs\fP/\fBS\fP and \fBn\fP/\fBN\fP do the
same things.
To move the cursor to the next/previous fuzzy match, use the
\fBn\fP/\fBN\fP/\fBSPACE\fP keys.
\fBs\fP means next \fPs\fPubstring match in this context while \fBn\fP
just means \fBn\fPext match.
.PP
If the user hits the \fBHOME\fP or \fBEND\fP key during a search session
then the list of matching words is reduced to the words starting
(respectively) ending with the current search pattern and the window
is refreshed.
For those who consider \fBHOME\fP and \fBEND\fP as non-intuitive,
the \fBCTRL\ A\fP and \fBCTRL\ Z\fP keys are also available in search mode
as an alternative.
This behaviour is persistent until the user hit the \fBESC\fP or
\fBENTER\fP key.
For example, if the search pattern in substring mode is \f(CBsh\fP and
the user hits \fBEND\fP, then only the words \fIending\fP with \f(CBsh\fP
will be added in the searched word list and enhanced.
Note that when a matching word is selected, its enhanced characters only
show one of the multiple matching possibilities.
When not in a search session \fBESC\fP can be also used to clear the
list of matching words and to reset the search buffer.
.PP
In summary, here is the meaning of the special keys in search mode:
.TS
tab(@);
lb s s
l l c
^ ^ l
l lw(6c) c .
Keys which clear the list of matching words.
Key@Meaning@Closes
@@the
@@search
@@session
_
Esc@Cancel search@Yes
_
.T&
lb s s
l l l
^ ^ l
l lw(6c) c .
Keys which keep or update the list of matching words.
Key@Meaning@Closes
@@the
@@search
@@session
_
\fB\(<-\fP@Previous word@Yes
\fB\(ua\fP@Previous line@Yes
\fBCTRL\ \(<-\fP@Start of line@Yes
\fBPgUp\fP@Previous page@Yes
\fBCTRL\ HOME\fP, \fBSHIFT\ HOME\fP, \fBCTRL\ K\fP@First word@Yes
\fB\(->\fP@Next word@Yes
\fB\(da\fP@Next line@Yes
\fBCTRL\ \(->\fP@END of line@Yes
\fBPgDn\fP@Next pages@Yes
\fBCTRL\ END\fP, \fBSHIFT\ END\fP, \fBCTRL\ J\fP@Last word@Yes
\fBHOME\fP, \fBCTRL\ A\fP@T{
Only keep the words starting with the search pattern
T}@No
\fBEND\fP, \fBCTRL\ Z\fP@T{
Only keep the words ending with the search pattern
T}@No
\fBINS\fP@Tag word@No
\fBDEL\fP@Untag word@No
_
.TE
.PP
Note that the search buffer is persistent as long as the same search
algorithm is used and \fBESC\fP has not been pressed.
.SS "Selection and Exit"
Pressing \fBq\fP gives the possibility to exit without selecting anything.
.PP
By default, \fBENTER\fP writes the selected word to stdout when not in
search mode otherwise it exits from this mode and does nothing more.
If you want to be able to select a word \fIeven\fP when in search mode,
use the \fB-r\fP option to change this behavior.
.SS "Tagging (multiple selections)"
When the tagging is activated by using the command line \fB-T\fP or
\fB-P\fP option, then the keys \fBt\fP, \fBT\fP, \fBINS\fP and \fBDEL\fP
can be used to tag/untag some words.
These tagged words will then be output on the standard output when
\fBENTER\fP is pressed.
.TP
\fBt\fP
Tag/untag or Pin/unpin the word under the cursor (toggle).
.TP
\fBT\fP
Tag or pin the matching words if any.
.TP
\fBU\fP
Untag or unpin the matching words if any.
.TP
\fBINS\fP
Tag or pin the word under the cursor.
.TP
\fBDEL\fP
Untag or unpin the word under the cursor.
.SS Help
A small help message can be displayed when hitting \fB?\fP.
This display will last for 10s or until a valid key or \fBESC\fP is
pressed.
.SS Scroll bar
A scroll bar is displayed at the right of the scrolling window.
Its appearance is meant to be classical but it has some particularities:
.IP * 2
The scroll bar is not displayed if all the input words fit on only one
line.
.IP * 2
Otherwise, the scroll bar is always displayed except when the \fB-q\fP
option is set.
This option completely disables the scroll bar display.
.IP * 2
When the scrolling window has only one line, the scroll bar has only 3
states:
.RS 2
.IP - 2
\fBv\fP when on all but the last line, indicating that you can go down
to see more.
.IP - 2
\fB^\fP when on the last line.
.IP - 2
\fB|\fP otherwise.
.RE
.IP * 2
When there is more than one line to display, \fB/\fP means that the window
displays the first line, \fB\\\fP the last line.
\fB|\fP is used to fill the gap, see below the different possible
configurations.
.TS
tab(@);
l l l l l
l l l l l
l l l l .
\\@\\@^@^@\\ @Do not remove this trailing space!
|@|@|@|@/
/@v@/@v
.TE
.PP
A \fB+\fP can also appear in the scroll bar in lieu of the vertical bar,
giving the relative position of the cursor line in the bunch of input
words.
.SS "Terminal resizing (also see BUGS/LIMITATIONS)"
The windows is redrawn if the terminal is resized.
The redrawing is actually done only 1s after the end of the resizing to
avoid artefacts on screen.
The cursor will remain on the current selected word but may be displayed
at another place in the window.
.SS Unicode support
This utility is Unicode aware and should be able to display correctly
any Unicode character (even double-width ones) as long as the current
encoding is \fBUTF-8\fP (\fBUTF-8\fP in the output of the \fIlocale\fP
command).
.SS Configuration
If a file with adequate permissions and the same name as the executable
but prefixed with a dot is present in the current directory
or in the user's home directory, then it will be parsed as a
\fIini\fP file.
The values read from the file in the home directory will be overridden by
the ones read from the local directory (if it is present).
Missing and bad keywords are silently skipped.
The values read, if valid, override the default hard-coded ones.
If a value is invalid an error message is shown and the program terminates.
The values of the timers must be given in units of \fB1/10\fP of a second.
Here is an example giving the syntax and the names of the keywords
allowed:
.PP
.nf
\f(CR--8<------------------------------------------------------------------
[colors]
; The terminal must have at least 8 colors and/or have attributes like bold
; and reverse for this to be useful
; if not the following settings will be ignored.
method=ansi ; classic | ansi (default)
cursor=0/2 ; cursor attributes
cursor_on_tag=0/2,u ; cursor on tag attributes
shift=6,b ; shift symbol attributes
message=0/3 ; message (title) attributes
bar = 7/4,b ; scroll bar attributes
search_field = 0/6 ; search field attributes
search_text = 7,bu ; search text attributes
match_field = 1,b ; matching words field attributes
match_text = 7,bu ; matching words text attributes
search_err_field = 1 ; approximate search field attributes
search_err_text = 1,r ; approximate search text attributes
; match_err_field = 3 ; approximate matching words field attributes
match_err_text = 1 ; approximate matching words text attributes
; include = b ; selectable color attributes
exclude = 4/0,u ; non-selectable color attributes
tag = 0/5 ; tagged (selected) attributes
daccess = 3,b ; direct access tag attributes
special1 = 7/4,b ; attributes for the special level 1
special2 = bu ; attributes for the special level 2
special3 = /3,b ; attributes for the special level 3
special4 = 7/4 ; attributes for the special level 4
special5 = 7/2,b ; attributes for the special level 5
[window]
lines = 7 ; default number of lines of the window
[limits]
word_length = 1024 ; arbitrary max length of input words (int)
words = 32767 ; arbitrary max number of allowed input
; words (int)
columns = 128 ; arbitrary max number of columns (int)
[timers]
search = 60 ; search timers in 1/10 s
help = 150 ; duration of the help message in 1/10 s
window = 7 ; delay before redrawing if the size of the
; terminal's window change in 1/10 s
direct_access = 6 ; duration allowed to add a new digit to
; the direct word access number in 1/10 s
[misc]
default_search_method = substring
--8<------------------------------------------------------------------
\fP
.fi
.IP * 2
The \fBmethod\fP keyword can take the two possible values displayed
above and determines if you want to use the native method (limited to 8
colors) of the \fBansi\fP method (ISO 8613-6) if your terminal supports
more than 8 colors.
The default value corresponds to \fBansi\fP.
The attributes syntax is [fg][/bg][,toggles] where \fBfg\fP and
\fBbg\fP are numbers representing the foreground and background
color and \fBtoggles\fP is a strings which can contain the characters
\fIb\fP, \fId\fP, \fIr\fP, \fIs\fP, \fIu\fP and \fIi\fP standing for
\fIb\fPold, \fId\fPim, \fIr\fPeverse, \fIs\fPtandout, \fIu\fPnderline
and \fIi\fPtalic.
.IP * 2
Spaces are allowed anywhere in the lines and between them, even around
the \fB=\fP.
.IP * 2
Everything following a \fB;\fP is ignored.
.IP * 2
When undefined, the default limits are:
.TS
tab(@);
l l .
words@32767
word_length@512
columns@256
.TE
.SH OPTIONS
.IP "\fB-h\fP or \fB-?\fP"
Displays a long (\fB-h\fP) or short (\fB-?\fP) help message and exits.
.IP "\fB-f\fP \fIconfiguration_file\fB"
This option gives the possibility to select an alternative configuration
file.
If the given file doesn't exist or is not readable then the default
values will be used.
The \fB.smenu\fP files in the user's home directory and in the current
directory, if present, will be ignored when this option is used.
.IP "\fB-n\fP \fI[lines\fB]"
Gives the maximum number of lines in the scrolling selection window.
If \fB-n\fP is not present the number of lines will be set to \fI5\fP.
If \fB-n\fP is present without argument, then the height of the terminal will
be used to determine the number of lines.
This remains true even if the terminal is resized.
If \fB-n\fP is present with a numerical argument, this value will be used
to determine the number of lines.
.IP "\fB-t\fP [\fIcolumns\fP]"
This option sets the tabulation mode and, if a number is specified,
attents to set the number of displayed columns to that number.
In this mode, embedded line separators are ignored.
The options \fB-A\fP and \fB-Z\fP can nevertheless be used to force words
to appear in the first (respectively last) position of the displayed line.
.PP
.RS
Note that the number of requested columns will be automatically reduced
if a word does not fit in the calculated column size.
.PP
In this mode each column has the same width.
.RE
.IP \fB-k\fP
By default, the spaces surrounding the output string will be deleted.
This option forces them to be retained.
.IP \fB-v\fP
By default, when searching, an alarm is produced by the terminal when
the user enters a character or makes a move which lead to no result or
to an error condition.
This argument make this beep visual by briefly showing the cursor.
.IP "\fB-s\fP \fIpattern\fP"
Place the cursor on the first word corresponding to the specified pattern.
\fIpattern\fP can be:
.RS
.IP * 2
A \fB#\fP immediately followed by a \fBnumber\fP giving the initial
position of the cursor (counting from 0).
If the word at this position is excluded, then the first previous non
excluded word is selected if it exists, otherwise the first non excluded
word is selected.
If this number if greater than the number of words, the cursor will be
set on the latest selectable position.
.IP * 2
A single \fB#\fP or the string \fB#last\fP to set the initial
cursor position to the latest selectable word position.
.IP * 2
A string starting with a \fB/\fP indicating that we want the cursor
to be set to the first word matching the given regular expression.
.IP * 2
A \fBprefix\fP string indicating that we want the cursor to be set on the
first word matching the string given (\fBa\fP will match \fBCancel\fP
by example).
.PP
Warning, when searching for a prefix or a regular expression, smenu
only looks for them after an eventual modification, so for example,
the command:
\f(CBsmenu -I/c/x/ -s/c <<< "a b c d"\fP won't find c and put the cursor
on \fBa\fP but \f(CBsmenu -I/c/x/v -s/c <<< "a b c d"\fP will find it and
put the cursor on the \fBx\fP substituting the \fBc\fP on screen only
\fI\\u\fP sequences can be used in the pattern.
.RE
.IP "\fB-m\fP \fImessage\fP"
Displays a message above the window.
If the current locale is not \fIUTF-8\fP, then all \fIUTF-8\fP characters
in it will be converted into a dot.
\fI\\u\fP sequences can be used in the message.
Note that the message will be truncated if it does not fit on a terminal
line.
.IP "\fB-w\fP"
When \fB-t\fP is followed by a number of columns, the default is to
compact the columns so that they use the less terminal width as
possible.
This option enlarges the columns in order to use the whole terminal width.
When in column mode, \fB-w\fP can be used to force all the columns to
have the same size (the largest one).
See option \fB-c\fP below.
.PP
.RS
Note that the column's size is only calculated once when the words are
displayed for the first time.
A terminal resize will not update this value.
This choice enables a faster display.
.RE
.PP
.IP \fB-d\fP
Tells the program to clean up the display before quitting by removing
the selection window after use as if it was never displayed.
.IP \fB-M\fP
Centers the display if possible.
.IP \fB-c\fP
Sets the column mode.
In this mode the lines of words do not wrap when the right border of
the terminal is reached but only when a special character is read.
Some words will not be displayed without an horizontal scrolling.
If such a scrolling is needed, some indications may appear on the left
and right edge of the window to help the user to reach the unseen words.
In this mode, the width of each column is minimal to keep the maximum
information visible on the terminal.
.IP \fB-l\fP
Sets the line mode.
This mode is the same as column mode but without any column alignment.
.IP \fB-r\fP
Enables \fBENTER\fP to validate the selection even in search mode.
.IP \fB-b\fP
Replaces all non-printable characters by a blank.
If this results in a blank word, it will be potentially deleted.
.IP "\fB-a \fIPREFIX:ATTR\fP [\fIPREFIX:ATTR\fP...]"
Sets the display attributes of the elements displayed and the cursor.
At least one attribute prefixed attribute must be given.
\fIPREFIX\fP can take the following values:
.RS
.IP \fIi\fP
included words.
.IP \fIe\fP
excluded words.
.IP \fIc\fP
cursor.
.IP \fIb\fP
scroll bar.
.IP \fIs\fP
shift indicator.
.IP \fIm\fP
message (title).
.IP \fIt\fP
tagged words.
.IP \fIct\fP
cursor on tagged words.
.IP \fIsf\fP
search field.
.IP \fIst\fP
search text.
.IP \fIsfe\fP
approximate search field with error.
.IP \fIste\fP
approximate search text with error.
.IP \fImf\fP
matching words field.
.IP \fImt\fP
matching words text.
.IP \fImfe\fP
matching words field with error.
.IP \fImte\fP
matching words text with error.
.IP \fIda\fP
direct access tag.
.RE
If more than one attribute is given, then they must be separated by
spaces.
See the \fB-1\fP option for the \fIATTR\fP syntax.
.IP "\fB-i\fP \fIregex\fP"
Sets the \fBi\fPnclude filter to match the selectable words.
All the other words will become implicitly non-selectable (excluded)
\fB-i\fP can be used more than once with cumulative effect.
\fI\\u\fP sequences can also be used in the regexp.
.IP "\fB-e\fP \fIregex\fP"
Sets the \fBe\fPxclude filter to match the non-selectable words.
All the other selectable words will become implicitly selectable (included)
\fB-e\fP can be used more than once with cumulative effect.
This filter has a higher priority than the include filter.
The \fIregex\fP selections made using \fB-i\fP and/or \fB-e\fP are done
before the possible words alterations made by \fB-I\fP or \fB-E\fP
(see below).
\fI\\u\fP sequences can also be used in the regexp.
.IP "\fB-C\fP [\fIi\fP|\fIe\fP] \
<\fIcol selectors\fP>"
These letters are case independent so \fII\fP can be used in place of
\fIi\fP per example.
In column mode, this option allows one to restrict the previous
selections or de-selections to some columns.
If no selection is given via \fB-i\fP and \fB-e\fP this option gives the
possibility to select entire columns by giving their numbers (1 based)
of extended regular expressions.
\fIi\fP or nothing select the specified ranges of columns.
\fIe\fP select all but the specified ranges of columns.
The words in the selected columns will be considered as \fBi\fPncluded
And the others \fBe\fPxcluded.
A selection by regular expressions means that a column containing a word
matching one of these expression will be included or excluded according
to the letter given after the option.
Regular expressions and column numbers can be freely mixed.
Regular expression in \fB-C\fP and \fB-R\fP can contain \fIUTF-8\fP
characters either directly or by using the \fI\\u\fP notation.
Example of columns selection: \f(CB-Ci2,3,/X./,5-7\fP forces the cursor
to only navigate in columns \fB2\fP,\fB3\fP,\fB5\fP,\fB6\fP and \fB7\fP
and those containing a two characters word starting with '\fBX\fP'.
If \fIe\fP was used in place of \fIi\fP, all the columns would have been
selected \fBexcept\fP the columns \fB2\fP,\fB3\fP,\fB5\fP,\fB6\fP,\fB7\fP
and those matching the extended regular expression '\f(CBX.\fP'.
Spaces are allowed in the selection string if they are protected.
The column mode is forced when this option is selected.
.IP "\fB-R\fP [\fIi\fP|\fIe\fP] \
<\fIrow selectors\fP>"
Similar to \fB-C\fP but for the rows.
One difference though: this is the line mode which is forced by this
option NOT the column mode.
\fB-C\fP and \fB-R\fP can be used more than once in a cumulative manner:
The selection mode (selection or de-selection) is given by the first
occurrence of the options, the other occurrences will only update the
selected or de-selected ranges.
.IP "\fB-S\fP /\fIregex\fP/replacement string/[\fIg\fP][\fIv\fP][\fIs\fP]"
Post-processes the words by applying a regular expression based
substitution.
The argument must be formatted as in the \fBsed\fP editor.
This option can be used more than once.
Each substitution will be applied in sequence on each word.
This sequence can be stopped if a \fBstop\fP flag is encountered.
.RS
\fBflags:\fP
.IP * 2
The optional trailing \fBg\fP (for \fIg\fPlobal) means that all matching
occurrences shall be replaced and not only the first one.
.IP * 2
The optional trailing \fBv\fP (for \fIv\fPisual) means that the altered
words will only be used for display and search.
The modifications will \fInot\fP be reflected in the returned word.
.IP * 2
The optional trailing \fBs\fP (for \fIs\fPtop) means that no more
substitution will be allowed on this word even if another \fB-S\fP is
used.
.IP * 2
The optional trailing \fBi\fP (for \fIi\fPgnore case) means that the
string search operation should ignore the case for this pattern.
Small example:
\f(CBR=$(echo a b c | smenu -S /b/B/)\fP
will display \f(CR"a B c"\fP and \f(CBR\fP will contain \fIB\fP if \fI
B\fP is
selected meanwhile
\f(CBR=$(echo a b c | smenu -S /b/B/\fBv\fP)\fR
will display the same as above but \f(CBR\fP will contain the original
word \fIb\fP if \fIB\fP is selected.
In both cases, only the word \fIB\fP will be searchable and not \fIb\fP.
.RE
.IP "\fB-I\fP /\fIregex\fP/replacement string/[\fIg\fP][\fIv\fP][\fIs\fP]"
Post-processes the \fBselectable\fP words by applying a regular
expression based substitution (see \fB-S\fP for details).
.IP "\fB-E\fP /\fIregex\fP/replacement string/[\fIg\fP][\fIv\fP][\fIs\fP]"
Post-processes the \fBexcluded\fP (or \fBnon-selectable\fP) words by
applying a regular expression based substitution (see \fB-S\fP for
details).
.PP
.RS
The \fB/\fP separator that \fB-I\fP and \fB-E\fP are using above can be
substituted by any other character except \fISPACE\fP, \fI\\t\fP,
\fI\\f\fP, \fI\\n\fP, \fI\\r\fP and \fI\\v\fP.
.PP
In the three previous options, \fIregex\fP is a \fBPOSIX\fP
\fBE\fPxtended \fBR\fPegular \fBE\fPxpression.
For details, please refer to the \fBregex\fP manual page.
.PP
Additionally \fI\\u\fP sequences can also be used in the regexp.
.PP
.RE
If a post-processing action (\fB-S\fP/\fB-I\fP/\fB-E\fP) results in an
empty (length 0) word, then we have two cases:
.RS
.IP "in column mode:"
Substitutions involving empty words can lead to misalignments, so it is
necessary to prohibit them and terminate the program.
These substitutions have to be made with other tools before using this
utility.
.IP "otherwise:"
The word is simply removed.
.RE
.IP "\fB-A\fP \fIregex\fP"
In column mode, forces all words matching the given regular expression
to be the first one in the displayed line.
If you want to only rely on this method to build the lines, just specify
an empty \fBregex\fP to set the end-of-line separator with \fI-L ''\fP)
.PP
.RS
\fI\\u\fP sequences can also be used in the regexp after \fB-A\fP.
.RE
.IP "\fB-Z\fP \fIregex\fP"
Similar to \fB-A\fP but forces the word to be the latest of its line.
The same trick with \fB-L\fP can also be used.
.PP
.RS
\fI\\u\fP sequences can also be used in the regexp after \fB-Z\fP.
.RE
.IP "\fB-N\fP [\fIregex\fP]"
This option allows one to number the selectable words matching a
specific regular expression.
These numbers are numbered starting from 1 and provides a direct access
to the words.
To use this functionality, the user must enter the number which
corresponds to the desired entry digit per digit.
Each new digit must be added in a time frame of 1/2 seconds (per default)
otherwise the number is considered complete and a newly entered digit
will start a new number.
If the number does not exists, then the cursor is restored to it's
initial position.
The sub-options of the \fB-D\fP option described below can change the
way \fB-N\fP sets and formats the numbers.
This option can be used more than once with cumulative effects.
\fB-N\fP, \fB-U\fP and \fB-F\fP can be mixed.
.IP "\fB-U\fP [\fIregex\fP]"
This option allows one to un-number words.
If placed after a previous \fB-N\fP, it can be used to remove the
numbering of selected words.
If placed before, the word which doesn't match its regular expression
will be numbered by default.
This mechanism is similar to to the inclusion/exclusion of words by
\fB-i\fP and \fB-e\fP.
This option can be used more than once with cumulative effects.
\fB-U\fP, \fB-N\fP and \fB-F\fP can be mixed.
.IP "\fB-F\fP"
This option is similar to \fB-N\fP but does not generate a continuous
flow of numbers but extracts them from the word itself.
With this option you can take full control of the numbering of the
displayed word.
Note that the numbering does not need to be ordered.
The resulting word after the extraction of the number must be non empty.
Some sub-option are required, see the \fB-D\fP option described below.
\fBNotice\fP that for this option to work correctly, all the embedded
numbers must have the same number of digits.
To get that, a preprocessing may be necessary on the words before using
this program.
\fB-F\fP, \fB-N\fP and \fB-U\fP can be mixed.
.IP "\fB-D\fP [\fIparameters\fP]"
This option allows one to change the default behaviour of the \fB-N\fP,
\fB-U\fP and \fB-F\fP options.
Its optional parameters are called sub-options and must respect the
format \fBx\fP:\fBy\fP where \fBx\fP can be:
.RS
.TP
\f(CBl\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is the UTF-8 character (in native or \fI\\u\fP form)
to print before the number.
The default is a single space.
.
.TP
\f(CBr\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is the UTF-8 character (in native or \fI\\u\fP form)
to print after the number.
The default is \f(CB)\fP.
.
.TP
\f(CBa\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is '\f(CBleft\fP' (or one of its prefixes) if the number
must be \fIleft\fP aligned, or '\f(CBright\fP' (or one of its prefixes)
if it must be \fIright\fP aligned.
The default is \f(CBright\fP.
.
.TP
\f(CBp\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is '\f(CBincluded\fP' (or one of its prefixes)
or '\f(CBall\fP' (or one of its prefixes) for the initial \fIp\fPadding of
the non numbered words.
'\f(CBincluded\fP' means that only \fIincluded\fP word will be padded
while '\f(CBall\fP' means pad \fIall\fP words.
The default is \f(CBall\fP.
.
.TP
\f(CBw\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is the \fIw\fPidth of the number between 1 and 5 included.
.
.TP
\f(CBf\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP controls if the numbering must \fIf\fPollow the last
extracted number (defaults to \f(CByes\fP) or if it must remain
independent.
.
.TP
\f(CBh\fP (\fB-F\fP option)
Tells what to do with the characters present before the embedded number if
any.
The allowed directives are: '\f(CBtrim\fP' which discads them if they
form an empty word (only made of spaces and tabulations), '\f(CBcut\fP'
which unconditionnaly discards them and '\f(CBkeep\fP' which places them
at the beginning of the resulting word.
The default value for this directive is '\f(CBkeep\fP'.
.
.TP
\f(CBo\fP (\fB-F\fP option)
Here \fBy\fP is the \fIo\fPffset of the first multibyte character of
the number to extract from the word (defaults to \f(CB0\fP).
If this offset if immediately followed by the character '\f(CB+\fP',
then the parser will look for the first number (if any) after the given
offset instead of using its absolute value to extract the number.
Note that when the '\f(CB+\fP' is used, it is necessary that the length
of all the numbers to extract have the same size as the algorithm looks
for a digit to identify the beginning of the number to extract.
Hence, for example, \fB1\fP should appear as \fB01\fP in the input is
\f(CBn\fP is set to \f(CB2\fP.
.
.TP
\f(CBn\fP (\fB-F\fP option)
Here \fBy\fP is the \fIn\fPumber of multibyte characters to extract
from the word starting at the offset given by the \f(CBo\fP sub-option.
.
.TP
\f(CBi\fP (\fB-F\fP option)
Here \fBy\fP is number of multibyte characters to \fIi\fPgnore after
the extracted number
.
.TP
\f(CBd\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is a multibyte separator.
When present, this directive instructs smenu to output the selected
numbered word(s) \fIprefixed\fP by its(their) direct access number(s)
and the given separator.
Only the numbered word(s) will be prefixed.
\f(CBd\fP stands for \fBd\fPecorate.
This directive can be useful when you want to post-process the output
according to its direct access number.
.
.TP
\f(CBs\fP (\fB-F\fP, \fB-N\fP and \fB-U\fP options)
Here \fBy\fP is the direct access number that will be set for the first
numbered word.
Its value is \fB1\fP by default, a value of \fB0\fP is possible.
.P
Example: \f(CWr:\\> l:\\< a:l d:_ \fP
To number all words with the default parameters, use the
syntax: "\f(CW-N .\fP" which is a shortcut for:
"\f(CW-N . l:' ' r:')' a:r p:a\fP"
The \fIpadding\fP sub-option specifies whether spaces must also be
added in front of excluded words or not to improve compactness.
When the \f(CBw\fP sub-option is not given the width of the numbers is
determined automatically but if \fB-F\fP is set and the value of the
\f(CBn\fP sub-option is given then this value is used.
.RE
.IP "\fB-1\fP ... \fB-5\fP \fIregex\fP [\fIATTR\fP]"
Allows one to give a special display color to up to 5 classes of words
specified by regular expressions.
They are called \fBspecial levels\fP.
Only selectable words will be considered.
By default, the 5 special levels have their foreground color set to
red, green, brown/yellow, purple and cyan.
All these colors also can be set or modified permanently in the
configuration files.
See the example file above for an example.
The optional second argument (\fIATTR\fP) can be used to override the
default or configured attributes of each class.
Its syntax is the same as the one used in the configuration file:
.nf
[\fIfg\fP][/\fIbg\fP][,{\fIb\fP|\fId\fP|\fIr\fP|\fIs\fP|\fIu\fP|\fIi\fP}] \
| [{\fIb\fP|\fId\fP|\fIr\fP|\fIs\fP|\fIu\fP|\fIi\fP}]
.fi
Examples of possible attributes are:
.nf
\f(CB2/0,bu \fPgreen on black bold underline
\f(CB/2 \fPgreen background
\f(CB5 \fPtext in purple
\f(CBrb \fPreverse bold
.fi
\fI\\u\fP sequences can be used in the pattern.
.IP "\fB-g\fP [\fIstring\fP]"
Replaces the blank after each words in column or tabular mode by a column
separator.
This separator is extracted from the \fIstring\fP argument and each
of its (multibyte) character is used one after the other to fill
the gutter.
If there are more columns that gutter characters then the last character
is used for the remaining columns.
When not given, the separator defaults to a vertical bar \fI|\fP (or a
full height vertical bar if the locale is set to UTF-8).
Each character can be given in normal or \fI\\u\fP form in the
\fIstring\fP argument.
Example: "\f(CB|- \fP" will allow one to separate the first two columns
with '\f(CB|\fP', then '\f(CB-\fP' will be used and '\f(CB \fP' will
separate the remaining columns if any.
.IP \fB-q\fP
Prevents the display of the scroll bar.
.IP "\fB-W\fP \fIbytes\fP"
This option can be used to specify the characters (or multibyte
sequences) which will be used to delimit the input words.
Multibyte sequences (UTF-8) can be natives of using the same ASCII
representation used in words (a leading \fI\\u\fP following by up to 8
hexadecimal characters).
Non-printable characters in arguments should be given using the standard
\fI$''\fP representation.
\fI$'\\t'\fP stands for the tabulation character for example.
The default delimiters are: \fISPACE\fP, \fI$'\\t'\fP and \fI$'\\n'\fP.
.IP "\fB-L\fP \fIbytes\fP"
This option can be used to specify the characters (or multibyte
sequences) which will be used to delimit the lines in the input stream.
Multibyte sequences (UTF-8) can be natives of using the same ASCII
representation used in words (a leading \fI\\u\fP following by up to 8
hexadecimal characters).
Non-printable characters in arguments should be given using the standard
$'' representation.
$'\\n' stands for the newline character for example.
The default delimiter is: \fI$'\\n'\fP.
This option is only useful when the \fB-c\fP or \fB-l\fP option is also
set.
The characters (or multibyte sequences) passed to \fB-L\fP are
automatically added to the list of word delimiters as if \fB-W\fP was
also used.
\fI\\u\fP sequences can also be used here.
.IP "\fB-T\fP [\fIseparator\fP]"
Enables the multiple selections or tag mode.
In this mode, several selectable words can be selected without leaving
the program.
The current word can be automatically tagged when the \fBENTER\fP key
is pressed to complete the selection process if the \fB-p\fP option is
also set or if no word has been tagged.
All the tagged words (and possibly the world under the cursor) will
be sent to stdout separated by the optional argument given after the
option \fB-T\fP.
Note than this \fIseparator\fP can have more than one character, contain
UTF-8 characters (in native or \fI\\u\fP form) and can even contain
control character as in \f(CB$'\\n'\fP.
A space is used as the default separator if none is given.
\fBCaution\fP: To get exactly the same behavior as in version 0.9.11
and earlier, you must also use the \fB-p\fP option.
.IP "\fB-P\fP [\fIseparator\fP]"
Works like \fB-T\fP but, unlike \fB-T\fP, the output depends on the order
in which the words were tagged.
In other words, the first tagged word comes first in the output, the
second tagged word comes next, and so on.
\fB-P\fP stands for "Pin".
.IP \fB-p\fP
This option modifies the default behavior of the \fB-T\fP and \fB-P\fP
options.
An untagged word under the cursor will be automatically tagged when
\fBENTER\fP is pressed.
.IP \fB-V\fP
Displays the current version and quits.
.TP
\fB-x \fItype\fP [\fIword\fP] \fIdelay\fP
.TQ
\fB-X \fItype\fP [\fIword\fP] \fIdelay\fP
Sets a timeout.
Three types of timeout are possible:
.RS
.TP 10
current:
At the timeout, the word under the cursor and/or the tagged words are
sent to the standard output if the \fBENTER\fP key has been pressed
.TP 10
quit:
At the timeout, nothing is selected as if the \fBq\fP key has been pressed
.TP 10
word:
At the timeout, the word given after the type is selected.
Note that this word doesn't need to be part of the words coming from
the standard input.
.PP
Each type can be be shortened as a prefix of its full name ("cur" for
"current" of "q" for "quit" per example).
The delay must be set in seconds and cannot be above 99999 seconds.
The remaining time (in seconds) is added at the end of the message
displayed above the selection window and is updated in real time each
second.
Each key press except \fBENTER\fP, \fBq\fP, \fBQ\fP and \fB^C\fP resets
the timer to its initial value.
The \fB-X\fP version works like \fB-x\fP but no periodic remaining
messages is displayed above the selection window.
.RE
.IP "\fB-/\fP \fIsearch_method\fP"
Affects the '\fB/\fP' key to a search method.
By default '\fB/\fP' is affected to '\fIfuzzy\fP' but the argument can
be any prefix of '\fIprefix\fP', '\fIsubstring\fP' or '\fIfuzzy\fP'.
.SH NOTES
If tabulators (\fI\\t\fP) are embedded in the input, there is no way
to replace them with the original number of spaces.
In this case use another filter (like \fIexpand\fR) to pre-process
the data.
.SH EXAMPLES
.SS 1
Simple Yes/No/Cancel request with "No" as default choice:
.PP
.nf
\f(CRIn \fBbash\fP:
\f(CBread R <<< $(echo "Yes No Cancel" \\
| smenu -d -m "Please choose:" -s /N)\fP
or
\f(CBR=$(echo "Yes No Cancel" \\
| smenu -d -m "Please choose:" -s /N)\fP
In \fBksh\fP:
\f(CBprint "Yes No Cancel" \\
| smenu -d -m "Please choose:" -s /N \\
| read R\fP
\fP
.fi
.SS 2
Get a 3 columns report about VM statistics for the current process in
\fBbash\fP/\fBksh\fP on Linux:
.PP
.nf
\f(CBR=$(grep Vm /proc/$$/status | expand | smenu -b -W$'\\n' -t3 -g -d)\fB
.PP
\fP
.fi
.SS 3
Create a one column selection window containing the list of the first
20 LVM physical volumes.
At the end, the selection window will be erased.
This example is written in \fBksh\fP).
.PP
.nf
\f(CB
pvs -a -o pv_name --noheadings \\
| smenu -m "PV list" -n20 -t1 -d -s //dev/root \\
| read R
\fP
.fi
The display will have a look similar to the following with the cursor
set on the word \fI/dev/root\fP:
.nf
\f(CRPV list
/dev/md126 \\
/dev/md127 |
/dev/root | <- cursor here.
/dev/sda2 |
/dev/sdb2 |
/dev/sdc1 |
/dev/sdc2 |
/dev/system/homevol /
\fP
.fi
.SS "4 (advanced)"
Imagine a file named \fBsample.mnu\fP with the following content:
.nf
\f(CR--8<---------------------------------
"1 First Entry" "3 Third entry"
"2 Second entry" "4 Fourth entry"
@@@ "5 Fifth entry"
@@@
"0 Exit menu"
--8<---------------------------------
\fP
.fi
Then this quite esoteric command will render it (centered on the screen) as:
.nf
\f(CR+----------------------------------+
| Test menu |
| |
| 1) First Entry 3) Third entry |
| 2) Second entry 4) Fourth entry |
| 5) Fifth entry |
| |
| 0) Exit menu |
+----------------------------------+
\fP
.fi
with the cursor on \fIQuit\fP and only the numbers and "Quit" selectable.
\f(CBR=$(smenu R=$(./smenu -q -d -s/Exit -M -n 30 -c \\
-e "@+" -E '/@+/ /' \\
-F -D n:1 i:1 \\
-m "Test menu"$'\n' < sample.mnu)
The selected entry will be available in \f(CBR\fP
Try to understand it as an exercise.
.SH ENVIRONMENT
\fINO_COLOR\fP: force a monochrome terminal when set.
.SH BUGS/LIMITATIONS
Some terminal emulators, those notably based on VTE version later than
0.35 (see https://github.com/GNOME/vte/commit/01380d), have a new feature
that gives them the possibility to wrap/unwrap already displayed lines
when resizing the window.
As far as I known, there is no terminfo entry to disable that.
On these types of terminals, the automatic re-display of the output of
smenu will be disturbed and some artifacts may appear on the screen if
the terminal window is resized.
.SH AUTHORS
\(co 2015 Pierre Gentile (p.gen.progs@gmail.com)