Experimental modal text editor built for extensibility and flexibility
Find a file
2025-09-17 19:25:33 -04:00
.vscode Initial commit 2025-08-27 03:25:15 -04:00
docs docs: add janet-cheatsheet.md (meant to be used by contributors, LLMs or whatever else wants to deal with the Janet language integration) 2025-08-30 03:33:22 -04:00
runtime/koa cleanup: runtime scroll leftover after rebase 2025-09-17 18:50:42 -04:00
src feat: initial rust rewrite 2025-09-17 14:19:28 +02:00
.envrc Initial commit 2025-08-27 03:25:15 -04:00
.gitattributes Initial commit 2025-08-27 03:25:15 -04:00
.gitignore feat: initial rust rewrite 2025-09-17 14:19:28 +02:00
build-runtime.sh feat: initial rust rewrite 2025-09-17 14:19:28 +02:00
Cargo.lock fix: use fork of janetrs 2025-09-17 18:22:48 +02:00
Cargo.toml fix: use fork of janetrs 2025-09-17 18:22:48 +02:00
flake.lock fix: adapt Nix flake to the latest Rust rewrite changes 2025-09-17 12:54:53 -04:00
flake.nix fix: adapt Nix flake to the latest Rust rewrite changes 2025-09-17 12:54:53 -04:00
LICENSE chore: add LICENSE 2025-09-17 19:25:33 -04:00
README.md docs: update README, resolves #16 2025-09-17 19:24:39 -04:00
runtime.jimage feat: initial rust rewrite 2025-09-17 14:19:28 +02:00

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:

  • Janet Integration: janetrs library integrated for embedding Janet
  • Basic TUI Interface: ratatui integration for terminal UI
  • Janet-Rust Bridge System: File system, TUI, and syntax bridges (minimal implementation)
  • Janet Event Loop Foundation: Event loop infrastructure in Janet (basic key forwarding only)
  • File Operations: Bridge functions for file I/O (not implemented)
  • Event Loop Handoff: Control handed from Rust to Janet main loop (partial)

Editor Core:

  • Janet Editor State: Core state management in Janet
  • Modal System Framework: Basic modal system structure in Janet
  • Janet Event Handling: Input processing framework in Janet
  • Complete Event Loop: Actual event processing
  • Text Editing in Janet: Text operations in Janet
  • High-Level UI Bridge: Rust renders editor state from Janet

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

  • Janet Integration & Bootstrap

    • Integrate janetrs library for Janet embedding
    • Set up Janet environment initialization in Rust
    • Create minimal Rust bootstrap that hands control to Janet
    • Design Janet API for editor state management
  • High-Level UI Bridge (Current Priority)

    • Create semantic rendering bridge functions
    • Maintain ratatui performance and features
    • Bridge accepts editor state from Janet, renders in Rust
    • Replace primitive ratatui calls with high-level operations
  • Editor State Migration to Janet

    • Port current editor state management to Janet
    • Implement modal system (Normal/Insert/Select/Command) in Janet
    • Create Janet text operations (insert, delete, cursor movement)
    • Implement Janet-based key binding system

Phase 2: Advanced Editor Operations (Janet-Driven)

  • Dynamic Configuration System

    • Implement live configuration system foundation
    • Create event-driven architecture for editor events
    • Design plugin architecture foundation
  • Movement Commands

    • Word navigation (w, b, e) with customizable word boundaries
    • Paragraph navigation ({, })
    • Go to line (G, gg) with jump lists
    • Page scrolling (Ctrl-D, Ctrl-U) with smooth scrolling options
    • Search and jump (/, ?, n, N) with regex support
  • Text Operations

    • Delete operations (dd, D, dw, etc.) with custom operators
    • Yank/Copy operations (yy, Y, yw, etc.) with multiple registers
    • Paste operations (p, P) with register selection
    • Undo/Redo (u, Ctrl-R) with branching undo tree
    • Replace mode (R) with preview
  • Extensible Command System

    • Command mode with Janet expression evaluation
    • Custom command definitions in Janet
    • Command history and completion
    • Macro recording and playback

Phase 3: Language Support & Syntax Highlighting

  • Tree-sitter Integration (via Rust bridge)

    • Integrate tree-sitter library
    • Create Janet API for syntax highlighting
    • Parse and highlight common languages:
      • Rust, Zig, C/C++
      • JavaScript/TypeScript
      • Python, Go, Java
      • Janet, Lua, Lisp dialects
      • Markdown, JSON, YAML
  • Semantic Features (Janet-configurable)

    • Bracket matching with custom rules
    • Indentation awareness per language
    • Comment toggling with language-specific styles
    • Code folding with custom fold markers

Phase 4: Advanced Editor Features

  • Multiple Buffers & Windows

    • Buffer management system in Janet
    • Split windows with customizable layouts
    • Tab interface with user-defined styling
    • Buffer-local configurations and hooks
  • Language Server Protocol (LSP)

    • LSP client implementation in Janet
    • Code completion with customizable sources
    • Go to definition and references
    • Error diagnostics with user-defined handlers
    • Custom LSP server configurations

Phase 5: Ultimate Extensibility & Community

  • Advanced Plugin System

    • Plugin manager with dependency resolution
    • API versioning and compatibility layer
    • Sandboxed plugin execution
    • Community plugin registry integration
  • Performance & Optimization

    • Janet code JIT compilation exploration
    • Lazy loading for large files
    • Async operations for non-blocking UI
    • Memory optimization for large codebases
  • Community & Ecosystem

    • Plugin development documentation
    • Example configurations and themes
    • Migration tools from other editors
    • Community contribution guidelines

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

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.