tweak editor inline chat visuals (#230521)

...to be more aligned with other peek experiences, like peek ref or edit breakpoint
pull/230598/head
Johannes Rieken 2024-10-04 19:47:00 +02:00 committed by GitHub
parent 91de654324
commit ad047e27d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 71 additions and 24 deletions

View File

@ -356,7 +356,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
this._positionMarkerId.clear();
}
private _decoratingElementsHeight(): number {
protected _decoratingElementsHeight(): number {
const lineHeight = this.editor.getOption(EditorOption.lineHeight);
let result = 0;

View File

@ -984,7 +984,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
const inputPartHeight = this.inputPart.inputPartHeight;
const lastElementVisible = this.tree.scrollTop + this.tree.renderHeight >= this.tree.scrollHeight;
const listHeight = height - inputPartHeight;
const listHeight = Math.max(0, height - inputPartHeight);
this.tree.layout(listHeight, width);
this.tree.getHTMLElement().style.height = `${listHeight}px`;
@ -998,7 +998,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
revealLastElement(this.tree);
}
this.listContainer.style.height = `${height - inputPartHeight}px`;
this.listContainer.style.height = `${listHeight}px`;
this._onDidChangeHeight.fire(height);
}

View File

@ -75,6 +75,8 @@ export interface IInlineChatWidgetConstructionOptions {
* The options for the chat widget
*/
chatWidgetViewOptions?: IChatWidgetViewOptions;
inZoneWidget?: boolean;
}
export interface IInlineChatMessage {
@ -123,7 +125,7 @@ export class InlineChatWidget {
constructor(
location: IChatWidgetLocationOptions,
options: IInlineChatWidgetConstructionOptions,
private readonly _options: IInlineChatWidgetConstructionOptions,
@IInstantiationService protected readonly _instantiationService: IInstantiationService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IKeybindingService private readonly _keybindingService: IKeybindingService,
@ -158,7 +160,7 @@ export class InlineChatWidget {
// filter responses that
// - are just text edits(prevents the "Made Edits")
// - are all empty
if (item.response.value.length > 0 && item.response.value.every(item => item.kind === 'textEditGroup' && options.chatWidgetViewOptions?.rendererOptions?.renderTextEditsAsSummary?.(item.uri))) {
if (item.response.value.length > 0 && item.response.value.every(item => item.kind === 'textEditGroup' && _options.chatWidgetViewOptions?.rendererOptions?.renderTextEditsAsSummary?.(item.uri))) {
return false;
}
if (item.response.value.length === 0) {
@ -168,7 +170,7 @@ export class InlineChatWidget {
}
return true;
},
...options.chatWidgetViewOptions
..._options.chatWidgetViewOptions
},
{
listForeground: inlineChatForeground,
@ -178,6 +180,7 @@ export class InlineChatWidget {
resultEditorBackground: editorBackground
}
);
this._elements.root.classList.toggle('in-zone-widget', !!_options.inZoneWidget);
this._chatWidget.render(this._elements.chatWidget);
this._elements.chatWidget.style.setProperty(asCssVariableName(chatRequestBackground), asCssVariable(inlineChatBackground));
this._chatWidget.setVisible(true);
@ -237,13 +240,13 @@ export class InlineChatWidget {
this._store.add(this._chatWidget.inputEditor.onDidFocusEditorWidget(() => this._ctxInputEditorFocused.set(true)));
this._store.add(this._chatWidget.inputEditor.onDidBlurEditorWidget(() => this._ctxInputEditorFocused.set(false)));
const statusMenuId = options.statusMenuId instanceof MenuId ? options.statusMenuId : options.statusMenuId.menu;
const statusMenuId = _options.statusMenuId instanceof MenuId ? _options.statusMenuId : _options.statusMenuId.menu;
// BUTTON bar
const statusMenuOptions = options.statusMenuId instanceof MenuId ? undefined : options.statusMenuId.options;
const statusMenuOptions = _options.statusMenuId instanceof MenuId ? undefined : _options.statusMenuId.options;
const statusButtonBar = scopedInstaService.createInstance(MenuWorkbenchButtonBar, this._elements.toolbar1, statusMenuId, {
toolbarOptions: { primaryGroup: '0_main' },
telemetrySource: options.chatWidgetViewOptions?.menus?.telemetrySource,
telemetrySource: _options.chatWidgetViewOptions?.menus?.telemetrySource,
menuOptions: { renderShortTitle: true },
...statusMenuOptions,
});
@ -251,8 +254,8 @@ export class InlineChatWidget {
this._store.add(statusButtonBar);
// secondary toolbar
const toolbar2 = scopedInstaService.createInstance(MenuWorkbenchToolBar, this._elements.toolbar2, options.secondaryMenuId ?? MenuId.for(''), {
telemetrySource: options.chatWidgetViewOptions?.menus?.telemetrySource,
const toolbar2 = scopedInstaService.createInstance(MenuWorkbenchToolBar, this._elements.toolbar2, _options.secondaryMenuId ?? MenuId.for(''), {
telemetrySource: _options.chatWidgetViewOptions?.menus?.telemetrySource,
menuOptions: { renderShortTitle: true, shouldForwardArgs: true },
actionViewItemProvider: (action: IAction, options: IActionViewItemOptions) => {
if (action instanceof MenuItemAction && action.item.id === MarkUnhelpfulActionId) {
@ -375,7 +378,7 @@ export class InlineChatWidget {
}
protected _getExtraHeight(): number {
return 2 /*border*/ + 4 /*shadow*/;
return this._options.inZoneWidget ? 1 : (2 /*border*/ + 4 /*shadow*/);
}
get value(): string {

View File

@ -13,7 +13,7 @@ import { EditorLayoutInfo, EditorOption } from '../../../../editor/common/config
import { Position } from '../../../../editor/common/core/position.js';
import { Range } from '../../../../editor/common/core/range.js';
import { ScrollType } from '../../../../editor/common/editorCommon.js';
import { ZoneWidget } from '../../../../editor/contrib/zoneWidget/browser/zoneWidget.js';
import { IOptions, ZoneWidget } from '../../../../editor/contrib/zoneWidget/browser/zoneWidget.js';
import { localize } from '../../../../nls.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
import { IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
@ -26,6 +26,19 @@ import { EditorBasedInlineChatWidget } from './inlineChatWidget.js';
export class InlineChatZoneWidget extends ZoneWidget {
private static readonly _options: IOptions = {
showFrame: true,
frameWidth: 1,
// frameColor: 'var(--vscode-inlineChat-border)',
// isResizeable: true,
showArrow: false,
isAccessible: true,
className: 'inline-chat-widget',
keepEditorSelection: true,
showInHiddenAreas: true,
ordinal: 50000,
};
readonly widget: EditorBasedInlineChatWidget;
private readonly _scrollUp = this._disposables.add(new ScrollUpState(this.editor));
@ -40,7 +53,7 @@ export class InlineChatZoneWidget extends ZoneWidget {
@IContextKeyService contextKeyService: IContextKeyService,
@IConfigurationService configurationService: IConfigurationService,
) {
super(editor, { showFrame: false, showArrow: false, isAccessible: true, className: 'inline-chat-widget', keepEditorSelection: true, showInHiddenAreas: true, ordinal: 50000 });
super(editor, InlineChatZoneWidget._options);
this._ctxCursorPosition = CTX_INLINE_CHAT_OUTER_CURSOR_POSITION.bindTo(contextKeyService);
@ -63,6 +76,7 @@ export class InlineChatZoneWidget extends ZoneWidget {
}
},
secondaryMenuId: MENU_INLINE_CHAT_WIDGET_SECONDARY,
inZoneWidget: true,
chatWidgetViewOptions: {
menus: {
telemetrySource: 'interactiveEditorWidget-toolbar',
@ -123,6 +137,9 @@ export class InlineChatZoneWidget extends ZoneWidget {
}
protected override _fillContainer(container: HTMLElement): void {
container.style.setProperty('--vscode-inlineChat-background', 'var(--vscode-editor-background)');
container.appendChild(this.widget.domNode);
}
@ -140,7 +157,7 @@ export class InlineChatZoneWidget extends ZoneWidget {
const chatContentHeight = this.widget.contentHeight;
const editorHeight = this.editor.getLayoutInfo().height;
const contentHeight = Math.min(chatContentHeight, Math.max(this.widget.minHeight, editorHeight * 0.42));
const contentHeight = this._decoratingElementsHeight() + Math.min(chatContentHeight, Math.max(this.widget.minHeight, editorHeight * 0.42));
const heightInLines = contentHeight / this.editor.getOption(EditorOption.lineHeight);
return { linesValue: heightInLines, pixelsValue: contentHeight };
}
@ -155,8 +172,8 @@ export class InlineChatZoneWidget extends ZoneWidget {
assertType(this.container);
const info = this.editor.getLayoutInfo();
const marginWithoutIndentation = info.glyphMarginWidth + info.decorationsWidth + info.lineNumbersWidth;
this.container.style.marginLeft = `${marginWithoutIndentation}px`;
const marginWithoutIndentation = info.glyphMarginWidth + info.lineNumbersWidth;
this.container.style.paddingLeft = `${marginWithoutIndentation}px`;
const revealZone = this._createZoneAndScrollRestoreFn(position);
super.show(position, this._computeHeight().linesValue);

View File

@ -3,13 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench .zone-widget.inline-chat-widget {
z-index: 3;
}
.monaco-workbench .zone-widget.inline-chat-widget .interactive-session {
max-width: unset;
}
.monaco-workbench .inline-chat {
color: inherit;
@ -21,6 +14,40 @@
position: relative;
}
.monaco-workbench .zone-widget.inline-chat-widget {
z-index: 3;
}
.monaco-workbench .zone-widget.inline-chat-widget .interactive-session {
max-width: unset;
}
.monaco-workbench .zone-widget.inline-chat-widget .interactive-session .chat-input-container {
border-color: var(--vscode-inlineChat-border);
}
.monaco-workbench .zone-widget.inline-chat-widget .interactive-session .chat-input-container:focus-within {
border-color: var(--vscode-focusBorder);
}
.monaco-workbench .zone-widget.inline-chat-widget .interactive-session .chat-input-container .interactive-input-part {
padding-top: 0px
}
.monaco-workbench .zone-widget.inline-chat-widget > .zone-widget-container {
background: var(--vscode-inlineChat-background);
}
.monaco-workbench .zone-widget.inline-chat-widget > .zone-widget-container > .inline-chat {
color: inherit;
border-radius: unset;
border: unset;
box-shadow: unset;
background: var(--vscode-inlineChat-background);
position: relative;
outline: none;
}
.monaco-workbench .inline-chat .chat-widget .interactive-session .interactive-input-part {
padding: 4px 8px 0 8px;
}