Skip to content

Commit

Permalink
support web links as context
Browse files Browse the repository at this point in the history
  • Loading branch information
benibenj committed Jan 7, 2025
1 parent 2bdb3e9 commit fee3f74
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/vs/editor/contrib/links/browser/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ export class LinkDetector extends Disposable implements IEditorContribution {
return null;
}

public getAllLinkOccurrences(): LinkOccurrence[] {
return Object.values(this.currentOccurrences);
}

private isEnabled(mouseEvent: ClickLinkMouseEvent, withKey?: ClickLinkKeyboardEvent | null): boolean {
return Boolean(
(mouseEvent.target.type === MouseTargetType.CONTENT_TEXT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as dom from '../../../../../base/browser/dom.js';
import { StandardMouseEvent } from '../../../../../base/browser/mouseEvent.js';
import { IManagedHoverTooltipMarkdownString } from '../../../../../base/browser/ui/hover/hover.js';
import { createInstantHoverDelegate } from '../../../../../base/browser/ui/hover/hoverDelegateFactory.js';
import { Codicon } from '../../../../../base/common/codicons.js';
import { Emitter } from '../../../../../base/common/event.js';
import { Disposable, DisposableStore, IDisposable } from '../../../../../base/common/lifecycle.js';
import { basename, dirname } from '../../../../../base/common/path.js';
Expand Down Expand Up @@ -38,7 +39,7 @@ import { fillEditorsDragData } from '../../../../browser/dnd.js';
import { ResourceLabels } from '../../../../browser/labels.js';
import { ResourceContextKey } from '../../../../common/contextkeys.js';
import { revealInSideBarCommand } from '../../../files/browser/fileActions.contribution.js';
import { IChatRequestVariableEntry, isPasteVariableEntry } from '../../common/chatModel.js';
import { IChatRequestVariableEntry, isLinkVariableEntry, isPasteVariableEntry } from '../../common/chatModel.js';
import { ChatResponseReferencePartStatusKind, IChatContentReference } from '../../common/chatService.js';

export const chatAttachmentResourceContextKey = new RawContextKey<string>('chatAttachmentResource', undefined, { type: 'URI', description: localize('resource', "The full value of the chat attachment resource, including scheme and path") });
Expand Down Expand Up @@ -185,6 +186,10 @@ export class ChatAttachmentsContentPart extends Disposable {
this.attachedContextDisposables.add(this.instantiationService.invokeFunction(accessor => hookUpResourceAttachmentDragAndContextMenu(accessor, widget, resource)));
}
}
} else if (isLinkVariableEntry(attachment)) {
ariaLabel = localize('chat.attachment.link', "Attached link, {0}", attachment.name);

label.setResource({ resource: attachment.value, name: attachment.name }, { icon: Codicon.link, title: attachment.value.toString() });
} else {
const attachmentLabel = attachment.fullName ?? attachment.name;
const withIcon = attachment.icon?.id ? `$(${attachment.icon.id}) ${attachmentLabel}` : attachmentLabel;
Expand Down
24 changes: 23 additions & 1 deletion src/vs/workbench/contrib/chat/browser/chatInputPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { CopyPasteController } from '../../../../editor/contrib/dropOrPasteInto/
import { DropIntoEditorController } from '../../../../editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.js';
import { ContentHoverController } from '../../../../editor/contrib/hover/browser/contentHoverController.js';
import { GlyphHoverController } from '../../../../editor/contrib/hover/browser/glyphHoverController.js';
import { LinkDetector } from '../../../../editor/contrib/links/browser/links.js';
import { SuggestController } from '../../../../editor/contrib/suggest/browser/suggestController.js';
import { localize } from '../../../../nls.js';
import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js';
Expand Down Expand Up @@ -158,6 +159,27 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
contextArr.push(this.implicitContext.toBaseEntry());
}

// retrieve links from the input editor
const linkOccurrences = this.inputEditor.getContribution<LinkDetector>(LinkDetector.ID)?.getAllLinkOccurrences() ?? [];
const linksSeen = new Set<string>();
for (const linkOccurrence of linkOccurrences) {
const link = linkOccurrence.link;
const uri = URI.isUri(link.url) ? link.url : link.url ? URI.parse(link.url) : undefined;
if (!uri || linksSeen.has(uri.toString())) {
continue;
}

linksSeen.add(uri.toString());
contextArr.push({
kind: 'link',
id: uri.toString(),
name: uri.fsPath,
value: uri,
isFile: false,
isDynamic: true,
});
}

// factor in nested file references into the implicit context
const variables = this.variableService.getDynamicVariables(sessionId);
for (const variable of variables) {
Expand Down Expand Up @@ -649,7 +671,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge

this._inputEditorElement = dom.append(editorContainer!, $(chatInputEditorContainerSelector));
const editorOptions = getSimpleCodeEditorWidgetOptions();
editorOptions.contributions?.push(...EditorExtensionsRegistry.getSomeEditorContributions([ContentHoverController.ID, GlyphHoverController.ID, CopyPasteController.ID]));
editorOptions.contributions?.push(...EditorExtensionsRegistry.getSomeEditorContributions([ContentHoverController.ID, GlyphHoverController.ID, CopyPasteController.ID, LinkDetector.ID]));
this._inputEditor = this._register(scopedInstantiationService.createInstance(CodeEditorWidget, this._inputEditorElement, options, editorOptions));
SuggestController.get(this._inputEditor)?.forceRenderingAbove();

Expand Down
12 changes: 11 additions & 1 deletion src/vs/workbench/contrib/chat/common/chatModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,13 @@ export interface ICommandResultVariableEntry extends Omit<IBaseChatRequestVariab
readonly isDynamic: true;
}

export type IChatRequestVariableEntry = IChatRequestImplicitVariableEntry | IChatRequestPasteVariableEntry | ISymbolVariableEntry | ICommandResultVariableEntry | IBaseChatRequestVariableEntry;
export interface ILinkVariableEntry extends Omit<IBaseChatRequestVariableEntry, 'kind'> {
readonly kind: 'link';
readonly isDynamic: true;
readonly value: URI;
}

export type IChatRequestVariableEntry = IChatRequestImplicitVariableEntry | IChatRequestPasteVariableEntry | ISymbolVariableEntry | ICommandResultVariableEntry | ILinkVariableEntry | IBaseChatRequestVariableEntry;

export function isImplicitVariableEntry(obj: IChatRequestVariableEntry): obj is IChatRequestImplicitVariableEntry {
return obj.kind === 'implicit';
Expand All @@ -95,6 +101,10 @@ export function isPasteVariableEntry(obj: IChatRequestVariableEntry): obj is ICh
return obj.kind === 'paste';
}

export function isLinkVariableEntry(obj: IChatRequestVariableEntry): obj is ILinkVariableEntry {
return obj.kind === 'link';
}

export function isChatRequestVariableEntry(obj: unknown): obj is IChatRequestVariableEntry {
const entry = obj as IChatRequestVariableEntry;
return typeof entry === 'object' &&
Expand Down

0 comments on commit fee3f74

Please sign in to comment.