提交 b29ab269 编写于 作者: E Eugene Pankov

WSL2 support - fixes #271

上级 f58cab08
......@@ -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)
......
......@@ -19,6 +19,7 @@ export interface Profile {
name: string
color?: string
sessionOptions: SessionOptions
shell?: string
isBuiltin?: boolean
icon?: string
}
......
......@@ -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}}
......
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<void> {
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<void> {
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<void> {
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()
......
......@@ -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
......
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}`,
})),
]
......
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)
}
......
......@@ -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<Profile> {
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<TerminalTabComponent> {
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
......
......@@ -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',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册