Merge pull request #136177 from jeanp413/fix-135596

Fixes error: can't run recursive splices when renaming a terminal tab
This commit is contained in:
Daniel Imms 2021-11-02 07:14:42 -07:00 committed by GitHub
commit 0577803a09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 17 deletions

View file

@ -178,7 +178,8 @@ export interface ITerminalService extends ITerminalInstanceHost {
requestStartExtensionTerminal(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): Promise<ITerminalLaunchError | undefined>;
isAttachedToTerminal(remoteTerm: IRemoteTerminalAttachTarget): boolean;
getEditableData(instance: ITerminalInstance): IEditableData | undefined;
setEditable(instance: ITerminalInstance, data: IEditableData | null): Promise<void>;
setEditable(instance: ITerminalInstance, data: IEditableData | null): void;
isEditable(instance: ITerminalInstance | undefined): boolean;
safeDisposeTerminal(instance: ITerminalInstance): Promise<void>;
getDefaultInstanceHost(): ITerminalInstanceHost;

View file

@ -880,9 +880,11 @@ export function registerTerminalActions() {
return;
}
await terminalService.setEditable(instance, {
terminalService.setEditable(instance, {
validationMessage: value => validateTerminalName(value),
onFinish: async (value, success) => {
// Cancel editing first as instance.rename will trigger a rerender automatically
terminalService.setEditable(instance, null);
if (success) {
try {
await instance.rename(value);
@ -890,7 +892,6 @@ export function registerTerminalActions() {
notificationService.error(e);
}
}
await terminalService.setEditable(instance, null);
}
});
}

View file

@ -477,18 +477,18 @@ export class TerminalService implements ITerminalService {
return this.activeInstance || this.createTerminal();
}
async setEditable(instance: ITerminalInstance, data?: IEditableData | null): Promise<void> {
setEditable(instance: ITerminalInstance, data?: IEditableData | null): void {
if (!data) {
this._editable = undefined;
} else {
this._editable = { instance: instance, data };
}
const pane = this._viewsService.getActiveViewWithId<TerminalViewPane>(TERMINAL_VIEW_ID);
const isEditing = this._isEditable(instance);
const isEditing = this.isEditable(instance);
pane?.terminalTabbedView?.setEditable(isEditing);
}
private _isEditable(instance: ITerminalInstance | undefined): boolean {
isEditable(instance: ITerminalInstance | undefined): boolean {
return !!this._editable && (this._editable.instance === instance || !instance);
}

View file

@ -439,7 +439,7 @@ export class TerminalTabbedView extends Disposable {
if (!isEditing) {
this._tabList.domFocus();
}
return this._tabList.refresh();
this._tabList.refresh(false);
}
focusTabs(): void {

View file

@ -192,7 +192,11 @@ export class TerminalTabList extends WorkbenchList<ITerminalInstance> {
return this._configurationService.getValue<'singleClick' | 'doubleClick'>(TerminalSettingId.TabsFocusMode);
}
refresh(): void {
refresh(cancelEditing: boolean = true): void {
if (cancelEditing && this._terminalService.isEditable(undefined)) {
this.domFocus();
}
this.splice(0, this.length, this._terminalGroupService.instances.slice());
}
@ -324,12 +328,12 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
template.actionBar.clear();
}
if (!template.elementDispoables) {
template.elementDispoables = new DisposableStore();
if (!template.elementDisposables) {
template.elementDisposables = new DisposableStore();
}
// Kill terminal on middle click
template.elementDispoables.add(DOM.addDisposableListener(template.element, DOM.EventType.AUXCLICK, e => {
template.elementDisposables.add(DOM.addDisposableListener(template.element, DOM.EventType.AUXCLICK, e => {
e.stopImmediatePropagation();
if (e.button === 1/*middle*/) {
this._terminalService.safeDisposeTerminal(instance);
@ -364,14 +368,13 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
const editableData = this._terminalService.getEditableData(instance);
template.label.element.classList.toggle('editable-tab', !!editableData);
if (editableData) {
this._renderInputBox(template.label.element.querySelector('.monaco-icon-label-container')!, instance, editableData);
template.elementDisposables.add(this._renderInputBox(template.label.element.querySelector('.monaco-icon-label-container')!, instance, editableData));
template.actionBar.clear();
}
}
private _renderInputBox(container: HTMLElement, instance: ITerminalInstance, editableData: IEditableData): IDisposable {
const label = this._labels.create(container);
const value = instance.title || '';
const inputBox = new InputBox(container, this._contextViewService, {
@ -439,7 +442,6 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => {
done(inputBox.isInputValid(), true);
}),
label,
styler
];
@ -449,11 +451,14 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
}
disposeElement(instance: ITerminalInstance, index: number, templateData: ITerminalTabEntryTemplate): void {
templateData.elementDispoables?.dispose();
templateData.elementDispoables = undefined;
templateData.elementDisposables?.dispose();
templateData.elementDisposables = undefined;
}
disposeTemplate(templateData: ITerminalTabEntryTemplate): void {
templateData.elementDisposables?.dispose();
templateData.elementDisposables = undefined;
templateData.label.dispose();
}
fillActionBar(instance: ITerminalInstance, template: ITerminalTabEntryTemplate): void {
@ -496,7 +501,7 @@ interface ITerminalTabEntryTemplate {
context: {
hoverActions?: IHoverAction[];
};
elementDispoables?: DisposableStore;
elementDisposables?: DisposableStore;
}