Maksim-Burtsev/merl

Keyboard-only code navigator for the terminal: fuzzy open, project search, go to definition and usages with VS Code-shaped keys. No mouse, no LSP, works over SSH.

Rust

0

143 commits

updated Sep 24, 2026

See the code

See what people are saying

SourceMessageScoreDate

Show HN: Whiteboard (YC W26) – An open-source IDE for thoughtful software design

There are a lot of emerging tools like this for which we will need a name. A similar one I randomly came across (https://github.com/Maksim-Burtsev/merl) calls itself a "Code Navigator." Along similar lines, I also don't know what we're calling tools like T3 or Superset. They're basically harnesses…

0

Sep 24, 2026

README

merl

merl

The one editor you need when agents write the code.

CI Release License Rust 2024 edition Last commit Homebrew tap version macOS and Linux

An agent works in one terminal split. merl sits in the other. You read what the agent wrote, walk its branch hunk by hunk, jump from a changed line into the code around it, fix the one line that is wrong, and go back to reading.

That is the whole tool: find your way around a project, review a diff with the code around it, and now and then type a secret into a .env. No setup, no config, no modes. It runs wherever a terminal does, SSH and tmux included.

merl on a checkout of gitea: open a file by a few letters of its name, find in the file, go to definition with the status line saying how it was proven, back, usages with the declarations first and the test last, then project search with the hits following the typing

A checkout of gitea, 5,500 files. Nothing was indexed or configured first.

Install

brew install maksim-burtsev/tap/merl

Or take a prebuilt binary for macOS (arm64) or Linux (x86_64, arm64) from the releases:

curl -fsSL https://github.com/Maksim-Burtsev/merl/releases/latest/download/merl-aarch64-apple-darwin.tar.gz | tar xz
sudo mv merl /usr/local/bin/

Or build it (Rust 1.85 or newer):

cargo install --git https://github.com/Maksim-Burtsev/merl

Then:

merl                 # the current directory
merl FILE:LINE[:COL] # what compilers, linters and grep print, pasted straight in
merl --review        # the branch you are on, as a diff over the real files
merl --tutor         # every key, hands on, in about ten minutes
merl --drill [N]     # N tasks (20) that name what to do, not the key; the keys you skip come most
merl --keys          # how often you press each key and miss it, the unused last

Why

Agents write most of the code now. Your part is to understand it and to review it, and merl does those two things out of the box, with nothing to configure and nothing to switch off.

  • Understand the code. Open a file by a few letters of its name, search the project as you type, go to a definition or list its usages, and come back with [. It follows you into the standard library and the dependencies.

  • Review a branch. merl --review draws the branch's diff over the real files, so from any changed line you can look up what it calls and who else uses it. It stays current while the agent keeps working, and a file you have walked through gets a tick that goes when the file changes. A review, step by step.

    merl --review on an agent's branch: c walks the hunks and on into the file where a function was rewritten, the deleted lines standing in grey above the new ones; Alt+Right hops word by word onto the new call, d goes into the helper the branch added and d again into the engine it queries, [ [ comes back to the hunk, and c walks the rest of the branch, down to the test the agent wrote
  • Touch up a line. Enter, type, Esc. It saves itself. Enough for a typo, a constant, or a secret you would rather not hand to an agent. More on editing.

I spent years switching things off in VS Code to get down to a tree, a highlighted file, go to definition and search. Vim and Helix want weeks of learning and a config first. merl starts there. It has no autocomplete, and it took me a while to notice: most of an editor is for typing code, and I had stopped typing it.

What merl is not

  • No plugins.
  • No language server and no index. Nothing to install per language, nothing to wait for.
  • No splits and no tabs. Your terminal has those.
  • No mouse.
  • No keymap to write. The keys are below and they stay.
  • No autocomplete, no snippets, no refactoring. The agent types.

None of these is on a roadmap. If you live in Vim or Helix and like it there, you do not need merl.

Keys

The dozen you will use every day. ? inside merl shows the rest.

KeyAction
o / Ctrl+EOpen a file (fuzzy)
sSearch the project
/ / Ctrl+FFind in the open file
d / F12Go to definition of the word under the cursor, or its implementations
u / Shift+F12Usages of the word under the cursor
DProject symbols (fuzzy)
[ / ]Back / forward in the jump history
c / CReview: next / previous hunk, on to the next file
Alt+Left / Alt+RightMove one word
EnterEdit at the cursor (Esc returns to navigation)
tShow or hide the file tree
?This help
qQuit
Every key
KeyAction
o / Ctrl+EOpen a file (fuzzy)
Ctrl+NNew file: type its path, Enter creates and edits it
/ / Ctrl+FFind in the open file
n / NNext / previous match
sSearch the project
d / F12Go to definition of the word under the cursor, or its implementations
DProject symbols (fuzzy)
u / Shift+F12Usages of the word under the cursor
[ / ]Back / forward in the jump history
c / CReview: next / previous hunk, on to the next file
mReview: mark the file as viewed, or take the mark off
: / Ctrl+GGo to line
tShow or hide the file tree
TPick a theme (live preview)
wWrap long lines, or cut them at the edge and scroll sideways
TabSwitch focus between tree and code
EnterEdit at the cursor (Esc returns to navigation)
Ctrl+SSave now (edits are saved on their own after a pause)
Ctrl+RReload from disk, dropping unsaved edits
Ctrl+Z / Ctrl+YUndo / redo
Ctrl+CCopy the selection, or the line, to the clipboard
Edit: Ctrl+XCut the selection, or the line
Edit: Alt+Backspace / Alt+DeleteDelete the word before / after the cursor
ArrowsMove the cursor; Up / Down go by screen row
Shift+Up / Shift+DownExtend the selection by a screen row
Shift+Left / Shift+RightExtend the selection by a char
Alt+Left / Alt+RightMove one word
Alt+Shift+Left / RightExtend the selection by a word
Ctrl+Shift+Left / RightExtend the selection to the start / end of the screen row, then of the line
vSelect the word, then the line, then the paragraph
Ctrl+D / Ctrl+UMove half a screen down / up
{ / }Previous / next paragraph (blank line)
PgUp / PgDnMove one screen
Home / EndStart / end of the screen row, then of the line
Ctrl+Home / Ctrl+EndStart / end of the file
EscClose an overlay, leave edit mode, or clear selection and find
?This help
qQuit
Tree: Up / DownMove
Tree: EnterOpen the file, or expand the directory
Tree: Left / RightCollapse / expand
Picker: Up / DownMove
Picker: EnterAccept
Picker: EscCancel
Picker: PgUp / PgDnMove one page
Help: Up / DownScroll

Languages

d, u and D work in all of these, with no language server and no index: a project works the moment you open it. In Python, TypeScript and Go, d also follows the type of the receiver (self.repo.save), and it always says how it found its target.

Languaged also reaches
Pythonthe standard library and the .venv
TypeScript, JavaScriptnode_modules
GoGOROOT and the modules in go.mod
Rustthe sysroot and the crates in Cargo.lock
C, C++the system headers
Swift.build/checkouts
PHPComposer's vendor/
Zigthe standard library
Java, Kotlin, Ruby, C#, Lua, Elixir
Shell, SQL, Makefile, Terraform, Dockerfile, YAML

What each rule reads and what it refuses to guess: docs/navigation.md.

Themes

T lists the themes and repaints merl in the one under the cursor as it moves. Enter keeps it, Esc puts the old one back. The default is tokyonight-moon. They were picked to sit in for hours: no neon, and light themes that look like paper.

docs/themes.md has a screenshot of each and how to add your own.

Config

There is none to write. T remembers your theme in ~/.config/merl/config.toml, and autosave_delay_ms (1000) lives there too.

Terminals

Any terminal, and the same keys over SSH and in tmux. Terminals keep Cmd for themselves, so copy is Ctrl+C and quit is q. Terminal.app is the weak one: no Shift+arrows, no Ctrl+Home, no copy.

In Ghostty, keybind = performable:cmd+c=copy_to_clipboard:mixed makes Cmd+C and Cmd+X work too.

Status

I use merl every working day. 1.0 is next, and what is left for it is in the milestone. Issues are welcome.

License

MIT. Syntax definitions come from bat via two-face; the themes keep their authors' licences.

cli
code-browser
code-navigation
developer-tools
go-to-definition
keyboard-driven
ratatui
ripgrep
rust
source-code-viewer
syntax-highlighting
terminal
tui

Contributors

Maksim-Burtsev

135 commits

claude[bot]

3 commits

Maksim-Burtsev/merl

Keyboard-only code navigator for the terminal: fuzzy open, project search, go to definition and usages with VS Code-shaped keys. No mouse, no LSP, works over SSH.

Rust

0

143 commits

updated Sep 24, 2026

See the code

See what people are saying

SourceMessageScoreDate

Show HN: Whiteboard (YC W26) – An open-source IDE for thoughtful software design

There are a lot of emerging tools like this for which we will need a name. A similar one I randomly came across (https://github.com/Maksim-Burtsev/merl) calls itself a "Code Navigator." Along similar lines, I also don't know what we're calling tools like T3 or Superset. They're basically harnesses…

0

Sep 24, 2026

README

merl

merl

The one editor you need when agents write the code.

CI Release License Rust 2024 edition Last commit Homebrew tap version macOS and Linux

An agent works in one terminal split. merl sits in the other. You read what the agent wrote, walk its branch hunk by hunk, jump from a changed line into the code around it, fix the one line that is wrong, and go back to reading.

That is the whole tool: find your way around a project, review a diff with the code around it, and now and then type a secret into a .env. No setup, no config, no modes. It runs wherever a terminal does, SSH and tmux included.

merl on a checkout of gitea: open a file by a few letters of its name, find in the file, go to definition with the status line saying how it was proven, back, usages with the declarations first and the test last, then project search with the hits following the typing

A checkout of gitea, 5,500 files. Nothing was indexed or configured first.

Install

brew install maksim-burtsev/tap/merl

Or take a prebuilt binary for macOS (arm64) or Linux (x86_64, arm64) from the releases:

curl -fsSL https://github.com/Maksim-Burtsev/merl/releases/latest/download/merl-aarch64-apple-darwin.tar.gz | tar xz
sudo mv merl /usr/local/bin/

Or build it (Rust 1.85 or newer):

cargo install --git https://github.com/Maksim-Burtsev/merl

Then:

merl                 # the current directory
merl FILE:LINE[:COL] # what compilers, linters and grep print, pasted straight in
merl --review        # the branch you are on, as a diff over the real files
merl --tutor         # every key, hands on, in about ten minutes
merl --drill [N]     # N tasks (20) that name what to do, not the key; the keys you skip come most
merl --keys          # how often you press each key and miss it, the unused last

Why

Agents write most of the code now. Your part is to understand it and to review it, and merl does those two things out of the box, with nothing to configure and nothing to switch off.

  • Understand the code. Open a file by a few letters of its name, search the project as you type, go to a definition or list its usages, and come back with [. It follows you into the standard library and the dependencies.

  • Review a branch. merl --review draws the branch's diff over the real files, so from any changed line you can look up what it calls and who else uses it. It stays current while the agent keeps working, and a file you have walked through gets a tick that goes when the file changes. A review, step by step.

    merl --review on an agent's branch: c walks the hunks and on into the file where a function was rewritten, the deleted lines standing in grey above the new ones; Alt+Right hops word by word onto the new call, d goes into the helper the branch added and d again into the engine it queries, [ [ comes back to the hunk, and c walks the rest of the branch, down to the test the agent wrote
  • Touch up a line. Enter, type, Esc. It saves itself. Enough for a typo, a constant, or a secret you would rather not hand to an agent. More on editing.

I spent years switching things off in VS Code to get down to a tree, a highlighted file, go to definition and search. Vim and Helix want weeks of learning and a config first. merl starts there. It has no autocomplete, and it took me a while to notice: most of an editor is for typing code, and I had stopped typing it.

What merl is not

  • No plugins.
  • No language server and no index. Nothing to install per language, nothing to wait for.
  • No splits and no tabs. Your terminal has those.
  • No mouse.
  • No keymap to write. The keys are below and they stay.
  • No autocomplete, no snippets, no refactoring. The agent types.

None of these is on a roadmap. If you live in Vim or Helix and like it there, you do not need merl.

Keys

The dozen you will use every day. ? inside merl shows the rest.

KeyAction
o / Ctrl+EOpen a file (fuzzy)
sSearch the project
/ / Ctrl+FFind in the open file
d / F12Go to definition of the word under the cursor, or its implementations
u / Shift+F12Usages of the word under the cursor
DProject symbols (fuzzy)
[ / ]Back / forward in the jump history
c / CReview: next / previous hunk, on to the next file
Alt+Left / Alt+RightMove one word
EnterEdit at the cursor (Esc returns to navigation)
tShow or hide the file tree
?This help
qQuit
Every key
KeyAction
o / Ctrl+EOpen a file (fuzzy)
Ctrl+NNew file: type its path, Enter creates and edits it
/ / Ctrl+FFind in the open file
n / NNext / previous match
sSearch the project
d / F12Go to definition of the word under the cursor, or its implementations
DProject symbols (fuzzy)
u / Shift+F12Usages of the word under the cursor
[ / ]Back / forward in the jump history
c / CReview: next / previous hunk, on to the next file
mReview: mark the file as viewed, or take the mark off
: / Ctrl+GGo to line
tShow or hide the file tree
TPick a theme (live preview)
wWrap long lines, or cut them at the edge and scroll sideways
TabSwitch focus between tree and code
EnterEdit at the cursor (Esc returns to navigation)
Ctrl+SSave now (edits are saved on their own after a pause)
Ctrl+RReload from disk, dropping unsaved edits
Ctrl+Z / Ctrl+YUndo / redo
Ctrl+CCopy the selection, or the line, to the clipboard
Edit: Ctrl+XCut the selection, or the line
Edit: Alt+Backspace / Alt+DeleteDelete the word before / after the cursor
ArrowsMove the cursor; Up / Down go by screen row
Shift+Up / Shift+DownExtend the selection by a screen row
Shift+Left / Shift+RightExtend the selection by a char
Alt+Left / Alt+RightMove one word
Alt+Shift+Left / RightExtend the selection by a word
Ctrl+Shift+Left / RightExtend the selection to the start / end of the screen row, then of the line
vSelect the word, then the line, then the paragraph
Ctrl+D / Ctrl+UMove half a screen down / up
{ / }Previous / next paragraph (blank line)
PgUp / PgDnMove one screen
Home / EndStart / end of the screen row, then of the line
Ctrl+Home / Ctrl+EndStart / end of the file
EscClose an overlay, leave edit mode, or clear selection and find
?This help
qQuit
Tree: Up / DownMove
Tree: EnterOpen the file, or expand the directory
Tree: Left / RightCollapse / expand
Picker: Up / DownMove
Picker: EnterAccept
Picker: EscCancel
Picker: PgUp / PgDnMove one page
Help: Up / DownScroll

Languages

d, u and D work in all of these, with no language server and no index: a project works the moment you open it. In Python, TypeScript and Go, d also follows the type of the receiver (self.repo.save), and it always says how it found its target.

Languaged also reaches
Pythonthe standard library and the .venv
TypeScript, JavaScriptnode_modules
GoGOROOT and the modules in go.mod
Rustthe sysroot and the crates in Cargo.lock
C, C++the system headers
Swift.build/checkouts
PHPComposer's vendor/
Zigthe standard library
Java, Kotlin, Ruby, C#, Lua, Elixir
Shell, SQL, Makefile, Terraform, Dockerfile, YAML

What each rule reads and what it refuses to guess: docs/navigation.md.

Themes

T lists the themes and repaints merl in the one under the cursor as it moves. Enter keeps it, Esc puts the old one back. The default is tokyonight-moon. They were picked to sit in for hours: no neon, and light themes that look like paper.

docs/themes.md has a screenshot of each and how to add your own.

Config

There is none to write. T remembers your theme in ~/.config/merl/config.toml, and autosave_delay_ms (1000) lives there too.

Terminals

Any terminal, and the same keys over SSH and in tmux. Terminals keep Cmd for themselves, so copy is Ctrl+C and quit is q. Terminal.app is the weak one: no Shift+arrows, no Ctrl+Home, no copy.

In Ghostty, keybind = performable:cmd+c=copy_to_clipboard:mixed makes Cmd+C and Cmd+X work too.

Status

I use merl every working day. 1.0 is next, and what is left for it is in the milestone. Issues are welcome.

License

MIT. Syntax definitions come from bat via two-face; the themes keep their authors' licences.

cli
code-browser
code-navigation
developer-tools
go-to-definition
keyboard-driven
ratatui
ripgrep
rust
source-code-viewer
syntax-highlighting
terminal
tui

Contributors

Maksim-Burtsev

135 commits

claude[bot]

3 commits

Languages

Rust

96.6%

Python

2.8%