From 72287cc7cb791418e4363cf563c8e22bd3c0a290 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Sun, 16 Dec 2018 17:09:35 +0100 Subject: [PATCH] profile settings tab --- .../src/components/tabHeader.component.ts | 7 +++ terminus-terminal/src/api.ts | 5 ++ .../profilesSettingsTab.component.pug | 14 ++++++ .../profilesSettingsTab.component.ts | 25 ++++++++++ .../components/shellSettingsTab.component.pug | 2 +- .../src/components/terminalTab.component.ts | 49 ++++++++++++++----- terminus-terminal/src/config.ts | 1 + .../src/frontends/htermFrontend.ts | 9 +++- terminus-terminal/src/index.ts | 6 ++- .../src/services/terminal.service.ts | 8 ++- terminus-terminal/src/settings.ts | 11 +++++ 11 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 terminus-terminal/src/components/profilesSettingsTab.component.pug create mode 100644 terminus-terminal/src/components/profilesSettingsTab.component.ts diff --git a/terminus-core/src/components/tabHeader.component.ts b/terminus-core/src/components/tabHeader.component.ts index 92e0ca59..af4ee46a 100644 --- a/terminus-core/src/components/tabHeader.component.ts +++ b/terminus-core/src/components/tabHeader.component.ts @@ -111,6 +111,13 @@ export class TabHeaderComponent { } ]) + if ((this.tab as any).saveAsProfile) { + contextMenu.append(new this.electron.MenuItem({ + label: 'Save as a profile', + click: () => this.zone.run(() => (this.tab as any).saveAsProfile()) + })) + } + let process = await this.tab.getCurrentProcess() if (process) { contextMenu.append(new this.electron.MenuItem({ diff --git a/terminus-terminal/src/api.ts b/terminus-terminal/src/api.ts index bcd25e88..12eff19d 100644 --- a/terminus-terminal/src/api.ts +++ b/terminus-terminal/src/api.ts @@ -23,6 +23,11 @@ export interface SessionOptions { pauseAfterExit?: boolean } +export interface Profile { + name: string, + sessionOptions: SessionOptions, +} + export interface ITerminalColorScheme { name: string foreground: string diff --git a/terminus-terminal/src/components/profilesSettingsTab.component.pug b/terminus-terminal/src/components/profilesSettingsTab.component.pug new file mode 100644 index 00000000..047b37c1 --- /dev/null +++ b/terminus-terminal/src/components/profilesSettingsTab.component.pug @@ -0,0 +1,14 @@ +h3 Saved Profiles + +.list-group.mt-3.mb-3 + .list-group-item.list-item-group-action.d-flex.align-items-center( + *ngFor='let profile of profiles', + (click)='editProfile(profile)', + ) + .mr-auto + div {{profile.name}} + .text-muted {{profile.description}} + button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)') + i.fa.fa-trash-o + +.text-muted To add a new profile, right-click a tab and select "Save as a profile" diff --git a/terminus-terminal/src/components/profilesSettingsTab.component.ts b/terminus-terminal/src/components/profilesSettingsTab.component.ts new file mode 100644 index 00000000..a5186dfe --- /dev/null +++ b/terminus-terminal/src/components/profilesSettingsTab.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core' +import { ConfigService } from 'terminus-core' +import { Profile } from '../api' + +@Component({ + template: require('./profilesSettingsTab.component.pug'), +}) +export class ProfilesSettingsTabComponent { + profiles: Profile[] = [] + + constructor ( + private config: ConfigService, + ) { + this.profiles = config.store.terminal.profiles + } + + async ngOnInit () { + } + + deleteProfile (profile: Profile) { + this.profiles = this.profiles.filter(x => x !== profile) + this.config.store.terminal.profiles = this.profiles + this.config.save() + } +} diff --git a/terminus-terminal/src/components/shellSettingsTab.component.pug b/terminus-terminal/src/components/shellSettingsTab.component.pug index a7da811f..e2e4232a 100644 --- a/terminus-terminal/src/components/shellSettingsTab.component.pug +++ b/terminus-terminal/src/components/shellSettingsTab.component.pug @@ -41,7 +41,7 @@ h3.mb-3 Shell button.btn.btn-secondary((click)='pickWorkingDirectory()') i.fa.fa-folder-open -.form-line +.form-line.align-items-start .header .title Environment .description Inject additional environment variables diff --git a/terminus-terminal/src/components/terminalTab.component.ts b/terminus-terminal/src/components/terminalTab.component.ts index de4e25e1..d2f12042 100644 --- a/terminus-terminal/src/components/terminalTab.component.ts +++ b/terminus-terminal/src/components/terminalTab.component.ts @@ -4,7 +4,6 @@ import { ToastrService } from 'ngx-toastr' import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core' import { AppService, ConfigService, BaseTabComponent, BaseTabProcess, ElectronService, HostAppService, HotkeysService, Platform } from 'terminus-core' -import { IShell } from '../api' import { Session, SessionsService } from '../services/sessions.service' import { TerminalService } from '../services/terminal.service' import { TerminalFrontendService } from '../services/terminalFrontend.service' @@ -33,10 +32,8 @@ export class TerminalTabComponent extends BaseTabComponent { sessionCloseSubscription: Subscription hotkeysSubscription: Subscription htermVisible = false - shell: IShell private output = new Subject() private bellPlayer: HTMLAudioElement - private contextMenu: any private termContainerSubscriptions: Subscription[] = [] get input$ (): Observable { return this.frontend.input$ } @@ -203,14 +200,28 @@ export class TerminalTabComponent extends BaseTabComponent { } }) - this.contextMenu = [ + this.frontend.focus() + } + + buildContextMenu (): Electron.MenuItemConstructorOptions[] { + return [ { label: 'New terminal', - click: () => { - this.zone.run(() => { - this.terminalService.openTab(this.shell) - }) - } + click: () => this.zone.run(() => { + this.terminalService.openTabWithOptions(this.sessionOptions) + }) + }, + { + label: 'New from profile', + submenu: this.config.store.terminal.profiles.length ? this.config.store.terminal.profiles.map(profile => ({ + label: profile.name, + click: () => this.zone.run(() => { + this.terminalService.openTabWithOptions(profile.sessionOptions) + }), + })) : [{ + label: 'No profiles saved', + enabled: false, + }], }, { label: 'Copy', @@ -232,8 +243,6 @@ export class TerminalTabComponent extends BaseTabComponent { } }, ] - - this.frontend.focus() } detachTermContainerHandlers () { @@ -255,7 +264,7 @@ export class TerminalTabComponent extends BaseTabComponent { if (event.type === 'mousedown') { if (event.which === 3) { if (this.config.store.terminal.rightClick === 'menu') { - this.hostApp.popupContextMenu(this.contextMenu) + this.hostApp.popupContextMenu(this.buildContextMenu()) } else if (this.config.store.terminal.rightClick === 'paste') { this.paste() } @@ -400,4 +409,20 @@ export class TerminalTabComponent extends BaseTabComponent { } return confirm(`"${children[0].command}" is still running. Close?`) } + + async saveAsProfile () { + let profile = { + sessionOptions: { + ...this.sessionOptions, + cwd: (await this.session.getWorkingDirectory()) || this.sessionOptions.cwd, + }, + name: this.sessionOptions.command, + } + this.config.store.terminal.profiles = [ + ...this.config.store.terminal.profiles, + profile, + ] + this.config.save() + this.toastr.info('Saved') + } } diff --git a/terminus-terminal/src/config.ts b/terminus-terminal/src/config.ts index 34e2625e..3bbc1251 100644 --- a/terminus-terminal/src/config.ts +++ b/terminus-terminal/src/config.ts @@ -51,6 +51,7 @@ export class TerminalConfigProvider extends ConfigProvider { }, customColorSchemes: [], environment: {}, + profiles: [], }, } diff --git a/terminus-terminal/src/frontends/htermFrontend.ts b/terminus-terminal/src/frontends/htermFrontend.ts index 7803379d..4466cb9e 100644 --- a/terminus-terminal/src/frontends/htermFrontend.ts +++ b/terminus-terminal/src/frontends/htermFrontend.ts @@ -153,7 +153,14 @@ export class HTermFrontend extends Frontend { } private setFontSize () { - preferenceManager.set('font-size', this.configuredFontSize * Math.pow(1.1, this.zoom)) + let size = this.configuredFontSize * Math.pow(1.1, this.zoom) + preferenceManager.set('font-size', size) + if (this.term) { + setTimeout(() => { + this.term.scrollPort_.characterSize = this.term.scrollPort_.measureCharacterSize() + this.term.setFontSize(size) + }) + } } private init () { diff --git a/terminus-terminal/src/index.ts b/terminus-terminal/src/index.ts index 842a1c24..03bb7a06 100644 --- a/terminus-terminal/src/index.ts +++ b/terminus-terminal/src/index.ts @@ -13,6 +13,7 @@ import { SettingsTabProvider } from 'terminus-settings' import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component' import { ShellSettingsTabComponent } from './components/shellSettingsTab.component' +import { ProfilesSettingsTabComponent } from './components/profilesSettingsTab.component' import { TerminalTabComponent } from './components/terminalTab.component' import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.component' import { ColorPickerComponent } from './components/colorPicker.component' @@ -24,7 +25,7 @@ import { TerminalService } from './services/terminal.service' import { ButtonProvider } from './buttonProvider' import { RecoveryProvider } from './recoveryProvider' import { TerminalColorSchemeProvider, TerminalDecorator, ShellProvider } from './api' -import { TerminalSettingsTabProvider, AppearanceSettingsTabProvider, ShellSettingsTabProvider } from './settings' +import { TerminalSettingsTabProvider, AppearanceSettingsTabProvider, ShellSettingsTabProvider, ProfilesSettingsTabProvider } from './settings' import { PathDropDecorator } from './pathDrop' import { TerminalConfigProvider } from './config' import { TerminalHotkeyProvider } from './hotkeys' @@ -60,6 +61,7 @@ import { hterm } from './hterm' { provide: SettingsTabProvider, useClass: AppearanceSettingsTabProvider, multi: true }, { provide: SettingsTabProvider, useClass: ShellSettingsTabProvider, multi: true }, + { provide: SettingsTabProvider, useClass: ProfilesSettingsTabProvider, multi: true }, { provide: SettingsTabProvider, useClass: TerminalSettingsTabProvider, multi: true }, { provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true }, @@ -91,6 +93,7 @@ import { hterm } from './hterm' TerminalTabComponent, AppearanceSettingsTabComponent, ShellSettingsTabComponent, + ProfilesSettingsTabComponent, TerminalSettingsTabComponent, ], declarations: [ @@ -98,6 +101,7 @@ import { hterm } from './hterm' TerminalTabComponent, AppearanceSettingsTabComponent, ShellSettingsTabComponent, + ProfilesSettingsTabComponent, TerminalSettingsTabComponent, ], }) diff --git a/terminus-terminal/src/services/terminal.service.ts b/terminus-terminal/src/services/terminal.service.ts index 970df592..bdd1ffa7 100644 --- a/terminus-terminal/src/services/terminal.service.ts +++ b/terminus-terminal/src/services/terminal.service.ts @@ -1,7 +1,7 @@ import { Observable, AsyncSubject } from 'rxjs' import { Injectable, Inject } from '@angular/core' import { AppService, Logger, LogService, ConfigService } from 'terminus-core' -import { IShell, ShellProvider } from '../api' +import { IShell, ShellProvider, SessionOptions } from '../api' import { TerminalTabComponent } from '../components/terminalTab.component' @Injectable() @@ -60,11 +60,15 @@ export class TerminalService { pauseAfterExit: pause, } + return this.openTabWithOptions(sessionOptions) + } + + openTabWithOptions (sessionOptions: SessionOptions): TerminalTabComponent { this.logger.log('Using session options:', sessionOptions) return this.app.openNewTab( TerminalTabComponent, - { sessionOptions, shell } + { sessionOptions } ) as TerminalTabComponent } } diff --git a/terminus-terminal/src/settings.ts b/terminus-terminal/src/settings.ts index 3ce0606a..c6cb91c4 100644 --- a/terminus-terminal/src/settings.ts +++ b/terminus-terminal/src/settings.ts @@ -4,6 +4,7 @@ import { SettingsTabProvider } from 'terminus-settings' import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component' import { ShellSettingsTabComponent } from './components/shellSettingsTab.component' import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.component' +import { ProfilesSettingsTabComponent } from './components/profilesSettingsTab.component' @Injectable() export class AppearanceSettingsTabProvider extends SettingsTabProvider { @@ -34,3 +35,13 @@ export class TerminalSettingsTabProvider extends SettingsTabProvider { return TerminalSettingsTabComponent } } + +@Injectable() +export class ProfilesSettingsTabProvider extends SettingsTabProvider { + id = 'profiles' + title = 'Profiles' + + getComponentType (): any { + return ProfilesSettingsTabComponent + } +}