feat: collapse codeblocks in editing sessions (#230005)

This commit is contained in:
Joyce Er 2024-09-27 12:31:21 -07:00 committed by GitHub
parent 8f86741073
commit aa0b6bb15a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 5 deletions

View file

@ -26,6 +26,8 @@ import { IChatProgressRenderableResponseContent } from '../../common/chatModel.j
import { isRequestVM, isResponseVM } from '../../common/chatViewModel.js';
import { CodeBlockModelCollection } from '../../common/codeBlockModelCollection.js';
import { URI } from '../../../../../base/common/uri.js';
import { IEditorService } from '../../../../services/editor/common/editorService.js';
import { InlineAnchorWidget } from '../chatInlineAnchorWidget.js';
const $ = dom.$;
@ -52,7 +54,8 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP
rendererOptions: IChatListItemRendererOptions,
@IContextKeyService contextKeyService: IContextKeyService,
@ITextModelService private readonly textModelService: ITextModelService,
@IInstantiationService instantiationService: IInstantiationService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IEditorService private readonly editorService: IEditorService,
) {
super();
@ -132,6 +135,7 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP
this.codeBlockModelCollection.update(data.element.sessionId, data.element, data.codeBlockIndex, { text, languageId: data.languageId }).then((e) => {
// Update the existing object's codemapperUri
this.codeblocks[data.codeBlockIndex].codemapperUri = e.codemapperUri;
this._onDidChangeHeight.fire();
});
}
@ -145,7 +149,20 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP
}
layout(width: number): void {
this.allRefs.forEach(ref => ref.object.layout(width));
this.allRefs.forEach((ref, index) => {
const codeblockModel = this.codeblocks[index];
if (codeblockModel.codemapperUri) {
const fileWidgetAnchor = $('.chat-codeblock');
this._register(this.instantiationService.createInstance(InlineAnchorWidget, fileWidgetAnchor, { uri: codeblockModel.codemapperUri }, { handleClick: (uri) => this.editorService.openEditor({ resource: uri }) }));
const existingCodeblock = ref.object.element.parentElement?.querySelector('.chat-codeblock');
if (!existingCodeblock) {
ref.object.element.parentElement?.appendChild(fileWidgetAnchor);
ref.object.element.style.display = 'none';
}
} else {
ref.object.layout(width);
}
});
}
addDisposable(disposable: IDisposable): void {

View file

@ -40,9 +40,12 @@ import { IChatWidgetService } from './chat.js';
export class InlineAnchorWidget extends Disposable {
public static readonly className = 'chat-inline-anchor-widget';
constructor(
element: HTMLAnchorElement,
element: HTMLAnchorElement | HTMLElement,
data: ContentRefData,
options: { handleClick?: (uri: URI) => void } = {},
@IContextKeyService originalContextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService,
@IFileService fileService: IFileService,
@ -60,7 +63,10 @@ export class InlineAnchorWidget extends Disposable {
const contextKeyService = this._register(originalContextKeyService.createScoped(element));
const anchorId = new Lazy(generateUuid);
element.classList.add('chat-inline-anchor-widget', 'show-file-icons');
element.classList.add(InlineAnchorWidget.className, 'show-file-icons');
if (options.handleClick) {
element.classList.add('clickable');
}
let iconText: string;
let iconClasses: string[];
@ -128,6 +134,8 @@ export class InlineAnchorWidget extends Disposable {
.catch(() => { });
this._register(dom.addDisposableListener(element, 'click', () => {
options.handleClick?.(location.uri);
telemetryService.publicLog2<{
anchorId: string;
}, {

View file

@ -246,7 +246,7 @@ export class ChatMarkdownDecorationsRenderer extends Disposable {
return;
}
store.add(this.instantiationService.createInstance(InlineAnchorWidget, a, data));
store.add(this.instantiationService.createInstance(InlineAnchorWidget, a, data, undefined));
}
private renderResourceWidget(name: string, args: IDecorationWidgetArgs | undefined, store: DisposableStore): HTMLElement {

View file

@ -9,6 +9,15 @@
margin: 0 1px;
padding: 1px 3px;
text-wrap: nowrap;
width: fit-content;
}
.chat-inline-anchor-widget .icon-label {
padding-right: 3px;
}
.chat-inline-anchor-widget .clickable {
cursor: pointer;
}
.interactive-item-container .value .rendered-markdown .chat-inline-anchor-widget {