GNU Readline for direct mode, DSE, LKE and MUPIP
Final Release Note
YottaDB can optionally use GNU Readline if it is installed on the system. It is enabled by setting the environment variable ydb_readline
to a nonzero numeric value (typically 1) or a case-independent string which is, or whose leading substring is, YES
or 'TRUE`.
When enabled, interactive use of YottaDB Direct Mode, LKE, DSE, and MUPIP use the Readline library to read input, enabling many features of Unix shells (including saving & recalling history). Implemented features include:
-
Line editing for direct mode, DSE, LKE, and MUPIP.
-
Command history is saved in
$HOME/.ydb_{YottaDB,DSE,LKE,MUPIP}_history
. When Readline is enabled:- Direct mode RECALL displays Readline history when entered at the beginning of the line.
- Recalling and editing prior commands with
^
or!
work when they are entered at the beginning of the line. Ending the line with:p
prints the recalled and edited command, instead of executing it. - Recalling and editing commands also executes them, unlike the RECALL command implemented by YottaDB.
- Entering UTF-8 mode characters works even in M mode.
- Settings are read from
$HOME/.inputrc
, whose location can be overridden by theINPUTRC
environment variable. The application name for use in$if
statements in theINPUTRC
file is "YottaDB". - If
history-size
is not set, it defaults to 1,000. The history file on disk will always be limited to 1000 entries no matter the setting ofhistory-size
. - Signals are handled by YottaDB and not by Readline.
Examples of history expansion:
-
!!
: Recall last command -
!$
: Last argument of last command -
!nnn
: Execute line in history number nnn -
!nnn:p
: Print line (but don't execute) nnn, and add it to the history to the end. You can press up arrow to recall that command for editing. -
!?xxxx
: Execute line containing text xxxx. BE CAREFUL WITH THIS ONE. It can lead to unexpected items getting executed. -
^string1^string2^
: In the last command, replace string1 with string2, and execute it. -
!nnn:s/old/new/
: In history item nnn, replace old with new and execute it.
Refer to the GNU Readline user documentation for more information on the functionality of Readline.
Limitations include:
-
DSE/LKE/MUPIP
- There is no history listing (equivalent to the direct mode RECALL command).
- History expansion module works only in direct mode.
-
Direct mode
- Only traditional characters terminate input lines (CR, LF, FF, and their UTF-8 variants); alternate terminators are not supported. (YottaDB direct mode has the ability terminate input using the TERMINATOR device parameter.)
- Wrap on device width (set using WIDTH device parameter) is not supported.
- MUPIP INTRPT (SIGUSR1) turns off line editing on the line being entered. You can still enter more characters or cancel the line using CTRL-C.
-
Readline is not supported for the READ command.
Description
I had a friend do some work on Mumps V1 and she implemented command line history using this library: https://github.com/arangodb/linenoise-ng. I wonder if you could replace the command line history in YDB with something more standard that implements all the keyboard shortcuts, stores more than 100 entries, and persists between sessions.
We can use one of the libraries like readline, libedit linenoise etc.
Draft Release Note
YottaDB can optionally use GNU Readline if it is installed on the system. It is enabled by setting the environment variable ydb_readline
to a nonzero numeric value (typically 1) or a case-independent string which is, or whose leading substring is, YES
or 'TRUE`.
When enabled, interactive use of YottaDB Direct Mode, LKE, DSE, and MUPIP use the Readline library to read input, enabling many features of Unix shells (including saving & recalling history). Implemented features include:
-
Line editing for direct mode, DSE, LKE, and MUPIP.
-
Command history is saved in
$HOME/.ydb_{YottaDB,DSE,LKE,MUPIP}_history
. When Readline is enabled:- Direct mode RECALL displays Readline history when entered at the beginning of the line.
- Recalling and editing prior commands with
^
or!
work when they are entered at the beginning of the line. Ending the line with:p
prints the recalled and edited command, instead of executing it. - Recalling and editing commands also executes them, unlike the RECALL command implemented by YottaDB.
- Entering UTF-8 mode characters works even in M mode.
- Settings are read from
$HOME/.inputrc
, whose location can be overridden by theINPUTRC
environment variable. - If
history-size
is not set, it defaults to 1,000. - Signals are handled by YottaDB and not by Readline.
Examples of history expansion:
-
!!
: Recall last command -
!$
: Last argument of last command -
!nnn
: Execute line in history number nnn -
!nnn:p
: Print line (but don't execute) nnn, and add it to the history to the end. You can press up arrow to recall that command for editing. -
!?xxxx
: Execute line containing text xxxx. BE CAREFUL WITH THIS ONE. It can lead to unexpected items getting executed. -
^string1^string2^
: In the last command, replace string1 with string2, and execute it. -
!nnn:s/old/new/
: In history item nnn, replace old with new and execute it.
Refer to the GNU Readline user documentation for more information on the functionality of Readline.
Limitations include:
-
DSE/LKE/MUPIP
- There is no history listing (equivalent to the direct mode RECALL command).
- History expansion module works only in direct mode.
-
Direct mode
- Only traditional characters terminate input lines (CR, LF, FF, and their UTF-8 variants); alternate terminators are not supported. (YottaDB direct mode has the ability terminate input using the TERMINATOR device parameter.)
- Wrap on device width (set using WIDTH device parameter) is not supported.
- MUPIP INTRPT (SIGUSR1) turns off line editing on the line being entered. You can still enter more characters or cancel the line using CTRL-C.
-
Readline is not supported for the READ command.
Developer's Notes for Draft Release Note
An initial integration of readline with YottaDB has been completed. It can be
turned on by setting ydb_readline
to a non-zero numeric value or
case-independent string or leading substrings of TRUE or YES.
When turned on, interactive use of YottaDB Direct Mode, LKE, DSE, and MUPIP now use the readline library to read input. This means that many of the features of Unix shells (including history saving) are now implemented.
Implemented features:
- Readline Editing for Direct Mode, DSE/LKE/MUPIP
- Save history in
~/.ydb_{YottaDB,DSE,LKE,MUPIP}_history
- Direct mode history expansion but only if the first character is ^ or !.
:p
(print only) at the end is supported. - Direct mode recall/rec works
- Direct mode recall xxx/rec xxx executes n (rather than display for editing, which is different from regular rec).
- UTF-8 reading works (even in M mode, which doesn't work in original code base except when using recall).
- Parsing the
~/.inputrc
file for Readline settings. You can override the location of that file using the environment variableINPUTRC
. - If history-size is unset (you set it using
history-size
in the~/.inputrc
file), maximum history size is 1000. - All signal handling in YottaDB
Sample ~/.inputrc
:
$if yottadb
set editing-mode vi
set history-size 100
set show-mode-in-prompt on
$endif
$if Bash
set editing-mode emacs
$endif
Some examples of history expansion that work:
-
!!
: Recall last command -
!$
: Last argument of last command -
!nnn
: Execute line in history number nnn -
!nnn:p
: Print line (but don't execute) nnn, and add it to the history to the end. You can press up arrow to recall that command for editing. -
!?xxxx
: Execute line containing text xxxx. BE CAREFUL WITH THIS ONE. It can lead to unexpected items getting executed. -
^string1^string2^
: In the last command, replace string1 with string2, and execute it. -
!nnn:s/old/new/
: In history item nnn, replace old with new and execute it.
Note while the Readline History module technically supports putting history
expansion characters at in any part of the line, we cannot do that in YottaDB
because !
, ?
, ^
, and :
are all valid M syntax elements; so history
expansion has been coded to only run if these characters are at the beginning
of the line.
Features that are not implemented:
- DSE/LKE/MUPIP: No history listing (the "rec" command)
- DSE/LKE/MUPIP: No history expansion like the one described above. The history expansion module was only written for direct mode.
- Direct mode: Handle alternate terminators (YottaDB has the ability to ask direct mode to terminate reads using a non-traditional terminator (e.g. the character 0) rather that the traditional line ending characters (CR, LF, FF, and their UTF-8 variants) using the TERMINATOR device parameter.
- Direct mode: Wrap on device width (set using WIDTH device parameter).
- Direct mode: Interrupt (SIGUSR1) turns off line editing on the line being entered. You can still enter more characters or cancel the line using CTRL-C. This is probably fixable by setting the right readline variables, but is left for a future iteration.
- READ command readline support
- Debug: Ability to print where the readline files are
- Debug: Ability to print readline version
For more usage information on the Readline library, consult these two manuals: