Initial commin (phase 1 and 2)

This commit is contained in:
2026-03-19 17:36:18 +01:00
commit 957b814f6f
21 changed files with 15948 additions and 0 deletions
+937
View File
@@ -0,0 +1,937 @@
# 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*