From 61c11abda227f1bcd70e29d72a5a7145a2de30bb Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Mon, 10 Jan 2022 20:39:29 +0100 Subject: [PATCH] don't include tab state in saved layouts --- tabby-core/src/api/index.ts | 2 +- tabby-core/src/api/tabRecovery.ts | 11 -------- .../src/components/baseTab.component.ts | 6 ++++- .../src/components/splitTab.component.ts | 27 +++++++------------ tabby-core/src/profiles.ts | 2 +- tabby-core/src/services/app.service.ts | 2 +- .../src/services/tabRecovery.service.ts | 13 ++++----- tabby-core/src/services/tabs.service.ts | 3 ++- .../src/components/terminalTab.component.ts | 8 +++--- tabby-local/src/recoveryProvider.ts | 14 ---------- .../src/components/serialTab.component.ts | 6 ++--- tabby-ssh/src/components/sshTab.component.ts | 6 ++--- tabby-ssh/src/recoveryProvider.ts | 7 ----- .../src/components/telnetTab.component.ts | 6 ++--- tabby-telnet/src/recoveryProvider.ts | 7 ----- 15 files changed, 38 insertions(+), 82 deletions(-) diff --git a/tabby-core/src/api/index.ts b/tabby-core/src/api/index.ts index bef85915..ee916fc7 100644 --- a/tabby-core/src/api/index.ts +++ b/tabby-core/src/api/index.ts @@ -1,5 +1,5 @@ export { BaseComponent, SubscriptionContainer } from '../components/base.component' -export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component' +export { BaseTabComponent, BaseTabProcess, GetRecoveryTokenOptions } from '../components/baseTab.component' export { TabHeaderComponent } from '../components/tabHeader.component' export { SplitTabComponent, SplitContainer, SplitDirection, SplitOrientation } from '../components/splitTab.component' export { TabRecoveryProvider, RecoveryToken } from './tabRecovery' diff --git a/tabby-core/src/api/tabRecovery.ts b/tabby-core/src/api/tabRecovery.ts index c804d261..51257c68 100644 --- a/tabby-core/src/api/tabRecovery.ts +++ b/tabby-core/src/api/tabRecovery.ts @@ -1,4 +1,3 @@ -import deepClone from 'clone-deep' import { BaseTabComponent } from '../components/baseTab.component' import { NewTabParameters } from '../services/tabs.service' @@ -38,14 +37,4 @@ export abstract class TabRecoveryProvider { * or `null` if this token is from a different tab type or is not supported */ abstract recover (recoveryToken: RecoveryToken): Promise> - - /** - * @param recoveryToken a recovery token found in the saved tabs list - * @returns [[RecoveryToken]] a new recovery token to create the duplicate tab from - * - * The default implementation just returns a deep copy of the original token - */ - duplicate (recoveryToken: RecoveryToken): RecoveryToken { - return deepClone(recoveryToken) - } } diff --git a/tabby-core/src/components/baseTab.component.ts b/tabby-core/src/components/baseTab.component.ts index 79bf4181..9ef8250a 100644 --- a/tabby-core/src/components/baseTab.component.ts +++ b/tabby-core/src/components/baseTab.component.ts @@ -11,6 +11,10 @@ export interface BaseTabProcess { name: string } +export interface GetRecoveryTokenOptions { + includeState: boolean +} + /** * Abstract base class for custom tab components */ @@ -136,7 +140,7 @@ export abstract class BaseTabComponent extends BaseComponent { * @return JSON serializable tab state representation * for your [[TabRecoveryProvider]] to parse */ - async getRecoveryToken (): Promise { + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { // eslint-disable-line @typescript-eslint/no-unused-vars return null } diff --git a/tabby-core/src/components/splitTab.component.ts b/tabby-core/src/components/splitTab.component.ts index 600a2336..cf70d54c 100644 --- a/tabby-core/src/components/splitTab.component.ts +++ b/tabby-core/src/components/splitTab.component.ts @@ -1,6 +1,6 @@ import { Observable, Subject } from 'rxjs' import { Component, Injectable, ViewChild, ViewContainerRef, EmbeddedViewRef, AfterViewInit, OnDestroy } from '@angular/core' -import { BaseTabComponent, BaseTabProcess } from './baseTab.component' +import { BaseTabComponent, BaseTabProcess, GetRecoveryTokenOptions } from './baseTab.component' import { TabRecoveryProvider, RecoveryToken } from '../api/tabRecovery' import { TabsService, NewTabParameters } from '../services/tabs.service' import { HotkeysService } from '../services/hotkeys.service' @@ -93,13 +93,13 @@ export class SplitContainer { return s } - async serialize (tabsRecovery: TabRecoveryService): Promise { + async serialize (tabsRecovery: TabRecoveryService, options?: GetRecoveryTokenOptions): Promise { const children: any[] = [] for (const child of this.children) { if (child instanceof SplitContainer) { - children.push(await child.serialize(tabsRecovery)) + children.push(await child.serialize(tabsRecovery, options)) } else { - children.push(await tabsRecovery.getFullRecoveryToken(child)) + children.push(await tabsRecovery.getFullRecoveryToken(child, options)) } } return { @@ -308,7 +308,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit /** @hidden */ async ngAfterViewInit (): Promise { if (this._recoveredState) { - await this.recoverContainer(this.root, this._recoveredState, this._recoveredState.duplicate) + await this.recoverContainer(this.root, this._recoveredState) this.updateTitle() this.layout() setTimeout(() => { @@ -574,8 +574,8 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit } /** @hidden */ - async getRecoveryToken (): Promise { - return this.root.serialize(this.tabRecovery) + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { + return this.root.serialize(this.tabRecovery, options) } /** @hidden */ @@ -795,7 +795,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit }) } - private async recoverContainer (root: SplitContainer, state: any, duplicate = false) { + private async recoverContainer (root: SplitContainer, state: any) { const children: (SplitContainer | BaseTabComponent)[] = [] root.orientation = state.orientation root.ratios = state.ratios @@ -806,10 +806,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit } if (childState.type === 'app:split-tab') { const child = new SplitContainer() - await this.recoverContainer(child, childState, duplicate) + await this.recoverContainer(child, childState) children.push(child) } else { - const recovered = await this.tabRecovery.recoverTab(childState, duplicate) + const recovered = await this.tabRecovery.recoverTab(childState) if (recovered) { const tab = this.tabsService.create(recovered) children.push(tab) @@ -840,11 +840,4 @@ export class SplitTabRecoveryProvider extends TabRecoveryProvider { - const token = await tab.getRecoveryToken() + const token = await tab.getRecoveryToken({ includeState: false }) const profile: PartialProfile = { id: `${this.id}:custom:${slugify(name)}:${uuidv4()}`, type: this.id, diff --git a/tabby-core/src/services/app.service.ts b/tabby-core/src/services/app.service.ts index 089503ea..58b914ab 100644 --- a/tabby-core/src/services/app.service.ts +++ b/tabby-core/src/services/app.service.ts @@ -318,7 +318,7 @@ export class AppService { if (checkCanClose && !await tab.canClose()) { return } - const token = await this.tabRecovery.getFullRecoveryToken(tab) + const token = await this.tabRecovery.getFullRecoveryToken(tab, { includeState: true }) if (token) { this.closedTabsStack.push(token) } diff --git a/tabby-core/src/services/tabRecovery.service.ts b/tabby-core/src/services/tabRecovery.service.ts index 4d674643..9f64c0a1 100644 --- a/tabby-core/src/services/tabRecovery.service.ts +++ b/tabby-core/src/services/tabRecovery.service.ts @@ -1,6 +1,6 @@ import { Injectable, Inject } from '@angular/core' import { TabRecoveryProvider, RecoveryToken } from '../api/tabRecovery' -import { BaseTabComponent } from '../components/baseTab.component' +import { BaseTabComponent, GetRecoveryTokenOptions } from '../components/baseTab.component' import { Logger, LogService } from './log.service' import { ConfigService } from './config.service' import { NewTabParameters } from './tabs.service' @@ -25,13 +25,13 @@ export class TabRecoveryService { } window.localStorage.tabsRecovery = JSON.stringify( (await Promise.all( - tabs.map(async tab => this.getFullRecoveryToken(tab)) + tabs.map(async tab => this.getFullRecoveryToken(tab, { includeState: true })) )).filter(token => !!token) ) } - async getFullRecoveryToken (tab: BaseTabComponent): Promise { - const token = await tab.getRecoveryToken() + async getFullRecoveryToken (tab: BaseTabComponent, options?: GetRecoveryTokenOptions): Promise { + const token = await tab.getRecoveryToken(options) if (token) { token.tabTitle = tab.title token.tabCustomTitle = tab.customTitle @@ -43,15 +43,12 @@ export class TabRecoveryService { return token } - async recoverTab (token: RecoveryToken, duplicate = false): Promise|null> { + async recoverTab (token: RecoveryToken): Promise|null> { for (const provider of this.config.enabledServices(this.tabRecoveryProviders ?? [])) { try { if (!await provider.applicableTo(token)) { continue } - if (duplicate) { - token = provider.duplicate(token) - } const tab = await provider.recover(token) tab.inputs = tab.inputs ?? {} tab.inputs.color = token.tabColor ?? null diff --git a/tabby-core/src/services/tabs.service.ts b/tabby-core/src/services/tabs.service.ts index 652ee880..30683be2 100644 --- a/tabby-core/src/services/tabs.service.ts +++ b/tabby-core/src/services/tabs.service.ts @@ -1,3 +1,4 @@ +import deepClone from 'clone-deep' import { Injectable, ComponentFactoryResolver, Injector } from '@angular/core' import { BaseTabComponent } from '../components/baseTab.component' import { TabRecoveryService } from './tabRecovery.service' @@ -48,7 +49,7 @@ export class TabsService { if (!token) { return null } - const dup = await this.tabRecovery.recoverTab(token, true) + const dup = await this.tabRecovery.recoverTab(deepClone(token)) if (dup) { return this.create(dup) } diff --git a/tabby-local/src/components/terminalTab.component.ts b/tabby-local/src/components/terminalTab.component.ts index 85199539..cdf66999 100644 --- a/tabby-local/src/components/terminalTab.component.ts +++ b/tabby-local/src/components/terminalTab.component.ts @@ -1,5 +1,5 @@ import { Component, Input, Injector } from '@angular/core' -import { BaseTabProcess, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild } from 'tabby-core' +import { BaseTabProcess, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild, GetRecoveryTokenOptions } from 'tabby-core' import { BaseTerminalTabComponent } from 'tabby-terminal' import { LocalProfile, SessionOptions } from '../api' import { Session } from '../session' @@ -74,7 +74,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent { this.recoveryStateChangedHint.next() } - async getRecoveryToken (): Promise { + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { const cwd = this.session ? await this.session.getWorkingDirectory() : null return { type: 'app:local-tab', @@ -83,10 +83,10 @@ export class TerminalTabComponent extends BaseTerminalTabComponent { options: { ...this.profile.options, cwd: cwd ?? this.profile.options.cwd, - restoreFromPTYID: this.session?.getPTYID(), + restoreFromPTYID: options?.includeState && this.session?.getPTYID(), }, }, - savedState: this.frontend?.saveState(), + savedState: options?.includeState && this.frontend?.saveState(), } } diff --git a/tabby-local/src/recoveryProvider.ts b/tabby-local/src/recoveryProvider.ts index 2a8fe1c5..d34d1b98 100644 --- a/tabby-local/src/recoveryProvider.ts +++ b/tabby-local/src/recoveryProvider.ts @@ -19,18 +19,4 @@ export class RecoveryProvider extends TabRecoveryProvider }, } } - - duplicate (recoveryToken: RecoveryToken): RecoveryToken { - return { - ...recoveryToken, - profile: { - ...recoveryToken.profile, - options: { - ...recoveryToken.profile.options, - restoreFromPTYID: null, - }, - }, - savedState: null, - } - } } diff --git a/tabby-serial/src/components/serialTab.component.ts b/tabby-serial/src/components/serialTab.component.ts index e8dce40e..8ff956be 100644 --- a/tabby-serial/src/components/serialTab.component.ts +++ b/tabby-serial/src/components/serialTab.component.ts @@ -2,7 +2,7 @@ import colors from 'ansi-colors' import { Component, Injector } from '@angular/core' import { first } from 'rxjs' -import { Platform, SelectorService } from 'tabby-core' +import { GetRecoveryTokenOptions, Platform, SelectorService } from 'tabby-core' import { BaseTerminalTabComponent } from 'tabby-terminal' import { SerialSession, BAUD_RATES, SerialProfile } from '../api' @@ -98,11 +98,11 @@ export class SerialTabComponent extends BaseTerminalTabComponent { super.attachSessionHandlers() } - async getRecoveryToken (): Promise { + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { return { type: 'app:serial-tab', profile: this.profile, - savedState: this.frontend?.saveState(), + savedState: options?.includeState && this.frontend?.saveState(), } } diff --git a/tabby-ssh/src/components/sshTab.component.ts b/tabby-ssh/src/components/sshTab.component.ts index 5e9bb799..aeaf970e 100644 --- a/tabby-ssh/src/components/sshTab.component.ts +++ b/tabby-ssh/src/components/sshTab.component.ts @@ -2,7 +2,7 @@ import colors from 'ansi-colors' import { Component, Injector, HostListener } from '@angular/core' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { first } from 'rxjs' -import { Platform, ProfilesService, RecoveryToken } from 'tabby-core' +import { GetRecoveryTokenOptions, Platform, ProfilesService, RecoveryToken } from 'tabby-core' import { BaseTerminalTabComponent } from 'tabby-terminal' import { SSHService } from '../services/ssh.service' import { KeyboardInteractivePrompt, SSHSession } from '../session/ssh' @@ -210,11 +210,11 @@ export class SSHTabComponent extends BaseTerminalTabComponent { this.session?.resize(this.size.columns, this.size.rows) } - async getRecoveryToken (): Promise { + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { return { type: 'app:ssh-tab', profile: this.profile, - savedState: this.frontend?.saveState(), + savedState: options?.includeState && this.frontend?.saveState(), } } diff --git a/tabby-ssh/src/recoveryProvider.ts b/tabby-ssh/src/recoveryProvider.ts index 7817c600..646164f5 100644 --- a/tabby-ssh/src/recoveryProvider.ts +++ b/tabby-ssh/src/recoveryProvider.ts @@ -19,11 +19,4 @@ export class RecoveryProvider extends TabRecoveryProvider { }, } } - - duplicate (recoveryToken: RecoveryToken): RecoveryToken { - return { - ...recoveryToken, - savedState: null, - } - } } diff --git a/tabby-telnet/src/components/telnetTab.component.ts b/tabby-telnet/src/components/telnetTab.component.ts index 2330c3d4..33db4159 100644 --- a/tabby-telnet/src/components/telnetTab.component.ts +++ b/tabby-telnet/src/components/telnetTab.component.ts @@ -1,7 +1,7 @@ import colors from 'ansi-colors' import { Component, Injector } from '@angular/core' import { first } from 'rxjs' -import { Platform, RecoveryToken } from 'tabby-core' +import { GetRecoveryTokenOptions, Platform, RecoveryToken } from 'tabby-core' import { BaseTerminalTabComponent } from 'tabby-terminal' import { TelnetProfile, TelnetSession } from '../session' @@ -97,11 +97,11 @@ export class TelnetTabComponent extends BaseTerminalTabComponent { } } - async getRecoveryToken (): Promise { + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { return { type: 'app:telnet-tab', profile: this.profile, - savedState: this.frontend?.saveState(), + savedState: options?.includeState && this.frontend?.saveState(), } } diff --git a/tabby-telnet/src/recoveryProvider.ts b/tabby-telnet/src/recoveryProvider.ts index 2eec6049..0ed7447b 100644 --- a/tabby-telnet/src/recoveryProvider.ts +++ b/tabby-telnet/src/recoveryProvider.ts @@ -19,11 +19,4 @@ export class RecoveryProvider extends TabRecoveryProvider { }, } } - - duplicate (recoveryToken: RecoveryToken): RecoveryToken { - return { - ...recoveryToken, - savedState: null, - } - } }