A modeless editor for the terminal
CMeDit brings the ease of a desktop editor to the speed of a terminal: drop-down menus, full mouse support, and the shortcuts your fingers already know. No modes. No new muscle memory. Ctrl+S saves, Ctrl+F finds, Ctrl+Q quits. That's the whole tutorial.
v0.3.1 · free & open source (GPL-3.0) · one binary, zero runtime dependencies · Linux, macOS & Windows
Why CMeDit
Terminal editors make you choose: learn a decades-old command language, or settle for something bare-bones. CMeDit refuses the choice. It's a full graphical-style editor that happens to be drawn in character cells.
Modeless, like every desktop app you've ever used. Shift+arrows select, the mouse selects and drags, double-click picks a word, Ctrl+C/Ctrl+V talk to your system clipboard. Can't remember a shortcut? It's in a menu, with the shortcut printed next to it. You will never look up how to exit.
A drop-down menu bar. A VS Code-style file explorer you can drag to resize. Dialogs
with buttons. A scrollbar with a thumb you can grab. Even the status bar is clickable:
tap Ln, Col to jump to a line, tap LF to switch line endings.
Everything visible, everything discoverable.
One self-contained binary that starts in milliseconds, opens multi-megabyte files instantly, and repaints only the cells that changed. It runs identically on your laptop, a container, or a server on the far side of an ocean.
Modern editor, no window system
> in the file
picker) fuzzy-searches every command in the editor.Real-time diagnostics, no language server
CMeDit auto-detects the linters already on your machine — ruff, flake8, eslint, stylelint, pyright and shellcheck — and re-lints the active file about half a second after you stop typing. No LSP install, no per-project extension marketplace, no per-host server process. Your unsaved buffer streams to the tool over stdin, so the diagnostics reflect what's on screen.
2E 1W on the status bar. Click it to
jump to the first problem; F8 (Find ▸ Next Problem) cycles.pyproject.toml, eslint.config.mjs
or .shellcheckrc takes effect automatically. eslint and stylelint are
picked up from node_modules/.bin too.exceptThe two diagnostics above
are ruff's F401 (unused import json) and E722 (bare except).
Nothing was configured — ruff was on $PATH, cmedit noticed, ran it
on the buffer, and drew the underlines.
The remote-work superpower
An SSH session is the fastest way to be on a machine, and usually
the most limiting. CMeDit closes the gap: the workflows that normally force you to
scp files home, mount remote drives, or install a remote IDE server just… work,
inside the terminal you already have open.
CSV and TSV files open as a real spreadsheet grid: navigate cells, edit in place, insert rows and columns, freeze the header, select rectangles to copy or clear, and sort by any column with Alt+S. The sort is numeric-aware, and one more keystroke flips it descending. Saving writes clean, properly-quoted RFC-4180 CSV.
Open a PNG, JPEG, GIF, WebP or BMP and CMeDit renders it right in the
terminal: at true pixel resolution on terminals with kitty graphics or sixel,
and in sharp 24-bit half-block cells everywhere else. Animated GIFs play in place
— natively on kitty terminals (a swap of graphics placements, no re-transmit),
stepped elsewhere. Drag a rectangle to zoom; a small picture sits centred at native
resolution instead of being blown up. That chart a job wrote to /var/log?
Just open it.
Project-wide find & replace runs on the remote box where the files
live. No syncing a working copy locally first. It prunes .git and
node_modules, skips binaries, and streams results in as they're found.
Engineering, not vibes
CMeDit is built from first principles directly on the terminal, with no UI framework in between, so it controls exactly what gets drawn, when, and how it travels.
Each frame repaints only the cells that changed and flushes in a single write, wrapped in synchronized output so you never see tearing.
Held keys, fast typing and wheel scrolling are batched per frame, so the display never falls behind your hands.
Multi-megabyte files open immediately; the genuinely huge ones load on a background thread with a spinner, never a freeze.
The search engine is linear-time by
construction, so a pathological pattern like (a+)+b simply cannot lock up a
project-wide search.
Binary files are detected and refused with a clear message instead of exploding into a million junk lines.
Snapshots share the unchanged text, so deep undo history stays cheap even in large files.
Workspace searches, file loads and the quick-open file walk all stream results in without blocking a keystroke.
At startup CMeDit probes what your terminal can do and upgrades feature-by-feature. No probe reply means no risky escape codes: a plain terminal gets a plain, correct stream.
And the rest
Create (Ins), rename (F2) and delete (Del) from the tree; open buffers follow renames, even under a renamed folder.
Files changed on disk get a ◆
marker within seconds. A git pull in another window shows up by itself.
The pair at your cursor is highlighted; Ctrl+] jumps between them. The scan is bounded, so huge files never stall.
Flip LF ⇄ CRLF and toggle the UTF-8 BOM from the View menu, or just click them on the status bar.
Alt+Z and Alt+L, plus whitespace markers, insert/overwrite, auto-indent, and tab or space indentation with block indent/outdent.
Opt-in trailing-whitespace trimming and final-newline fixing, applied as a normal undoable edit, never behind your back.
Reopen a file, today or next week, and the cursor is exactly where you left it.
F1 shows a keyboard card; the full manual opens as a searchable document inside the editor itself.
File ▸ Settings (Ctrl+,): arrow-key value pickers, changes apply behind the dialog, Save writes them back to your config file surgically — your comments survive.
URLs in your text and file names in the explorer, search results and status bar are OSC 8 hyperlinks — Ctrl+Click opens them, in any terminal that supports links.
The same codebase with a Windows platform layer (hand-rolled kernel32 FFI, no extra packages). Runs in Windows Terminal; legacy conhost gets the portable fallback path like any minimal terminal.
File names are tinted by type (source green, docs cyan, data yellow, binaries dimmed); displayable images get a magenta ❏ marker so you can spot them without opening.
Get it
CMeDit builds offline with a plain make; its only dependencies
ship with the compiler. The result is a single binary you can drop onto any machine,
including the ones you SSH into.
Free software under the GPL-3.0. For full system-clipboard integration,
install any of xclip, wl-clipboard, xsel or use
macOS's built-in pbcopy. Otherwise CMeDit falls back to the OSC 52
escape, which is what makes clipboard-over-SSH work anyway.
Required reading
CMeDit is written in Haskell, a language with a storied tradition of producing white papers instead of products. Out of respect for that tradition, our first public release ships with both. The paper covers the architecture, the from-scratch image decoders and regex engine, and the unprecedented result that the software itself actually exists.