Skip to content

chat: enhance slash command completions and add tests for active file boosting#308742

Open
zuizuihao wants to merge 2 commits intomicrosoft:mainfrom
zuizuihao:SPG/copilot/issue-307605-chat-input-completions
Open

chat: enhance slash command completions and add tests for active file boosting#308742
zuizuihao wants to merge 2 commits intomicrosoft:mainfrom
zuizuihao:SPG/copilot/issue-307605-chat-input-completions

Conversation

@zuizuihao
Copy link
Copy Markdown

@zuizuihao zuizuihao commented Apr 9, 2026

Issue: #307605

Overview

When typing # in Copilot Chat (Agent mode), the currently active file appears near the bottom of
the suggestion list instead of at the top. The user has to scroll past unrelated files to find the
file they are already editing.

Where does this code live?

Although the GitHub issue was auto-tagged chat-ext-issue (a triage routing label), the actual
code responsible lives in the microsoft/vscode repo — not in a separate Copilot Chat
extension repo. Chat input completions were internalized into VS Code core:

src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletions.ts

That is why the fix goes here.

How to reproduce

  1. Open two or more files in the editor (e.g. foo.ts and bar.ts).
  2. Click on the Chat panel and make sure it gets focus (this causes the Chat editor to become
    the most-recently-activated editor, pushing your code files down the MRU list).
  3. Press Ctrl+1 (or click) to switch back to a code file — e.g. bar.ts — so it is now the
    active editor.
  4. Click back into the Copilot Chat input and type #.
  5. Observed: bar.ts is not at the top of the file suggestions; it may appear second, third,
    or not boosted at all.
  6. Expected: bar.ts should appear first, labeled "Active file".

The Chat panel interaction in step 2 is important: it inserts a vscode-chat-editor:// entry at
position 0 of the MRU history. Because that scheme is filtered out in the completion loop, the
boost intended for the active file never fires.

Original root cause

File: src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletions.ts
Class: BuiltinDynamicCompletions · Method: addFileAndFolderEntries

The method builds # file suggestions from editor MRU history. To boost the active file to the
top, it originally checked whether the history entry was at raw array index 0:

// before fix — inside the history loop
const newLen = result.suggestions.push(
    makeCompletionItem(
        item.resource,
        FileKind.FILE,
        i === 0 ? localize('activeFile', 'Active file') : undefined,
        i === 0   // boostPriority — sets sortText: ' ' (sorts above all others)
    )
);

IHistoryService.getHistory() returns the MRU editor history — not "the currently active editor."
Index 0 is just whichever editor was activated most recently, which is often the Chat panel itself.
The loop also filters out unsupported schemes (e.g. vscode-chat-editor://) before pushing
suggestions, so the boosted slot can be skipped entirely while a regular code file further down
the list gets no boost.

In short: the code used history array position as a proxy for active-editor identity, and that
proxy breaks the moment the Chat panel is focused.

Root cause

Bug 1 — i === 0 uses the raw history array index, not the filtered index

i comes from this.historyService.getHistory().entries(). When getHistory()[0] is a
vscode-chat-editor:// URI, it gets skipped by the isSupportedChatFileScheme filter — but
i is still 0 only for that skipped entry. The first valid file gets i === 1, so it is
never boosted.

Bug 2 — findActiveCodeEditor() returns the chat input editor

When the user clicks into the chat input, codeEditorService.getActiveCodeEditor() returns the
chat input editor (scheme vscode-chat-input). The method checks for vscodeNotebookCell but
not for vscodeChatInput, so it reports the chat input as the "active code editor" instead of
the file the user was editing.

Bug 3 — file filterText puts the # leader mid-string, so tools often outscore files

VS Code's suggest widget sorts by match score first, then falls back to initial ordering. In
practice, this means sortText only helps after the suggest model has already grouped items by
score. When # is typed:

  • Tool items have filterText: "#toolName"# matches at position 0 (prefix match, high score).
  • File items had filterText: "b.txt #b.txt /path"# matches at position 6
    (middle-of-string match, low score).

Because tools consistently scored higher, they tended to appear above files even when the active
file had sortText: ' '. The active-file boost still matters for ordering among similarly scored
file entries, but it cannot compensate for a worse filter match.

How these bugs were introduced

Event Details
PR #256738 (July 2025) Introduced the i === 0 heuristic to fix #256737. Assumed getHistory()[0] is always the active file.
Commit a2cf16dfac7e (Oct 2025) Added isSupportedChatFileScheme filtering in the same loop. Did not update the boost logic — now getHistory()[0] can be filtered out, leaving no file boosted.
Commit 6dffc1fcfae9 (Feb 2026) Expanded file filterText to include basename and path for better fuzzy matching, but moved the # leader away from the front of the string.
Commit 41d219f6c3da (Jan 2026) Removed explicit tool de-emphasis, so tools and files now compete on normal suggest ranking and match score matters more.

Fix

The current patch keeps the fix scoped to the active-file ranking problem while preserving the
broader file-matching improvements from February 2026:

  1. findActiveCodeEditor() — skip vscodeChatInput scheme (same as the existing
    vscodeNotebookCell skip), so the method falls back to the first visible file editor.
  2. addFileAndFolderEntries() — resolve activeResource from findActiveCodeEditor() before
    the loop. Inside the loop, compare each history entry to activeResource via isEqual() and
    boost the match.
  3. File filterText — keep the # leader at the start of the string while still including
    basename and relative path, e.g. #b.txt b.txt /path, so files remain easy to fuzzy-match by
    name/path without losing the prefix-score advantage when the user has typed only #.
  // findActiveCodeEditor — skip chat input editors
- if (model) {
+ if (model && model.uri.scheme !== Schemas.vscodeChatInput) {
      return codeEditor;
  }

  // file completion item — keep the leader at the front of filterText
- filterText: `${basename} ${typedLeader}${basename} ${uriLabel}`,
+ filterText: `${typedLeader}${basename} ${basename} ${uriLabel}`,

  // addFileAndFolderEntries — use real active editor, not history index
+ const activeResource = this.findActiveCodeEditor()?.getModel()?.uri;
  ...
- for (const [i, item] of this.historyService.getHistory().entries()) {
+ for (const item of this.historyService.getHistory()) {
      ...
-     makeCompletionItem(resource, ..., i === 0 ? 'Active file' : undefined, i === 0);
+     const isActiveFile = !!activeResource && isEqual(resource, activeResource);
+     makeCompletionItem(resource, ..., isActiveFile ? 'Active file' : undefined, isActiveFile);

Before Fix:
issue
after Fix:
fix

Copilot AI review requested due to automatic review settings April 9, 2026 10:13
@zuizuihao
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves chat input file reference completions by correctly identifying/boosting the active file and ensuring completion filtering behaves consistently with the typed leader (#/@). It also adds a focused browser test suite to prevent regressions in these behaviors.

Changes:

  • Update active-editor detection to ignore chat input editors and fall back to visible file editors.
  • Fix file completion filterText so the typed leader is kept at the front.
  • Add new tests covering active-file boosting, filterText leader placement, and “active editor is chat input” scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletions.ts Adjusts active editor detection and file completion metadata (boosting + filterText) to improve correctness of chat file completions.
src/vs/workbench/contrib/chat/test/browser/chatInputCompletions.test.ts Adds new browser tests validating active file boosting and filterText behavior for chat file completions.

@zuizuihao zuizuihao force-pushed the SPG/copilot/issue-307605-chat-input-completions branch from 834fd32 to 69e3dec Compare April 9, 2026 10:29
@zuizuihao
Copy link
Copy Markdown
Author

seems this issue is regression, this feature is introduced in #256737 , any insights @Tyriar @alexr00 ? it's painful without the active documents in the front, I used every day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show the active file as the first entry when typing # in chat

2 participants