mirror of
https://github.com/eugeny/tabby
synced 2026-09-28 07:55:59 +00:00
Fix WSL sessions not starting in home directory on newer Windows builds (#11663)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Eugene <inbox@null.page>
This commit is contained in:
co-authored by
Copilot
Eugene
parent
63a318185a
commit
cdae0b6ea2
@@ -5,6 +5,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
|
||||
export const WIN_BUILD_CONPTY_SUPPORTED = 17692
|
||||
export const WIN_BUILD_CONPTY_STABLE = 18309
|
||||
export const WIN_BUILD_WSL_EXE_DISTRO_FLAG = 17763
|
||||
export const WIN_BUILD_WSL_EXE_CD_FLAG = 19041
|
||||
export const WIN_BUILD_FLUENT_BG_SUPPORTED = 17063
|
||||
|
||||
export function getWindows10Build (): number|undefined {
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as fs from 'mz/fs'
|
||||
import slugify from 'slugify'
|
||||
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HostAppService, Platform, isWindowsBuild, WIN_BUILD_WSL_EXE_DISTRO_FLAG } from 'tabby-core'
|
||||
import { HostAppService, Platform, isWindowsBuild, WIN_BUILD_WSL_EXE_DISTRO_FLAG, WIN_BUILD_WSL_EXE_CD_FLAG } from 'tabby-core'
|
||||
|
||||
import { ShellProvider, Shell } from 'tabby-local'
|
||||
|
||||
@@ -63,6 +63,11 @@ export class WSLShellProvider extends ShellProvider {
|
||||
const lxss = wnr.getRegistryKey(wnr.HK.CU, lxssPath)
|
||||
const shells: Shell[] = []
|
||||
|
||||
// WSL only honors `--cd` for Linux-style paths (e.g. `~`) starting with this build.
|
||||
// On older builds, omit it and fall back to the previous (native cwd inheritance) behavior.
|
||||
// https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp
|
||||
const homeDirArgs = isWindowsBuild(WIN_BUILD_WSL_EXE_CD_FLAG) ? ['--cd', '~'] : undefined
|
||||
|
||||
if (lxss?.DefaultDistribution) {
|
||||
const defaultDistKey = wnr.getRegistryKey(wnr.HK.CU, lxssPath + '\\' + String(lxss.DefaultDistribution.value))
|
||||
if (defaultDistKey?.DistributionName) {
|
||||
@@ -71,6 +76,7 @@ export class WSLShellProvider extends ShellProvider {
|
||||
id: 'wsl',
|
||||
name: 'WSL / Default distro',
|
||||
command: wslPath,
|
||||
homeDirArgs,
|
||||
env: {
|
||||
TERM: 'xterm-color',
|
||||
COLORTERM: 'truecolor',
|
||||
@@ -114,6 +120,7 @@ export class WSLShellProvider extends ShellProvider {
|
||||
name: `WSL / ${name}`,
|
||||
command: wslPath,
|
||||
args: ['-d', name],
|
||||
homeDirArgs,
|
||||
fsBase,
|
||||
env: {
|
||||
TERM: 'xterm-color',
|
||||
|
||||
@@ -17,6 +17,13 @@ export interface Shell {
|
||||
|
||||
cwd?: string
|
||||
|
||||
/**
|
||||
* Args that make the shell start in its own home directory (e.g. WSL's `--cd ~`).
|
||||
* Only applied when the session has no working directory of its own, since these
|
||||
* would otherwise override it.
|
||||
*/
|
||||
homeDirArgs?: string[]
|
||||
|
||||
/**
|
||||
* SVG icon
|
||||
*/
|
||||
@@ -39,6 +46,8 @@ export interface SessionOptions {
|
||||
restoreFromPTYID: string | null
|
||||
command: string
|
||||
args: string[]
|
||||
/** See {@link Shell.homeDirArgs} */
|
||||
homeDirArgs: string[]
|
||||
cwd: string | null
|
||||
env: Record<string, string>
|
||||
width: number | null
|
||||
|
||||
@@ -16,6 +16,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
|
||||
restoreFromPTYID: null,
|
||||
command: '',
|
||||
args: [],
|
||||
homeDirArgs: [],
|
||||
cwd: null,
|
||||
env: {
|
||||
__nonStructural: true,
|
||||
@@ -82,6 +83,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
|
||||
...this.configDefaults.options,
|
||||
command: shell.command,
|
||||
args: shell.args ?? [],
|
||||
homeDirArgs: shell.homeDirArgs ?? [],
|
||||
env: shell.env,
|
||||
cwd: shell.cwd ?? null,
|
||||
shellType: shell.shellType ?? null,
|
||||
|
||||
@@ -7,6 +7,17 @@ import { getEnvironment, substituteEnv } from './environment'
|
||||
import { resolveGuestCWD } from './wslPath'
|
||||
import { isDirectory, isDirectorySync } from './util'
|
||||
|
||||
function usableCWD (path?: string|null): string|undefined {
|
||||
if (!path) {
|
||||
return undefined
|
||||
}
|
||||
if (!isDirectorySync(path)) {
|
||||
console.warn('Ignoring invalid CWD:', path)
|
||||
return undefined
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi
|
||||
|
||||
function mergeEnv (...envs) {
|
||||
@@ -87,16 +98,18 @@ export class Session extends BaseSession {
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
let cwd = resolveGuestCWD(options.cwd, options.fsBase) || process.env.HOME
|
||||
// resolveGuestCWD maps a POSIX cwd reported by a guest shell (WSL) onto its
|
||||
// Windows-visible path before we validate it.
|
||||
const explicitCWD = usableCWD(resolveGuestCWD(options.cwd, options.fsBase))
|
||||
|
||||
if (!isDirectorySync(cwd)) {
|
||||
console.warn('Ignoring invalid CWD:', cwd)
|
||||
cwd = undefined
|
||||
}
|
||||
// A shell that knows how to start in its own home directory (WSL's `--cd ~`) only gets
|
||||
// to do so when we have no working directory for it - those args outrank the cwd below.
|
||||
const args = explicitCWD ? options.args : [...options.args, ...options.homeDirArgs]
|
||||
|
||||
const cwd = explicitCWD ?? usableCWD(process.env.HOME)
|
||||
|
||||
try {
|
||||
pty = await this.ptyInterface.spawn(options.command, options.args, {
|
||||
pty = await this.ptyInterface.spawn(options.command, args, {
|
||||
name: 'xterm-256color',
|
||||
cols: options.width ?? 80,
|
||||
rows: options.height ?? 30,
|
||||
|
||||
Reference in New Issue
Block a user