Skip to content

Commit

Permalink
Offset terminal when inline chat appears to ensure cursor is visible
Browse files Browse the repository at this point in the history
This will overlay the terminal inline chat widget on top of the terminal the same
as previously where the cursor would be visible. If it would not be visible, the
terminal wrapper element is now shifted upwards to ensure it's visible. This comes
with a couple of downsides:

- The very top of the terminal cannot be accessed as overflow is clipped by the
  view.
- The chat may overlap content if there is any below the cursor, which is an
  unlikely edge case.

This isn't as good as a zone widget-like system in xterm.js could be, but that is
quite the undertaking and complicates the renderer code quite a bit. So this is
a good compromise.

Fixes #4720
  • Loading branch information
Tyriar committed Apr 12, 2024
1 parent a43d090 commit 9675a34
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { Dimension, IFocusTracker, trackFocus } from 'vs/base/browser/dom';
import { Event } from 'vs/base/common/event';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { MicrotaskDelay } from 'vs/base/common/symbols';
import 'vs/css!./media/terminalChatWidget';
import { localize } from 'vs/nls';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
Expand All @@ -15,6 +16,7 @@ import { IChatProgress } from 'vs/workbench/contrib/chat/common/chatService';
import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatWidget';
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, TerminalChatCommandId, TerminalChatContextKeys } from 'vs/workbench/contrib/terminalContrib/chat/browser/terminalChat';
import { TerminalStickyScrollContribution } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollContribution';

const enum Constants {
HorizontalMargin = 10
Expand Down Expand Up @@ -73,6 +75,7 @@ export class TerminalChatWidget extends Disposable {
this._register(Event.any(
this._inlineChatWidget.onDidChangeHeight,
this._instance.onDimensionsChanged,
Event.debounce(this._instance.xterm!.raw.onCursorMove, () => void 0, MicrotaskDelay),
)(() => this._relayout()));

const observer = new ResizeObserver(() => this._relayout());
Expand Down Expand Up @@ -102,6 +105,7 @@ export class TerminalChatWidget extends Disposable {
}
this._dimension = new Dimension(width, height);
this._inlineChatWidget.layout(this._dimension);

this._updateVerticalPosition();
}

Expand Down Expand Up @@ -134,7 +138,9 @@ export class TerminalChatWidget extends Disposable {
return;
}
if (top > terminalWrapperHeight - widgetHeight) {
this._container.style.top = '';
this._setTerminalOffset(widgetHeight);
} else {
this._setTerminalOffset(undefined);
}
}

Expand All @@ -154,6 +160,19 @@ export class TerminalChatWidget extends Disposable {
this._visibleContextKey.set(false);
this._inlineChatWidget.value = '';
this._instance.focus();
this._setTerminalOffset(undefined);
}
private _setTerminalOffset(offset: number | undefined) {
if (offset === undefined || this._container.classList.contains('hide')) {
this._terminalElement.style.position = '';
this._terminalElement.style.bottom = '';
TerminalStickyScrollContribution.get(this._instance)?.hideUnlock();
} else {
this._terminalElement.style.position = 'relative';
this._terminalElement.style.bottom = `${offset}px`;
TerminalStickyScrollContribution.get(this._instance)?.hideLock();

}
}
focus(): void {
this._inlineChatWidget.focus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ export class TerminalStickyScrollContribution extends Disposable implements ITer
this._refreshState();
}

hideLock() {
this._overlay.value?.lockHide();
}

hideUnlock() {
this._overlay.value?.unlockHide();
}

private _refreshState(): void {
if (this._overlay.value) {
this._tryDisable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ export class TerminalStickyScrollOverlay extends Disposable {
});
}

lockHide() {
this._element?.classList.add('lock-hide');
}

unlockHide() {
this._element?.classList.remove('lock-hide');
}

private _setState(state: OverlayState) {
if (this._state === state) {
return;
Expand Down

0 comments on commit 9675a34

Please sign in to comment.