Files
microhx/SPECIFICATION.md

938 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 | `<Esc>` |
| `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 | `<C-v>` |
| `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., `<C-q>` 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` / `<C-r>` | 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 = {
["<leader>w"] = ":write",
["<leader>q"] = ":quit",
["<C-s>"] = ":write",
["<leader>f"] = ":telescope find_files",
},
insert = {
["jk"] = "<Esc>",
},
},
-- 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<char, Position>,
path: Option<PathBuf>,
language: Option<Language>,
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<SelectionRange>,
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<Tree>,
highlights: Vec<HighlightRange>,
theme: SyntaxTheme,
// Grammars compiled into binary
grammars: HashMap<Language, Grammar>,
}
```
**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<Diagnostic>,
completion_items: Vec<CompletionItem>,
// 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 <path>` | Open file |
| `:close` | Close buffer |
| `:buffer <n>` | Switch buffer |
| `:next` / `:prev` | Next/prev buffer |
| `:split` / `:vsplit` | Horizontal/vertical split |
| `:find <pattern>` | Find in buffer |
| `:replace <from> <to>` | Replace in buffer |
| `:set <option>` | Set option |
| `:command` | Show commands |
| `:help` | Open help |
| `:terminal` | Open terminal |
| `:lsp_restart` | Restart LSP |
| `:lsp_status` | LSP status |
### 10.2 Command Parser
```rust
pub struct Command {
name: String,
args: Vec<String>,
bang: bool, // ! modifier
range: Option<LineRange>, // e.g., :10,20delete
}
```
---
## 11. File Management
### 11.1 Features
- Auto-save (configurable)
- Backup files (optional)
- File watching (notify crate)
- Recent files list
- Project root detection
- Git integration (optional)
### 11.2 Buffer Management
```rust
pub struct BufferManager {
buffers: HashMap<BufferId, Buffer>,
active: BufferId,
order: Vec<BufferId>,
recent: Vec<BufferId>,
}
```
---
## 12. Configuration System
### 12.1 Config Locations
| Platform | Path |
|----------|------|
| Linux | `~/.config/microhx/` |
| macOS | `~/Library/Application Support/microhx/` |
| Windows | `%APPDATA%/microhx/` |
### 12.2 Config Files
```
~/.config/microhx/
├── init.lua # Main config
├── plugins/ # Plugin directory
├── themes/ # Custom themes
├── keys/ # Keymap presets
└── logs/ # Log files
```
### 12.3 Settings Schema
```rust
pub struct Settings {
// Editor
pub theme: String,
pub line_numbers: bool,
pub relative_numbers: bool,
pub cursor_line: bool,
pub color_column: Option<u32>,
// Indentation
pub tab_width: u32,
pub insert_spaces: bool,
pub auto_indent: bool,
// Display
pub font_size: f32,
pub line_height: f32,
pub wrap_lines: bool,
pub smooth_scrolling: bool,
// Behavior
pub auto_save: bool,
pub auto_save_delay: u64,
pub restore_cursor: bool,
pub confirm_quit: bool,
// Search
pub inc_search: bool,
pub hl_search: bool,
// LSP
pub lsp_enable: bool,
pub lsp_completion: bool,
pub lsp_diagnostics: bool,
}
```
---
## 13. Performance Goals
| Metric | Target |
|--------|--------|
| Startup time | < 100ms (TUI), < 200ms (GUI) |
| Memory usage | < 50MB (small files), < 200MB (large) |
| Input latency | < 16ms (60 FPS) |
| File open (10k lines) | < 50ms |
| Syntax highlight | Incremental, < 5ms update |
| Search (100k lines) | < 100ms |
---
## 14. Project Structure
```
microhx/
├── Cargo.toml
├── Cargo.lock
├── README.md
├── SPECIFICATION.md
├── LICENSE
├── .github/
│ └── workflows/
├── src/
│ ├── main.rs
│ ├── lib.rs
│ ├── app.rs # Main application state
│ ├── editor/
│ │ ├── mod.rs
│ │ ├── buffer.rs
│ │ ├── cursor.rs
│ │ ├── mode.rs
│ │ ├── keymap.rs
│ │ ├── selection.rs
│ │ └── undo.rs
│ ├── ui/
│ │ ├── mod.rs
│ │ ├── editor_view.rs
│ │ ├── statusbar.rs
│ │ ├── tabs.rs
│ │ ├── command_palette.rs
│ │ └── components/
│ ├── lua/
│ │ ├── mod.rs
│ │ ├── plugin.rs
│ │ ├── api.rs
│ │ └── config.rs
│ ├── lsp/
│ │ ├── mod.rs
│ │ ├── client.rs
│ │ └── messages.rs
│ ├── syntax/
│ │ ├── mod.rs
│ │ ├── highlight.rs
│ │ └── language.rs
│ ├── commands/
│ │ ├── mod.rs
│ │ ├── parser.rs
│ │ └── builtin.rs
│ └── config/
│ ├── mod.rs
│ └── settings.rs
├── plugins/
│ ├── telescope/
│ ├── lsp/
│ └── treesitter/
├── themes/
│ ├── dracula.toml
│ ├── nord.toml
│ └── gruvbox.toml
├── tests/
│ ├── unit/
│ ├── integration/
│ └── lua/
└── assets/
└── icons/
```
---
## 15. Development Roadmap
### Phase 1: Core Foundation (MVP)
- [ ] Basic buffer management (ropey)
- [ ] Modal system (Normal, Insert, Visual)
- [ ] Object-verb keybindings (Helix-style)
- [ ] Lua config loading (mlua)
- [ ] CLI mode with crossterm
- [ ] File open/save
- [ ] Static build setup (musl)
### Phase 2: Essential Features
- [ ] Complete keybinding system
- [ ] Undo/redo (tree-based)
- [ ] Search/replace
- [ ] Command system
- [ ] Status bar
- [ ] Line numbers
- [ ] User-definable modes
### Phase 3: Built-in LSP + Tree-sitter
- [ ] Tree-sitter integration
- [ ] Syntax highlighting engine
- [ ] LSP client (tower-lsp)
- [ ] Diagnostics display
- [ ] Completions popup
- [ ] Goto definition/hover
### Phase 4: Advanced Editing
- [ ] Multiple selections
- [ ] Macros
- [ ] Marks
- [ ] Registers
- [ ] Split windows
- [ ] TUI mode (ratatui)
### Phase 5: Polish & Plugins
- [ ] Plugin system
- [ ] Theme system
- [ ] GUI mode (egui)
- [ ] Performance optimization
- [ ] Documentation
- [ ] CI/CD with static builds
---
## 16. Design Principles
1. **Performance First** - Every operation should be fast and memory-efficient
2. **Modal by Default** - Object-verb workflow (Kakoune/Helix style)
3. **Lua Everything** - Configuration and plugins use Lua exclusively
4. **Built-in Intelligence** - LSP + Tree-sitter included, no external deps
5. **Three Modes** - CLI, TUI, and GUI with shared core
6. **Static Friendly** - Compile once, run anywhere (musl, old glibc)
7. **User Modes** - Extensible modal system for custom workflows
8. **Sensible Defaults** - Works out of the box, customizable when needed
9. **No Bloat** - Features are opt-in, core stays lean
---
## 17. Naming
**MicroHX** = Micro (small, fast) + HX (Hex/Editor suffix, modern feel)
Pronunciation: /ˈmaɪ.kroʊ.heɪks/ (MY-kro-hayks)
---
## 18. License
MIT License - See LICENSE file
---
## 19. Contributing
See CONTRIBUTING.md for guidelines on:
- Code style
- Testing requirements
- Pull request process
- Reporting issues
---
*Last updated: 2026-03-17*