# MicroHX - Modern Modal Text Editor Specification ## 1. Overview **MicroHX** is a modern, high-performance modal text editor written in Rust, featuring: - **Modal editing** with Kakoune/Helix-style object-verb keybindings - **Lua scripting** for configuration and plugins - **Three UI modes**: GUI (egui), Terminal (TUI), and CLI (headless) - **Built-in LSP + Tree-sitter** for language intelligence and syntax highlighting - **User-definable modes** for custom editing workflows - **Static compilation** for maximum portability (old Linux/glibc compatibility) - **Extensible architecture** with a focus on performance and simplicity --- ## 2. Core Architecture ### 2.1 Technology Stack | Component | Technology | |-----------|------------| | Language | Rust (edition 2024+) | | UI Framework | egui + eframe | | Terminal Backend | egui_term / ratatui | | CLI Mode | crossterm + direct rendering | | Scripting | Lua 5.4 (via mlua) | | Text Buffer | Rope data structure (via ropey) | | Async Runtime | tokio | | Syntax Highlighting | tree-sitter (built-in) | | LSP Client | lsp-types + tower-lsp (built-in) | | Static Linking | musl-libc, zig build | ### 2.2 Architecture Layers ``` ┌─────────────────────────────────────────────────────────┐ │ UI Layer (Pluggable) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ GUI Mode │ │ Terminal │ │ CLI │ │ │ │ (eframe) │ │ (ratatui) │ │ (headless) │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ Editor Core Layer │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ Buffer │ │ View/ │ │ Command │ │ │ │ Manager │ │ Window │ │ System │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ Mode │ │ Keymap │ │ Clipboard │ │ │ │ System │ │ Engine │ │ Manager │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ Plugin Layer (Lua) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ Plugin │ │ Config │ │ API │ │ │ │ Loader │ │ Parser │ │ Bindings │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ Services Layer (Built-in) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ LSP │ │ Tree- │ │ File │ │ │ │ Client │ │ sitter │ │ Watcher │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ Search/ │ │ Undo/ │ │ Theme │ │ │ │ Replace │ │ Redo │ │ Engine │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` --- ## 3. Modal System ### 3.1 Editor Modes | Mode | Name | Description | Default Key | |------|------|-------------|-------------| | `Normal` | Normal | Navigation and commands | `` | | `Insert` | Insert | Text insertion | `i` | | `Visual` | Visual | Text selection (selections shown) | `v` | | `VisualLine` | Visual Line | Line-wise selection | `V` | | `VisualBlock` | Visual Block | Block-wise selection | `` | | `Command` | Command | Command palette/input | `:` | | `Search` | Search | Search forward | `/` | | `SearchBack` | Search Backward | Search backward | `?` | | `Replace` | Replace | Single char replace | `r` | | `OperatorPending` | Operator Pending | Awaiting motion | `d`, `c`, `y`, etc. | | `User1-5` | User Defined | Custom user modes | configurable | ### 3.2 User-Definable Modes Users can define custom modes via Lua with: - Custom keybindings - Custom status bar indicators - Mode-specific behaviors - Inheritance from base modes ```lua -- Example: Define a custom "presentation" mode modes = { presentation = { base = "normal", -- inherits from normal mode indicator = "PRESENT", keys = { ["n"] = "next_slide", ["p"] = "prev_slide", ["q"] = "exit_presentation", }, settings = { line_numbers = false, cursor_line = false, read_only = true, }, }, } ``` ### 3.3 Mode State Machine ```rust pub enum EditorMode { Normal, Insert, Visual(VisualMode), Command, Search(SearchDirection), Replace, OperatorPending(Operator), UserDefined(String), // Custom user modes } pub enum VisualMode { Char, Line, Block, } pub enum SearchDirection { Forward, Backward, } pub enum Operator { Delete, Change, Yank, Put, Format, Indent, Outdent, } ``` --- ## 4. Keybinding System ### 4.1 Key Representation ```rust pub struct KeyEvent { pub code: KeyCode, pub modifiers: Modifiers, } pub struct Modifiers { pub ctrl: bool, pub alt: bool, pub shift: bool, pub super_: bool, } ``` ### 4.2 Keybinding Layers 1. **Global** - Always active (e.g., `` quit) 2. **Mode-specific** - Active only in specific modes 3. **Buffer-local** - Per-filetype overrides 4. **Plugin** - Plugin-defined bindings ### 4.3 Keybinding Philosophy: Object-Verb (Kakoune/Helix Style) MicroHX uses **object-verb** keybinding style by default (like Kakoune/Helix), NOT verb-object (like Vim): | Style | Example | Meaning | |-------|---------|---------| | **Object-Verb** | `dw` | Select word, then delete | | **Verb-Object** | `dw` | Delete word | **Benefits of Object-Verb:** - Selection is always visible before action - More intuitive for multi-cursor editing - Consistent with "select then act" mental model - Better for preview/undo before commit ### 4.4 Default Keymaps (Normal Mode) - Helix Style #### Motions (Object Selectors) | Key | Action | |-----|--------| | `h/j/k/l` | Left/Down/Up/Right | | `w/b` | Word forward/backward | | `e` | End of word | | `0/$` | Line start/end | | `gg/G` | Document start/end | | `v` | Select mode (extend selection) | | `t/T` | Till char forward/backward | | `f/F` | Find char forward/backward | | `%` | Jump to matching bracket | | `m` | Open marks menu | #### Actions (Verbs) | Key | Action | |-----|--------| | `d` | Delete selection | | `y` | Yank (copy) selection | | `c` | Change (delete + insert) | | `p/P` | Paste after/before | | `r` | Replace with char | | `~` | Toggle case | | `>` / `<` | Indent / Outdent | | `=` | Format selection | | `f` | Format via LSP | | `g` | Goto (definition, references, etc.) | | `s` | Select (sub-selections) | | `i` | Select inside object | | `a` | Select around object | #### Object Examples | Sequence | Action | |----------|--------| | `w` | Select word | | `ww` | Select next word | | `dw` | Delete word | | `cw` | Change word | | `yw` | Yank word | | `diw` | Delete inside word | | `daw` | Delete around word | | `cit` | Change inside tag | | `ci"` | Change inside quotes | | `ca"` | Change around quotes | | `dib` | Delete inside block `()` | | `dab` | Delete around block `()` | #### Goto Commands (`g` prefix) | Key | Action | |-----|--------| | `gd` | Goto definition | | `gr` | Goto references | | `gi` | Goto implementation | | `gt` | Goto type definition | | `gh` | Show hover docs | | `gk` | Show signature help | | `gf` | Open file under cursor | | `gg` | Goto line start | | `gG` | Goto line end | #### Selection Commands (`s` prefix) | Key | Action | |-----|--------| | `s` | Select current | | `S` | Split selection | | `sa` | Select all occurrences | | `sr` | Remove primary selection | | `sn` | Select next occurrence | | `sp` | Select previous occurrence | #### Other | Key | Action | |-----|--------| | `:` | Command palette | | `/` | Search forward | | `?` | Search backward | | `*` | Select next match of selection | | `u` / `` | Undo / Redo | | `i` | Insert mode | | `a` | Append mode | | `o` / `O` | Open line below/above | | `I` / `A` | Insert at line start/end | | `.` | Repeat last change | | `ZQ` | Quit without saving | | `ZZ` | Save and quit | --- ## 5. Lua Plugin System ### 5.1 Configuration Structure ```lua -- ~/.config/microhx/init.lua return { -- Editor settings settings = { theme = "dracula", line_numbers = true, relative_numbers = true, cursor_line = true, tab_width = 4, auto_save = false, }, -- Keybindings keys = { normal = { ["w"] = ":write", ["q"] = ":quit", [""] = ":write", ["f"] = ":telescope find_files", }, insert = { ["jk"] = "", }, }, -- Plugins to load plugins = { "telescope", "lsp", "treesitter", }, -- Plugin configurations telescope = { theme = "dropdown", }, lsp = { servers = { "rust_analyzer", "lua_ls" }, }, } ``` ### 5.2 Plugin API ```lua -- Plugin structure return { name = "my-plugin", version = "0.1.0", -- Called on plugin load setup = function(config) -- Initialize plugin end, -- Called on editor startup init = function() -- Register commands, keybindings, etc. end, -- Event handlers events = { on_file_open = function(buffer) end, on_file_save = function(buffer) end, on_cursor_move = function(buffer, pos) end, on_mode_change = function(old_mode, new_mode) end, on_key = function(key) end, }, -- Commands commands = { my_command = function(args) end, }, } ``` ### 5.3 Core API Exposed to Lua ```lua -- Buffer API buffer = microhx.buffer buffer.get_text() -> string buffer.set_text(text: string) buffer.get_cursor() -> row, col buffer.set_cursor(row, col) buffer.get_selection() -> start, end buffer.insert(text: string) buffer.delete(start, end) buffer.line_count() -> number buffer.get_line(n) -> string -- Editor API editor = microhx.editor editor.mode() -> string editor.command(cmd: string) editor.notify(msg: string, level: "info"|"warn"|"error") editor.open_file(path: string) editor.save() editor.quit() -- UI API ui = microhx.ui ui.statusbar.set_text(text: string) ui.statusbar.add_segment(text: string, highlight: string) ui.input(prompt: string, callback: function) ui.confirm(msg: string, callback: function) -- Config API config = microhx.config config.get(path: string) -> any config.set(path: string, value: any) -- Event API events = microhx.events events.on(event: string, callback: function) events.off(event: string, callback: function) events.emit(event: string, ...) ``` --- ## 6. UI Components (egui) ### 6.1 Layout Structure ``` ┌──────────────────────────────────────────────────────────┐ │ Menu Bar (optional) File Edit View Buffer Help │ ├──────────────────────────────────────────────────────────┤ │ Tab Bar [file1.rs] [file2.rs] [+] │ ├────────────┬─────────────────────────────────────────────┤ │ │ │ │ Line │ │ │ Numbers │ Text Buffer │ │ │ │ │ │ │ │ │ │ ├────────────┴─────────────────────────────────────────────┤ │ Status Bar NORMAL | rust | 123:45 | UTF-8 | 🚀 │ └──────────────────────────────────────────────────────────┘ ``` ### 6.2 UI Components | Component | Description | |-----------|-------------| | `EditorView` | Main text rendering area | | `LineNumbers` | Line number gutter | | `ScrollBar` | Scroll indicators | | `StatusBar` | Mode, position, file info | | `TabBar` | Open buffer tabs | | `CommandPalette` | Fuzzy-find commands | | `FilePicker` | File browser/telescope | | `DiagnosticPanel` | LSP errors/warnings | | `CompletionPopup` | Autocomplete suggestions | | `HoverPopup` | Documentation hover | ### 6.3 UI Modes MicroHX supports three distinct UI modes with the same core editor logic: #### GUI Mode (Default) - Full egui/eframe native window - Mouse support - Native menus and dialogs - System clipboard integration - Multiple windows/tabs #### Terminal Mode (TUI) - Full terminal UI with ratatui - 256 color / true color support - Mouse support (when terminal allows) - Feature flag: `--features tui` - Command: `microhx-tui` #### CLI Mode (Headless) - No UI rendering - pure terminal I/O - Minimal dependencies - Ideal for remote/SSH usage - Static binary friendly - Feature flag: `--features cli` - Command: `microhx-cli` - Uses crossterm for direct terminal control ```rust // Build matrix example #[cfg(feature = "gui")] fn main() { microhx::run_gui(); } #[cfg(feature = "tui")] fn main() { microhx::run_tui(); } #[cfg(feature = "cli")] fn main() { microhx::run_cli(); } ``` ### 6.4 Static Compilation For maximum portability (old Linux systems, embedded, containers): ```bash # Cross-compile static binary with musl cargo build --release --target x86_64-unknown-linux-musl --features cli # Or use zig for even better compatibility cargo zigbuild --release --target x86_64-unknown-linux-gnu.2.17 --features cli # Result: single static binary, no glibc dependency $ file target/x86_64-unknown-linux-musl/release/microhx statically linked ``` **Static Build Requirements:** - LuaJIT statically linked (or use mlua with lua-src) - Tree-sitter grammars compiled into binary - No dynamic LSP dependencies (use rust-based lsp-client) - Fonts embedded or use terminal fonts only (CLI/TUI) --- ## 7. Text Buffer & Editing ### 7.1 Rope-based Buffer ```rust use ropey::Rope; pub struct Buffer { rope: Rope, undo_tree: UndoTree, marks: HashMap, path: Option, language: Option, modified: bool, } ``` ### 7.2 Undo/Redo System - Tree-based undo history - Branch-aware (undo + new change = new branch) - Persistent undo sessions (optional) ### 7.3 Selection System ```rust pub struct Selection { ranges: Vec, primary: usize, } pub struct SelectionRange { anchor: Position, head: Position, reversed: bool, } ``` - Multiple selections support - Cursor-style editing (Kakoune-inspired) --- ## 8. Syntax Highlighting (Built-in Tree-sitter) MicroHX includes **tree-sitter** as a core component - no external dependencies required. ### 8.1 Tree-sitter Integration ```rust pub struct Highlighter { parser: Parser, tree: Option, highlights: Vec, theme: SyntaxTheme, // Grammars compiled into binary grammars: HashMap, } ``` **Features:** - Incremental parsing (only re-parse changed regions) - Threaded parsing for large files - Grammar hot-reloading - Query-based highlighting (like Neovim) - Local injections (markdown code blocks, etc.) ### 8.2 Language Support | Language | Tree-sitter | LSP | |----------|-------------|-----| | Rust | ✅ | ✅ | | Lua | ✅ | ✅ | | Python | ✅ | ✅ | | JavaScript/TS | ✅ | ✅ | | C/C++ | ✅ | ✅ | | Go | ✅ | ✅ | | Zig | ✅ | ✅ | | TOML | ✅ | ✅ | | JSON | ✅ | ✅ | | YAML | ✅ | ✅ | | Markdown | ✅ | - | | HTML | ✅ | - | | CSS | ✅ | - | --- ## 9. LSP Integration (Built-in) MicroHX includes a **native LSP client** built on `lsp-types` and `tower-lsp` - no external server required for basic functionality. Language servers still need to be installed separately, but the client is built-in. ### 9.1 LSP Client Architecture ```rust pub struct LspClient { server: LanguageServer, capabilities: ServerCapabilities, diagnostics: Vec, completion_items: Vec, // Built-in client, no external dependencies transport: JsonRpcTransport, } ``` **Features:** - Async message handling (tokio) - Auto-restart on crash - Multiple server support (workspace folders) - Progress reporting - Dynamic capability registration ### 9.2 Supported Features - [x] Diagnostics (errors, warnings) - [x] Hover documentation - [x] Go to definition - [x] Find references - [x] Symbol search - [x] Code completion - [x] Signature help - [x] Formatting (range & document) - [x] Code actions - [x] Rename symbol - [x] Document symbols - [x] Inlay hints - [x] Semantic tokens --- ## 10. Command System ### 10.1 Built-in Commands | Command | Description | |---------|-------------| | `:write` / `:w` | Save file | | `:quit` / `:q` | Quit | | `:wq` | Save and quit | | `:q!` | Force quit | | `:open ` | Open file | | `:close` | Close buffer | | `:buffer ` | Switch buffer | | `:next` / `:prev` | Next/prev buffer | | `:split` / `:vsplit` | Horizontal/vertical split | | `:find ` | Find in buffer | | `:replace ` | Replace in buffer | | `:set