Isocline
Isocline is a portable GNU readline alternative
Install / Use
/learn @daanx/IsoclineREADME
Isocline: a portable readline alternative.
Isocline is a pure C library that can be used as an alternative to the GNU readline library (latest release v1.0.9, 2022-01-15).
-
Small: less than 8k lines and can be compiled as a single C file without any dependencies or configuration (e.g.
gcc -c src/isocline.c). -
Portable: works on Unix, Windows, and macOS, and uses a minimal subset of ANSI escape sequences.
-
Features: extensive multi-line editing mode (
shift-tab), (24-bit) color, history, completion, unicode, undo/redo, incremental history search, inline hints, syntax highlighting, brace matching, closing brace insertion, auto indentation, graceful fallback, support for custom allocators, etc. -
License: MIT.
-
Comes with a Haskell binding ([
System.Console.Isocline][hdoc].
Enjoy, Daan
<!-- <img align="right" width="350px" src="doc/history-win.png"/> -->Demo
Shows in order: unicode, syntax highlighting, brace matching, jump to matching brace, auto indent, multiline editing, 24-bit colors, inline hinting, filename completion, and incremental history search.
<sub>(screen capture was made with [termtosvg] by Nicolas Bedos)</sub>
Usage
Include the isocline header in your C or C++ source:
#include <include/isocline.h>
and call ic_readline to get user input with rich editing abilities:
char* input;
while( (input = ic_readline("prompt")) != NULL ) { // ctrl+d/c or errors return NULL
printf("you typed:\n%s\n", input); // use the input
free(input);
}
See the [example] for a full example with completion, syntax highligting, history, etc.
Run the Example
You can compile and run the [example] as:
$ gcc -o example -Iinclude test/example.c src/isocline.c
$ ./example
or, the Haskell [example][HaskellExample]:
$ ghc -ihaskell test/Example.hs src/isocline.c
$ ./test/Example
Editing with Isocline
Isocline tries to be as compatible as possible with standard [GNU Readline] key bindings.
Overview:
home/ctrl-a cursor end/ctrl-e
┌─────────────────┼───────────────┐ (navigate)
│ ctrl-left │ ctrl-right │
│ ┌───────┼──────┐ │ ctrl-r : search history
▼ ▼ ▼ ▼ ▼ tab : complete word
prompt> it is the quintessential language shift-tab: insert new line
▲ ▲ ▲ ▲ esc : delete input, done
│ └──────────────┘ │ ctrl-z : undo
│ alt-backsp alt-d │
└─────────────────────────────────┘ (delete)
ctrl-u ctrl-k
<sub>Note: on macOS, the meta (alt) key is not directly available in most terminals.
Terminal/iTerm2 users can activate the meta key through
Terminal → Preferences → Settings → Use option as meta key.</sub>
Key Bindings
These are also shown when pressing F1 on a Isocline prompt. We use ^ as a shorthand for ctrl-:
| Navigation | |
|-------------------|-------------------------------------------------|
| left,^b | go one character to the left |
| right,^f | go one character to the right |
| up | go one row up, or back in the history |
| down | go one row down, or forward in the history |
| ^left | go to the start of the previous word |
| ^right | go to the end the current word |
| home,^a | go to the start of the current line |
| end,^e | go to the end of the current line |
| pgup,^home | go to the start of the current input |
| pgdn,^end | go to the end of the current input |
| alt-m | jump to matching brace |
| ^p | go back in the history |
| ^n | go forward in the history |
| ^r,^s | search the history starting with the current word |
| Deletion | |
|-------------------|-------------------------------------------------|
| del,^d | delete the current character |
| backsp,^h | delete the previous character |
| ^w | delete to preceding white space |
| alt-backsp | delete to the start of the current word |
| alt-d | delete to the end of the current word |
| ^u | delete to the start of the current line |
| ^k | delete to the end of the current line |
| esc | delete the current input, or done with empty input |
| Editing | |
|-------------------|-------------------------------------------------|
| enter | accept current input |
| ^enter,^j,shift-tab | create a new line for multi-line input |
| ^l | clear screen |
| ^t | swap with previous character (move character backward) |
| ^z,^_ | undo |
| ^y | redo |
| tab | try to complete the current input |
| Completion menu | |
|-------------------|-------------------------------------------------|
| enter,left | use the currently selected completion |
| 1 - 9 | use completion N from the menu |
| tab, down | select the next completion |
| shift-tab, up | select the previous completion |
| esc | exit menu without completing |
| pgdn,^enter,^j | show all further possible completions |
| Incremental history search | |
|-------------------|-------------------------------------------------|
| enter | use the currently found history entry |
| backsp,^z | go back to the previous match (undo) |
| tab,^r,up | find the next match |
| shift-tab,^s,down | find an earlier match |
| esc | exit search |
Build the Library
Build as a Single Source
Copy the sources (in include and src) into your project, or add the library as a [submodule]:
$ git submodule add https://github.com/daanx/isocline
and add isocline/src/isocline.c to your build rules -- no configuration is needed.
Build with CMake
Clone the repository and run cmake to build a static library (.a/.lib):
$ git clone https://github.com/daanx/isocline
$ cd isocline
$ mkdir -p build/release
$ cd build/release
$ cmake ../..
$ cmake --build .
This builds a static library libisocline.a (or isocline.lib on Windows)
and the example program:
$ ./example
Build the Haskell Library
See the Haskell [readme][Haskell] for instructions to build and use the Haskell library.
API Reference
-
See the [C API reference][docapi] and the [example] for example usage of history, completion, etc.
-
See the [Haskell API reference][hdoc] on Hackage and the Haskell [example][HaskellExample].
Motivation
Isocline was created for use in the [Koka] interactive compiler. This required: pure C (no dependency on a C++ runtime or other libraries), portable (across Linux, macOS, and Windows), unicode support, a BSD-style license, and good functionality for completion and multi-line editing.
Some other excellent libraries that we considered: [GNU readline], editline, linenoise, replxx, and Haskeline.
Formatted Output
Isocline also exposes functions for rich terminal output
as ic_print (and ic_println and ic_printf).
Inspired by the (Python) [Rich][RichBBcode] library,
this supports a form of [bbcode]'s to format the output:
ic_println( "[b]bold [red]and red[/red][/b]" );
Each print automatically closes any open tags that were
not yet closed. Also, you can use a general close
tag as [/] to close the innermost tag, so the
following print is equivalent to the earlier one:
ic_println( "[b]bold [red]and red[/]" );
There can be multiple styles in one tag (where the first name is used for the closing tag):
ic_println( "[u #FFD700]underlined gold[/]" );
Sometimes, you need to display arbitrary messages
that may contain sequences that you would not like
to be interpreted as bbcode tags. One way to do
this is the [!tag] which ignores formatting
up to a close tag of the form [/tag].
ic_printf( "[red]red? [!pre]%s[/pre].\n", "[blue]not blue!" );
Predefined styles include b (bold),
u (underline), i (italic), and r (reverse video), but
you can (re)define any style yourself as:
ic_style_def("warning", "crimson u");
and use them like any builtin style or property:
ic_println( "[warning]this is a warning![/]" );
which is great for adding themes to your application.
Each ic_print function always closes any unclosed tags automatically.
To open a style persistently, use ic_style_open with a matching
ic_style_close which scopes over any ic_print statements in between.
ic_style_open("warning");
ic_println("[b]crimson underlined and bold[/]");
ic_style_close();
Advanced
BBCode Format
An open tag can have multiple white space separated
entries that are
either a style name, or a primitive property[=value].
Styles
Isocline provides the following builtin styles as property shorthands:
b (bold), u (underline), i (italic), r (reverse video),
and some builtin styles for syntax highlighting:
keyword, control (control-flow keywords), string,
comment, number, type, constant.
Predefined styles used by Isocline itself are:
ic-prompt: prompt style
