skip to content

Code Completion

How inline completion actually works — what context it can see, why multi-line suggestions drift, and the latency-versus-accuracy trade-off in tools like Copilot and Cursor. Interviewers ask because knowing what the model can and cannot see explains most bad suggestions.

part ofAI-assisted developmentoverview, primer and where to startread it →
on this pageshow

questions

5

When an inline completer proposes the next line, what material has it actually seen?

level: juniorimportance: must knowfreq 70%

answer

  1. A bounded slice of text
  2. Ask what it had in view
  3. Both sides of the cursor
  4. Plus fragments you did not choose
  5. Outside the slice, outside the answer

basics

~20 s

An inline completer sees a bounded slice of text - the code on both sides of your cursor, plus fragments of other files the editor adds - and nothing else. Most bad suggestions are explained by what fell outside that slice.

solid answer

~40 s

Think of it as a request assembled for you, in the moment you paused. It carries the text before your cursor and usually the text after it, both cut to fit a size budget, plus whatever else the tool decided to add - commonly fragments of files you have open, or ones it retrieved because they resemble the code you are writing. Which fragments, and how they are picked, differs per tool and changes; that the request is bounded does not. Anything not in it was not available for that suggestion: not the ticket, not a convention written down elsewhere in the repository, not a function nobody opened. So when a suggestion is wrong, the first question is not *why did the model reason badly* but *was the deciding fact even in view*.

code

pseudocode · 15 lines
pseudocode
# everything the completer had, for this one suggestion:
#   [a] this file, from the top down to the cursor
#   [b] this file, from the cursor down
#   [c] fragments of other files the editor chose to add - you did not pick them
# nothing else in the service was in [a]-[c].

function listOrdersPage(customerId, pageToken):
    |<- cursor

# suggested:
    return orders.findPage(customerId, pageToken)

# NOT in [a]-[c], and either one would have changed the suggestion:
#   orders.findPage(customerId, cursor, limit)  - three arguments, defined one file away
#   every other handler here returns a page record, never a raw row list

go deeper

for a junior

Be able to say that a completer works from a bounded slice of text around your cursor plus whatever else the editor adds, and that nothing outside it reached the model. That one fact explains most surprising suggestions.

for a middle

Explain the layers and what each contributes: the text above the cursor supplies names and style, the text below constrains what your line has to lead to, and added fragments come from files you did not choose. Then map a wrong suggestion onto a gap.

for a senior

Show that you diagnose in that order on real work - establish what was in view before concluding anything about the model - and that you arrange the work so the material a suggestion needs is near it, rather than complaining the tool did not go and find it.

for a principal

Own the consequence for where the team writes things down: a rule recorded only in a document that nothing opens is invisible to a tool reading code, however clearly it is written. Where a convention is recorded changes which tools can honour it.

## What an inline completer is actually being asked You pause. The editor assembles a request on your behalf, a model continues the text, and the continuation appears where you were about to type. The important word is **assembled**: you did not choose what went into that request, you were not shown it, and it was built to a size budget in the time your pause allowed. Almost every other property of inline completion follows from that one sentence. This topic's own charter names GitHub Copilot and Cursor. This answer deliberately says nothing about what either does today - those details are product-specific, they change, and what follows is about the shape, which changes far more slowly. ## The layers of what it has | layer | what it is | who chose it | what its absence explains | |---|---|---|---| | **prefix** | this file, from the top down to your cursor | the tool, cutting to a budget | a suggestion that ignores something declared far above | | **suffix** | this file, from your cursor down | the tool | a suggestion that does not lead to what the rest of the function needs | | **added fragments** | pieces of other files - commonly ones open in the editor, or ones retrieved because they resemble the code at the cursor | the tool, not you | a suggestion that contradicts a signature or a convention defined elsewhere | | **nothing else** | - | - | everything that was never assembled into the request | The first two layers are the anchor. They are why a completer uses your local variable names and your indentation without being told, and why the suggestion at the top of an empty file is so much worse than the one on line two hundred. The third layer is the one people underestimate in both directions: it is why opening the right file sometimes visibly improves suggestions, and it is also why a suggestion can change from one minute to the next for no reason you can see. ## What is not in there unless something put it there - the ticket or issue you are working from; - a convention recorded in a document nobody opened; - a decision taken in a conversation last week; - the body of a function in a file that was never in view; - what the tests assert about the thing you are writing; - how the program actually behaves when it runs. None of that is a limitation of the model. It is a description of the request. ## Reading a bad suggestion backwards 1. **Was the deciding fact in the request at all?** If the signature it got wrong lives one file away and nothing opened that file, stop - there is nothing to explain about reasoning. 2. **If it was in this file, where?** Material far above the cursor is the first thing a budget cuts. Material below the cursor is available, but a continuation is being written forward from where you stand. 3. **Only then ask whether it reasoned badly** about material it demonstrably had. Knowing a fact was in view does not prove it was used, so step 3 is a real step and not a formality. The value of the order is that the cheap check comes first, and on this subject the cheap check is usually where the answer is. Not every disappointing suggestion is a context gap - a model can produce something poor from a perfectly adequate request. But the context gaps are the class you can do something about, which is why they are worth ruling in or out first. ## Two ecosystems, two amounts inferable How much a completer can get right about a call site it was never shown depends partly on the ecosystem you are in. In a **statically-typed** one, the editor can often supply an exact signature for a symbol whose body was never in view, and a call that does not match is rejected before the code runs - so there is both more to go on and less room for a mismatch to stay quiet. In a **dynamically-typed** one there is frequently less that can be handed over about a symbol, and less that rejects a mismatch until the line executes. Same completer, same discipline; a different amount of the answer is knowable without the definition in front of it. ## Answering this in an interview Describe the shape rather than the product: a bounded request, assembled for you, made of the text around your cursor plus fragments the tool chose. Then give one concrete case - a suggestion that was wrong because the thing deciding it was one file away - and say what you checked first. The sentence carrying this whole subject is *what it could see determines what it could get right*, and it lands far harder with an example attached to it.

  • Two developers at the same cursor in the same file get different suggestions. What could differ?
    What each request carried. Different files open, different recent edits, a longer file cut at a different point, and the tool's own variation between runs. The visible file is not necessarily the whole of what was sent, so an identical cursor does not mean an identical request.
  • A suggestion improved after you opened the file it needed. What does that tell you, and what does it not?
    It tells you the deciding material was outside the request and is now inside it - a context gap rather than a reasoning failure. It does not tell you the new suggestion is right, and it does not promise the same file will be picked up next time. You still read it against the code.

saying these in an interview costs you the question

  • Assumes the completer has the whole repository in view
  • Explains every wrong suggestion as the model being bad at code
  • Believes the completer knows which ticket you are working from
  • Treats a suggested call as evidence that the call is right here
  • Never asks what was outside the window before blaming the tool
open as a page

You accept an inline suggestion with one keystroke - what can you actually check in that moment?

level: middleimportance: should knowfreq 50%

basics

~20 s

Enough to triage, not to review: whether it does what you were about to write, and whether its names exist here. Anything you cannot settle in that moment should be rejected rather than accepted to check later.

open as a page

Why does a multi-line completion get less trustworthy toward its last line than its first?

level: middleimportance: should knowfreq 55%

basics

~20 s

The first line continues code you wrote and can inspect; every line after it mostly continues text the tool just produced and nobody has checked. One early wrong assumption is then carried, consistently, by everything below it.

open as a page

In a service you joined last week, where should you check an inline completer's suggestions hardest?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Wherever this service departs from the widespread way of doing something. A continuation follows shapes that recur, so on your unusual code the recurring shape is the wrong one - and it reads as entirely reasonable to anyone new here.

open as a page

An inline completer must answer in the pause between keystrokes - what does that deadline cost?

level: middleimportance: nice to knowfreq 35%

basics

~20 s

Your typing sets the deadline, not the tool: a suggestion that arrives after you wrote the line is worthless however good it is. Everything done to meet that deadline narrows what the suggestion could account for.

open as a page