Skip to content

Conversation

@pierceboggan
Copy link
Contributor

@.mov

Copy link
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

Extends chat input completions so @ can trigger the same “context reference” completions as #.

Changes:

  • Broadened completion word patterns and trigger characters to include @ in addition to #.
  • Adjusted filtering/matching to consider the typed leader and (in some cases) match against both basename and URI label.
  • Added pattern-based filtering for tool completions when a leader-prefixed prefix is present.

return {
label: { label: basename, description: labelDescription },
filterText: `${chatVariableLeader}${basename}`,
filterText: `${basename} ${typedLeader}${basename} ${uriLabel}`,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

uriLabel is referenced in filterText but is not defined in this scope, which will cause a TypeScript compile error. Use labelDescription (already computed) or introduce a const uriLabel = this.labelService.getUriLabel(resource, { relative: true }); before constructing the completion item.

Suggested change
filterText: `${basename} ${typedLeader}${basename} ${uriLabel}`,
filterText: `${basename} ${typedLeader}${basename} ${labelDescription}`,

Copilot uses AI. Check for mistakes.
Comment on lines +854 to 856
const typedLeader = range.varWord?.word?.charAt(0) === chatAgentLeader ? chatAgentLeader : chatVariableLeader;
const basename = this.labelService.getUriBasenameLabel(currentResource);
const text = `${chatVariableLeader}file:${basename}:${currentSelection.startLineNumber}-${currentSelection.endLineNumber}`;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

When the user types @, filterText is adjusted to @… but the inserted text (text) and the displayed label still hardcode chatVariableLeader (#). This makes @ behave differently from # (and contradicts the PR intent of “just like #”). Consider building text and label with typedLeader so the completion both matches and inserts using the leader the user typed.

See below for a potential fix:

			const text = `${typedLeader}file:${basename}:${currentSelection.startLineNumber}-${currentSelection.endLineNumber}`;
			const fullRangeText = `:${currentSelection.startLineNumber}:${currentSelection.startColumn}-${currentSelection.endLineNumber}:${currentSelection.endColumn}`;
			const description = this.labelService.getUriLabel(currentResource, { relative: true }) + fullRangeText;

			const result: CompletionList = { suggestions: [] };
			result.suggestions.push({
				label: { label: `${typedLeader}selection`, description },

Copilot uses AI. Check for mistakes.
Comment on lines 862 to 864
label: { label: `${chatVariableLeader}selection`, description },
filterText: `${chatVariableLeader}selection`,
filterText: `${typedLeader}selection`,
insertText: range.varWord?.endColumn === range.replace.endColumn ? `${text} ` : text,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

When the user types @, filterText is adjusted to @… but the inserted text (text) and the displayed label still hardcode chatVariableLeader (#). This makes @ behave differently from # (and contradicts the PR intent of “just like #”). Consider building text and label with typedLeader so the completion both matches and inserts using the leader the user typed.

See below for a potential fix:

			const text = `${typedLeader}file:${basename}:${currentSelection.startLineNumber}-${currentSelection.endLineNumber}`;
			const fullRangeText = `:${currentSelection.startLineNumber}:${currentSelection.startColumn}-${currentSelection.endLineNumber}:${currentSelection.endColumn}`;
			const description = this.labelService.getUriLabel(currentResource, { relative: true }) + fullRangeText;

			const result: CompletionList = { suggestions: [] };
			result.suggestions.push({
				label: { label: `${typedLeader}selection`, description },

Copilot uses AI. Check for mistakes.
const typedLeader = info.varWord?.word?.charAt(0) === chatAgentLeader ? chatAgentLeader : chatVariableLeader;

const makeSymbolCompletionItem = (symbolItem: { name: string; location: Location; kind: SymbolKind }, pattern: string): CompletionItem => {
const text = `${chatVariableLeader}sym:${symbolItem.name}`;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Similar to the selection completion: filterText uses typedLeader, but the inserted text always uses chatVariableLeader (#). If @sym:… is intended to be a first-class equivalent to #sym:…, text should be derived from typedLeader (or, alternatively, keep filterText aligned with the inserted leader).

Suggested change
const text = `${chatVariableLeader}sym:${symbolItem.name}`;
const text = `${typedLeader}sym:${symbolItem.name}`;

Copilot uses AI. Check for mistakes.
Comment on lines 1058 to 1060
label: { label: symbolItem.name, description: uriLabel },
filterText: `${chatVariableLeader}${symbolItem.name}`,
filterText: `${typedLeader}${symbolItem.name}`,
insertText: info.varWord?.endColumn === info.replace.endColumn ? `${text} ` : text,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Similar to the selection completion: filterText uses typedLeader, but the inserted text always uses chatVariableLeader (#). If @sym:… is intended to be a first-class equivalent to #sym:…, text should be derived from typedLeader (or, alternatively, keep filterText aligned with the inserted leader).

Copilot uses AI. Check for mistakes.
Comment on lines 1254 to 1262
const withLeader = `${chatVariableLeader}${name}`;
suggestions.push({
label: withLeader,
range,
detail,
documentation,
filterText: `${typedLeader}${name}`,
insertText: withLeader + ' ',
kind: CompletionItemKind.Tool,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Tool completions will still insert #toolName even when triggered by @, because withLeader is always built from chatVariableLeader. To make @ behave “just like #”, compute withLeader using typedLeader (and consider also updating label so the UI matches what will be inserted).

Copilot uses AI. Check for mistakes.
class BuiltinDynamicCompletions extends Disposable {
private static readonly addReferenceCommand = '_addReferenceCmd';
private static readonly VariableNameDef = new RegExp(`${chatVariableLeader}[\\w:-]*`, 'g'); // MUST be using `g`-flag
private static readonly VariableNameDef = new RegExp(`[${chatVariableLeader}${chatAgentLeader}][\\w:-]*`, 'g'); // MUST be using `g`-flag
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Building a character class via interpolation can become fragile if either leader ever changes to a regex-special character inside [] (e.g. -, ], ^, \). Consider escaping the leaders before interpolating them into the regex to keep this robust.

See below for a potential fix:

function escapeForCharClass(text: string): string {
	return text.replace(/[-\\\]^]/g, '\\$&');
}

class BuiltinDynamicCompletions extends Disposable {
	private static readonly addReferenceCommand = '_addReferenceCmd';
	private static readonly VariableNameDef = new RegExp(`[${escapeForCharClass(chatVariableLeader)}${escapeForCharClass(chatAgentLeader)}][\\w:-]*`, 'g'); // MUST be using `g`-flag

Copilot uses AI. Check for mistakes.
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.

1 participant