Vibe Coding · Editors & Agents
Cursor: the editor as conversation
An editor where chat is a first-class citizen and inline edits replace the autocomplete stream.
Cursor's bet was simple: rebuild the editor around the LLM instead of bolting it on. Two years in, the bet has paid off. Inline edits and chat-with-codebase are the killer features; the rest is keyboard polish.
I switched from VS Code to Cursor full-time in 2025, kept the same extensions, kept the same theme, kept the same keybinds. What changed is how I move through code.
The mental model shift#
I no longer think in autocomplete. I think in targeted edits: select a span, describe the change, accept the diff. It's closer to dictating to a copy editor than typing.
Concretely, the move that replaced 80% of my keystrokes:
Ctrl+Lopens the chat panel with the current selection auto-attached- Describe the change in plain English
- Diff appears inline;
Ctrl+Yaccepts it
For most edits — converting a callback to async/await, extracting a helper, swapping a logger — that's faster than typing it. The model produces a syntactically clean diff; I read it, accept, move on.
The features I actually use#
After dropping the ones I tried-and-abandoned, here's the daily kit:
Tab for predictive cursor jumps#
When you make an edit, Cursor predicts where you'll move next — usually the next instance of a renamed symbol, or the next callsite — and shows a ghost cursor. Press Tab to jump there. Press it again to make the same edit.
It sounds gimmicky. After a week, it's the feature I miss most when pairing in plain VS Code.
@-mention to attach files to chat#
@filename in the chat panel pulls that file into context. @folder/ pulls the whole folder. @web does a search. @docs for library documentation.
The big unlock: you can attach a test file and a failing run output, then ask "what's wrong with the implementation?" The model reads both and proposes a fix grounded in the actual failure, not a hallucinated one.
@src/services/billing.py @tests/test_billing.py @run_output.log
The test test_prorated_refund is failing. Diagnose and propose a fix.Composer mode for multi-file changes#
Ctrl+I opens Composer, which is essentially Claude Code rebadged inside the editor. You describe a multi-file change, watch it propose edits across files, accept or reject each.
I use Composer for any change touching ≥3 files. Below that, inline edit is faster.
The features I dropped#
Honest list of things that didn't survive my workflow:
- Auto-debug. Conceptually nice; in practice I read the stack trace faster myself.
- Full-codebase chat without
@-mentions. The relevance of the auto-pulled context is still hit-or-miss; explicit@references give me predictable behavior. - Background agent for long tasks. I prefer Claude Code's CLI for those — better progress visibility.
A real workflow: porting a Python module to Rust#
I had a Python module doing JSON-line processing, ~600 lines, single file, well-tested. Wanted a Rust port for the speed.
The flow that worked:
@module.py @tests/test_module.pyin chat- "Port this to idiomatic Rust. Use
serde_json::Valuefor the dynamic shape. Match the test cases attests/test_module.pyline-for-line. Output a single-file Rust module + a Cargo.toml." - Got a working first cut in ~30 seconds
- Ran the tests — 38/40 passed
- Pasted the 2 failing test outputs back in: "these two are failing, here's the output, fix"
- Got it to 40/40 in two more iterations
Total time: 12 minutes for a port that would have taken me 4–6 hours hand-typed. The savings weren't in the typing — they were in not having to re-derive things like "how does serde_json represent a missing-vs-null field?"
The keyboard discipline#
A trap I see new Cursor users fall into: they type their thought into the chat, then also type the same thing into the editor. Pick one. Either you're driving the keyboard or you're driving the model. Switching every line wastes both.
My rule of thumb:
- Trivial edit (< 5 lines, mechanical): type it
- Multi-line edit with logic:
Ctrl+L, describe, accept - Multi-file edit: `Ctrl+I\