breadline
Introduction
This egg provides an incomplete set of bindings to the GNU Readline library, suitable for augmenting csi and writing a csi-like application with line editing support. See the bundled examples for a .csirc providing Scheme completion.
Author
Vasilij Schneidermann
Repository
https://depp.brause.cc/breadline
Current state of the bindings
- Basic interface for reading input and managing history
- Completion interface
- Text manipulation
- Redisplay and event hooks
- Customization of aspects crucial for Scheme programming
Requirements
You'll need to have a not too old version of GNU Readline installed. This egg has been tested with version 7, but version 6 should work as well. In case the auto-detected flags don't work for you, make sure to set READLINE_CFLAGS and READLINE_LDLIBS before installation. The following subsections show known workarounds for platforms where the default build script does not suffice:
Ubuntu 18.04
export READLINE_CFLAGS=-I/usr/include/readline export READLINE_LDLIBS=-lreadline chicken-install breadline
An alternative solution is to set up /usr/share/pkgconfig/readline.pc as described on Simon Marache-Francisco's blog. Edit the file to contain the following, then run chicken-install breadline:
Name: Readline Description: Gnu Readline library for command line editing URL: http://tiswww.cwru.edu/php/chet/readline/rltop.html Version: 7.0 Requires.private: tinfo Libs: -lreadline Cflags: -I/usr/include/readline
macOS Homebrew
Ensure that pkg-config and readline have been installed via Homebrew.
Consider Homebrew's remarks after installing readline:
readline is keg-only, which means it was not symlinked into /usr/local, because macOS provides BSD libedit. For compilers to find readline you may need to set: export LDFLAGS="-L/usr/local/opt/readline/lib" export CPPFLAGS="-I/usr/local/opt/readline/include" For pkg-config to find readline you may need to set: export PKG_CONFIG_PATH="/usr/local/opt/readline/lib/pkgconfig"
Therefore export all of these, then run chicken-install breadline.
In case it still doesn't work and pkg-config --libs readline fails, this may be the fault of an incorrect readline.pc file, see Homebrew's issue tracker and update.
mingw-msys2
Assuming a 64bit installation, the egg can be installed as follows:
pacman -S pkg-config mingw-w64-x86_64-readline export READLINE_CFLAGS=$(pkg-config --cflags readline) export READLINE_LDLIBS=$(pkg-config --libs readline) chicken-install breadline
API
History
[procedure] (history-length)Returns the current history length.
[parameter] (history-file)[parameter] (history-file PATH)
Specifies the location of the history file for make-readline-port. Defaults to #f which means to neither read nor write out the history. PATH may be relative to the current working directory.
[procedure] (add-history! ITEM)Adds ITEM to the current history.
[procedure] (read-history! FILE)Reads in history items from FILE and adds them to the current history.
[procedure] (write-history! FILE)Writes out current history items to FILE.
[procedure] (stifle-history! MAX)Configure the current history to hold at most MAX items.
[procedure] (unstifle-history!)Undo any history stifling. Returns the previously set maximum amount of history items as set by stifle-history!. If the history was not stifled before, the value is negative.
Completion
[procedure] (completer-set! PROC)Set the completion handler to PROC. PROC is called repeatedly to collect completions with a fixnum state argument and a string prefix. A state argument of zero means that the completion procedure may initialize its data, it is incremented for every subsequent call. The completion procedure must either return a completion matching the given string prefix or #f to signal that no further completions follow. It is up to the completion procedure to keep track of what completions have been offered and whether any further completions are vailable.
[procedure] (completer-word-break-characters-set STRING)Sets the word-breaking characters for completion to STRING. The default value of \t\n\"\\'`@$><=;|&{( is suitable for Bash's completion.
Text Manipulation
[procedure] (line-buffer)Returns a string representing the current line contents.
[procedure] (point)[procedure] (end)
Returns a number representing the position of point and end of the line. If point is at the end of the line, point and end are equal.
[procedure] (display-prompt)Returns a string representing the current prompt. This is usually identical to the prompt strings, but may differ from them, for example when performing incremental search.
[procedure] (insert-text STRING)Insert STRING into the line at the current cursor position. Returns the number of characters inserted.
[procedure] (delete-text START END)Delete the text between START and END in the current line. Returns the number of characters deleted.
[procedure] (stuff-char CHAR)Insert CHAR into the Readline input stream. It will be "read" before Readline attempts to read characters from the terminal. Up to 512 characters may be pushed back. Returns 1 if the character was successfully inserted; 0 otherwise.
Redisplay
[procedure] (redisplay)Change what's displayed on the screen to reflect the current contents of Readline's buffer.
[procedure] (redisplay-function-set! PROCEDURE)Sets a function that will be called periodically when Readline performs redisplay. The argument should be a thunk. Its return value is ignored.
The default behavior may be enabled by passing #f.
Event hooks
[procedure] (event-hook-set! PROCEDURE)Registers a hook that will be called periodically when Readline is waiting for terminal input. By default, this will be called at most ten times a second if there is no keyboard input. The argument should be a thunk. Its return value is ignored.
Only one event hook may be registered at a time. A previously-registered hook may be disabled by passing #f.
[procedure] (pre-input-hook-set! PROCEDURE)Registers a hook that will be called every time the first input prompt has been printed, just before readline starts reading input characters. The argument should be a thunk. Its return value is ignored.
Only one pre-input hook may be registered at a time. A previously-registered hook may be disabled by passing #f.
Customization
[procedure] (variable-bind! VARIABLE VALUE)Sets a GNU Readline variable to a value. Both VARIABLE and VALUE must be strings.
[procedure] (variable-value VARIABLE)Retrieves the current value of the given GNU Readline variable. VARIABLE must be a string.
[procedure] (basic-quote-characters-set STRING)Sets the quoting characters to STRING, the default value being "'. This setting is used for paren blinking to determine strings.
[procedure] (paren-blink-timeout-set MICROSECS)Sets the timeout for paren blinking in microseconds, the default value being 500000 microseconds. Note that typing a closing paren will not blink the opening paren unless blink-matching-paren has been set.
Line editing
[procedure] (readline PROMPT)Read in a line of user input after printing PROMPT. Returns the user input or #f if input has been terminated with C-d.
[procedure] (make-readline-port [PROMPT])Returns an input port using GNU Readline for line editing and history management. PROMPT may be a string or a thunk returning a string and defaults to (repl-prompt).
Cleanup
[procedure] (cleanup-after-signal!)[procedure] (reset-after-signal!)
Procedures to call in sequence after receiving a signal in a signal handler to ensure a clean terminal and readline state.
[procedure] (reset-terminal! [TERMINAL-NAME])Procedure to call after program exit to ensure a clean terminal state. The optional argument TERMINAL-NAME defaults to the value of the TERM environment variable.
Examples
(import (chicken process signal)) (import breadline) (set-signal-handler! signal/int (lambda _ (cleanup-after-signal!) (reset-after-signal!))) (on-exit reset-terminal!) (let loop () (let ((input (readline "> "))) (if input (begin ;; processing code goes here (print input) (add-history! input) (loop)) (newline))))
Further examples for usage in csi and writing your own completer can be found in the repository.
License
Copyright 2016 Vasilij Schneidermann This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A full copy of the GPL license can be found at <http://www.gnu.org/licenses/>.
Version history
0.12
- Fix Scheme completions code to not error out on CHICKEN 5.4.0
0.11
- Make event-hook-set! and pre-input-hook-set! only set the hook when using the functions and unset it when passing #f. This resolves a segfault in a readline port while pressing complex key sequences.
0.10
- Introduce line-buffer, point, end, display-prompt and redisplay-function-set! to allow for syntax highlighting.
0.9.1
- Abort build on non-zero exit
0.9
- Make use of callback-based interface to handle interrupts graciously (thanks Evhan!)
0.8
- Expose cleanup procedures for signal and exit handlers
- Make use of these procedures in examples
0.7
- Quote user-provided environment variables in Windows build script
- Add build instructions for Ubuntu 18.04 and mingw-msys2
0.6
- Change build script to use Scheme when possible
- Improve examples
0.5
- Improve pkg-config check
0.4
- Use custom build script trying to use pkg-config, then falling back to CFLAGS and LDFLAGS
0.3
- Support thunks for make-readline-port and its prompt (thanks Marco Maggi!)
- Expose history-length procedure (thanks Marco Maggi!)
0.2
- Link explicitly against ncurses (thanks Marco Maggi!)
- Expose event and pre-input hooks and text modification functions (thanks Evhan!)
0.1
- Initial release