1
6
Fork
You've already forked spiral
0
A minimalistic, composable, no-system-dependency command line editing library. Provides support for keybindings, selection of text, modal editing, history, syntax highlighting and more. Has an API composed of reading input, editing line and rendering the user interface. Available as a Zig module and C header file.
  • Zig 93.4%
  • C 6.6%
2025年08月30日 00:42:32 +03:00
examples Gave the example a simpler name signifying its purpose 2025年07月14日 14:53:35 +03:00
src errorCode -> intFromError, more idiomatic name 2025年08月30日 00:42:32 +03:00
.gitignore Initial commit 2025年03月27日 15:52:23 +03:00
build.zig Version 0.3.0 2025年08月12日 17:20:02 +03:00
build.zig.zon Version 0.3.0 2025年08月12日 17:20:02 +03:00
CHANGELOG.md Added spiral_process_key_event 2025年08月17日 14:58:17 +03:00
demo.gif Recorded and added demo.gif into README.md 2025年07月14日 15:04:22 +03:00
LICENSE.txt Added README.md and LICENSE, finally 2025年07月12日 21:36:52 +03:00
README.md Recorded minor mode command introduction in md files 2025年08月12日 15:07:12 +03:00
spiral.h Added spiral_process_key_event 2025年08月17日 14:58:17 +03:00
zls.build.json zls should now work in Zig examples 2025年07月12日 17:07:16 +03:00

Overview

Spiral — a Helix and Readline inspired line editor. As a Readline, it provides a set of functions for use by applications that allow users to edit command lines as they are typed in. As a Helix, it copies the editing model from that text editor.

Features

  • Raw terminal requests/responses & event reading. Uses DEC modes and primary device attributes for terminal configuration. Parses events of different types from CSI escape sequences. Supports Kitty keyboard protocol: this allows Spiral to disambiguate modifier keys, especially Ctrl and Alt keys.

  • Helix keybindings. Editor takes inspiration from Helix editing model: normal, insert and select mode; cursor movement affects the selection; yank/paste buffer; entering numbers to repeat certain command; etc. The difference is that Spiral adapts the Helix model from TUI text editor to CLI.

  • Clipboard paste. Inserting a sequence of bytes pasted from clipboard into the editor, instead of interpreting it as series of commands.

  • Multi-line editing. Currently edited line is spanned on screen across multiple terminal rows, properly moving the cursor even when screen width changes.

  • Line history. Editor keeps a sequence of lines that allow users to avoid retyping again old lines, but rather using keys to retrieve and re-edit past lines of text.

    Furthermore, users are responsible for adding lines to the history. This allows to filter lines getting into the history, history loading from/saving to file, setting limit on history size, and possibly more.

  • Unicode support. Uses unicode grapheme clusters as a unit of movement. Supports case detection/conversion, general categories, correct display width for grapheme clusters, all according to Unicode 16.0.0 standard.

  • Customizable keybindings (Zig API only). Keymap is defined by a series of std data structures, allowing users to put their own keybindings into the editor.

  • Syntax highlighting (Experimental). Custom, context-aware colorization of edited line.

  • Composable API. Spiral divides its functionality into three components:

    • reading & configuring terminal;
    • processing input & editing line;
    • writing to the terminal & rendering the interface.

    Items from every component can be used individually. Every component is interchangeable with other possible implementations. This allows users to replace those features from Spiral that they may not like: for example, using different interface or editor model.

  • Simplified/unified API. In contrast to the composable API, this feature was made for those who don't want to configure Spiral and just want a common line editor. Unified API combines all three components of Spiral functionality, is a lot simpler to use, but it is less flexible.

  • All errors are values. All system and library errors are returned as int numbers or Zig error codes. In C API, error values use the existing POSIX standard1 .

    Spiral doesn't abort on allocation errors. This allows users to gracefully finish their program on unexpected errors.

  • Custom allocation. Spiral doesn't call malloc, free or built-in Zig allocators. Instead, it presents an interface for the user to define their own allocator implementation, in the spirit of Zig. This enables many use cases and optimization opportunities for Spiral users.

  • Generic API. As well as custom allocators, some types in Spiral are implemented generically: either by using Zig's anytype or dynamic dispatch in C. For example, Spiral has no strong opinion on what is the best way to implement syntax highlighting, so users can tailor their implementation for best match to their use case.

  • No system dependencies. Spiral doesn't link to any system libraries, potentially even libc is optional. It only uses POSIX APIs.

  • Cross-platform. Should work on all POSIX-compatible systems: Linux, MacOS, BSD operating systems. Although I don't personally test all of them.

  • Uses modern technologies. Supports Kitty keyboard protocol, as well as various modes for terminal in-band signaling. Does not limit itself to ANSI.SYS escape sequences in order to implement additional features. Uses modern Zig programming language.

Future ideas

  • Undo/redo changes. Storing the history of line modifications: insertion/removal on characters.

  • Tab completion. Perhaps one of the most common features expected from any line editing library.

  • Configuration file. A library extension that allows applications to read user's config to tailor Spiral behaviour to application user's needs.

Demonstration

asciicast

On left pane: compiled example.

On right pane: keys that are sent to the left pane.

For recording, this software was used:

Building

This project uses Zig build system, version 0.14.0. The build dependencies are just Zig compiler and one amazing Unicode library that will get pulled automatically by a build process.

Build system itself has some options that will guide you towards installing the library. It is advised to run this command to see them first.

zig build --help

Build system:

  • exports Spiral and spiral-extern Zig modules for other Zig projects;
  • can compile and install either static or shared library;
  • can install header file;
  • can compile and install examples;
  • can generate Zig API documentation.

Documentation

Spiral has its documentation in following forms:

  • Zig API documentation. Generated by Zig build system. Also hosted for every release at: https://archive.lch361.net/spiral-doc/zig-api
  • Examples. Standalone source files located in examples directory showcasing the usage of Spiral's Zig and C API.
  • Reference manual for C API (Not implemented yet). It will be either in the form of man pages, PDF document or HTML website.
  • User manual (Not implemented yet). It should describe keymap and configuration for users of applications using Spiral library.

Keymap

For now, if you want to use this library and know the keybindings, see:

Questions & answers

Why name it "Spiral"?

Name was inspired by Helix editor: although Spiral takes many editing features from that text editor, it is a drastically different project from Helix. Spiral is a library, whereas Helix is an application; Spiral is CLI, whereas Helix is TUI; however, both fulfill the similar purpose — text editing.

What is the motivation behind developing this library?

  1. The wish to develop a new library with a set of features that no other library or application has.
  2. Personal disappointment with lack of features in certain libraries:
    • Readline, Linenoise don't support syntax highlighting and don't handle Unicode very well;
    • isocline doesn't allow to use custom keybindings;
    • Reedline can only be used in Rust programming language.
  3. The wish to implement command line editing in my own projects: lcalc.
  4. The wish to experiment with Zig and try to develop a system library with this programming language.

Why developing the C API if Zig is a better programming language?

C has one thing that Zig hasn't: its native API is stable. This is the main reason why C is always used as a language for header files in operating systems. C API was created as a way to give the users of Spiral a broader choice of languages to use for their application. The library itself is implemented in Zig for a more pleasant development experience.

What software uses Spiral?

See the Library users Wiki page.

Contributing

As a free software, Spiral welcomes contributions from anyone in any form.

Currently, the best way to contribute to Spiral is to start using this library in a free and open source project. This leads to discovering bugs and new use cases, which lead to further design iterations of Spiral.

Another way to contribute to Spiral is to spread the word about this library. This leads to more people being interested in Spiral and contributing to its development. The more people involved, the more possibility there is to build great new things with Spiral.

If you have ideas on how to improve Spiral's design and implementation, that's great! Feel free to open issues and pull requests.

And last, but not least, you can donate directly to the author of Spiral. This will give me more free time and energy to develop and maintain Spiral for you. Thanks!

License

This is a library designed to empower free software, and so it's released under the GNU General Public License 3.0!

This software is provided as is, with no warranty.

Author

lch361 (a. k. a. Lich)

Like this project? Follow my other work at https://lch361.net!