A minimalistic text editor in the spirit of the Emacs family of editors, built in Rust.
This editor follows the Emacs tradition in three key ways: (a) it's buffer-oriented rather than file-oriented, (b) it uses the default GNU Emacs keybinding set, and (c) it's fully programmable via an embedded scripting language. Unlike the current trend toward "modal" editors, this is a direct manipulation editor and proud of it.
Roe uses Julia as its extension language (where Emacs uses Elisp). Keybindings, commands, and interactive modes can all be defined in Julia. The core editor is implemented in Rust for performance, while Julia provides the high-level customization layer.
Roe supports two rendering backends:
- Terminal (
roe): Lightweight, runs in your terminal - Vello/GPU (
roe-vello): Native window with GPU-accelerated rendering via Vello/wgpu
Both renderers share the same core editor, keybindings, and Julia integration.
- Emacs-style keybindings: Familiar keyboard shortcuts for Emacs users, fully customizable
- Julia scripting: Define commands, keybindings, and interactive modes in Julia
- Buffer-oriented editing: Beyond embedding a Lisp and having macros, one of the core pieces that differentiates an "emacs" from other editors is working with "buffers" not just files and having buffer interaction as a fundamental tool use. Windows are views into buffers, and not all buffers need to be backed by files.
- Window management: Split windows horizontally/vertically, switch between them, same as emacs.
- Mouse support: Even in console mode, click to position cursor, drag window borders to resize, click to switch windows, etc.
- Modular architecture: Has an extensible mode system for different editing behaviors
- Syntax highlighting: Major modes with syntax highlighting and auto-indentation for Julia, Rust, and Markdown
- Dual rendering: Terminal or GPU-accelerated native window
Keybindings are defined in Julia and can be customized in your .roe.jl configuration file. The
defaults follow GNU Emacs conventions. Use define_key("C-x C-s", "save-buffer") syntax to add or
override bindings.
- Arrow keys or
C-f/b/n/p: Move right/left/down/up C-a: Beginning of lineC-e: End of lineHome/End: Beginning/end of line
M-forC-Right: Move forward by wordM-borC-Left: Move backward by word
M-{: Move backward by paragraphM-}: Move forward by paragraph
C-vorPage Down: Page downM-vorPage Up: Page upM-Up: Page up (alternative)M-Down: Page down (alternative)
C-Home: Beginning of bufferC-End: End of buffer
C-x 2: Split window horizontallyC-x 3: Split window verticallyC-x o: Switch to other windowC-x 0: Delete current windowC-x 1: Delete all other windows
C-x b: Switch to another bufferC-x k: Kill (close) a buffer
- Click: Position cursor at click location
- Click in window: Switch to clicked window
- Drag window borders: Resize windows by dragging their borders
- Mouse events in modes: Mouse events are forwarded to modes for future extensibility
C-x C-f: Find fileC-x C-s: Save file
- Type to insert text
<Backspace>: Delete character before cursor<Delete>: Delete character at cursor<Enter>: Insert newline
C-Space: Set mark at cursor (start region selection)
C-w: Kill (cut) region between mark and cursorM-w: Copy region to kill ring without deletingC-k: Kill (cut) from cursor to end of lineC-y: Yank (paste) most recent killC-S-y: Yank from kill-ring index 0
M-x: Command mode (interactive command execution)C-g: Cancel current operation (e.g., clear region selection)C-x C-c: QuitEsc: Escape
# Set up Julia (downloads and configures Julia distribution)
./scripts/setup-julia.sh
# Build the project
cargo build --release
# Run terminal version
./scripts/run.sh [files...]
# Run Vello/GPU version
./scripts/run-vello.sh [files...]Roe loads configuration from .roe.jl in the current directory on startup. Example configuration:
# Configuration is defined as a Dict named roe_config
roe_config = Dict(
# Font settings (Vello renderer only)
"font" => Dict(
"family" => "JetBrains Mono", # Any installed font
"size" => 14
),
# Color scheme (optional - defaults are used if not specified)
# "colors" => Dict(
# "background" => "#1e1e1e",
# "foreground" => "#d4d4d4",
# "selection" => "#264f78",
# "modeline" => "#007acc",
# "cursor" => "#aeafad"
# )
)Custom keybindings can also be defined in Julia:
using Roe
# Custom keybindings
define_key("C-s", "save-buffer") # Quick save
define_key("C-q", "quit") # Quick quit
define_key("F5", "my-build-command") # Custom command
# Define a custom command
define_command("insert-date", "Insert current date") do ctx
InsertAction(ctx.cursor_pos, string(Dates.today()))
endSee jl/keybindings.jl for the full list of default keybindings.
Roe is built with a clean separation of concerns:
- roe-core: Core editor logic, buffer management, window system, Julia integration
- roe-terminal: Terminal renderer using crossterm
- roe-vello: GPU renderer using Vello/wgpu with Parley for text layout
Key concepts:
- Buffer: Text storage using
ropeyfor efficient editing - Window: View into a buffer with cursor and scroll position
- Mode: Defines behavior and keybindings for different editing contexts
- Editor: Coordinates buffers, windows, and modes
- Frame: Represents available screen real estate
This is a work-in-progress editor. Currently implemented:
- Text editing: Basic insertion, deletion, cursor movement
- Advanced movement: Word-wise, paragraph-wise, and page navigation with Emacs key bindings
- Window management: Split windows horizontally/vertically, switch between windows
- Buffer management: Multiple buffers, switching, killing with interactive selection
- Region selection: Mark system with visual highlighting
- Kill ring: Cut, copy, paste with kill ring history
- Command mode: Interactive command execution (M-x) with completion
- File operations: Open and save files with interactive file selector
- Mouse integration: Click-to-position cursor, window switching, border dragging for resizing
- Incremental search (isearch): Simple forward and backward incremental search.
- Dual rendering:
- Terminal UI with efficient incremental rendering via crossterm
- GPU-accelerated native window via Vello/wgpu with configurable fonts
- Julia scripting: Full integration with Julia for customization:
- Customizable keybindings via
define_key() - User-defined commands via
define_command() - Interactive modes written in Julia (file selector, buffer switcher, Julia REPL)
- FFI access to buffer contents from Julia
- Theme/font configuration via Julia config file
- Customizable keybindings via
- Syntax highlighting & major modes:
- Julia mode with JuliaSyntax.jl-based highlighting and smart indentation
- Rust mode with TreeSitter-based highlighting
- Markdown mode with highlighting and list/blockquote continuation
- Macro system: Record and playback keystroke sequences
- Search and replace: Interactive search, query-replace functionality
- LSP integration: Language server protocol support for modern development features
- Advanced editing: Multiple cursors, rectangular selections, etc.
- Undo/redo: Currently partially implemented
This editor is very much a work-in-progress and almost certainly has bugs. It also probably won't meet your real editing needs yet. However, feedback and bug reports are very welcome!
If you encounter issues or have suggestions, please file them in the project's issue tracker. Even if the editor isn't ready for daily use, your input helps guide development priorities and catch problems early.
Please report:
- Crashes or unexpected behavior
- Missing features that are essential for your workflow
- Performance issues
- Ideas for improvements or missing Emacs functionality