Editor Setup
An editor that fights the agent workflow costs more time than it saves.
Learning Objectives
- Turn on format-on-save in your editor and pick a formatter that matches the project's language
- Keep an integrated terminal one keystroke from the code you are reading
- Run a regex search across the whole project in one keystroke and jump to any hit
- Bind the project's test command to one key and watch the output stream into an editor panel
- Tell, in one sentence, why each of those four capabilities matters when an agent is editing your code
The Problem
You ask an agent to fix a bug. It edits four files. You open the diff. The diff is full of "changes" you did not ask for: tabs instead of spaces, double quotes swapped for single, a trailing newline gone. None of them change behaviour. All of them pollute the diff so you cannot see what actually changed.
You try to run the tests. You alt-tab to a terminal. You type the command. You alt-tab back. The output is mixed in with shell startup noise. You alt-tab back to read it. Three round-trips for one fact.
You try to find where the agent introduced a function call. You open the file. You Ctrl-F. You type the name. The first hit is a comment. The second is a string. You repeat. Fifteen seconds, and you have stopped paying attention to what you were looking for.
The editor is in your way. Each moment costs a few seconds. The few seconds are where you stop paying attention to what the agent actually did. The fix is not a faster brain — it is an editor that does not make you stop and fix what it should have done for you.
The Concept
Four capabilities, each of which makes one specific moment in the agent workflow free. They are independent. Pick whichever ones you do not already have.
1. Format-on-save
Format-on-save means the editor runs a formatter (Prettier, Black, gofmt, rustfmt, whatever fits the language) every time you save a file. You stop worrying about whitespace, quote style, and trailing commas. The formatter owns them.
This matters with agents more than without, because the model has an opinion about style that may not match yours. Format-on-save rewrites whatever the agent produced, in your style, silently, on save. The diff stays clean. You review the diff, not the formatter's opinions.
The opposite — disabling formatting because "the agent got it close enough" — is the start of a codebase where every file is formatted in the dialect of whoever last touched it.
2. Integrated terminal
An integrated terminal is a shell pane that lives inside the editor window, one keystroke from the code. You do not alt-tab. The shell shares the editor's working directory, so paths and short commands just work.
The moments it earns its keep:
- You just accepted an agent change. You type
git diff --statto see the shape. - The agent says "I ran the tests." You type the test command yourself to verify.
- The agent produced a build error. You run the build again, in the same pane the agent was in, and copy the failing line straight from your terminal scrollback.
A separate terminal app is fine if you have a fast switch and a shared clipboard. An integrated terminal just removes the switch.
3. Project-wide search
Project-wide search means: in one keystroke, search every file in the project for a regex, show the hits in a list, jump to any hit in one more keystroke. Not a file picker. Not "find in current file." Across the project, instantly.
This is the move you reach for when the agent edited something and you want to know where else it is used, or where a name came from, or whether a particular error message appears anywhere in the codebase. The grep-in-terminal fallback works, but a search panel that lists hits and jumps on enter is the difference between "I read every hit" and "I read the first one and gave up."
4. A real test runner, bound to one key
A real test runner means: one keystroke runs the project's test command — whatever the language uses, pytest, npm test, go test, cargo test, or the project's own runner. The output streams into a panel. The failures are clickable. Running it again is the same keystroke.
This matters because the agent's job does not end at "the code compiles." The agent's job ends at "the tests pass." You want to verify that in the same window where you are reading the code. If running the tests is three commands and a context switch, you will skip it. If it is one key, you will not.
The reframe: an editor that fights the agent workflow costs more time than it saves; pick one that disappears during the four moments that matter — saving, diffing, searching, testing.
flowchart LR
A[Agent edits] --> B[Save]
B --> C[Format-on-save]
C --> D[Diff]
D --> E[Search references]
E --> F[Run tests]
F --> G{Pass?}
G -->|yes| H[Approve]
G -->|no| ABuild It
Pick whichever editor you already use. Do not switch editors in this lesson. The four capabilities are present in every modern one — VS Code, JetBrains, Sublime, Vim, Neovim, Helix, Zed. Configure the one you have.
1. Turn on format-on-save
- VS Code:
Editor: Format On Savesetting; install a formatter extension that matches the language (prettier,black,rustfmt, etc.). - JetBrains:
Settings → Tools → Actions on Save → Reformat code. - Neovim: a
BufWritePreautocommand that pipes the buffer through the language's formatter. - Helix: built in; run
formaton save with:set auto-format on.
Verify by saving a file with bad indentation. Pass when the bad indentation disappears without you touching it.
2. Open the integrated terminal
- VS Code: `
Ctrl+`` opens the terminal panel. - JetBrains:
View → Tool Windows → Terminal, orAlt+F12. - Vim / Neovim: a terminal split (
:terminal). - Helix: `
Ctrl+`` to open a terminal.
Verify by running pwd and confirming it matches the editor's working directory.
3. Bind project-wide search to one key
- VS Code:
Ctrl+Shift+Ffor the search panel,Ctrl+Shift+Hfor replace. - JetBrains:
Ctrl+Shift+Ffor find-in-path,Ctrl+Shift+Rfor replace-in-path. - Sublime:
Ctrl+Shift+F. - Vim / Neovim:
rgor:grepbehind a leader-key mapping. - Helix:
Space-sfor ripgrep search.
Verify by searching for a name you know appears in five files. Pass when the hits appear in a list and a click or Enter jumps to the location.
4. Bind the project's test command to one key
This is the one that requires you to know the project's test command. Find it once — usually in package.json, pyproject.toml, Makefile, or the README. Bind it.
- VS Code: open
keybindings.jsonand add a binding that runs the command in the integrated terminal, or use an extension likevscode-test-runner. - JetBrains: most run configs run with the green arrow; for a single binding,
Run → Edit Configurations, then a keybinding. - Vim / Neovim: a leader-key mapping that runs
:!pytest(or whatever) and streams the output. - Helix:
:sh pytestor a user keybinding.
Verify by running the tests once. Pass when the output streams into a panel, a failing line is clickable, and pressing the same key runs the tests again from a clean state.
5. Put them together on one agent change
Make a scratch change, or use the agent to make one. Then in one session, without leaving the editor:
- Save the file. Watch the formatter run.
- Read the diff in the integrated terminal with
git diff. - Search for a name the change introduced, using project-wide search.
- Run the tests with your bound key.
Pass when each step is one keystroke or one click, and you never alt-tabbed.
Use It
| Moment in the workflow | Capability you reach for |
|---|---|
| You saved an agent's edit | Format-on-save (already ran, silently) |
| You want the shape of what changed | git diff --stat in the integrated terminal |
| You want the content of what changed | git diff in the integrated terminal, or the editor's diff view |
| You want to know where a name is used | Project-wide search |
| You want to verify the change actually works | Bound test-runner key |
| The agent's edit broke something | Bound test-runner key → read failing line in panel → search for the broken symbol |
| Don't do this | Do this instead |
|---|---|
| Read the diff in a separate terminal app | git diff in the integrated terminal |
Type npm test (or its equivalent) every time | Bound key on the project's actual test command |
| Tell the agent "make sure the code is formatted" | Turn on format-on-save and stop asking |
| Open three files to find one reference | Project-wide search across the whole project |
| Read a failing test by alt-tabbing to a terminal | Click the failing line in the test panel |
Exercises
- Format-on-save earns its keep. In any source file, add five lines with deliberately bad indentation. Save. Pass when the file is correctly formatted without you touching the spacing. Pass: the file's whitespace matches the project's style after one save, with no manual edits from you.
- Search five files in one keystroke. Pick a function name that you know is referenced in five or more files in your project. Run project-wide search for it. Pass when all five references appear in a list and jumping to any one of them is one keystroke. Pass: a hit list with five or more entries, each openable in one keystroke.
- Tests run in one key. Bind the project's test command to one key. Run the tests. Pass when the output streams into a panel inside the editor (not a separate window) and a failing line is clickable. Pass: one keystroke runs the tests; output is in an editor panel; a failure line opens its file when clicked.
- Verify an agent change without leaving the editor. Use an agent (or your past self on a scratch branch) to make a small change that touches two files. Without leaving the editor, run the four-step verification from Build It step 5. Pass when each step is one keystroke, and you can name which lines changed without scrolling. Pass: all four steps happen in the editor; you can name the changed lines from memory afterwards.
Key Terms
| Term | What people say | What it actually means | Why the misconception matters |
|---|---|---|---|
| Format-on-save | The editor pipes the file through a formatter every time you save | Some people treat formatting as a manual chore, or as "what the agent should remember." It is neither. The editor does it, invisibly, every save — and with an agent in the loop, "what the agent should remember" is the worst possible plan. | |
| Integrated terminal | A shell pane inside the editor window, sharing its working directory | People think of terminals as separate apps. With agents, you spend half your time in shell and half reading code. A switch costs attention, not seconds, and attention is what you are trying to spend on the change. | |
| Project-wide search | A single-keystroke regex search across every file in the project, with a jumpable hit list | People confuse it with "find in current file." Current-file search finds text. Project-wide search finds code — including hits in files you did not know mattered. With agents, you almost always want the latter. | |
| Test runner | A program that runs the project's tests and reports pass/fail per file or per case, bound to one key | People treat tests as something you "remember to run." A test runner bound to one key is the difference between remembering and not — and between verifying and trusting the agent's word. | |
| Save | A signal to the editor that the buffer is ready, plus a trigger for hooks like formatters and linters | Save is no longer just "write the file to disk." In an agent workflow, save is the moment the diff stops being dirty, the formatter runs, and you cross from "agent is still typing" to "agent is done, and you can review." |
What this lesson skipped
No editor recommendation. Use the one you have. Switching editors is its own lesson and its own cost.
No LSP setup, no language-server configuration, no extension roundup. Most editors wire the language server automatically when you open a file of the right type.
No theme, no font, no keybinding tutorial beyond the four keys above. Taste is not what this course teaches.
No AI editor features — inline suggestions, agent sidebars, chat panels. Those are agent-shaped additions layered on top of the four capabilities above. They are worth knowing, but they are not what makes the editor fit the workflow.
What this lesson assumed: you already have an editor installed, a project open, and the project's test command runnable from a shell. If you do not have those, Lesson 1 (Dev Environment) is where they live.
Check yourself
3 questions. Answer before you reveal — recognising the right option is not the same as being able to produce it.
-
An agent rewrote a function and renamed it in the file, but three other files still call the old name and now fail to build. Which tool is designed for exactly this?
Show answer
B. Rename-everywhere (F2 in VS Code), which updates every reference structurally
Rename-everywhere understands scope — it changes the declaration and each reference, and it won't touch a same-named string or a different symbol. Find-and-replace changes text, so it will happily corrupt something that merely looks identical.
-
An agent's change touches 14 files and you can't tell if 3 of them are wrong. What is the fastest honest way to judge it?
Show answer
B.
git diff --statfirst to see the shape, thengit diffper suspicious file--statshows how many lines moved per file in one screen — that tells you where the risk is before you read a single line of content. Then narrow to the files that look wrong. Option A works but scales badly; option D answers a question you didn't ask. -
Why does this lesson teach
git stash pushinstead ofgit checkout -- filefor rejecting an agent's bad edit?Show answer
A.
checkoutdeletes the change permanently; the stash keeps it recoverable so you can still read what the agent triedgit checkout -- filethrows the working-tree version away — including the good half of an edit you might want. The stash is a commit off-branch: your file returns to its committed state and nothing is lost. You can read it withgit stash show -p stash@{0}and bring it back withgit stash pop.