A toy text editor in Rust ala the Antirez/Paige/Philipp lineage.
I built this over the 2025 holiday season as a fun project with minimal constraints. I followed the tutorial through chapter 6. A big shout out to Philipp and forbears for the great incremental learning experience.
I skipped syntax highlighting because I ran out of my alloted time for the project (real reason) and because syntax highlighting over the entire buffer without regards to the viewport size is not very realistic, performance-wise, and does not help me flex new muscles (the excuse).
The end result isn't fully polished w.r.t. bugs, nor overly optimized for performance, but it is still reasonably complete and uses design patterns that you'd expect in a usable terminal-based editor (e.g. buffered, viewport-based rendering, clear ownership and avoding dynamic types wherever they don't add value - basically built well without a lot of time spent in optimization (.... is the hope)).
The final architecture evolved through the development process (MVC ultimately makes sense for a UI app, eh?) and the final codebase is reasonably clean through repeated timely refactoring interleaved with feature development.
Read all of the above as - I enjoyed working on the codebase, and made sure it evolved in a way where working on it remains enjoyable.
Here's hecto in action:
I used the Warp terminal and Google's Antigravity IDE for this project.
- I have been using AI coding assistants for years at this point, and the one thing about them is that they are changing really fast. I intend to continue to evolve my usage of the tools as the tools and my needs evolve.
- I use the tools heavily for documentation (No reason any code should be undocumented in 2026 anymore) and guided refactoring (Back in 2013, I wished that compiler-driven developer tools could help me refactor code better. The AI tools of today have delivered.). I consistently use the refactor-then-build-feature-then-refactor loop for incremental evolution of the codebase, and AI can speed up the refactor steps in that loop in a big way.
- I did not use AI tools for project architecture, design, or planning. Not that AI tools are not useful for those things, but using AI there would have taken away the fun of learning and building the project. I do use AI to summarize / glean insights about the current state of the code (e.g. building public API graphs, etc.) to help me make design decision.
Below follows a README for the project generated by Gemini Flash. It's free (in terms of developer-hours), complete, and somewhat lacking in character ;)
Hecto is a terminal-based text editor written in Rust, inspired by the "Build Your Own Text Editor" tutorial but significantly expanded with a modular, clean architecture. It aims to provide a robust foundation for learning and building terminal-based editing tools.
- Grapheme-Aware Rendering: Correctly handles multi-byte and multi-column Unicode characters (emojis, accented characters, etc.).
- Modular Architecture: Clear separation between state management, rendering logic, and input handling.
- Rich UI Components: Includes a main text area, left rail (gutter), status bar, and message bar.
- Searching: Functional forward and backward search with incremental highlights.
- File Management: Supports opening, editing, saving, and "saving as" new files.
The project follows a modular design to ensure maintainability and testability:
- State (
src/state/): Contains the core data structures.Buffer: Represents the text being edited (either empty or backed by a file).EditorState: The global state containing the current mode, buffer, and user messages.
- View (
src/view/): Handles the rendering of the UI.Sections: Coordinates the layout and drawing of different screen regions.TextArea: The main text editing region.StatusBar&MessageBar: Informational and interactive bars at the bottom.
- Controller (
src/controller/): Implements the logic for handling commands and transitioning between modes. - Editor (
src/editor.rs): The top-level orchestrator that runs the event loop and ties everything together. - Crossterm Extensions (
src/crosstermx/): Type-safe wrappers around thecrosstermlibrary for terminal interactions.
src/
├── controller/ # Input handling and mode transition logic
├── crosstermx/ # Terminal utility wrappers
├── editor/ # High-level editor components and command definitions
├── state/ # Core data models (Buffer, EditorState)
├── utilities/ # Miscellaneous helpers (Hashing)
├── view/ # Rendering logic and UI components
├── main.rs # Application entry point
└── types.rs # Common POD types (Position, Location, Bounds)
- Rust (latest stable)
To run the editor:
cargo run -- [filename]If no filename is provided, the editor opens with a welcome screen.
Ctrl-q: QuitCtrl-s: SaveCtrl-d: Save AsCtrl-f: FindArrow Keys: NavigateEnter: New lineBackspace/Delete: Remove textEsc: Cancel prompt/input
MIT
