mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-20 00:04:14 +08:00
feat: support attaching selection to chat editing view (#233021)
* feat: support attaching selection to chat editing view * feat: support attaching file to chat editing view
This commit is contained in:
parent
3c62ba9766
commit
49907c09c4
@ -45,7 +45,7 @@ import { IChatRequestVariableEntry } from '../../common/chatModel.js';
|
||||
import { ChatRequestAgentPart } from '../../common/chatParserTypes.js';
|
||||
import { IChatVariableData, IChatVariablesService } from '../../common/chatVariables.js';
|
||||
import { ILanguageModelToolsService } from '../../common/languageModelToolsService.js';
|
||||
import { IChatWidget, IChatWidgetService, IQuickChatService, showChatView } from '../chat.js';
|
||||
import { IChatWidget, IChatWidgetService, IQuickChatService, showChatView, showEditsView } from '../chat.js';
|
||||
import { imageToHash, isImage } from '../chatPasteProviders.js';
|
||||
import { isQuickChat } from '../chatWidget.js';
|
||||
import { convertBufferToScreenshotVariable, ScreenshotVariableId } from '../contrib/screenshot.js';
|
||||
@ -53,8 +53,10 @@ import { CHAT_CATEGORY } from './chatActions.js';
|
||||
|
||||
export function registerChatContextActions() {
|
||||
registerAction2(AttachContextAction);
|
||||
registerAction2(AttachFileAction);
|
||||
registerAction2(AttachSelectionAction);
|
||||
registerAction2(AttachFileToChatAction);
|
||||
registerAction2(AttachSelectionToChatAction);
|
||||
registerAction2(AttachFileToEditingSessionAction);
|
||||
registerAction2(AttachSelectionToEditingSessionAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,13 +161,13 @@ interface IScreenShotQuickPickItem extends IQuickPickItem {
|
||||
icon?: ThemeIcon;
|
||||
}
|
||||
|
||||
class AttachFileAction extends Action2 {
|
||||
class AttachFileToChatAction extends Action2 {
|
||||
|
||||
static readonly ID = 'workbench.action.chat.attachFile';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: AttachFileAction.ID,
|
||||
id: AttachFileToChatAction.ID,
|
||||
title: localize2('workbench.action.chat.attachFile.label', "Add File to Chat"),
|
||||
category: CHAT_CATEGORY,
|
||||
f1: false,
|
||||
@ -190,13 +192,13 @@ class AttachFileAction extends Action2 {
|
||||
}
|
||||
}
|
||||
|
||||
class AttachSelectionAction extends Action2 {
|
||||
class AttachSelectionToChatAction extends Action2 {
|
||||
|
||||
static readonly ID = 'workbench.action.chat.attachSelection';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: AttachSelectionAction.ID,
|
||||
id: AttachSelectionToChatAction.ID,
|
||||
title: localize2('workbench.action.chat.attachSelection.label', "Add Selection to Chat"),
|
||||
category: CHAT_CATEGORY,
|
||||
f1: false,
|
||||
@ -225,6 +227,72 @@ class AttachSelectionAction extends Action2 {
|
||||
}
|
||||
}
|
||||
|
||||
class AttachFileToEditingSessionAction extends Action2 {
|
||||
|
||||
static readonly ID = 'workbench.action.edits.attachFile';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: AttachFileToEditingSessionAction.ID,
|
||||
title: localize2('workbench.action.edits.attachFile.label', "Add File to {0}", 'Copilot Edits'),
|
||||
category: CHAT_CATEGORY,
|
||||
f1: false,
|
||||
precondition: ContextKeyExpr.and(ChatContextKeys.enabled, ActiveEditorContext.isEqualTo('workbench.editors.files.textFileEditor')),
|
||||
menu: {
|
||||
id: MenuId.ChatCommandCenter,
|
||||
group: 'a_chat',
|
||||
order: 11,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
override async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
|
||||
const variablesService = accessor.get(IChatVariablesService);
|
||||
const textEditorService = accessor.get(IEditorService);
|
||||
|
||||
const activeUri = textEditorService.activeEditor?.resource;
|
||||
if (textEditorService.activeTextEditorControl?.getEditorType() === EditorType.ICodeEditor && activeUri && [Schemas.file, Schemas.vscodeRemote, Schemas.untitled].includes(activeUri.scheme)) {
|
||||
(await showEditsView(accessor.get(IViewsService)))?.focusInput();
|
||||
variablesService.attachContext('file', activeUri, ChatAgentLocation.EditingSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AttachSelectionToEditingSessionAction extends Action2 {
|
||||
|
||||
static readonly ID = 'workbench.action.edits.attachSelection';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: AttachSelectionToEditingSessionAction.ID,
|
||||
title: localize2('workbench.action.edits.attachSelection.label', "Add Selection to {0}", 'Copilot Edits'),
|
||||
category: CHAT_CATEGORY,
|
||||
f1: false,
|
||||
precondition: ContextKeyExpr.and(ChatContextKeys.enabled, ActiveEditorContext.isEqualTo('workbench.editors.files.textFileEditor')),
|
||||
menu: {
|
||||
id: MenuId.ChatCommandCenter,
|
||||
group: 'a_chat',
|
||||
order: 12,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
override async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
|
||||
const variablesService = accessor.get(IChatVariablesService);
|
||||
const textEditorService = accessor.get(IEditorService);
|
||||
|
||||
const activeEditor = textEditorService.activeTextEditorControl;
|
||||
const activeUri = textEditorService.activeEditor?.resource;
|
||||
if (textEditorService.activeTextEditorControl?.getEditorType() === EditorType.ICodeEditor && activeUri && [Schemas.file, Schemas.vscodeRemote, Schemas.untitled].includes(activeUri.scheme)) {
|
||||
const selection = activeEditor?.getSelection();
|
||||
if (selection) {
|
||||
(await showEditsView(accessor.get(IViewsService)))?.focusInput();
|
||||
variablesService.attachContext('file', { uri: activeUri, range: selection }, ChatAgentLocation.EditingSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class AttachContextAction extends Action2 {
|
||||
|
||||
static readonly ID = 'workbench.action.chat.attachContext';
|
||||
|
||||
@ -720,7 +720,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
||||
dom.clearNode(container);
|
||||
const hoverDelegate = store.add(createInstantHoverDelegate());
|
||||
const attachments = this.location === ChatAgentLocation.EditingSession
|
||||
? [...this.attachmentModel.attachments.entries()].filter(([_, attachment]) => !attachment.isFile)
|
||||
// Render as attachments anything that isn't a file, but still render specific ranges in a file
|
||||
? [...this.attachmentModel.attachments.entries()].filter(([_, attachment]) => !attachment.isFile || attachment.isFile && typeof attachment.value === 'object' && !!attachment.value && 'range' in attachment.value)
|
||||
: [...this.attachmentModel.attachments.entries()];
|
||||
dom.setVisibility(Boolean(attachments.length) || Boolean(this.implicitContext?.value), this.attachedContextContainer);
|
||||
if (!attachments.length) {
|
||||
|
||||
@ -17,7 +17,7 @@ import { IChatModel, IChatRequestVariableData, IChatRequestVariableEntry } from
|
||||
import { ChatRequestDynamicVariablePart, ChatRequestToolPart, ChatRequestVariablePart, IParsedChatRequest } from '../common/chatParserTypes.js';
|
||||
import { IChatContentReference } from '../common/chatService.js';
|
||||
import { IChatRequestVariableValue, IChatVariableData, IChatVariableResolver, IChatVariableResolverProgress, IChatVariablesService, IDynamicVariable } from '../common/chatVariables.js';
|
||||
import { IChatWidgetService, showChatView } from './chat.js';
|
||||
import { IChatWidgetService, showChatView, showEditsView } from './chat.js';
|
||||
import { ChatDynamicVariableModel } from './contrib/chatDynamicVariables.js';
|
||||
|
||||
interface IChatData {
|
||||
@ -161,11 +161,13 @@ export class ChatVariablesService implements IChatVariablesService {
|
||||
}
|
||||
|
||||
async attachContext(name: string, value: string | URI | Location, location: ChatAgentLocation) {
|
||||
if (location !== ChatAgentLocation.Panel) {
|
||||
if (location !== ChatAgentLocation.Panel && location !== ChatAgentLocation.EditingSession) {
|
||||
return;
|
||||
}
|
||||
|
||||
const widget = this.chatWidgetService.lastFocusedWidget ?? await showChatView(this.viewsService);
|
||||
const widget = location === ChatAgentLocation.EditingSession
|
||||
? await showEditsView(this.viewsService)
|
||||
: (this.chatWidgetService.lastFocusedWidget ?? await showChatView(this.viewsService));
|
||||
if (!widget || !widget.viewModel) {
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user