Outdated egg!

This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.

If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.

  1. Outdated egg!
  2. parley - Negotiate your input
    1. Introduction
    2. Usage
    3. Requirements
    4. Source code
    5. Documentation
      1. parley
      2. terminal-supported?
      3. history-to-file
      4. history-from-file
      5. add-key-binding!
      6. make-parley-port
      7. Example
      8. Parameters:
      9. Core Keybindings
      10. User defined key bindings
        1. Example key binding
      11. Using parley in CSI
      12. Using parley-auto-completion
        1. auto-completion-handler
        2. beep?
        3. completion-choices
        4. completion-list
        5. print-completions
        6. word-class
    6. Author
    7. License
    8. Version History

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

(require-extension parley)
(require-extension 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:

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.

[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

Christian Kellermann

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

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