Experimental modal text editor built for extensibility and flexibility
modal text-editor
README.md

Koa - A Modal Code Editor #

An experimental fully extensible modal code editor for the terminal. The Rust codebase provides a minimal bootstrap layer while Janet handles all editor logic, enabling maximum extensibility and live customization.

Key Features:

  • Janet-based Core: Editor logic written in Janet for ultimate flexibility
  • Live Reconfiguration: Hot-swap key bindings, behaviors, and plugins
  • Rust Bootstrap: Minimal, efficient native layer for TUI and system integration
  • Tree-sitter Integration: Syntax highlighting, indentation and more via native bindings
  • Unlimited Extensibility: Complete editor customization without recompilation

Current Status #

Bootstrap Foundation:

Editor Core:

Architecture #

Rust-Janet Hybrid Design:

┌─────────────────────────────────────────────────────────────┐
│                    Janet Layer (Editor Logic)               │
├─────────────────────────────────────────────────────────────┤
│ • Modal system & state management                           │
│ • Text operations & buffer management                       │
│ • Key bindings & command system                             │
│ • Plugin system & user configuration                        │
│ • File I/O coordination                                     │
└─────────────────────────────────────────────────────────────┘
                            ↕ High-Level Bridge
┌─────────────────────────────────────────────────────────────┐
│                Rust Layer (UI & System Core)                │
├─────────────────────────────────────────────────────────────┤
│ • Complete UI rendering                                     │
│ • TUI operations & terminal management                      │
│ • File I/O and system calls                                 │
│ • Tree-sitter integration                                   │
│ • Performance-critical operations                           │
└─────────────────────────────────────────────────────────────┘

Current Structure:

.
├── src/                # Rust source code
│   ├── main.rs         # Bootstrap: Janet init + event loop
│   ├── app.rs          # Application state and main loop
│   ├── event.rs        # Event handling system
│   ├── ui.rs           # UI rendering
│   └── janet/          # Rust-Janet bridge modules
│       ├── mod.rs      # Module definitions
│       ├── keymap.rs   # Key handling bridge
│       └── state.rs    # State management bridge
└── runtime/            # Janet runtime source code
    └── koa/            # Koa Janet modules
        ├── koa.janet   # Main entrypoint
        ├── keymap.janet # Keybindings (minimal)
        └── stubs.janet # Placeholder functions

Roadmap #

Phase 1: Strategic Hybrid Foundation #

Phase 2: Advanced Editor Operations (Janet-Driven) #

Phase 3: Language Support & Syntax Highlighting #

Phase 4: Advanced Editor Features #

Phase 5: Ultimate Extensibility & Community #

Architecture Philosophy #

Rust-Janet Hybrid Approach: This architecture balances flexibility with performance:

Rust Layer (Performance Core): Handles operations where performance matters:

  • Complete UI rendering using ratatui
  • TUI operations with proper terminal management
  • File I/O and system calls
  • Tree-sitter integration for syntax highlighting
  • Memory-intensive operations

Janet Layer (Logic Core): Provides maximum extensibility:

  • All editor logic and behavior
  • Complete customization and extensibility
  • Hot-swappable configurations and key bindings
  • Plugin system and user extensions
  • Domain-specific languages for configuration

High-Level Bridge: Clean interface between layers:

  • Janet computes editor state and decisions
  • Rust renders state efficiently using native ratatui features
  • Minimal bridge calls with semantic operations
  • Clear separation of concerns

This approach maximizes both flexibility and performance, avoiding the overhead of primitive bridge operations while maintaining the extensibility benefits of Janet scripting.

Building and Running #

# Build the editor (add --release for production build)
cargo build

# Run with a file
cargo run -- demo.rs

# Run without arguments for empty buffer
cargo run

cargo build and cargo run now automatically compile runtime/koa/koa.janet into runtime.jimage via build.rs before Rust compilation starts. Ensure the janet executable is available in PATH.

Testing #

cargo test

Key Bindings #

Note: Most key bindings are not yet implemented. Current functionality is limited to basic character input.

Normal Mode #

  • hjkl or arrow keys - Movement (undo current selections)
  • ^ or Home - Beginning of line
  • $ or End - End of line
  • i - Enter insert mode
  • v - Enter select mode (preserves current selections)
  • : - Enter command mode
  • w - Move to next word
  • b - Move to previous word
  • PageUp - Move to top
  • PageDown - Move to bottom
  • o - Create line below and enter insert mode
  • O - Create line above and enter insert mode
  • x - Select whole line or next line if the current one is already fully selected
  • d - Delete character under cursor or the current selection if one exists
  • D - Duplicate selected line
  • Delete - Delete character under cursor
  • Backspace - Delete character before cursor

Insert Mode #

  • arrow keys - Movement
  • Escape - Return to normal mode
  • Backspace - Delete character before cursor
  • Delete - Delete character under cursor
  • Enter - Insert newline
  • Tab - Insert 4 spaces
  • Home - Beginning of line
  • End - End of line

Select Mode #

  • hjkl or arrow keys - Movement (extends selection)
  • ^ or Home - Beginning of line
  • $ or End - End of line
  • d or Delete - Delete selection
  • i - Delete selection and enter insert mode
  • x - Select whole line or next line if the current one is already fully selected
  • w - Expand selection to next word
  • b - Shorten selection to previous word
  • Escape, v - Return to normal mode

Command Mode #

  • Escape - Return to normal mode
  • w - Save file
  • q - Quit editor (does not handle unsaved changes confirmation yet!)

Contributing #

This is a learning project exploring modal editor design with Rust and Janet. Contributions and suggestions are welcome!

License #

GPLv2 License - Feel free to use this code for learning and experimentation.