revert chat code block pasting (#234297)
* revert commit * compile/hygiene
This commit is contained in:
Родитель
d12854f6ba
Коммит
b410e9c0ac
|
@ -1758,14 +1758,7 @@ export interface IWorkspaceTextEdit {
|
|||
}
|
||||
|
||||
export interface WorkspaceEdit {
|
||||
edits: Array<IWorkspaceTextEdit | IWorkspaceFileEdit | ICustomEdit>;
|
||||
}
|
||||
|
||||
export interface ICustomEdit {
|
||||
readonly resource: URI;
|
||||
readonly metadata?: WorkspaceEditMetadata;
|
||||
undo(): Promise<void> | void;
|
||||
redo(): Promise<void> | void;
|
||||
edits: Array<IWorkspaceTextEdit | IWorkspaceFileEdit>;
|
||||
}
|
||||
|
||||
export interface Rejection {
|
||||
|
|
|
@ -7962,14 +7962,7 @@ declare namespace monaco.languages {
|
|||
}
|
||||
|
||||
export interface WorkspaceEdit {
|
||||
edits: Array<IWorkspaceTextEdit | IWorkspaceFileEdit | ICustomEdit>;
|
||||
}
|
||||
|
||||
export interface ICustomEdit {
|
||||
readonly resource: Uri;
|
||||
readonly metadata?: WorkspaceEditMetadata;
|
||||
undo(): Promise<void> | void;
|
||||
redo(): Promise<void> | void;
|
||||
edits: Array<IWorkspaceTextEdit | IWorkspaceFileEdit>;
|
||||
}
|
||||
|
||||
export interface Rejection {
|
||||
|
|
|
@ -28,7 +28,6 @@ import { BulkTextEdits } from './bulkTextEdits.js';
|
|||
import { IEditorService } from '../../../services/editor/common/editorService.js';
|
||||
import { ILifecycleService, ShutdownReason } from '../../../services/lifecycle/common/lifecycle.js';
|
||||
import { IWorkingCopyService } from '../../../services/workingCopy/common/workingCopyService.js';
|
||||
import { OpaqueEdits, ResourceAttachmentEdit } from './opaqueEdits.js';
|
||||
|
||||
function liftEdits(edits: ResourceEdit[]): ResourceEdit[] {
|
||||
return edits.map(edit => {
|
||||
|
@ -41,11 +40,6 @@ function liftEdits(edits: ResourceEdit[]): ResourceEdit[] {
|
|||
if (ResourceNotebookCellEdit.is(edit)) {
|
||||
return ResourceNotebookCellEdit.lift(edit);
|
||||
}
|
||||
|
||||
if (ResourceAttachmentEdit.is(edit)) {
|
||||
return ResourceAttachmentEdit.lift(edit);
|
||||
}
|
||||
|
||||
throw new Error('Unsupported edit');
|
||||
});
|
||||
}
|
||||
|
@ -128,8 +122,6 @@ class BulkEdit {
|
|||
resources.push(await this._performTextEdits(<ResourceTextEdit[]>group, this._undoRedoGroup, this._undoRedoSource, progress));
|
||||
} else if (group[0] instanceof ResourceNotebookCellEdit) {
|
||||
resources.push(await this._performCellEdits(<ResourceNotebookCellEdit[]>group, this._undoRedoGroup, this._undoRedoSource, progress));
|
||||
} else if (group[0] instanceof ResourceAttachmentEdit) {
|
||||
resources.push(await this._performOpaqueEdits(<ResourceAttachmentEdit[]>group, this._undoRedoGroup, this._undoRedoSource, progress));
|
||||
} else {
|
||||
console.log('UNKNOWN EDIT');
|
||||
}
|
||||
|
@ -156,12 +148,6 @@ class BulkEdit {
|
|||
const model = this._instaService.createInstance(BulkCellEdits, undoRedoGroup, undoRedoSource, progress, this._token, edits);
|
||||
return await model.apply();
|
||||
}
|
||||
|
||||
private async _performOpaqueEdits(edits: ResourceAttachmentEdit[], undoRedoGroup: UndoRedoGroup, undoRedoSource: UndoRedoSource | undefined, progress: IProgress<void>): Promise<readonly URI[]> {
|
||||
this._logService.debug('_performOpaqueEdits', JSON.stringify(edits));
|
||||
const model = this._instaService.createInstance(OpaqueEdits, undoRedoGroup, undoRedoSource, progress, this._token, edits);
|
||||
return await model.apply();
|
||||
}
|
||||
}
|
||||
|
||||
export class BulkEditService implements IBulkEditService {
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from '../../../../base/common/cancellation.js';
|
||||
import { isObject } from '../../../../base/common/types.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { ResourceEdit } from '../../../../editor/browser/services/bulkEditService.js';
|
||||
import { ICustomEdit, WorkspaceEditMetadata } from '../../../../editor/common/languages.js';
|
||||
import { IProgress } from '../../../../platform/progress/common/progress.js';
|
||||
import { IUndoRedoService, UndoRedoElementType, UndoRedoGroup, UndoRedoSource } from '../../../../platform/undoRedo/common/undoRedo.js';
|
||||
|
||||
export class ResourceAttachmentEdit extends ResourceEdit implements ICustomEdit {
|
||||
|
||||
static is(candidate: any): candidate is ICustomEdit {
|
||||
if (candidate instanceof ResourceAttachmentEdit) {
|
||||
return true;
|
||||
} else {
|
||||
return isObject(candidate)
|
||||
&& (Boolean((<ICustomEdit>candidate).undo && (<ICustomEdit>candidate).redo));
|
||||
}
|
||||
}
|
||||
|
||||
static lift(edit: ICustomEdit): ResourceAttachmentEdit {
|
||||
if (edit instanceof ResourceAttachmentEdit) {
|
||||
return edit;
|
||||
} else {
|
||||
return new ResourceAttachmentEdit(edit.resource, edit.undo, edit.redo, edit.metadata);
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly resource: URI,
|
||||
readonly undo: () => Promise<void> | void,
|
||||
readonly redo: () => Promise<void> | void,
|
||||
metadata?: WorkspaceEditMetadata
|
||||
) {
|
||||
super(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
export class OpaqueEdits {
|
||||
|
||||
constructor(
|
||||
private readonly _undoRedoGroup: UndoRedoGroup,
|
||||
private readonly _undoRedoSource: UndoRedoSource | undefined,
|
||||
private readonly _progress: IProgress<void>,
|
||||
private readonly _token: CancellationToken,
|
||||
private readonly _edits: ResourceAttachmentEdit[],
|
||||
@IUndoRedoService private readonly _undoRedoService: IUndoRedoService,
|
||||
) { }
|
||||
|
||||
async apply(): Promise<readonly URI[]> {
|
||||
const resources: URI[] = [];
|
||||
|
||||
for (const edit of this._edits) {
|
||||
if (this._token.isCancellationRequested) {
|
||||
break;
|
||||
}
|
||||
|
||||
await edit.redo();
|
||||
|
||||
this._undoRedoService.pushElement({
|
||||
type: UndoRedoElementType.Resource,
|
||||
resource: edit.resource,
|
||||
label: edit.metadata?.label || 'Custom Edit',
|
||||
code: 'paste',
|
||||
undo: edit.undo,
|
||||
redo: edit.redo,
|
||||
}, this._undoRedoGroup, this._undoRedoSource);
|
||||
|
||||
this._progress.report(undefined);
|
||||
resources.push(edit.resource);
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
}
|
|
@ -78,12 +78,6 @@ import { ILanguageModelIgnoredFilesService, LanguageModelIgnoredFilesService } f
|
|||
import { ChatGettingStartedContribution } from './actions/chatGettingStarted.js';
|
||||
import { Extensions, IConfigurationMigrationRegistry } from '../../../common/configuration.js';
|
||||
import { ChatEditorOverlayController } from './chatEditorOverlay.js';
|
||||
import { ITextModelContentProvider, ITextModelService } from '../../../../editor/common/services/resolverService.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { ILanguageService } from '../../../../editor/common/languages/language.js';
|
||||
import { ITextModel } from '../../../../editor/common/model.js';
|
||||
import { IModelService } from '../../../../editor/common/services/model.js';
|
||||
import { ChatInputPart } from './chatInputPart.js';
|
||||
import { ChatRelatedFilesContribution } from './contrib/chatInputRelatedFilesContrib.js';
|
||||
|
||||
// Register configuration
|
||||
|
@ -189,9 +183,6 @@ class ChatResolverContribution extends Disposable {
|
|||
constructor(
|
||||
@IEditorResolverService editorResolverService: IEditorResolverService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ITextModelService private readonly textModelService: ITextModelService,
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@ILanguageService private readonly languageService: ILanguageService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -212,32 +203,12 @@ class ChatResolverContribution extends Disposable {
|
|||
}
|
||||
}
|
||||
));
|
||||
|
||||
this._register(new ChatInputBoxContentProvider(this.textModelService, this.modelService, this.languageService));
|
||||
}
|
||||
}
|
||||
|
||||
AccessibleViewRegistry.register(new ChatResponseAccessibleView());
|
||||
AccessibleViewRegistry.register(new PanelChatAccessibilityHelp());
|
||||
AccessibleViewRegistry.register(new QuickChatAccessibilityHelp());
|
||||
class ChatInputBoxContentProvider extends Disposable implements ITextModelContentProvider {
|
||||
constructor(
|
||||
textModelService: ITextModelService,
|
||||
private readonly modelService: IModelService,
|
||||
private readonly languageService: ILanguageService,
|
||||
) {
|
||||
super();
|
||||
this._register(textModelService.registerTextModelContentProvider(ChatInputPart.INPUT_SCHEME, this));
|
||||
}
|
||||
|
||||
async provideTextContent(resource: URI): Promise<ITextModel | null> {
|
||||
const existing = this.modelService.getModel(resource);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
return this.modelService.createModel('', this.languageService.createById('chatinput'), resource);
|
||||
}
|
||||
}
|
||||
|
||||
class ChatSlashStaticSlashCommandsContribution extends Disposable {
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from '../../../../../base/browser/dom.js';
|
||||
import { IManagedHoverTooltipMarkdownString } from '../../../../../base/browser/ui/hover/hover.js';
|
||||
import { createInstantHoverDelegate } from '../../../../../base/browser/ui/hover/hoverDelegateFactory.js';
|
||||
import { Emitter } from '../../../../../base/common/event.js';
|
||||
import { Disposable, DisposableStore } from '../../../../../base/common/lifecycle.js';
|
||||
|
@ -20,8 +19,8 @@ import { IInstantiationService } from '../../../../../platform/instantiation/com
|
|||
import { IOpenerService, OpenInternalOptions } from '../../../../../platform/opener/common/opener.js';
|
||||
import { FolderThemeIcon, IThemeService } from '../../../../../platform/theme/common/themeService.js';
|
||||
import { ResourceLabels } from '../../../../browser/labels.js';
|
||||
import { IChatRequestVariableEntry, isPasteVariableEntry } from '../../common/chatModel.js';
|
||||
import { revealInSideBarCommand } from '../../../files/browser/fileActions.contribution.js';
|
||||
import { IChatRequestVariableEntry } from '../../common/chatModel.js';
|
||||
import { ChatResponseReferencePartStatusKind, IChatContentReference } from '../../common/chatService.js';
|
||||
|
||||
export class ChatAttachmentsContentPart extends Disposable {
|
||||
|
@ -127,25 +126,6 @@ export class ChatAttachmentsContentPart extends Disposable {
|
|||
if (!this.attachedContextDisposables.isDisposed) {
|
||||
this.attachedContextDisposables.add(this.hoverService.setupManagedHover(hoverDelegate, widget, hoverElement));
|
||||
}
|
||||
} else if (isPasteVariableEntry(attachment)) {
|
||||
ariaLabel = localize('chat.attachment', "Attached context, {0}", attachment.name);
|
||||
|
||||
const hoverContent: IManagedHoverTooltipMarkdownString = {
|
||||
markdown: {
|
||||
value: `\`\`\`${attachment.language}\n${attachment.code}\n\`\`\``,
|
||||
},
|
||||
markdownNotSupportedFallback: attachment.code,
|
||||
};
|
||||
|
||||
const classNames = ['file-icon', `${attachment.language}-lang-file-icon`];
|
||||
label.setLabel(attachment.fileName, undefined, { extraClasses: classNames });
|
||||
widget.appendChild(dom.$('span.attachment-additional-info', {}, `Pasted ${attachment.pastedLines}`));
|
||||
|
||||
widget.style.position = 'relative';
|
||||
|
||||
if (!this.attachedContextDisposables.isDisposed) {
|
||||
this.attachedContextDisposables.add(this.hoverService.setupManagedHover(hoverDelegate, widget, hoverContent, { trapFocus: true }));
|
||||
}
|
||||
} else {
|
||||
const attachmentLabel = attachment.fullName ?? attachment.name;
|
||||
const withIcon = attachment.icon?.id ? `$(${attachment.icon.id}) ${attachmentLabel}` : attachmentLabel;
|
||||
|
|
|
@ -11,7 +11,6 @@ import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js
|
|||
import { StandardMouseEvent } from '../../../../base/browser/mouseEvent.js';
|
||||
import * as aria from '../../../../base/browser/ui/aria/aria.js';
|
||||
import { Button } from '../../../../base/browser/ui/button/button.js';
|
||||
import { IManagedHoverTooltipMarkdownString } from '../../../../base/browser/ui/hover/hover.js';
|
||||
import { IHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegate.js';
|
||||
import { createInstantHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegateFactory.js';
|
||||
import { renderLabelWithIcons } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
|
||||
|
@ -76,7 +75,7 @@ import { revealInSideBarCommand } from '../../files/browser/fileActions.contribu
|
|||
import { ChatAgentLocation, IChatAgentService } from '../common/chatAgents.js';
|
||||
import { ChatContextKeys } from '../common/chatContextKeys.js';
|
||||
import { ChatEditingSessionState, IChatEditingService, IChatEditingSession, WorkingSetEntryState } from '../common/chatEditingService.js';
|
||||
import { IChatRequestVariableEntry, isPasteVariableEntry } from '../common/chatModel.js';
|
||||
import { IChatRequestVariableEntry } from '../common/chatModel.js';
|
||||
import { ChatRequestDynamicVariablePart } from '../common/chatParserTypes.js';
|
||||
import { IChatFollowup } from '../common/chatService.js';
|
||||
import { IChatResponseViewModel } from '../common/chatViewModel.js';
|
||||
|
@ -843,23 +842,6 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
|||
store.add(this.hoverService.setupManagedHover(hoverDelegate, widget, hoverElement, { trapFocus: false }));
|
||||
resolve();
|
||||
}));
|
||||
} else if (isPasteVariableEntry(attachment)) {
|
||||
ariaLabel = localize('chat.attachment', "Attached context, {0}", attachment.name);
|
||||
|
||||
const hoverContent: IManagedHoverTooltipMarkdownString = {
|
||||
markdown: {
|
||||
value: `\`\`\`${attachment.language}\n${attachment.code}\n\`\`\``,
|
||||
},
|
||||
markdownNotSupportedFallback: attachment.code,
|
||||
};
|
||||
|
||||
const classNames = ['file-icon', `${attachment.language}-lang-file-icon`];
|
||||
label.setLabel(attachment.fileName, undefined, { extraClasses: classNames });
|
||||
widget.appendChild(dom.$('span.attachment-additional-info', {}, `Pasted ${attachment.pastedLines}`));
|
||||
|
||||
widget.style.position = 'relative';
|
||||
store.add(this.hoverService.setupManagedHover(hoverDelegate, widget, hoverContent, { trapFocus: true }));
|
||||
this.attachButtonAndDisposables(widget, index, attachment, hoverDelegate);
|
||||
} else {
|
||||
const attachmentLabel = attachment.fullName ?? attachment.name;
|
||||
const withIcon = attachment.icon?.id ? `$(${attachment.icon.id}) ${attachmentLabel}` : attachmentLabel;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from '../../../../base/common/cancellation.js';
|
||||
import { createStringDataTransferItem, IDataTransferItem, IReadonlyVSDataTransfer, VSDataTransfer } from '../../../../base/common/dataTransfer.js';
|
||||
import { IDataTransferItem, IReadonlyVSDataTransfer } from '../../../../base/common/dataTransfer.js';
|
||||
import { HierarchicalKind } from '../../../../base/common/hierarchicalKind.js';
|
||||
import { IRange } from '../../../../editor/common/core/range.js';
|
||||
import { DocumentPasteContext, DocumentPasteEditProvider, DocumentPasteEditsSession } from '../../../../editor/common/languages.js';
|
||||
|
@ -17,25 +17,19 @@ import { Codicon } from '../../../../base/common/codicons.js';
|
|||
import { localize } from '../../../../nls.js';
|
||||
import { IChatRequestVariableEntry } from '../common/chatModel.js';
|
||||
import { IExtensionService, isProposedApiEnabled } from '../../../services/extensions/common/extensions.js';
|
||||
import { Mimes } from '../../../../base/common/mime.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
|
||||
const COPY_MIME_TYPES = 'application/vnd.code.additional-editor-data';
|
||||
|
||||
export class PasteImageProvider implements DocumentPasteEditProvider {
|
||||
|
||||
public readonly kind = new HierarchicalKind('chat.attach.image');
|
||||
public readonly kind = new HierarchicalKind('image');
|
||||
public readonly copyMimeTypes = ['image/*'];
|
||||
public readonly providedPasteEditKinds = [this.kind];
|
||||
|
||||
public readonly copyMimeTypes = [];
|
||||
public readonly pasteMimeTypes = ['image/*'];
|
||||
|
||||
constructor(
|
||||
private readonly chatWidgetService: IChatWidgetService,
|
||||
private readonly extensionService: IExtensionService,
|
||||
private readonly extensionService: IExtensionService
|
||||
) { }
|
||||
|
||||
async provideDocumentPasteEdits(model: ITextModel, ranges: readonly IRange[], dataTransfer: IReadonlyVSDataTransfer, context: DocumentPasteContext, token: CancellationToken): Promise<DocumentPasteEditsSession | undefined> {
|
||||
async provideDocumentPasteEdits(_model: ITextModel, _ranges: readonly IRange[], dataTransfer: IReadonlyVSDataTransfer, context: DocumentPasteContext, token: CancellationToken): Promise<DocumentPasteEditsSession | undefined> {
|
||||
if (!this.extensionService.extensions.some(ext => isProposedApiEnabled(ext, 'chatReferenceBinaryData'))) {
|
||||
return;
|
||||
}
|
||||
|
@ -69,7 +63,7 @@ export class PasteImageProvider implements DocumentPasteEditProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
||||
const widget = this.chatWidgetService.getWidgetByInputUri(_model.uri);
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
|
@ -94,7 +88,9 @@ export class PasteImageProvider implements DocumentPasteEditProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
return getCustomPaste(model, imageContext, mimeType, this.kind, localize('pastedImageAttachment', 'Pasted Image Attachment'), this.chatWidgetService);
|
||||
widget.attachmentModel.addContext(imageContext);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +107,7 @@ async function getImageAttachContext(data: Uint8Array, mimeType: string, token:
|
|||
isImage: true,
|
||||
icon: Codicon.fileMedia,
|
||||
isDynamic: true,
|
||||
isFile: false,
|
||||
mimeType
|
||||
};
|
||||
}
|
||||
|
@ -140,126 +137,6 @@ export function isImage(array: Uint8Array): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
export class CopyTextProvider implements DocumentPasteEditProvider {
|
||||
public readonly providedPasteEditKinds = [];
|
||||
public readonly copyMimeTypes = [COPY_MIME_TYPES];
|
||||
public readonly pasteMimeTypes = [];
|
||||
|
||||
async prepareDocumentPaste(model: ITextModel, ranges: readonly IRange[], dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<undefined | IReadonlyVSDataTransfer> {
|
||||
if (model.uri.scheme === ChatInputPart.INPUT_SCHEME) {
|
||||
return;
|
||||
}
|
||||
const customDataTransfer = new VSDataTransfer();
|
||||
const rangesString = JSON.stringify({ ranges: ranges[0], uri: model.uri.toString() });
|
||||
customDataTransfer.append(COPY_MIME_TYPES, createStringDataTransferItem(rangesString));
|
||||
return customDataTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
export class PasteTextProvider implements DocumentPasteEditProvider {
|
||||
|
||||
public readonly kind = new HierarchicalKind('chat.attach.text');
|
||||
public readonly providedPasteEditKinds = [this.kind];
|
||||
|
||||
public readonly copyMimeTypes = [];
|
||||
public readonly pasteMimeTypes = [COPY_MIME_TYPES];
|
||||
|
||||
constructor(
|
||||
private readonly chatWidgetService: IChatWidgetService
|
||||
) { }
|
||||
|
||||
async provideDocumentPasteEdits(model: ITextModel, ranges: readonly IRange[], dataTransfer: IReadonlyVSDataTransfer, context: DocumentPasteContext, token: CancellationToken): Promise<DocumentPasteEditsSession | undefined> {
|
||||
if (model.uri.scheme !== ChatInputPart.INPUT_SCHEME) {
|
||||
return;
|
||||
}
|
||||
const text = dataTransfer.get(Mimes.text);
|
||||
const editorData = dataTransfer.get('vscode-editor-data');
|
||||
const additionalEditorData = dataTransfer.get(COPY_MIME_TYPES);
|
||||
|
||||
if (!editorData || !text || !additionalEditorData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const textdata = await text.asString();
|
||||
const metadata = JSON.parse(await editorData.asString());
|
||||
const additionalData = JSON.parse(await additionalEditorData.asString());
|
||||
|
||||
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
|
||||
const copiedContext = await getCopiedContext(textdata, additionalData.uri, metadata.mode, additionalData.ranges);
|
||||
|
||||
if (token.isCancellationRequested || !copiedContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentContextIds = widget.attachmentModel.getAttachmentIDs();
|
||||
if (currentContextIds.has(copiedContext.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return getCustomPaste(model, copiedContext, Mimes.text, this.kind, localize('pastedCodeAttachment', 'Pasted Code Attachment'), this.chatWidgetService);
|
||||
}
|
||||
}
|
||||
|
||||
async function getCopiedContext(code: string, file: string, language: string, ranges: IRange): Promise<IChatRequestVariableEntry | undefined> {
|
||||
const fileName = file.split('/').pop() || 'unknown file';
|
||||
const start = ranges.startLineNumber;
|
||||
const end = ranges.endLineNumber;
|
||||
const resultText = `Copied Selection of Code: \n\n\n From the file: ${fileName} From lines ${start} to ${end} \n \`\`\`${code}\`\`\``;
|
||||
const pastedLines = start === end ? localize('pastedAttachment.oneLine', '1 line') : localize('pastedAttachment.multipleLines', '{0} lines', end + 1 - start);
|
||||
return {
|
||||
kind: 'paste',
|
||||
value: resultText,
|
||||
id: `${fileName}${start}${end}${ranges.startColumn}${ranges.endColumn}`,
|
||||
name: `${fileName} ${pastedLines}`,
|
||||
icon: Codicon.code,
|
||||
isDynamic: true,
|
||||
pastedLines,
|
||||
language,
|
||||
fileName,
|
||||
code,
|
||||
references: [{
|
||||
reference: URI.parse(file),
|
||||
kind: 'reference'
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
async function getCustomPaste(model: ITextModel, context: IChatRequestVariableEntry, handledMimeType: string, kind: HierarchicalKind, title: string, chatWidgetService: IChatWidgetService): Promise<DocumentPasteEditsSession> {
|
||||
const customEdit = {
|
||||
resource: model.uri,
|
||||
variable: context,
|
||||
undo: () => {
|
||||
const widget = chatWidgetService.getWidgetByInputUri(model.uri);
|
||||
if (!widget) {
|
||||
throw new Error('No widget found for undo');
|
||||
}
|
||||
widget.attachmentModel.delete(context.id);
|
||||
},
|
||||
redo: () => {
|
||||
const widget = chatWidgetService.getWidgetByInputUri(model.uri);
|
||||
if (!widget) {
|
||||
throw new Error('No widget found for redo');
|
||||
}
|
||||
widget.attachmentModel.addContext(context);
|
||||
},
|
||||
metadata: { needsConfirmation: false, label: context.name }
|
||||
};
|
||||
|
||||
return {
|
||||
edits: [{
|
||||
insertText: '', title, kind, handledMimeType,
|
||||
additionalEdit: {
|
||||
edits: [customEdit],
|
||||
}
|
||||
}],
|
||||
dispose() { },
|
||||
};
|
||||
}
|
||||
|
||||
export class ChatPasteProvidersFeature extends Disposable {
|
||||
constructor(
|
||||
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
|
||||
|
@ -268,7 +145,5 @@ export class ChatPasteProvidersFeature extends Disposable {
|
|||
) {
|
||||
super();
|
||||
this._register(languageFeaturesService.documentPasteEditProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, pattern: '*', hasAccessToAllModels: true }, new PasteImageProvider(chatWidgetService, extensionService)));
|
||||
this._register(languageFeaturesService.documentPasteEditProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, pattern: '*', hasAccessToAllModels: true }, new PasteTextProvider(chatWidgetService)));
|
||||
this._register(languageFeaturesService.documentPasteEditProvider.register('*', new CopyTextProvider()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1299,11 +1299,6 @@ have to be updated for changes to the rules above, or to support more deeply nes
|
|||
border: none;
|
||||
}
|
||||
|
||||
.chat-attached-context-attachment .attachment-additional-info {
|
||||
opacity: 0.7;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.chat-attached-context-attachment .chat-attached-context-pill-image {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
|
|
|
@ -56,14 +56,6 @@ export interface IChatRequestImplicitVariableEntry extends Omit<IBaseChatRequest
|
|||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface IChatRequestPasteVariableEntry extends Omit<IBaseChatRequestVariableEntry, 'kind'> {
|
||||
readonly kind: 'paste';
|
||||
code: string;
|
||||
language: string;
|
||||
fileName: string;
|
||||
pastedLines: string;
|
||||
}
|
||||
|
||||
export interface ISymbolVariableEntry extends Omit<IBaseChatRequestVariableEntry, 'kind'> {
|
||||
readonly kind: 'symbol';
|
||||
readonly isDynamic: true;
|
||||
|
@ -75,16 +67,12 @@ export interface ICommandResultVariableEntry extends Omit<IBaseChatRequestVariab
|
|||
readonly isDynamic: true;
|
||||
}
|
||||
|
||||
export type IChatRequestVariableEntry = IChatRequestImplicitVariableEntry | IChatRequestPasteVariableEntry | ISymbolVariableEntry | ICommandResultVariableEntry | IBaseChatRequestVariableEntry;
|
||||
export type IChatRequestVariableEntry = IChatRequestImplicitVariableEntry | ISymbolVariableEntry | ICommandResultVariableEntry | IBaseChatRequestVariableEntry;
|
||||
|
||||
export function isImplicitVariableEntry(obj: IChatRequestVariableEntry): obj is IChatRequestImplicitVariableEntry {
|
||||
return obj.kind === 'implicit';
|
||||
}
|
||||
|
||||
export function isPasteVariableEntry(obj: IChatRequestVariableEntry): obj is IChatRequestPasteVariableEntry {
|
||||
return obj.kind === 'paste';
|
||||
}
|
||||
|
||||
export function isChatRequestVariableEntry(obj: unknown): obj is IChatRequestVariableEntry {
|
||||
const entry = obj as IChatRequestVariableEntry;
|
||||
return typeof entry === 'object' &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче