Restore viewport context when no selection (#231804)

Was including the full file, after the implicit context widget was added. This sends a Location as the reference value for the current viewport.
This commit is contained in:
Rob Lourens
2024-10-20 19:38:14 -07:00
committed by GitHub
parent 235982f240
commit 05ff1fda3c
3 changed files with 49 additions and 13 deletions
@@ -41,7 +41,7 @@ export class ImplicitContextAttachmentWidget extends Disposable {
this.domNode.classList.toggle('disabled', !this.attachment.enabled);
const label = this.resourceLabels.create(this.domNode, { supportIcons: true });
const file = URI.isUri(this.attachment.value) ? this.attachment.value : this.attachment.value!.uri;
const range = URI.isUri(this.attachment.value) ? undefined : this.attachment.value!.range;
const range = URI.isUri(this.attachment.value) || !this.attachment.isSelection ? undefined : this.attachment.value!.range;
const fileBasename = basename(file);
const fileDirname = dirname(file);
@@ -34,6 +34,7 @@ export class ChatImplicitContextContribution extends Disposable implements IWork
if (codeEditor) {
activeEditorDisposables.add(codeEditor.onDidChangeModel(() => this.updateImplicitContext()));
activeEditorDisposables.add(Event.debounce(codeEditor.onDidChangeCursorSelection, () => undefined, 500)(() => this.updateImplicitContext()));
activeEditorDisposables.add(Event.debounce(codeEditor.onDidScrollChange, () => undefined, 500)(() => this.updateImplicitContext()));
}
this.updateImplicitContext();
@@ -45,21 +46,51 @@ export class ChatImplicitContextContribution extends Disposable implements IWork
const codeEditor = this.codeEditorService.getActiveCodeEditor();
const model = codeEditor?.getModel();
const selection = codeEditor?.getSelection();
const newValue = model ?
(selection && !selection?.isEmpty() ? { uri: model.uri, range: selection } satisfies Location : model.uri) :
undefined;
let newValue: Location | URI | undefined;
let isSelection = false;
if (model) {
if (selection && !selection.isEmpty()) {
newValue = { uri: model.uri, range: selection } satisfies Location;
isSelection = true;
} else {
const visibleRanges = codeEditor?.getVisibleRanges();
if (visibleRanges && visibleRanges.length > 0) {
// Merge visible ranges. Maybe the reference value could actually be an array of Locations?
// Something like a Location with an array of Ranges?
let range = visibleRanges[0];
visibleRanges.slice(1).forEach(r => {
range = range.plusRange(r);
});
newValue = { uri: model.uri, range } satisfies Location;
} else {
newValue = model.uri;
}
}
}
const widgets = updateWidget ? [updateWidget] : this.chatWidgetService.getAllWidgets(ChatAgentLocation.Panel);
for (const widget of widgets) {
if (widget.input.implicitContext) {
widget.input.implicitContext.value = newValue;
widget.input.implicitContext.setValue(newValue, isSelection);
}
}
}
}
export class ChatImplicitContext extends Disposable implements IChatRequestImplicitVariableEntry {
readonly id = 'vscode.implicit';
get id() {
if (URI.isUri(this.value)) {
return 'vscode.implicit.file';
} else if (this.value) {
if (this._isSelection) {
return 'vscode.implicit.selection';
} else {
return 'vscode.implicit.viewport';
}
} else {
return 'vscode.implicit';
}
}
get name(): string {
if (URI.isUri(this.value)) {
@@ -76,14 +107,22 @@ export class ChatImplicitContext extends Disposable implements IChatRequestImpli
get modelDescription(): string {
if (URI.isUri(this.value)) {
return `User's active file`;
} else {
} else if (this._isSelection) {
return `User's active selection`;
} else {
return `User's current visible code`;
}
}
// TODO@roblourens
readonly isDynamic = true;
readonly isFile = true;
private _isSelection = false;
public get isSelection(): boolean {
return this._isSelection;
}
private _onDidChangeValue = new Emitter<void>();
readonly onDidChangeValue = this._onDidChangeValue.event;
@@ -92,11 +131,6 @@ export class ChatImplicitContext extends Disposable implements IChatRequestImpli
return this._value;
}
set value(value: Location | URI | undefined) {
this._value = value;
this._onDidChangeValue.fire();
}
private _enabled = true;
get enabled() {
return this._enabled;
@@ -112,8 +146,9 @@ export class ChatImplicitContext extends Disposable implements IChatRequestImpli
this._value = value;
}
setValue(value: Location | URI) {
setValue(value: Location | URI | undefined, isSelection: boolean) {
this._value = value;
this._isSelection = isSelection;
this._onDidChangeValue.fire();
}
@@ -49,6 +49,7 @@ export interface IBaseChatRequestVariableEntry {
export interface IChatRequestImplicitVariableEntry extends Omit<IBaseChatRequestVariableEntry, 'kind'> {
readonly kind: 'implicit';
readonly value: URI | Location | undefined;
readonly isSelection: boolean;
enabled: boolean;
}