mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-31 04:35:14 +01:00
Add chat file icon widget
Moving logic into class and adopting `IconLabel`
This commit is contained in:
@@ -180,13 +180,11 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
|
||||
if (options.actionHandler) {
|
||||
const _activateLink = function (event: StandardMouseEvent | StandardKeyboardEvent): void {
|
||||
let target: HTMLElement | null = event.target;
|
||||
if (target.tagName !== 'A') {
|
||||
target = target.parentElement;
|
||||
if (!target || target.tagName !== 'A') {
|
||||
return;
|
||||
}
|
||||
const target = event.target.closest('a[data-href]');
|
||||
if (!DOM.isHTMLElement(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let href = target.dataset['href'];
|
||||
if (href) {
|
||||
|
||||
@@ -7,19 +7,23 @@ import { applyDragImage } from '../../../../base/browser/dnd.js';
|
||||
import * as dom from '../../../../base/browser/dom.js';
|
||||
import { Button } from '../../../../base/browser/ui/button/button.js';
|
||||
import { getDefaultHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegateFactory.js';
|
||||
import { IconLabel } from '../../../../base/browser/ui/iconLabel/iconLabel.js';
|
||||
import { toErrorMessage } from '../../../../base/common/errorMessage.js';
|
||||
import { Lazy } from '../../../../base/common/lazy.js';
|
||||
import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { Disposable, DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { revive } from '../../../../base/common/marshalling.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { Location } from '../../../../editor/common/languages.js';
|
||||
import { ILanguageService } from '../../../../editor/common/languages/language.js';
|
||||
import { getIconClasses } from '../../../../editor/common/services/getIconClasses.js';
|
||||
import { IModelService } from '../../../../editor/common/services/model.js';
|
||||
import { ICommandService } from '../../../../platform/commands/common/commands.js';
|
||||
import { IHoverService } from '../../../../platform/hover/browser/hover.js';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
|
||||
import { ILabelService } from '../../../../platform/label/common/label.js';
|
||||
import { ILogService } from '../../../../platform/log/common/log.js';
|
||||
import { listActiveSelectionBackground, listActiveSelectionForeground } from '../../../../platform/theme/common/colorRegistry.js';
|
||||
import { listActiveSelectionBackground, listActiveSelectionForeground } from '../../../../platform/theme/common/colors/listColors.js';
|
||||
import { asCssVariable } from '../../../../platform/theme/common/colorUtils.js';
|
||||
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
|
||||
import { fillEditorsDragData } from '../../../browser/dnd.js';
|
||||
@@ -32,6 +36,7 @@ import { IChatVariablesService } from '../common/chatVariables.js';
|
||||
import { ILanguageModelToolsService } from '../common/languageModelToolsService.js';
|
||||
import { IChatWidgetService } from './chat.js';
|
||||
import { ChatAgentHover, getChatAgentHoverOptions } from './chatAgentHover.js';
|
||||
import './media/chatInlineFileLinkWidget.css';
|
||||
|
||||
/** For rendering slash commands, variables */
|
||||
const decorationRefUrl = `http://_vscodedecoration_`;
|
||||
@@ -78,10 +83,10 @@ interface IDecorationWidgetArgs {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export class ChatMarkdownDecorationsRenderer {
|
||||
export class ChatMarkdownDecorationsRenderer extends Disposable {
|
||||
|
||||
constructor(
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IChatAgentService private readonly chatAgentService: IChatAgentService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@@ -90,9 +95,11 @@ export class ChatMarkdownDecorationsRenderer {
|
||||
@IChatWidgetService private readonly chatWidgetService: IChatWidgetService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@IChatVariablesService private readonly chatVariablesService: IChatVariablesService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@ILanguageModelToolsService private readonly toolsService: ILanguageModelToolsService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
) { }
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
convertParsedRequestToMarkdown(parsedRequest: IParsedChatRequest): string {
|
||||
let result = '';
|
||||
@@ -247,28 +254,9 @@ export class ChatMarkdownDecorationsRenderer {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = location.range ? `${location.range.startLineNumber}-${location.range.endLineNumber}` : '';
|
||||
a.setAttribute('data-href', location.uri.with({ fragment }).toString());
|
||||
|
||||
const label = this.labelService.getUriLabel(location.uri, { relative: true });
|
||||
a.replaceChildren(dom.$('code', undefined, label));
|
||||
|
||||
const title = location.range ?
|
||||
`${label}#${location.range.startLineNumber}-${location.range.endLineNumber}` :
|
||||
label;
|
||||
store.add(this.hoverService.setupManagedHover(getDefaultHoverDelegate('element'), a, title));
|
||||
|
||||
// Drag and drop
|
||||
a.draggable = true;
|
||||
store.add(dom.addDisposableListener(a, 'dragstart', e => {
|
||||
this.instantiationService.invokeFunction(accessor => fillEditorsDragData(accessor, [location.uri], e));
|
||||
|
||||
const theme = this.themeService.getColorTheme();
|
||||
applyDragImage(e, label, 'monaco-drag-image', theme.getColor(listActiveSelectionBackground)?.toString(), theme.getColor(listActiveSelectionForeground)?.toString());
|
||||
}));
|
||||
store.add(this.instantiationService.createInstance(InlineFileLinkWidget, a, location));
|
||||
}
|
||||
|
||||
|
||||
private renderResourceWidget(name: string, args: IDecorationWidgetArgs | undefined, store: DisposableStore): HTMLElement {
|
||||
const container = dom.$('span.chat-resource-widget');
|
||||
const alias = dom.$('span', undefined, name);
|
||||
@@ -294,3 +282,49 @@ export class ChatMarkdownDecorationsRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class InlineFileLinkWidget extends Disposable {
|
||||
|
||||
constructor(
|
||||
element: HTMLAnchorElement,
|
||||
location: Location | { uri: URI; range: undefined },
|
||||
@IHoverService hoverService: IHoverService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@ILanguageService languageService: ILanguageService,
|
||||
@IModelService modelService: IModelService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
) {
|
||||
super();
|
||||
|
||||
element.classList.add('chat-inline-file-link-widget');
|
||||
|
||||
const fragment = location.range ? `${location.range.startLineNumber}-${location.range.endLineNumber}` : '';
|
||||
element.setAttribute('data-href', location.uri.with({ fragment }).toString());
|
||||
|
||||
const label = labelService.getUriLabel(location.uri, { relative: true });
|
||||
const title = location.range ?
|
||||
`${label}#${location.range.startLineNumber}-${location.range.endLineNumber}` :
|
||||
label;
|
||||
|
||||
element.replaceChildren();
|
||||
|
||||
const resourceLabel = this._register(new IconLabel(element, { supportHighlights: false, supportIcons: true }));
|
||||
resourceLabel.setLabel(label, undefined, {
|
||||
extraClasses: getIconClasses(modelService, languageService, location.uri)
|
||||
});
|
||||
|
||||
// Hover
|
||||
this._register(hoverService.setupManagedHover(getDefaultHoverDelegate('element'), element, title));
|
||||
|
||||
// Drag and drop
|
||||
element.draggable = true;
|
||||
this._register(dom.addDisposableListener(element, 'dragstart', e => {
|
||||
instantiationService.invokeFunction(accessor => fillEditorsDragData(accessor, [location.uri], e));
|
||||
|
||||
const theme = themeService.getColorTheme();
|
||||
applyDragImage(e, label, 'monaco-drag-image', theme.getColor(listActiveSelectionBackground)?.toString(), theme.getColor(listActiveSelectionForeground)?.toString());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.chat-inline-file-link-widget .monaco-icon-label {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.chat-inline-file-link-widget .monaco-icon-label .monaco-highlighted-label {
|
||||
white-space: normal;
|
||||
}
|
||||
Reference in New Issue
Block a user