1
0
Fork
You've already forked koa
0
forked from amartin/koa
Experimental modal text editor built for extensibility and flexibility
  • Zig 59.5%
  • Janet 38.3%
  • Nix 2.2%
Find a file
xsty 246afff6af feat(keymap): add _ motion ( #6 )
Reviewed-on: amartin/koa#6
Co-authored-by: xsty <xsty@noreply.codeberg.org>
Co-committed-by: xsty <xsty@noreply.codeberg.org>
2025年09月02日 10:42:42 +02: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 feat(keymap): add _ motion ( #6 ) 2025年09月02日 10:42:42 +02:00
src cleanup: remove old legacy Zig-based editor codebase 2025年08月31日 20:54:14 -04:00
.envrc Initial commit 2025年08月27日 03:25:15 -04:00
.gitattributes Initial commit 2025年08月27日 03:25:15 -04:00
.gitignore Initial commit 2025年08月27日 03:25:15 -04:00
build.zig cleanup: remove old legacy Zig-based editor codebase 2025年08月31日 20:54:14 -04:00
build.zig.zon refactor!: move runtime Janet files to runtime directory out of the src directory 2025年08月31日 02:48:19 -04:00
demo.zig feat: implement barebones editor with basic keybinds, modes and commands 2025年08月28日 02:52:18 -04:00
flake.lock feat: add keycodes struct in keymaps file, format source code 2025年08月31日 13:42:22 -04:00
flake.nix feat: add keycodes struct in keymaps file, format source code 2025年08月31日 13:42:22 -04:00
README.md docs: update README.md 2025年08月31日 21:13:54 -04:00
test_runner.zig feat: further improve testing with zig build test, place tests inside their respective structures for better code readability 2025年08月28日 15:31:45 -04:00

Koa - A Modal Code Editor

A fully extensible and experimental modal code editor for the terminal. The Zig 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
  • Zig Bootstrap: Minimal, efficient native layer for TUI and system integration
  • Tree-sitter Integration: Syntax highlighting via native bindings (WIP)
  • Unlimited Extensibility: Complete editor customization without recompilation

Current Status

Bootstrap Foundation (Zig):

  • Janet Integration: jzignet library integrated for embedding Janet
  • Janet-Zig Bridge System: File system, TUI, and syntax bridges implemented
  • Janet Event Loop Foundation: Event loop infrastructure implemented in Janet
  • Basic TUI Interface: libvaxis integration for terminal UI
  • File Operations: Bridge functions for file I/O (placeholders until jzignet string support)
  • Event Loop Handoff: Control handed from Zig to Janet main loop

Editor Core (Strategic Hybrid):

  • Janet Editor State: Core state management moved to Janet
  • Modal System Framework: Basic modal system structure in Janet
  • Janet Event Handling: Input processing framework in Janet
  • Complete Event Loop: Implement actual event processing
  • Text Editing in Janet: Port text operations to Janet
  • High-Level UI Bridge: Zig renders editor state from Janet

Architecture

Strategic 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
┌─────────────────────────────────────────────────────────────┐
│ Zig Layer (UI & System Core) │
├─────────────────────────────────────────────────────────────┤
│ • Complete UI rendering │
│ • TUI operations & child window management │
│ • File I/O and system calls │
│ • Tree-sitter integration │
│ • Performance-critical operations │
└─────────────────────────────────────────────────────────────┘

Current Structure (strategic hybrid):

.
├── src/ # Zig source code
│ ├── main.zig # Bootstrap: Janet init + hybrid event loop
│ ├── runtime.zig # Bootstrap: Janet runtime loader
│ ├── janet_env.zig # Bootstrap: Janet environment management
│ ├── syntax.zig # Tree-sitter bindings (legacy, superseded by bridges/syntax.zig)
│ └── bridges/ # Zig-Janet bridge modules
│ ├── vaxis.zig # High-level UI bridge
│ ├── fs.zig # File system operations
│ └── syntax.zig # Tree-sitter bindings (TBD)
└── runtime/ # Janet runtime source code
 ├── core.janet # Core runtime entrypoint (init file)
 ├── modal.janet # Modal system
 ├── buffer.janet # Buffer management
 ├── keymap.janet # Keybindings
 ├── editor.janet # Editor state and management
 ├── movement.janet # Movement logic
 ├── selection.janet # Selection logic
 ├── utils.janet # Utility functions
 └── config.janet # Configuration system (TBD)

Roadmap

Phase 1: Strategic Hybrid Foundation

  • Janet Integration & Bootstrap

    • Integrate jzignet library for Janet embedding
    • Set up Janet environment initialization in Zig
    • Create minimal Zig 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 existing ui.zig performance and features
    • Bridge accepts editor state from Janet, renders in Zig
    • Replace primitive vaxis 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 Zig bridge)

    • Integrate neurocyte/tree-sitter library
    • Create Janet API for syntax highlighting
    • Parse and highlight common languages:
      • Zig, Rust, 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

Strategic Hybrid Approach: This architecture balances flexibility with performance:

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

  • Complete UI rendering using existing optimized ui.zig
  • TUI operations with proper child window 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
  • Zig renders state efficiently using native vaxis 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 (or so I hope!).

Building and Running

# Build the editor (add -Doptimize=ReleaseFast for production build)
zig build
# Run with a file
./zig-out/bin/koa demo.zig
# Run without arguments for empty buffer
./zig-out/bin/koa

Testing

zig build test

Key Bindings

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 (20 lines jump)
  • PageDown - Move to bottom (20 lines jump)
  • 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 (hardcoded for now)
  • 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
  • W - Save file and quit (temporary until command mode gets better)
  • q - Quit editor (does not handle unsaved changes confirmation yet!)

Contributing

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

License

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