An experimental modal text editor with a client–server architecture and tree-sitter integration.
Aether splits editing across two processes: a long-lived server, running locally, holds all text state — buffer contents, cursors, selections, the undo stack, per-viewport soft wrap — while thin clients render what the server sends and forward keystrokes. Multiple clients can share a buffer, see each other's cursors, and share a single undo stack.
- Modal editing (normal/insert mode)
- Tree-sitter integration (highlighting, indentation, navigation)
- Surround/unsurround, toggle-comment, join and move lines
- Undo and redo stacks for edits and cursor/selection motions
- Fuzzy pickers for files/buffers/projects, file explorer, project-wide grep
- Mouse support, soft wrap, system-clipboard integration
- Git integration (gutter, inline diff, blame, hunk staging)
- LSP (diagnostics, hover, go-to-definition, format)
- Terminal and web clients
Type Space ? for the in-app overlay. Holding the Shift key extends the selection (e.g., Shift-w); a leading
count repeats a motion (e.g., 3w).
| Key | Action |
|---|---|
h/l |
Character left/right |
j/Alt-j |
Logical/visual line down |
k/Alt-k |
Logical/visual line up |
w/Alt-w |
Small/big word forward |
b/Alt-b |
Small/big word backward |
e/Alt-e |
Small/big word end |
0, Home |
Logical line start |
Alt-l, End |
Logical line end |
Alt-h |
First non-blank of line |
g/Alt-g |
Go to line (count, default 1)/last line |
d/Alt-d |
Cursor down a page/half page |
u/Alt-u |
Cursor up a page/half page |
f/Alt-f |
Find character forward/backward (next key is the target) |
t/Alt-t |
Till character forward/backward |
m/Alt-m |
Matching bracket/inner matching bracket |
]/[ |
Next/previous navigation unit |
}/{ |
Select to end/start of unit |
Alt-Left/Alt-Right |
Jump back/forward (cross-file history) |
| Key | Action |
|---|---|
c |
Collapse selection |
o |
Swap cursor and anchor |
y/Alt-y |
Expand/contract selection to syntax node |
x/Alt-x |
Select line downward/upward |
z/Alt-z |
Undo/redo cursor motion |
r |
Repeat last motion |
- |
Center cursor in window |
| Key | Action |
|---|---|
/ |
Search |
? |
Search, selecting from the cursor to the match |
Alt-/ |
Search for current selection |
n/Alt-n |
Next/previous match |
>/< |
Next/previous grep result |
Esc |
Clear the active search |
Most Ctrl edits operate in both modes. The clipboard/edit keys are selection-scoped in normal and line-scoped in insert (since insert has no selection).
| Key | Normal | Insert |
|---|---|---|
Ctrl-c |
Change selection | Change line |
Ctrl-d |
Delete selection | Delete line |
Ctrl-y |
Copy selection | Copy line |
Ctrl-x |
Cut selection | Cut line |
Ctrl-v |
Paste before selection | Paste at cursor |
Ctrl-r |
Replace selection with clipboard | Replace line with clipboard |
Ctrl-s |
Surround selection (next key = delimiter) | Surround line |
Ctrl-Alt-s |
Unsurround selection | Unsurround line |
Ctrl-z/Ctrl-Alt-z |
Undo/redo | Undo/redo |
Ctrl-l/Ctrl-h |
Indent/dedent | Indent/dedent |
Ctrl-j/Ctrl-k |
Move line(s) down/up | Move line(s) down/up |
Ctrl-g |
Join lines | Join lines |
Ctrl-t |
Toggle comment | Toggle comment |
Ctrl-o/Ctrl-Alt-o |
Open line below/above | Open line below/above |
| Key | Action |
|---|---|
i/a |
Insert at selection start/end |
Alt-i/Alt-a |
Insert at first non-blank of line/last line end |
Esc |
Leave insert mode |
| Chord | Action |
|---|---|
Space f |
Find files |
Space b |
Switch buffer |
Space g |
Grep workspace |
Space e |
File explorer |
Space p |
Switch project |
Space , |
Project settings |
Space s/Space Alt-s |
Save/save as |
Space r |
Reload from disk |
Space n |
New scratch buffer |
Space c |
Close buffer |
Space q |
Quit |
Space ? |
Show keyboard shortcuts |
| Chord | Action |
|---|---|
Space w |
Toggle soft wrap |
| Chord | Action |
|---|---|
Space a |
Stage/unstage the change under the cursor (or selected lines) |
Space v |
Revert the change under the cursor (or selected lines) |
Space h/Space Alt-h |
Next/previous hunk |
Space i |
Toggle inline diff |
Space o |
Blame commit details for the cursor line |
| Chord | Action |
|---|---|
Space d/Space Alt-d |
Go to definition/references |
Space k |
Hover (type & docs) |
Space j |
Show diagnostic at cursor |
Space x/Space Alt-x |
Next/previous diagnostic |
Space t |
Diagnostics list |
Space m |
Format document |
Space l |
LSP servers (status, restart) |
Aether is a standard Cargo workspace.
cargo build --releaseThis produces two binaries:
aether— the server daemonae— the terminal client
-
Start the server:
aether
-
Start the client, optionally naming a project and a file/directory to open:
ae # start with the project picker open ae aether # open the "aether" project in a scratch buffer ae aether src/main.rs # open a file ae aether src/ # open the file explorer at a directory
fileis resolved against the current working directory and must fall within one of the project's roots. A directory opens the file browser there.Projects are created and managed from the project picker (
Space p); runningaewith no arguments opens it.
The web client (web/, TypeScript) is served by the same server process. Build the bundle once,
then open it in a browser:
cd web
npm install # first time only
npm run build # tsc (typecheck + compile), then Vite bundles to web/distnpm run build runs tsc && vite build. The server serves web/dist directly — the path is baked
from the crate and read at runtime, so a rebuilt bundle is picked up without rebuilding the server.
With the server running, open http://127.0.0.1:2384. There's no token to copy: the daemon is
loopback-only and authorizes by Host/Origin, so a browser on the same machine just connects.