* revert commit

* compile/hygiene
This commit is contained in:
Justin Chen 2024-11-20 21:29:57 +00:00 коммит произвёл GitHub
Родитель d12854f6ba
Коммит b410e9c0ac
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
10 изменённых файлов: 15 добавлений и 331 удалений

Просмотреть файл

@ -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 {

9
src/vs/monaco.d.ts поставляемый
Просмотреть файл

@ -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' &&