diff --git a/terminus-core/src/services/config.service.ts b/terminus-core/src/services/config.service.ts index 1ff0d581..b45d43e3 100644 --- a/terminus-core/src/services/config.service.ts +++ b/terminus-core/src/services/config.service.ts @@ -155,6 +155,8 @@ export class ConfigService { } save (): void { + // Scrub undefined values + this._store = JSON.parse(JSON.stringify(this._store)) fs.writeFileSync(this.path, yaml.safeDump(this._store), 'utf8') this.emitChange() this.hostApp.broadcastConfigChange(this.store) diff --git a/terminus-terminal/src/api/interfaces.ts b/terminus-terminal/src/api/interfaces.ts index 4fa98fa3..f19a5e0d 100644 --- a/terminus-terminal/src/api/interfaces.ts +++ b/terminus-terminal/src/api/interfaces.ts @@ -19,6 +19,7 @@ export interface Profile { name: string color?: string sessionOptions: SessionOptions + shell?: string isBuiltin?: boolean icon?: string } diff --git a/terminus-terminal/src/components/shellSettingsTab.component.pug b/terminus-terminal/src/components/shellSettingsTab.component.pug index ab12d6e1..342c167e 100644 --- a/terminus-terminal/src/components/shellSettingsTab.component.pug +++ b/terminus-terminal/src/components/shellSettingsTab.component.pug @@ -11,7 +11,7 @@ h3.mb-3 Shell ) option( *ngFor='let profile of profiles', - [ngValue]='slugify(profile.name).toLowerCase()' + [ngValue]='terminal.getProfileID(profile)' ) {{profile.name}} diff --git a/terminus-terminal/src/components/shellSettingsTab.component.ts b/terminus-terminal/src/components/shellSettingsTab.component.ts index 605ee2f5..e5e075a5 100644 --- a/terminus-terminal/src/components/shellSettingsTab.component.ts +++ b/terminus-terminal/src/components/shellSettingsTab.component.ts @@ -1,4 +1,3 @@ -import slugify from 'slugify' import { Component } from '@angular/core' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { Subscription } from 'rxjs' @@ -17,14 +16,13 @@ export class ShellSettingsTabComponent { Platform = Platform isConPTYAvailable: boolean isConPTYStable: boolean - slugify = slugify private configSubscription: Subscription constructor ( public config: ConfigService, public hostApp: HostAppService, + public terminal: TerminalService, private electron: ElectronService, - private terminalService: TerminalService, private ngbModal: NgbModal, ) { config.store.terminal.environment = config.store.terminal.environment || {} @@ -38,7 +36,7 @@ export class ShellSettingsTabComponent { } async ngOnInit (): Promise { - this.shells = await this.terminalService.shells$.toPromise() + this.shells = await this.terminal.shells$.toPromise() } ngOnDestroy (): void { @@ -46,21 +44,22 @@ export class ShellSettingsTabComponent { } async reload (): Promise { - this.profiles = await this.terminalService.getProfiles({ includeHidden: true }) + this.profiles = await this.terminal.getProfiles({ includeHidden: true }) } - pickWorkingDirectory (): void { - const shell = this.shells.find(x => x.id === this.config.store.terminal.shell) + async pickWorkingDirectory (): Promise { + const profile = await this.terminal.getProfileByID(this.config.store.terminal.profile) + const shell = this.shells.find(x => x.id === profile?.shell) if (!shell) { return } - const paths = this.electron.dialog.showOpenDialog( + const paths = (await this.electron.dialog.showOpenDialog( this.hostApp.getWindow(), { defaultPath: shell.fsBase, properties: ['openDirectory', 'showHiddenFiles'], } - ) + )).filePaths if (paths) { this.config.store.terminal.workingDirectory = paths[0] } @@ -69,7 +68,8 @@ export class ShellSettingsTabComponent { newProfile (shell: Shell): void { const profile: Profile = { name: shell.name || '', - sessionOptions: this.terminalService.optionsFromShell(shell), + shell: shell.id, + sessionOptions: this.terminal.optionsFromShell(shell), } this.config.store.terminal.profiles = [profile, ...this.config.store.terminal.profiles] this.config.save() diff --git a/terminus-terminal/src/components/terminalSettingsTab.component.pug b/terminus-terminal/src/components/terminalSettingsTab.component.pug index f71b07b5..481f1121 100644 --- a/terminus-terminal/src/components/terminalSettingsTab.component.pug +++ b/terminus-terminal/src/components/terminalSettingsTab.component.pug @@ -30,7 +30,7 @@ h3.mb-3 Terminal ) | Audible -.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.bell != "audible" && config.store.terminal.shell.startsWith("wsl")') +.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.bell != "audible" && config.store.terminal.profile.startsWith("wsl")') .mr-auto WSL terminal bell can only be muted via Volume Mixer button.btn.btn-secondary((click)='openWSLVolumeMixer()') Show Mixer diff --git a/terminus-terminal/src/hotkeys.ts b/terminus-terminal/src/hotkeys.ts index 39e8290c..c049427e 100644 --- a/terminus-terminal/src/hotkeys.ts +++ b/terminus-terminal/src/hotkeys.ts @@ -1,4 +1,3 @@ -import slugify from 'slugify' import { Injectable } from '@angular/core' import { HotkeyDescription, HotkeyProvider } from 'terminus-core' import { TerminalService } from './services/terminal.service' @@ -78,7 +77,7 @@ export class TerminalHotkeyProvider extends HotkeyProvider { return [ ...this.hotkeys, ...profiles.map(profile => ({ - id: `profile.${slugify(profile.name).toLowerCase()}`, + id: `profile.${this.terminal.getProfileID(profile)}`, name: `New tab: ${profile.name}`, })), ] diff --git a/terminus-terminal/src/index.ts b/terminus-terminal/src/index.ts index b29d89af..4a3c8acc 100644 --- a/terminus-terminal/src/index.ts +++ b/terminus-terminal/src/index.ts @@ -1,5 +1,4 @@ import * as fs from 'mz/fs' -import slugify from 'slugify' import { NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' @@ -187,8 +186,7 @@ export default class TerminalModule { // eslint-disable-line @typescript-eslint/ hostApp.newWindow() } if (hotkey.startsWith('profile.')) { - const profiles = await terminal.getProfiles() - const profile = profiles.find(x => slugify(x.name).toLowerCase() === hotkey.split('.')[1]) + const profile = await terminal.getProfileByID(hotkey.split('.')[1]) if (profile) { terminal.openTabWithOptions(profile.sessionOptions) } diff --git a/terminus-terminal/src/services/terminal.service.ts b/terminus-terminal/src/services/terminal.service.ts index 130d24f4..2fc9c35d 100644 --- a/terminus-terminal/src/services/terminal.service.ts +++ b/terminus-terminal/src/services/terminal.service.ts @@ -40,6 +40,7 @@ export class TerminalService { ...this.config.store.terminal.profiles, ...skipDefault ? [] : shells.filter(x => includeHidden || !x.hidden).map(shell => ({ name: shell.name, + shell: shell.id, icon: shell.icon, sessionOptions: this.optionsFromShell(shell), isBuiltin: true, @@ -47,14 +48,25 @@ export class TerminalService { ] } + getProfileID (profile: Profile): string { + return slugify(profile.name).toLowerCase() + } + + async getProfileByID (id: string): Promise { + const profiles = await this.getProfiles({ includeHidden: true }) + return profiles.find(x => this.getProfileID(x) === id) || profiles[0] + } + /** * Launches a new terminal with a specific shell and CWD * @param pause Wait for a keypress when the shell exits */ async openTab (profile?: Profile, cwd?: string|null, pause?: boolean): Promise { if (!profile) { - const profiles = await this.getProfiles({ includeHidden: true }) - profile = profiles.find(x => slugify(x.name).toLowerCase() === this.config.store.terminal.profile) || profiles[0] + profile = await this.getProfileByID(this.config.store.terminal.profile) + if (!profile) { + profile = (await this.getProfiles({ includeHidden: true }))[0] + } } cwd = cwd || profile.sessionOptions.cwd diff --git a/terminus-terminal/src/shells/wsl.ts b/terminus-terminal/src/shells/wsl.ts index 7bfccf77..7d9c1bf7 100644 --- a/terminus-terminal/src/shells/wsl.ts +++ b/terminus-terminal/src/shells/wsl.ts @@ -88,13 +88,15 @@ export class WSLShellProvider extends ShellProvider { if (!childKey.DistributionName) { continue } + const wslVersion = (childKey.Flags.value & 8) ? 2 : 1 const name = childKey.DistributionName.value + const fsBase = (wslVersion === 2) ? `\\\\wsl$\\${name}` : (childKey.BasePath.value as string + '\\rootfs') const shell: Shell = { id: `wsl-${slugify(name)}`, name: `WSL / ${name}`, command: wslPath, args: ['-d', name], - fsBase: childKey.BasePath.value as string + '\\rootfs', + fsBase, env: { TERM: 'xterm-color', COLORTERM: 'truecolor',