
Develops an interactive console application readline library with history support using a cross-platform approach. Includes REPL-style loop capabilities, configurable line editing, and extensive keybinding options. Integrates Rust's readline functionality via FFI.
Cross-platform Kotlin/Native readline library with history support for interactive console apps.
π Documentation
π Homepage (under construction)
[!IMPORTANT]
The project is in a very early stage; thus, breaking changes should be expected.
A minimal REPL-style loop with history persistence:
fun main() {
val history = "history.txt" // Filesystem path to the history file.
// Configure the LineEditor.
val config = LineEditorConfig(
maxHistorySize = 100,
completionType = CompletionType.LIST,
// See the documentation for more options.
)
// Create a new LineEditor instance.
val editor = SimpleLineEditor(
linePrefix = "> ",
config = config,
).also { editor ->
// Set up the completer and highlighter.
editor
.withCompleter(SimpleFileCompleter()) // Provides file completion (optional).
.withHighlighter(SimpleHighlighter()) // Provides color highlighting (optional).
// Load the history from the disk (throws LineEditorError if it fails).
editor.loadHistory(history).getOrThrow()
}
println("Welcome to the LineEditor example!")
println("Press Ctrl+C to exit")
while (true) {
// Read a line from the user.
editor.readLine()
.onFailure { err ->
// err is a LineEditorError
println(err.message)
break
}
.onSuccess { line ->
// We can also add the line to the history automatically by setting autoAddHistory = true in the config.
editor.addHistoryEntry(line)
println(line)
}
}
// Save the history to disk.
editor.saveHistory(history)
}See more examples here
For all modes:
| Keystroke | Action |
|---|---|
| Home | Move cursor to the beginning of line |
| End | Move cursor to end of line |
| Left | Move cursor one character left |
| Right | Move cursor one character right |
| Ctrl-C | Interrupt/Cancel edition |
| Ctrl-D, Del | (if line is not empty) Delete character under cursor |
| Ctrl-D | (if line is empty) End of File |
| Ctrl-J, Ctrl-M, Enter | Finish the line entry |
| Ctrl-R | Reverse Search history (Ctrl-S forward, Ctrl-G cancel) |
| Ctrl-T | Transpose previous character with current character |
| Ctrl-U | Delete from start of line to cursor |
| Ctrl-V (unix) | Insert any special character without performing its associated action (#65) |
| Ctrl-V (windows) | Paste from clipboard |
| Ctrl-W | Delete word leading up to cursor (using white space as a word boundary) |
| Ctrl-Y | Paste from Yank buffer |
| Ctrl-Z | Suspend (Unix only) |
| Ctrl-_ | Undo |
| Keystroke | Action |
|---|---|
| Ctrl-A, Home | Move cursor to the beginning of line |
| Ctrl-B, Left | Move cursor one character left |
| Ctrl-E, End | Move cursor to end of line |
| Ctrl-F, Right | Move cursor one character right (or complete hint if cursor is at the end of line) |
| Ctrl-H, Backspace | Delete character before cursor |
| Shift-Tab | Previous completion |
| Ctrl-I, Tab | Next completion |
| Ctrl-K | Delete from cursor to end of line |
| Ctrl-L | Clear screen |
| Ctrl-N, Down | Next match from history |
| Ctrl-P, Up | Previous match from history |
| Ctrl-X Ctrl-G | Abort |
| Ctrl-X Esc | Abort |
| Ctrl-X Ctrl-U | Undo |
| Ctrl-X Backspace | Delete from cursor to the beginning of line |
| Ctrl-Y | Paste from Yank buffer (Meta-Y to paste next yank instead) |
| Ctrl-] | Search character forward |
| Ctrl-Alt-] | Search character backward |
| Meta-< | Move to first entry in history |
| Meta-> | Move to last entry in history |
| Meta-B, Alt-Left | Move cursor to previous word |
| Ctrl-Left | See Alt-Left |
| Meta-C | Capitalize the current word |
| Meta-D | Delete forwards one word |
| Meta-F, Alt-Right | Move cursor to next word |
| Ctrl-Right | See Alt-Right |
| Meta-L | Lower-case the next word |
| Meta-T | Transpose words |
| Meta-U | Upper-case the next word |
| Meta-Y | See Ctrl-Y |
| Meta-Backspace | Kill from the start of the current word, or, if between words, to the start of the previous word |
| Meta-0, 1, ..., - | Specify the digit to the argument. β starts a negative argument. |
Readline Emacs Editing Mode Cheat Sheet
| Keystroke | Action |
|---|---|
| $, End | Move cursor to end of line |
| . | Redo the last text modification |
| ; | Redo the last character finding command |
| , | Redo the last character finding command in opposite direction |
| 0, Home | Move cursor to the beginning of line |
| ^ | Move to the first non-blank character of line |
| a | Insert after cursor |
| A | Insert at the end of line |
| b | Move one word or token left |
| B | Move one non-blank word left |
| c | Change text of a movement command |
| C | Change text to the end of line (equivalent to c$) |
| d | Delete text of a movement command |
| D, Ctrl-K | Delete to the end of the line |
| e | Move to the end of the current word |
| E | Move to the end of the current non-blank word |
| f | Move right to the next occurrence of char
|
| F | Move left to the previous occurrence of char
|
| h, Ctrl-H, Backspace | Move one character left |
| l, Space | Move one character right |
| Ctrl-L | Clear screen |
| i | Insert before cursor |
| I | Insert at the beginning of line |
| +, j, Ctrl-N | Move forward one command in history |
| -, k, Ctrl-P | Move backward one command in history |
| p | Insert the yanked text at the cursor (paste) |
| P | Insert the yanked text before the cursor |
| r | Replaces a single character under the cursor (without leaving command mode) |
| R | Replaces a single character under the cursor (entering the replace mode) |
| s | Delete a single character under the cursor and enter input mode |
| S | Change current line (equivalent to 0c$) |
| t | Move right to the next occurrence of char, then one char backward |
| T | Move left to the previous occurrence of char, then one char forward |
| u | Undo |
| w | Move one word or token right |
| W | Move one non-blank word right |
| x | Delete a single character under the cursor |
| X | Delete a character before the cursor |
| y | Yank a movement into buffer (copy) |
| < | Dedent |
| > | Indent |
| Keystroke | Action |
|---|---|
| Ctrl-H, Backspace | Delete character before cursor |
| Shift-Tab | Previous completion |
| Ctrl-I, Tab | Next completion |
| Right | Complete hint if cursor is at the end of line |
| Alt- | Fast command mode |
| Esc | Switch to command mode |
Readline vi Editing Mode Cheat Sheet
The library is published to Maven Central. Use the latest version shown by the badge above.
Kotlin DSL (example for a native target):
kotlin {
// Choose your native targets, e.g.:
macosX64()
linuxX64()
mingwX64()
sourceSets {
// With the default hierarchy, a shared nativeMain is available when you have multiple native targets
val nativeMain by getting {
dependencies {
implementation("io.github.smyrgeorge:readline4k:<latest>")
}
}
}
}If you use only one native target, add the dependency to that target's Main source set (e.g., macosX64Main, linuxX64Main, or mingwX64Main).
Under the hood, readline4k leverages the rustyline project to provide
comprehensive readline functionality, with communication between Kotlin and the Rust library handled through FFI
(Foreign Function Interface).
MIT β see LICENSE.
Cross-platform Kotlin/Native readline library with history support for interactive console apps.
π Documentation
π Homepage (under construction)
[!IMPORTANT]
The project is in a very early stage; thus, breaking changes should be expected.
A minimal REPL-style loop with history persistence:
fun main() {
val history = "history.txt" // Filesystem path to the history file.
// Configure the LineEditor.
val config = LineEditorConfig(
maxHistorySize = 100,
completionType = CompletionType.LIST,
// See the documentation for more options.
)
// Create a new LineEditor instance.
val editor = SimpleLineEditor(
linePrefix = "> ",
config = config,
).also { editor ->
// Set up the completer and highlighter.
editor
.withCompleter(SimpleFileCompleter()) // Provides file completion (optional).
.withHighlighter(SimpleHighlighter()) // Provides color highlighting (optional).
// Load the history from the disk (throws LineEditorError if it fails).
editor.loadHistory(history).getOrThrow()
}
println("Welcome to the LineEditor example!")
println("Press Ctrl+C to exit")
while (true) {
// Read a line from the user.
editor.readLine()
.onFailure { err ->
// err is a LineEditorError
println(err.message)
break
}
.onSuccess { line ->
// We can also add the line to the history automatically by setting autoAddHistory = true in the config.
editor.addHistoryEntry(line)
println(line)
}
}
// Save the history to disk.
editor.saveHistory(history)
}See more examples here
For all modes:
| Keystroke | Action |
|---|---|
| Home | Move cursor to the beginning of line |
| End | Move cursor to end of line |
| Left | Move cursor one character left |
| Right | Move cursor one character right |
| Ctrl-C | Interrupt/Cancel edition |
| Ctrl-D, Del | (if line is not empty) Delete character under cursor |
| Ctrl-D | (if line is empty) End of File |
| Ctrl-J, Ctrl-M, Enter | Finish the line entry |
| Ctrl-R | Reverse Search history (Ctrl-S forward, Ctrl-G cancel) |
| Ctrl-T | Transpose previous character with current character |
| Ctrl-U | Delete from start of line to cursor |
| Ctrl-V (unix) | Insert any special character without performing its associated action (#65) |
| Ctrl-V (windows) | Paste from clipboard |
| Ctrl-W | Delete word leading up to cursor (using white space as a word boundary) |
| Ctrl-Y | Paste from Yank buffer |
| Ctrl-Z | Suspend (Unix only) |
| Ctrl-_ | Undo |
| Keystroke | Action |
|---|---|
| Ctrl-A, Home | Move cursor to the beginning of line |
| Ctrl-B, Left | Move cursor one character left |
| Ctrl-E, End | Move cursor to end of line |
| Ctrl-F, Right | Move cursor one character right (or complete hint if cursor is at the end of line) |
| Ctrl-H, Backspace | Delete character before cursor |
| Shift-Tab | Previous completion |
| Ctrl-I, Tab | Next completion |
| Ctrl-K | Delete from cursor to end of line |
| Ctrl-L | Clear screen |
| Ctrl-N, Down | Next match from history |
| Ctrl-P, Up | Previous match from history |
| Ctrl-X Ctrl-G | Abort |
| Ctrl-X Esc | Abort |
| Ctrl-X Ctrl-U | Undo |
| Ctrl-X Backspace | Delete from cursor to the beginning of line |
| Ctrl-Y | Paste from Yank buffer (Meta-Y to paste next yank instead) |
| Ctrl-] | Search character forward |
| Ctrl-Alt-] | Search character backward |
| Meta-< | Move to first entry in history |
| Meta-> | Move to last entry in history |
| Meta-B, Alt-Left | Move cursor to previous word |
| Ctrl-Left | See Alt-Left |
| Meta-C | Capitalize the current word |
| Meta-D | Delete forwards one word |
| Meta-F, Alt-Right | Move cursor to next word |
| Ctrl-Right | See Alt-Right |
| Meta-L | Lower-case the next word |
| Meta-T | Transpose words |
| Meta-U | Upper-case the next word |
| Meta-Y | See Ctrl-Y |
| Meta-Backspace | Kill from the start of the current word, or, if between words, to the start of the previous word |
| Meta-0, 1, ..., - | Specify the digit to the argument. β starts a negative argument. |
Readline Emacs Editing Mode Cheat Sheet
| Keystroke | Action |
|---|---|
| $, End | Move cursor to end of line |
| . | Redo the last text modification |
| ; | Redo the last character finding command |
| , | Redo the last character finding command in opposite direction |
| 0, Home | Move cursor to the beginning of line |
| ^ | Move to the first non-blank character of line |
| a | Insert after cursor |
| A | Insert at the end of line |
| b | Move one word or token left |
| B | Move one non-blank word left |
| c | Change text of a movement command |
| C | Change text to the end of line (equivalent to c$) |
| d | Delete text of a movement command |
| D, Ctrl-K | Delete to the end of the line |
| e | Move to the end of the current word |
| E | Move to the end of the current non-blank word |
| f | Move right to the next occurrence of char
|
| F | Move left to the previous occurrence of char
|
| h, Ctrl-H, Backspace | Move one character left |
| l, Space | Move one character right |
| Ctrl-L | Clear screen |
| i | Insert before cursor |
| I | Insert at the beginning of line |
| +, j, Ctrl-N | Move forward one command in history |
| -, k, Ctrl-P | Move backward one command in history |
| p | Insert the yanked text at the cursor (paste) |
| P | Insert the yanked text before the cursor |
| r | Replaces a single character under the cursor (without leaving command mode) |
| R | Replaces a single character under the cursor (entering the replace mode) |
| s | Delete a single character under the cursor and enter input mode |
| S | Change current line (equivalent to 0c$) |
| t | Move right to the next occurrence of char, then one char backward |
| T | Move left to the previous occurrence of char, then one char forward |
| u | Undo |
| w | Move one word or token right |
| W | Move one non-blank word right |
| x | Delete a single character under the cursor |
| X | Delete a character before the cursor |
| y | Yank a movement into buffer (copy) |
| < | Dedent |
| > | Indent |
| Keystroke | Action |
|---|---|
| Ctrl-H, Backspace | Delete character before cursor |
| Shift-Tab | Previous completion |
| Ctrl-I, Tab | Next completion |
| Right | Complete hint if cursor is at the end of line |
| Alt- | Fast command mode |
| Esc | Switch to command mode |
Readline vi Editing Mode Cheat Sheet
The library is published to Maven Central. Use the latest version shown by the badge above.
Kotlin DSL (example for a native target):
kotlin {
// Choose your native targets, e.g.:
macosX64()
linuxX64()
mingwX64()
sourceSets {
// With the default hierarchy, a shared nativeMain is available when you have multiple native targets
val nativeMain by getting {
dependencies {
implementation("io.github.smyrgeorge:readline4k:<latest>")
}
}
}
}If you use only one native target, add the dependency to that target's Main source set (e.g., macosX64Main, linuxX64Main, or mingwX64Main).
Under the hood, readline4k leverages the rustyline project to provide
comprehensive readline functionality, with communication between Kotlin and the Rust library handled through FFI
(Foreign Function Interface).
MIT β see LICENSE.