{"id":30954834,"url":"https://github.com/smyrgeorge/readline4k","last_synced_at":"2025-09-11T11:54:49.106Z","repository":{"id":310879816,"uuid":"1041010931","full_name":"smyrgeorge/readline4k","owner":"smyrgeorge","description":"Cross-platform Kotlin/Native readline library with history support for interactive console apps.","archived":false,"fork":false,"pushed_at":"2025-09-07T08:25:17.000Z","size":588,"stargazers_count":18,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-07T10:13:57.878Z","etag":null,"topics":["cmd","command-line","command-prompt","linux","macos","readline","terminal","windows"],"latest_commit_sha":null,"homepage":"https://smyrgeorge.github.io","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smyrgeorge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"smyrgeorge"}},"created_at":"2025-08-19T21:02:53.000Z","updated_at":"2025-09-07T08:25:21.000Z","dependencies_parsed_at":"2025-08-20T20:44:26.122Z","dependency_job_id":"46875dd1-9448-4a3a-a1d6-a134e9cb61ea","html_url":"https://github.com/smyrgeorge/readline4k","commit_stats":null,"previous_names":["smyrgeorge/readline4k"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/smyrgeorge/readline4k","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smyrgeorge%2Freadline4k","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smyrgeorge%2Freadline4k/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smyrgeorge%2Freadline4k/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smyrgeorge%2Freadline4k/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smyrgeorge","download_url":"https://codeload.github.com/smyrgeorge/readline4k/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smyrgeorge%2Freadline4k/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274631303,"owners_count":25321240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmd","command-line","command-prompt","linux","macos","readline","terminal","windows"],"created_at":"2025-09-11T11:54:47.405Z","updated_at":"2025-09-11T11:54:49.100Z","avatar_url":"https://github.com/smyrgeorge.png","language":"Kotlin","funding_links":["https://github.com/sponsors/smyrgeorge"],"categories":[],"sub_categories":[],"readme":"# readline4k\n\n![Build](https://github.com/smyrgeorge/readline4k/actions/workflows/ci.yml/badge.svg)\n![Maven Central](https://img.shields.io/maven-central/v/io.github.smyrgeorge/readline4k)\n![GitHub License](https://img.shields.io/github/license/smyrgeorge/readline4k)\n![GitHub commit activity](https://img.shields.io/github/commit-activity/w/smyrgeorge/readline4k)\n![GitHub issues](https://img.shields.io/github/issues/smyrgeorge/readline4k)\n[![Kotlin](https://img.shields.io/badge/kotlin-2.2.10-blue.svg?logo=kotlin)](http://kotlinlang.org)\n\n![](https://img.shields.io/static/v1?label=\u0026message=Platforms\u0026color=grey)\n![](https://img.shields.io/static/v1?label=\u0026message=Linux\u0026color=blue)\n![](https://img.shields.io/static/v1?label=\u0026message=macOS\u0026color=blue)\n![](https://img.shields.io/static/v1?label=\u0026message=Windows\u0026color=blue)\n\nCross-platform Kotlin/Native readline library with history support for interactive console apps.\n\n📖 [Documentation](https://smyrgeorge.github.io/readline4k/)\n\n🏠 [Homepage](https://smyrgeorge.github.io/) (under construction)\n\n\u003e [!IMPORTANT]  \n\u003e The project is in a very early stage; thus, breaking changes should be expected.\n\n## Supported Platforms\n\n- Unix (tested on FreeBSD, Linux, and macOS)\n- Windows\n    - cmd.exe\n    - Powershell\n\n### Note that:\n\n- Powershell ISE is not supported\n- Mintty (Cygwin/MinGW) is not supported\n- Highlighting / Colors are not supported on Windows \u003c Windows 10 except with ConEmu and ColorMode::Forced.\n\n## Features\n\n- Cross-platform line editing for Unix (Linux, macOS, FreeBSD) and Windows consoles.\n- Simple, composable API:\n  - Read one line with a prompt prefix and get Result\u003cString\u003e back (non-throwing API).\n  - Clear screen, manage history, and attach completion/highlighting strategies.\n- History management:\n  - In-memory history with max size and duplicate handling policy.\n  - Load from/save to a file, clear history, and optional auto-add on successful read.\n  - Optionally ignore lines starting with a space.\n- Pluggable completion:\n  - Interface-based Completer with cursor-aware token replacement.\n  - Built-in SimpleFileCompleter for filesystem paths (tilde expansion, hidden files rules, dir trailing slash).\n  - Multiple completion modes: Circular cycling or List with common-prefix and paging; show-all-if-ambiguous option.\n- Configurable highlighting:\n  - Highlighter interface to style prompt, inline hints, and candidates (e.g., via ANSI colors).\n  - Color modes: Enabled, Forced, or Disabled to match terminal capabilities.\n- Editing behavior and keymaps:\n  - Emacs or Vi editing modes.\n  - Bell styles: audible or none (with sensible Windows default).\n- Terminal features (where supported):\n  - Bracketed paste, synchronized output, and signal handling on Unix-like systems.\n- I/O behavior:\n  - STDIO by default or Prefer terminal behavior when available.\n\n## Quick start\n\nA minimal REPL-style loop with history persistence:\n\n```kotlin\nfun main() {\n    val history = \"history.txt\" // Filesystem path to the history file.\n\n    // Configure the LineEditor.\n    val config = LineEditorConfig(\n        maxHistorySize = 100,\n        completionType = CompletionType.LIST,\n        // See the documentation for more options.\n    )\n\n    // Create a new LineEditor instance.\n    val editor = SimpleLineEditor(\n        linePrefix = \"\u003e \",\n        config = config,\n    ).also { editor -\u003e\n        // Set up the completer and highlighter.\n        editor\n            .withCompleter(SimpleFileCompleter()) // Provides file completion (optional).\n            .withHighlighter(SimpleHighlighter()) // Provides color highlighting (optional).\n\n        // Load the history from the disk (throws LineEditorError if it fails).\n        editor.loadHistory(history).getOrThrow()\n    }\n\n    println(\"Welcome to the LineEditor example!\")\n    println(\"Press Ctrl+C to exit\")\n\n    while (true) {\n        // Read a line from the user.\n        editor.readLine()\n            .onFailure { err -\u003e\n                // err is a LineEditorError\n                println(err.message)\n                break\n\n            }\n            .onSuccess { line -\u003e\n                // We can also add the line to the history automatically by setting autoAddHistory = true in the config.\n                editor.addHistoryEntry(line)\n                println(line)\n            }\n    }\n\n    // Save the history to disk.\n    editor.saveHistory(history)\n}\n```\n\nSee more examples [here](./examples/src/nativeMain/kotlin/io/github/smyrgeorge/readline4k/examples)\n\n## Actions\n\nFor all modes:\n\n| Keystroke             | Action                                                                      |\n|-----------------------|-----------------------------------------------------------------------------|\n| Home                  | Move cursor to the beginning of line                                        |\n| End                   | Move cursor to end of line                                                  |\n| Left                  | Move cursor one character left                                              |\n| Right                 | Move cursor one character right                                             |\n| Ctrl-C                | Interrupt/Cancel edition                                                    |\n| Ctrl-D, Del           | (if line is _not_ empty) Delete character under cursor                      |\n| Ctrl-D                | (if line _is_ empty) End of File                                            |\n| Ctrl-J, Ctrl-M, Enter | Finish the line entry                                                       |\n| Ctrl-R                | Reverse Search history (Ctrl-S forward, Ctrl-G cancel)                      |\n| Ctrl-T                | Transpose previous character with current character                         |\n| Ctrl-U                | Delete from start of line to cursor                                         |\n| Ctrl-V (unix)         | Insert any special character without performing its associated action (#65) |\n| Ctrl-V (windows)      | Paste from clipboard                                                        |\n| Ctrl-W                | Delete word leading up to cursor (using white space as a word boundary)     |\n| Ctrl-Y                | Paste from Yank buffer                                                      |\n| Ctrl-Z                | Suspend (Unix only)                                                         |\n| Ctrl-\\_               | Undo                                                                        |\n\n### Emacs mode (default mode)\n\n| Keystroke         | Action                                                                                           |\n|-------------------|--------------------------------------------------------------------------------------------------|\n| Ctrl-A, Home      | Move cursor to the beginning of line                                                             |\n| Ctrl-B, Left      | Move cursor one character left                                                                   |\n| Ctrl-E, End       | Move cursor to end of line                                                                       |\n| Ctrl-F, Right     | Move cursor one character right (or complete hint if cursor is at the end of line)               |\n| Ctrl-H, Backspace | Delete character before cursor                                                                   |\n| Shift-Tab         | Previous completion                                                                              |\n| Ctrl-I, Tab       | Next completion                                                                                  |\n| Ctrl-K            | Delete from cursor to end of line                                                                |\n| Ctrl-L            | Clear screen                                                                                     |\n| Ctrl-N, Down      | Next match from history                                                                          |\n| Ctrl-P, Up        | Previous match from history                                                                      |\n| Ctrl-X Ctrl-G     | Abort                                                                                            |\n| Ctrl-X Esc        | Abort                                                                                            |\n| Ctrl-X Ctrl-U     | Undo                                                                                             |\n| Ctrl-X Backspace  | Delete from cursor to the beginning of line                                                      |\n| Ctrl-Y            | Paste from Yank buffer (Meta-Y to paste next yank instead)                                       |\n| Ctrl-] \u003cchar\u003e     | Search character forward                                                                         |\n| Ctrl-Alt-] \u003cchar\u003e | Search character backward                                                                        |\n| Meta-\u003c            | Move to first entry in history                                                                   |\n| Meta-\u003e            | Move to last entry in history                                                                    |\n| Meta-B, Alt-Left  | Move cursor to previous word                                                                     |\n| Ctrl-Left         | See Alt-Left                                                                                     |\n| Meta-C            | Capitalize the current word                                                                      |\n| Meta-D            | Delete forwards one word                                                                         |\n| Meta-F, Alt-Right | Move cursor to next word                                                                         |\n| Ctrl-Right        | See Alt-Right                                                                                    |\n| Meta-L            | Lower-case the next word                                                                         |\n| Meta-T            | Transpose words                                                                                  |\n| Meta-U            | Upper-case the next word                                                                         |\n| Meta-Y            | See Ctrl-Y                                                                                       |\n| Meta-Backspace    | Kill from the start of the current word, or, if between words, to the start of the previous word |\n| Meta-0, 1, ..., - | Specify the digit to the argument. `–` starts a negative argument.                               |\n\n[Readline Emacs Editing Mode Cheat Sheet](http://www.catonmat.net/download/readline-emacs-editing-mode-cheat-sheet.pdf)\n\n### vi command mode\n\n| Keystroke            | Action                                                                      |\n|----------------------|-----------------------------------------------------------------------------|\n| $, End               | Move cursor to end of line                                                  |\n| .                    | Redo the last text modification                                             |\n| ;                    | Redo the last character finding command                                     |\n| ,                    | Redo the last character finding command in opposite direction               |\n| 0, Home              | Move cursor to the beginning of line                                        |\n| ^                    | Move to the first non-blank character of line                               |\n| a                    | Insert after cursor                                                         |\n| A                    | Insert at the end of line                                                   |\n| b                    | Move one word or token left                                                 |\n| B                    | Move one non-blank word left                                                |\n| c\u003cmovement\u003e          | Change text of a movement command                                           |\n| C                    | Change text to the end of line (equivalent to c$)                           |\n| d\u003cmovement\u003e          | Delete text of a movement command                                           |\n| D, Ctrl-K            | Delete to the end of the line                                               |\n| e                    | Move to the end of the current word                                         |\n| E                    | Move to the end of the current non-blank word                               |\n| f\u003cchar\u003e              | Move right to the next occurrence of `char`                                 |\n| F\u003cchar\u003e              | Move left to the previous occurrence of `char`                              |\n| h, Ctrl-H, Backspace | Move one character left                                                     |\n| l, Space             | Move one character right                                                    |\n| Ctrl-L               | Clear screen                                                                |\n| i                    | Insert before cursor                                                        |\n| I                    | Insert at the beginning of line                                             |\n| +, j, Ctrl-N         | Move forward one command in history                                         |\n| -, k, Ctrl-P         | Move backward one command in history                                        |\n| p                    | Insert the yanked text at the cursor (paste)                                |\n| P                    | Insert the yanked text before the cursor                                    |\n| r                    | Replaces a single character under the cursor (without leaving command mode) |\n| R                    | Replaces a single character under the cursor (entering the replace mode)    |\n| s                    | Delete a single character under the cursor and enter input mode             |\n| S                    | Change current line (equivalent to 0c$)                                     |\n| t\u003cchar\u003e              | Move right to the next occurrence of `char`, then one char backward         |\n| T\u003cchar\u003e              | Move left to the previous occurrence of `char`, then one char forward       |\n| u                    | Undo                                                                        |\n| w                    | Move one word or token right                                                |\n| W                    | Move one non-blank word right                                               |\n| x                    | Delete a single character under the cursor                                  |\n| X                    | Delete a character before the cursor                                        |\n| y\u003cmovement\u003e          | Yank a movement into buffer (copy)                                          |\n| \u003c\u003cmovement\u003e          | Dedent                                                                      |\n| \u003e\u003cmovement\u003e          | Indent                                                                      |\n\n### vi insert mode\n\n| Keystroke         | Action                                        |\n|-------------------|-----------------------------------------------|\n| Ctrl-H, Backspace | Delete character before cursor                |\n| Shift-Tab         | Previous completion                           |\n| Ctrl-I, Tab       | Next completion                               |\n| Right             | Complete hint if cursor is at the end of line |\n| Alt-\u003cchar\u003e        | Fast command mode                             |\n| Esc               | Switch to command mode                        |\n\n[Readline vi Editing Mode Cheat Sheet](http://www.catonmat.net/download/bash-vi-editing-mode-cheat-sheet.pdf)\n\n[ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code)\n\n## Usage\n\nThe library is published to Maven Central.\nUse the latest version shown by the badge above.\n\nKotlin DSL (example for a native target):\n\n```kotlin\nkotlin {\n    // Choose your native targets, e.g.:\n    macosX64()\n    linuxX64()\n    mingwX64()\n\n    sourceSets {\n        // With the default hierarchy, a shared nativeMain is available when you have multiple native targets\n        val nativeMain by getting {\n            dependencies {\n                implementation(\"io.github.smyrgeorge:readline4k:\u003clatest\u003e\")\n            }\n        }\n    }\n}\n```\n\nIf you use only one native target, add the dependency to that target's Main source set (e.g., macosX64Main,\nlinuxX64Main, or mingwX64Main).\n\n## Acknowledgements\n\nUnder the hood, `readline4k` leverages the [rustyline](https://github.com/kkawakam/rustyline) project to provide\ncomprehensive readline functionality, with communication between Kotlin and the Rust library handled through FFI\n(Foreign Function Interface).\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmyrgeorge%2Freadline4k","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmyrgeorge%2Freadline4k","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmyrgeorge%2Freadline4k/lists"}