Skip to content

Commit

Permalink
Merge pull request #207888 from microsoft/tyriar/207488
Browse files Browse the repository at this point in the history
Simplify terminal chat layout, fix width of content
  • Loading branch information
Tyriar authored Mar 15, 2024
2 parents a737ec7 + af87eac commit ca3acd1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
visibility: hidden;
}

.terminal-inline-chat .chatMessageContent {
width: 400px !important;
}

.terminal-inline-chat .chatMessageContent .value {
padding-top: 10px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ export class TerminalChatController extends Disposable implements ITerminalContr
this._chatAccessibilityService.acceptResponse(responseContent, accessibilityRequestId);
const containsCode = responseContent.includes('```');
this._chatWidget?.value.inlineChatWidget.updateChatMessage({ message: new MarkdownString(responseContent), requestId: this._currentRequest.id, providerId: 'terminal' }, false, containsCode);
this._chatWidget?.value.updateHeight();
this._responseContainsCodeBlockContextKey.set(containsCode);
this._chatWidget?.value.inlineChatWidget.updateToolbar(true);
this._messages.fire(Message.ACCEPT_INPUT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/

import { Dimension, IFocusTracker, trackFocus } from 'vs/base/browser/dom';
import { Disposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import 'vs/css!./media/terminalChatWidget';
import { localize } from 'vs/nls';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
Expand All @@ -14,8 +15,9 @@ import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inline
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
import { MENU_TERMINAL_CHAT_INPUT, MENU_TERMINAL_CHAT_WIDGET, MENU_TERMINAL_CHAT_WIDGET_FEEDBACK, MENU_TERMINAL_CHAT_WIDGET_STATUS, TerminalChatContextKeys } from 'vs/workbench/contrib/terminalContrib/chat/browser/terminalChat';

const widgetHeightMargin = 100;
const widgetWidthMargin = 40;
const enum Constants {
HorizontalMargin = 10
}

export class TerminalChatWidget extends Disposable {

Expand All @@ -30,7 +32,7 @@ export class TerminalChatWidget extends Disposable {
private readonly _visibleContextKey: IContextKey<boolean>;

constructor(
terminalElement: HTMLElement,
private readonly _terminalElement: HTMLElement,
private readonly _instance: ITerminalInstance,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService
Expand All @@ -42,7 +44,7 @@ export class TerminalChatWidget extends Disposable {

this._container = document.createElement('div');
this._container.classList.add('terminal-inline-chat');
terminalElement.appendChild(this._container);
_terminalElement.appendChild(this._container);

this._inlineChatWidget = this._instantiationService.createInstance(
InlineChatWidget,
Expand All @@ -54,73 +56,80 @@ export class TerminalChatWidget extends Disposable {
telemetrySource: 'terminal-inline-chat'
}
);
this._register(Event.any(
this._inlineChatWidget.onDidChangeHeight,
this._instance.onDimensionsChanged,
)(() => this._relayout()));

const observer = new ResizeObserver(() => this._relayout());
observer.observe(this._terminalElement);
this._register(toDisposable(() => observer.disconnect()));

this._reset();
this._container.appendChild(this._inlineChatWidget.domNode);

this._focusTracker = this._register(trackFocus(this._container));
}

private _dimension?: Dimension;

private _relayout() {
if (this._dimension) {
this._doLayout(this._inlineChatWidget.getHeight());
}
}

private _doLayout(heightInPixel: number) {
const width = Math.min(640, this._terminalElement.clientWidth - 12/* padding */ - 2/* border */ - Constants.HorizontalMargin);
const height = Math.min(480, heightInPixel, this._getTerminalHeight() ?? Number.MAX_SAFE_INTEGER);
if (width === 0 || height === 0) {
return;
}
this._dimension = new Dimension(width, height);
this._inlineChatWidget.layout(this._dimension);
this._updateVerticalPosition();
}

private _reset() {
this._inlineChatWidget.placeholder = localize('default.placeholder', "Ask how to do something in the terminal");
this._inlineChatWidget.updateInfo(localize('welcome.1', "AI-generated commands may be incorrect"));
}

reveal(): void {
this._inlineChatWidget.layout(new Dimension(640, 150));
this._doLayout(this._inlineChatWidget.getHeight());
this._container.classList.remove('hide');
this._focusedContextKey.set(true);
this._visibleContextKey.set(true);
this._inlineChatWidget.focus();
this.updateHeight();
this._updateWidth();
this._register(this._instance.onDimensionsChanged(() => {
this.updateHeight();
this._updateWidth();
}));
}

private _updateVerticalPosition(): void {
const font = this._instance.xterm?.getFont();
if (!font?.charHeight) {
return;
}
const terminalWrapperHeight = this._getTerminalHeight() ?? 0;
const cellHeight = font.charHeight * font.lineHeight;
const topPadding = terminalWrapperHeight - (this._instance.rows * cellHeight);
const cursorY = (this._instance.xterm?.raw.buffer.active.cursorY ?? 0) + 1;
const height = font.charHeight * font.lineHeight;
const top = cursorY * height + 12;
const top = topPadding + cursorY * cellHeight;
this._container.style.top = `${top}px`;
const widgetHeight = this._inlineChatWidget.getHeight();
const terminalHeight = this._getTerminalHeight();
if (!terminalHeight) {
if (!terminalWrapperHeight) {
return;
}
if (top > terminalHeight - widgetHeight) {
if (top > terminalWrapperHeight - widgetHeight) {
this._container.style.top = '';
}
}

private _getTerminalHeight(): number | undefined {
const font = this._instance.xterm?.getFont();
if (!font?.charHeight) {
return;
}
return font.charHeight * font.lineHeight * this._instance.rows;

}

updateHeight() {
const terminalHeight = this._getTerminalHeight();
if (!terminalHeight || terminalHeight < widgetHeightMargin) {
return;
}
this._inlineChatWidget.layout(new Dimension(this._inlineChatWidget.domNode.clientWidth, terminalHeight - widgetHeightMargin));
this._updateVerticalPosition();
}

private _updateWidth() {
const terminalWidth = this._instance.domElement.clientWidth;
if (terminalWidth && terminalWidth < 640) {
this._inlineChatWidget.layout(new Dimension(terminalWidth - widgetWidthMargin, this._inlineChatWidget.getHeight()));
}
return this._terminalElement.clientHeight;
// const font = this._instance.xterm?.getFont();
// if (!font?.charHeight) {
// return;
// }
// return font.charHeight * font.lineHeight * this._instance.rows;
}

hide(): void {
Expand Down

0 comments on commit ca3acd1

Please sign in to comment.