Features

March 31, 2026 · View on GitHub

Automatic backups

Automatic backups are enabled by default.

Automatic backups are recommended to keep it enabled Backup to ~/.cache/moe/backups by default.

You can set an interval to execute backups.

Crash recovery

When the editor crashes due to an unhandled exception, all modified (unsaved) buffers are automatically saved to ~/.cache/moe/crash_recovery/<timestamp>/. A recovery.json file in the directory maps recovery filenames to their original file paths.

On next startup, if recovery files are found, a notification is shown in the status line.

QuickRun

QuickRun is like vim-quickrun.

You can use \ + r in normal mode. And run or Q command in Command mode.
Currently QuickRun supports these languages by default and runs the following command internally.

  • Nim nim c -r filename
  • C gcc filename && ./a.out
  • C++ g++ filename && ./a.out
  • bash bash filename
  • sh sh filename

You can overwrite the command to be executed in the setting. That way you can use other compilers and languages.

VSCode theme

moe supports VS Code themes in addition to dark, vivid, light, which are provided as standard.
moe is searching and reflects the current VSCode theme if you already installed VSCode and you set "vscode" in the configuration file.

Build on save

moe can build on save if you set true in BuildOnSave.enable in the configuration file.
By default, the nim c filename command is executed.
You can set workSpaceRoot and command to be executed in the configuration file.

History mode (Backup file manager)

History mode is experimental feature.

You can check, restore and delete backup files in this mode.
If you select backup file, you can check the difference from the current original file.

General-purpose autocomplete

moe can now use simple auto-complete.
It is possible to auto-complete a words in the currently open buffer.

Register

moe can use Vim-like registers.

Number register

NameDescription
0Yanked text
1Deleted line. One line or less is stored in the small delete register -
2Every time a new delete command is issued, the contents of 1 are stored
3~9Similar to 2, the contents of the previous register are stored sequentially

Small delete register

NameDescription
-Deleted text

Named register

NameDescription
a~zAny text can be stored

No name register

Stores the value of the last used register.

Bookmarks

moe supports line bookmarks inspired by vim-bookmarks. Bookmarks are per-buffer, displayed in the sidebar with a indicator, and persisted across sessions in ~/.cache/moe/bookmarks.json.

KeysDescription
mmToggle bookmark on current line
mnJump to next bookmark
mpJump to previous bookmark
mcClear all bookmarks in current buffer
:bookmarksOpen Bookmark Manager

Bookmarks automatically adjust their positions when lines are inserted or deleted. They are saved on exit and restored when files are reopened.

In the sidebar, bookmark markers take priority over git/session change indicators but are overridden by syntax error/warning markers. The bookmark marker symbol can be customized via Standard.bookmarkMarker in the configuration file.

Bookmark Manager

:bookmarks opens an interactive Bookmark Manager mode that lists all bookmarks across all open buffers.

KeysDescription
j / DownMove selection down
k / UpMove selection up
EnterJump to selected bookmark
DDelete selected bookmark
ggMove to first entry
GMove to last entry
Ctrl+dHalf page down
Ctrl+uHalf page up
q / EscapeClose Bookmark Manager
:Enter command mode

FileTree

moe has a file tree sidebar that displays the directory structure alongside the editor window.

  • :filetree - Open the fileTree sidebar. If already open, it closes and reopens.
  • Can also be opened automatically on startup via [StartUp.FileTree] in the configuration file.

The fileTree supports navigation (j/k/gg/G), expanding/collapsing directories (Enter/o/x), changing root (C/u), incremental search (//n/N), and toggling hidden files (.).

See How to use - FileTree Mode for key bindings.

Runtime Key Mapping

moe supports Vim-like runtime key mapping commands. You can remap keys during an editing session using Command mode commands.

  • :nmap {lhs} {rhs} - Map keys in Normal mode
  • :imap {lhs} {rhs} - Map keys in Insert mode
  • :vmap {lhs} {rhs} - Map keys in Visual modes
  • :rmap {lhs} {rhs} - Map keys in Replace mode
  • :cmap {lhs} {rhs} - Map keys in Command mode
  • :map {lhs} {rhs} - Map keys in all modes (except Command mode)

All mappings are non-recursive (equivalent to Vim's noremap). noremap, nnoremap, inoremap, vnoremap, cnoremap are available as aliases.

Mappings are session-only and are not persisted across restarts. For persistent key mappings, use the [KeyMapping] section in moerc.toml or keybindings.toml. Use [KeyMapping.All] to apply mappings to all modes at once, [KeyMapping.VisualAll] for all visual modes, mode-specific sections like [KeyMapping.Normal], [KeyMapping.Visual], [KeyMapping.VisualLine], [KeyMapping.VisualBlock] for individual modes, or special mode sections like [KeyMapping.Filer], [KeyMapping.BufferManager], [KeyMapping.Terminal], etc. See configfile.md and configfile.md.

Key notation supports regular keys (a, j), modifier keys (C-s, M-x), special keys (Escape, Enter, Tab, F1-F12), and multi-key sequences in both space-separated (j j) and Vim-style concatenated (jj) notation.

See How to use - Runtime Key Mapping for full details.

EditorConfig

moe supports EditorConfig for maintaining consistent coding styles across editors.

When a file is opened, moe automatically looks for .editorconfig files and applies the settings to the buffer. EditorConfig is enabled by default and can be disabled in the configuration file.

Supported properties:

PropertyDescription
indent_stylespace or tab
indent_sizeNumber of columns for indentation
tab_widthNumber of columns for tab character
end_of_linelf, crlf, or cr
charsetutf-8, utf-8-bom, utf-16be, utf-16le
trim_trailing_whitespacetrue or false (applied on save)
insert_final_newlinetrue or false

Per-buffer overrides are automatically applied when switching between windows, so different files can have different settings simultaneously.

Buffer Backends

moe supports multiple buffer backend implementations. Each backend offers different performance characteristics suited to different editing scenarios. You can configure the default backend in moerc.toml.

Auto (Default)

Automatically selects the optimal backend based on file size. Files smaller than 10 MB use GapBuffer, and files 10 MB or larger use PieceTable.

GapBuffer

A line-oriented gap buffer. Lines are stored in a flat array with a logical gap at the current edit position. Edits near the gap are very fast; edits far from the gap require moving the gap first.

Best for small to medium files with sequential/localized edits.

OperationTime Complexity
Get lineO(1)
Insert/Delete lineO(1) amortized
Insert into lineO(L) (L = line length)
Delete rangeO(k) (k = lines spanned)
Undo/RedoO(operation cost)

SqrtDecomp

A block list (sqrt decomposition). Lines are partitioned into blocks of up to 1024 lines. Blocks split when they grow too large and merge when they shrink too small, keeping block sizes balanced at roughly sqrt(n).

Best for large files with scattered (random-access) edit patterns.

OperationTime Complexity
Get lineO(sqrt(n))
Insert/Delete lineO(sqrt(n))
Insert into lineO(sqrt(n) + L)
Delete rangeO(sqrt(n) * k)
Line count / Char countO(1) (cached)
Undo/RedoO(operation cost)

Rope

A B-tree rope where text is stored as raw bytes in leaf nodes. Internal nodes maintain subtree byte length and newline count metadata, enabling efficient tree walks. Tree height is O(log n) for all operations.

Best for large files with arbitrary-position edits requiring consistent O(log n) performance.

OperationTime Complexity
Get lineO(log n + L)
Insert/Delete lineO(log n)
Insert into lineO(log n + |text|)
Delete rangeO(log n)
Find line startO(log n)
Undo/RedoO(operation cost)

PieceTable

A persistent Red-Black tree of "pieces", each describing a span in one of two append-only text buffers (original and add). The tree uses path-copying (Okasaki-style functional updates) so that old tree roots remain valid even after mutations. This enables O(1) snapshot-based undo/redo.

Best for any file size; particularly suited when undo/redo performance matters.

OperationTime Complexity
Get lineO(log P + L)
Insert/Delete lineO(log P)
Insert into lineO(log P)
Delete rangeO(K log P)
Find line startO(log P)
Take snapshotO(1)
Restore snapshot (Undo/Redo)O(1)

(P = number of pieces in the tree. Coalescing keeps P bounded in practice.)

Undo/Redo

  • GapBuffer, SqrtDecomp, Rope: Operation-based undo/redo. Each edit records its inverse operation (e.g., insert ↔ delete). Undo replays the inverse; redo replays the original.
  • PieceTable: Snapshot-based undo/redo. Before each edit, an O(1) snapshot of the tree root is captured. Undo/redo simply swaps the current root with the saved snapshot. Transactions (multi-operation edits) are also covered by a single snapshot.

Comparison Summary

FeatureGapBufferSqrtDecompRopePieceTable
Line accessO(1)O(sqrt n)O(log n)O(log P)
Line insert/deleteO(1) amortO(sqrt n)O(log n)O(log P)
Char countO(n)O(1)O(1)O(1)
Find line startO(n)O(n)O(log n)O(log P)
Undo/RedoO(op)O(op)O(op)O(1)
StructureMutable arrayMutable blocksMutable B-treePersistent RB-tree
Ideal file sizeSmall–MediumLargeLargeAny

Terminal mode

moe has a built-in terminal emulator. You can run a shell or any command inside the editor window.

  • :terminal - Open an interactive shell (default shell)
  • :terminal command - Run a specific command (e.g. :terminal ls -la)

Terminal mode has two sub-modes:

  • Terminal-Input: All keystrokes are forwarded to the running shell/command. Press Ctrl-\ Ctrl-n to switch to Terminal-Normal sub-mode.
  • Terminal-Normal: Browse the terminal output. Press i or a to return to Terminal-Input sub-mode. Press : to enter command mode.

When a command finishes (e.g. :terminal ls), the output is displayed in a read-only scrollback view (Terminal-Normal sub-mode). When an interactive shell exits, the terminal window is automatically closed.