- parley - Negotiate your input
parley - Negotiate your input
Introduction
parley is a BSD licensed line editing module implemented in scheme which integrates nicely with CHICKEN's scheduler.
As of version 0.9 either single line editing mode or multiline editing mode is supported. See (refresh-line) in the parameter listing below.
Usage
(import parley) (import parley-auto-completion) ;; Add when needed
Requirements
stty and core units.
Source code
The parley source code repository is hosted on bitbucket: https://bitbucket.org/ckeen/parley
Documentation
parley
[procedure] (parley STRING)Prompts the user with prompt STRING and reads a whole line. This uses non-blocking I/O and returns a string or #eof!.
terminal-supported?
[procedure] (terminal-supported? PORT STRING)Checks if the terminal connected on PORT with name STRING is supported. If not parley will resort back to a dumb (non-blocking) readline implementation. Unsupported terminals will not trigger any user defined key-bindings.
history-to-file
[procedure] (history-to-file STRING)Dumps the current history to a file named in STRING. The file is overwritten if it already exists.
history-from-file
[procedure] (history-from-file STRING)Reads a previously saved history into memory. Note that currently parley's history is global.
add-key-binding!
[procedure] (add-key-binding! CHAR PROC #!key (esc-sequence #f))Register's PROC to be executed when CHAR is entered. If esc-sequence is #t, PROC will be called upon the sequence #\1b[CHAR.
make-parley-port
[procedure] (make-parley-port PORT #!key (prompt #f) (prompt2 #f) (history-file #f))Creates a scheme port that reads from PORT and writes to (current-output-port). See below for a usage example in CSI.
Example
#;1> (parley "> ") > Hello, World! "Hello, World!" #;2>
Parameters:
[parameter] (history-max-lines NUMBER)Number of lines the history will hold. If this maximum is exceeded the oldest line will be discarded.
[parameter] (mark-more-input? STRING)If not set to #f the string will be printed over the left and right edges, when there is more input hidden on either side of the screen. Defaults to "…" and is effective in single line mode only.
[parameter] (refresh-line REFRESH-PROCEDURE)This parameter sets the editing mode for parley. It is either singleline-refresh the default or multiline-refresh.
Core Keybindings
Currently the following keybindings are implemented:
- Cursor movement: Arrow keys (left right), CTRL-A, CTRL-E
- History: Arrow keys (up down), CTRL-P, CTRL-N for previous and next in history
- Editing / Deletion: CTRL-U for the current line, CTRL-K for everything after the cursor, CTRL-T swap current char with previous
- Terminal handling: CTRL-L clears the screen
User defined key bindings
A handler for a character is a procedure that accepts and returns a parley state record. The following getters and setters for the record state are exported:
- prompt
- The shown prompt for the line or "", getter only
- line
- The current line as string
- pos
- The current (0-based) cursor position wrt to line
- return
- A continuation that should be called if the input is done. This usually breaks out of the prompt loop.
- offset
- The offset of the current line. This is non zero if earlier function printed something on our line (like display)
New keybindings are added with the add-key-binding! procedure, which will override the current handler for the given key if present. If you like to add an escape sequence set the esc-sequence: keyword parameter to #t. This will match on ESQ Sequences like '\x1b[<char>'.
Example key binding
This handler deletes the all the text from the cursor position to the end of the line:
(use parley srfi-14) (define (delete-last-word line pos) (let* ((del-pos (or (string-index-right line (char-set-union char-set:whitespace char-set:punctuation) 0 pos) 0)) (left-part (if (> del-pos 0) (string-take line del-pos) "")) (npos (- pos (- pos del-pos)))) (values (string-append left-part (string-drop line pos)) npos))) (define (cw parley-state) (receive (l p) (delete-last-word (state-line parley-state) (state-pos parley-state)) (state-pos-set! parley-state p) (state-line-set! parley-state l) parley-state)) (add-key-binding! #\x17 cw)
Using parley in CSI
Parley of course can also be used within csi. Just add this to .csirc:
(use parley) (let ((old (current-input-port))) (current-input-port (make-parley-port old)))
Using parley-auto-completion
Parley offers by default no support for autocompletion. One could add her own handler and bind this to a convenient key, but as this might be of a more general interest this module is provided to enable programmers to add completion to their input prompts.
The behaviour of the completion mechanism can be tweaked through a small number of parameters. The items to look for completions can either be a simple list of strings (by using the completion-list procedure) or a more sophisticated handler procedure that can react to the already written input, cursor position and last word. This makes command/argument completions possible that are depending on the context. Of course one can also define what a word actually means for the running application.
auto-completion-handler
A procedure to pass to add-key-binding! (see above).
beep?
[parameter] (beep? #t)If #t (the default) a alarm character is sent when there are more than one possible completions.
completion-choices
[parameter] (completion-choices (lambda (input position last-word) '()))A parameter holding the selection procedure. The procedure is called to actually return a list of possible completions depending on the whole input line, the current cursor position and the detected last-word. Should return either the empty list if no completions can be found or a list of strings.
completion-list
[procedure] (completion-list list-of-strings)Convenience procedure to provide a simple string list to look for possible completions. Sets the completion-choices parameter.
print-completions
[parameter] (print-completions (lambda (completions) ...))Handles how the completions are handled. By default it prints the number of completions a newline and each completion separated by a space character, ending with a newline.
word-class
[parameter] (word-class '($ (+ (~ whitespace))))This defines how the last word in the input string is found. word-class takes any irregex expression.
Author
License
Copyright 2014 Christian Kellermann <ckeen@pestilenz.org>. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY CHRISTIAN KELLERMANN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CHRISTIAN KELLERMANN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Christian Kellermann.
Version History
- 1.0
- Chicken 5 support
- 0.9
- Multiline edit and incompatible handler API change, fixed single line mode
- 0.8.2
- Bugfix which has been shadowed by a flaw in stty
- 0.8
- Add input history, mark when there's off the screen input, thanks Jean Snell-Pym, parley-auto-completion module added
- 0.7
- Internal refactoring and support for CTRL-L thanks to Moritz Heidkamp
- 0.6
- Bugfix for bug 721 (thanks to Alan Post for the report), improved pasting support.
- 0.5
- Do not overwrite output on the same line, when starting. Thanks to Matthias Bauer.
- 0.4
- Handle eof correctly
- 0.3
- do not flush input when setting terminal attributes, thanks again certainty
- 0.2
- bugfix release, thanks to certainty
- 0.1
- initial release