Fork 0
A line editing library for the slope programming language (WIP)
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
sloum 702abc3135 Adds a paste buffer and pasting 6 months ago
README.md Adds a paste buffer and pasting 6 months ago
main.slo Adds a paste buffer and pasting 6 months ago
module.json Adds a paste buffer and pasting 6 months ago



This line-edit module is a native slope line reading library that can be used where you might, in another language, use bindings to libreadline. line-edit is a pure slope affair that utilizes terminal escape sequences to control the line and an internal buffer to track state.

What it does

At a basic level, it allows a user to input text... and to navigate that text as they are inputting it: moving the cursor around, clearing the line, etc.

line-edit allows the programmer to supply a prompt and a seed value to the line. The prompt is not editable by the user. The seed value is an initial value that the buffer is set to and can be edited by the user.

Using (line-edit::line "$ " "") would give the user the prompt $ with no seed value and will return a string containing the text that they entered.

line-edit provides a few basic control key chords to enable navigating the line without arrow keys if need be, but nowhere near as robust as libreadline.

If the entry is longer than the available terminal width minus the prompt length then an offset value is kept in the buffer to allow for horizontal scolling of the input line.

What it does not do

  • Completion
  • Fancy stuff like moving the cursor to the next/previous word
  • Support multiline input
  • Wrap long lines (horizontal scrolling is used instead)
  • Support actual tab characters as input (tab will instead convert to a number of spaces equal to the tabwidth setting - see below)

How to use it

There are basically two procedures and a few variables available to a user of the module.

Reading a key

This is exposed to the user, but is mostly present as a part of reading a line. However, it may be useful for any number of situations and should thus be documented here.

(load-mod line-edit)
(define my-key-press (line-edit::get-key))

Key Responses / Variables

The returned value will be a number. That number will generally correspond to the ascii value of the key being pressed, or the rune (codepoint) of a UTF-8 character. Some values have variables set for convenience; these are listed as follows:

^A, ^B, ^D, ^E, ^F, ^K, ^L, ^P, ^U, ^V, up-key, down-key, left-key, right-key, delete-key, home-key, end-key, page-up-key, page-down-key, escape-key, new-line, return, backspace

You can use these like so:

(load-mod line-edit)
(if (equal? (line-edit::home-key) (line-edit::get-key))
  (display "Home key was pressed")
  (display "A key was pressed... but it wasn't the home key"))

Reading a line

This is the main procedure of the module. The procedure signature is:

(line-edit::get-line [prompt: string] [seed: string]) => string

Both prompt and seed are required, but both/either can be an empty string.

Usage takes the form of:

(load-mod line-edit)
(define name (line-edit::get-line "Name: " ""))

Key Bindings

line-edit includes a modest set of key bindings:

Key(s) Effect
Home, Up, ^A Move cursor to the beginning of the line
End, Down, ^E Move cursor to the end of the line
Left, ^B Move the cursor one character to the left
Right, ^F Move the cursor one character to the right
Delete, ^D Delete the character under the cursor
Backspace Delete the character before the cursor
^K Delete from the cursor to the end of the line
^L Empty the line (delete all content in the buffer)
^P Enter paste mode (the next read can accept pasted data)
^U Delete from the beginning of the line to the cursor
^V Paste the contents of the paste buffer
Enter, Return Submit the line
Most printable chars Add the character to the buffer at the cursor location

As noted above, tab is not registered for input as it donks up the horizontal scrolling provided by line-edit.

The Paste Buffer

The paste buffer survives accross multiple calls to module procedures, including get-line. As such, it can be used as a paste buffer for the whole slope interpreter session, not just a single procedure call. Anything that is deleted with Ctrl+K, Ctrl+U, or Ctrl+L gets put into the paste buffer. The paste buffer only has one level which gets overwritten any time one of the above key chords gets pressed (even if no deletion occurs, such as ^U at the beginning of the line, which will leave an empty paste buffer).

Pasting text into line-edit

Unicode parsing is funky here. To enable good usage of utf-8 text, in line with the rest of slope as a programming system, a single utf-8 character (including the ascii set) can be pasted and will appear as intended. Due to a mixture of complicated specs and design decisions for this module the key chord ^P should be entered before attempting to paste more than a single character. Doing so will allow a paste and read pasted data up to the first newline. Unicode is properly supported within this paste. There is a maximum paste size of ~2kb.

The TAB key

Tab spacing is variable by user by system. In order to not wade into that mess line-edit will accept the tab key being pressed but will enter spaces up to the next tabstop, as defined by the line-edit::tabwidth procedure.

To get/set the tab width:

(load-mod line-edit)
(display (line-edit::tabwidth)) ; 4
(line-edit::tabwidth 8)         ; sets the tabwidth to 8
(display (line-edit::tabwidth)) ; 8

This behavior will accurately replicate what tabs do, but via spaces.

If in a call to line-edit::get-line you provide default text that has a literal tab character in it, it will be display, but movement and cursor alignment will be off and will be a very odd user experience. It is advised that you convert any default text to use tab stops that work with the tabwidth setting the line-edit module is using at the time of the procedure call.