Cursor inline edit: tips 46–60
PLCursor’s inline edit rewrites the selected code from a short natural-language instruction, or inserts new code at the cursor when nothing is selected. The selection sets the boundary of the change, so its scope decides the result as much as the wording does. Inline edit suits changes inside one file that a type check or a focused test can confirm.
This page is for developers who already use Cursor’s agent and Tab but get coin-flip results from inline edit. You select a 60-line function, type “make this better”, and get back a rewrite that renamed two variables, dropped a guard clause and added an import you never use. Then you read the whole diff line by line, which is slower than typing the change yourself. The fix is a tighter selection, an instruction that names one transformation and its limits, and a gate that checks the result for you.
What you’ll walk away with from inline edit
Section titled “What you’ll walk away with from inline edit”- A selection table that maps what you select to what inline edit may change and to the check that ends the edit.
- Seven copy-paste inline edit instructions: generate a helper, match a pattern in the file, convert a structure, add error handling, convert JavaScript to strict TypeScript, extract magic values, and write tests.
- A chaining routine for refactors: pin behaviour with a test, make one transformation per edit, and run a gate between edits.
- A four-signal check that confirms an inline edit without reading every line, and a table for when to switch to the agent.
How does the selection shape an inline edit?
Section titled “How does the selection shape an inline edit?”Tip 46: Match the selection to the change you want
Section titled “Tip 46: Match the selection to the change you want”Inline edit treats the selection as its boundary: it rewrites what you selected and leaves the rest of the file alone. A selection that is larger than the change invites edits you did not ask for. A selection that is smaller than the change produces code that no longer fits its surroundings.
| What you select | What inline edit changes | Good for | The check that ends it |
|---|---|---|---|
| Nothing (cursor on an empty line) | Inserts new code at the cursor | A helper, a type, a small block described in a short instruction | Type check, then a test that calls it |
| One or two lines | Those lines | A condition, a return value, a single expression | Your own read of the lines, then the type checker |
| One whole function | The function body, and the signature only if you allow it | Error handling, a structural conversion, input validation | The function’s unit tests |
| Several related functions | All of them as one unit | The same change applied consistently, such as adding logging to three handlers | Tests for each function, plus git diff --stat showing one file |
Select the smallest block that contains every line that must change. To change two lines in a 60-line function, select those two lines, not the function.
Tip 47: Put the context in the selection or in the instruction
Section titled “Tip 47: Put the context in the selection or in the instruction”In practice inline edit works from the selection and the file around it. It does not reliably open a type or helper that lives in another file, so it guesses the shape and the guess compiles only by luck.
When the type sits in the same file, extend the selection upward to include it:
// Select both the type and the function, then run inline edit.type UserRole = 'admin' | 'editor' | 'viewer';
function getPermissions(role: UserRole): Permission[] { // ...}When the type lives elsewhere, state its shape in the instruction: “User has id: string, email: string and role: UserRole.” If the change needs more than two such facts, the change spans files, and Tip 60 applies.
Tip 48: Generate at an empty line for small, self-contained code
Section titled “Tip 48: Generate at an empty line for small, self-contained code”With the cursor on an empty line and nothing selected, inline edit writes new code at that position. It is lighter than opening the agent for a block you can describe in a short instruction. Treat inline edit as writing only at the cursor or inside the selection; creating files, editing other files and running commands are the agent’s job.
Then write, or ask the agent to write, a test with fake timers that proves a second call within waitMs cancels the first. A generated helper with no test is unverified code.
How do you write an inline edit instruction that lands the first time?
Section titled “How do you write an inline edit instruction that lands the first time?”Tip 49: Name one transformation and what must not change
Section titled “Tip 49: Name one transformation and what must not change”Name the transformation, then name the invariants. The invariants stop the rewrite from spreading beyond the change you asked for.
| Vague | Specific |
|---|---|
| “Make this better” | “Return early for null, undefined and the empty string, throwing a TypeError that names the parameter. Do not change the success path.” |
| “Optimise” | “Replace the nested loops with a Set lookup so the function is linear in the input size. Keep the output order unchanged.” |
| “Fix the types” | “Add explicit types to every parameter and the return value. No any. Keep the function signature’s parameter order.” |
A useful default ending for any instruction is “Do not change the signature, the return type or any line outside the selection.”
Tip 50: Point at a pattern that already exists in the file
Section titled “Tip 50: Point at a pattern that already exists in the file”When the same file already shows the pattern you want, name it. Inline edit can read the rest of the file, so a named example beats a paragraph describing the pattern.
If the pattern lives in another file, copy a short example of it into the instruction. A project rule does not reach inline edit: Cursor’s help says rules apply to Agent (Chat) only, not to Tab completion, Inline Edit or Bugbot PR reviews (checked 2026-10-12).
Tip 51: Use “convert X to Y” for structural changes
Section titled “Tip 51: Use “convert X to Y” for structural changes”A conversion gives inline edit a clear before and after, so it is the most dependable shape of instruction: callbacks to async/await, a switch to a lookup object, a class component to a function component with hooks, or a loop to map and filter. Always add the behaviour that must survive the conversion.
After the conversion, update the callers. They sit outside the selection, so this is the point where the agent, not inline edit, takes over.
How do you chain inline edits through a refactor?
Section titled “How do you chain inline edits through a refactor?”Tip 52: Pin the behaviour with a test before the first edit
Section titled “Tip 52: Pin the behaviour with a test before the first edit”A chain of rewrites is only safe when something tells you behaviour did not move. For code without tests, ask the agent for characterization tests that record what the function does today, including the odd cases, before you touch it. Characterization tests covers the technique in depth.
These tests are your oracle for the whole chain. If an edit turns them red, the edit changed behaviour. Reject it rather than edit the test.
Tip 53: Make one transformation per edit, with a gate between edits
Section titled “Tip 53: Make one transformation per edit, with a gate between edits”A single instruction to “add types, validation and error handling” produces one large diff that you can only check by reading it. Three edits produce three small diffs, each checked by a command.
- Select the function and run inline edit: “Add explicit types to every parameter and the return value. No
any.” - Gate:
npx tsc --noEmit. Accept only when it exits 0. - Run inline edit again: “Validate each parameter against the types above and throw a
TypeErrornaming the parameter.” - Gate:
npx vitest run src/billing/. The characterization tests must still pass unchanged. - Run inline edit again: “Wrap the database call in try/catch and rethrow as
AppError, preserving the cause.” - Gate: the same test run, plus
npx eslint src/billing/invoice.ts. - Commit. Each commit is then a checkpoint you can return to with Git, in addition to Cursor’s own checkpoints.
Order the chain so no step undoes an earlier one. “Add logging” followed by “remove all side effects” leaves incoherent code.
Tip 54: Finish the agent’s output with inline edit
Section titled “Tip 54: Finish the agent’s output with inline edit”The agent drafts a module quickly and misses house conventions in a few places. Fixing those places with inline edit is cheaper than another agent round-trip, because each fix is local and the rest of the draft stays put.
- Let the agent finish, and let its own gate (tests and type check) pass first.
- Select one function and run inline edit, for example: “Rename boolean parameters to start with
isorhas, and update their uses inside this function only.” - Select a
throw new Error(...)block and run inline edit: “ThrowAppErrorfrom@/lib/errorswith the same message and acodefield.” - Run the same gate the agent ran. A convention fix that breaks a test was not a convention fix.
Which transformations suit inline edit best?
Section titled “Which transformations suit inline edit best?”Tip 55: Add error handling to happy-path code
Section titled “Tip 55: Add error handling to happy-path code”Check it with a test that makes the fetch fail once and then succeed, and a test that returns malformed JSON.
Tip 56: Convert JavaScript to strict TypeScript
Section titled “Tip 56: Convert JavaScript to strict TypeScript”The gate is npx tsc --noEmit with strict on. A conversion that needs a new // @ts-expect-error hides a type problem rather than solving it; reject it.
Tip 57: Extract magic numbers and strings
Section titled “Tip 57: Extract magic numbers and strings”This edit changes no behaviour, so the existing tests must pass with no edits to the tests.
Tip 58: Write tests from the implementation, then prove they can fail
Section titled “Tip 58: Write tests from the implementation, then prove they can fail”Inline edit only writes where the cursor is, so run it at an empty line in the test file, not in the source file, and paste the function’s signature into the instruction so it knows what it is testing. Tests written from the implementation tend to assert what the code does, bugs included, so a passing run proves little until you see the tests fail.
Accept the tests, then break the function on purpose, for example by flipping a < to <=, and run the tests. At least one test must fail. Undo the break. A suite that stays green is decoration. Test-driven development in Cursor covers writing the tests first instead.
How do you check an inline edit without reading every line?
Section titled “How do you check an inline edit without reading every line?”Tip 59: Use a four-signal check before you accept
Section titled “Tip 59: Use a four-signal check before you accept”Inline edit proposes its change as a diff you accept or reject. Read the diff for its shape, not line by line, and let commands judge its content:
- Scope. The changed lines sit inside your selection. After you accept,
git diff --statlists one file with roughly the line count you expected (commit or stash first, or compare against the last commit, so the stat shows only this edit). Anything else means the selection or the instruction was too loose. - Removals and imports. Scan only the red lines and any new
import. A dropped guard clause or an unused import shows up here in seconds. - Types and lint.
npx tsc --noEmitandnpx eslint <file>exit 0. Keep the type checker in watch mode withnpx tsc --noEmit --watchso this signal arrives before you finish reading. - Behaviour. The tests for that module pass, and for a refactor, the characterization tests from Tip 52 pass unchanged.
You sign off the edit when all four are green and you commit it. The pull request adds a second gate: CI runs the full suite, and a reviewer or a review bot sees the combined diff. Reading evidence instead of code explains why this order of checks scales further than reading each diff.
Tip 60: Switch to the agent when the change leaves the selection
Section titled “Tip 60: Switch to the agent when the change leaves the selection”| Signal | Stay with inline edit | Switch to the agent |
|---|---|---|
| Files touched | One, inside a selection you can make | Two or more, or callers need updating |
| Context needed | In the selection, the same file, or two facts in the instruction | Types and helpers across the codebase |
| Proof | You run one command after accepting | The change needs a write, test and fix loop |
| Instruction length | One transformation plus its invariants, a short paragraph at most | Several transformations, or it reads like a plan |
When you switch, carry the same discipline into the prompt: the tests that define done and the commands that gate the result. Agent chat workflows in Cursor shows that prompt shape, and agent modes in Cursor covers when to plan first.
When Cursor inline edits go wrong
Section titled “When Cursor inline edits go wrong”| Symptom | Likely cause | Recovery |
|---|---|---|
| The rewrite changed more than you asked for | The selection was larger than the change, or the instruction had no invariants | Reject, select only the lines that must change, and add “Do not change anything else” |
| The code uses a type or field that does not exist | The type lives in another file | Reject, state the type’s shape in the instruction, or use the agent |
| The diff looks right but a test now fails | A behaviour change hidden in a refactor, often a reordered condition or a removed early return | Undo with the editor’s Undo command or git restore <file>, then split the edit into smaller steps |
| Generated tests all pass, even against broken code | The tests restate the implementation | Break the code on purpose; rewrite any test that stays green with specific expected values |
| Each edit in a chain undoes the last one | Contradictory steps | Revert to the last green commit and reorder the chain so every step builds on the previous one |
| The same convention needs fixing in every edit | The convention exists only in your head, or in a rule that inline edit does not read | Write it into a project rule for the agent, and paste a short example of it into each inline edit instruction (Cursor’s help says rules do not apply to Inline Edit, checked 2026-10-12) |
If you already accepted several edits and the tests are red, do not ask for a fix on top. Return to the last commit where the gate passed and repeat the chain in smaller steps.
Where to go next after inline edit
Section titled “Where to go next after inline edit”- Before this page: Cursor core features, tips 16–30, and Cursor Tab autocomplete, tips 31–45, which hands a Tab scaffold to inline edit.
- Next: agent chat workflows in Cursor, for changes that span files and need a write, test and fix loop.
- For larger restructurings: refactoring strategies in Cursor, and reusable instructions in Cursor prompt templates.
- If you also run Claude Code beside Cursor: IDE and CLI coordination shows how to keep inline edits and the CLI from writing the same file.