diff --git a/plugins/terminal/intellij.terminal.iml b/plugins/terminal/intellij.terminal.iml
index 64469073b938..fbd2d2ca13e6 100644
--- a/plugins/terminal/intellij.terminal.iml
+++ b/plugins/terminal/intellij.terminal.iml
@@ -111,5 +111,7 @@
+
+
\ No newline at end of file
diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml
index fed2cd572883..d27436d501f4 100644
--- a/plugins/terminal/resources/META-INF/terminal.xml
+++ b/plugins/terminal/resources/META-INF/terminal.xml
@@ -63,6 +63,9 @@
+
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
index 3db188e763dc..3d6bf4d9e8e5 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
@@ -36,6 +36,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static org.jetbrains.plugins.terminal.LocalBlockTerminalRunner.*;
+import static org.jetbrains.plugins.terminal.TerminalStartupKt.startProcess;
import static org.jetbrains.plugins.terminal.util.ShellNameUtil.*;
public class LocalTerminalDirectRunner extends AbstractTerminalRunner {
@@ -110,21 +111,33 @@ public class LocalTerminalDirectRunner extends AbstractTerminalRunner,
+ envs: Map,
+ initialWorkingDirectory: Path,
+ initialTermSize: TermSize,
+): PtyProcess {
+ return runBlockingMaybeCancellable {
+ val (eelApi, workingDirectory) = getEelApi(initialWorkingDirectory, command)
+ val remoteCommand = convertCommandToRemote(eelApi, command)
+ doStartProcess(eelApi, remoteCommand, envs, workingDirectory, initialTermSize)
+ }
+}
+
+private suspend fun convertCommandToRemote(eelApi: EelApi, command: List): List {
+ if (isWslCommand(command)) {
+ val shell = eelApi.exec.fetchLoginShellEnvVariables()["SHELL"] ?: "/bin/sh"
+ return listOf(shell, LocalTerminalDirectRunner.LOGIN_CLI_OPTION, LocalTerminalStartCommandBuilder.INTERACTIVE_CLI_OPTION)
+ }
+ return command
+}
+
+private fun isWslCommand(command: List): Boolean {
+ if (SystemInfo.isWindows) {
+ val exePath = command.getOrNull(0) ?: return false
+ val exeFileName = PathUtil.getFileName(exePath)
+ return exeFileName.equals("wsl.exe", true) || exeFileName.equals("wsl", true)
+ }
+ return false
+}
+
+private suspend fun getEelApi(
+ workingDirectory: Path,
+ command: List,
+): Pair {
+ val wslDistribNameFromCommandline = getWslDistributionNameFromCommand(command)
+ if (wslDistribNameFromCommandline != null) {
+ val wslDistribNameFromWorkingDirectory = WslPath.parseWindowsUncPath(workingDirectory.toString())?.distributionId
+ if (wslDistribNameFromCommandline != wslDistribNameFromWorkingDirectory) {
+ val wslRootPath = WSLDistribution(wslDistribNameFromCommandline).getUNCRootPath()
+ val eelApi = wslRootPath.getEelDescriptor().upgrade()
+ val userHome = runCatching { eelApi.exec.fetchLoginShellEnvVariables()["HOME"] }.getOrNull()
+ return eelApi to wslRootPath.resolve(userHome ?: ".")
+ }
+ }
+ return workingDirectory.getEelDescriptor().upgrade() to workingDirectory
+}
+
+private fun getWslDistributionNameFromCommand(command: List): String? {
+ if (isWslCommand(command)) {
+ val distributionOptionName = command.getOrNull(1)
+ if (distributionOptionName == "-d" || distributionOptionName == "--distribution") {
+ return command.getOrNull(2)
+ }
+ }
+ return null
+}
+
+@Throws(ErrnoException::class)
+private suspend fun doStartProcess(
+ eelApi: EelApi,
+ command: List,
+ envs: Map,
+ workingDirectory: Path,
+ initialTermSize: TermSize,
+): PtyProcess {
+ // TODO migrate to generated builders in 252 (not available in 251)
+ @Suppress("DEPRECATION")
+ val execOptions = EelExecApi.ExecuteProcessOptions.Builder(command.first())
+ .args(command.takeLast(command.size - 1))
+ .env(envs)
+ .workingDirectory(workingDirectory.asEelPath())
+ .ptyOrStdErrSettings(EelExecApi.Pty(initialTermSize.columns, initialTermSize.rows, true))
+ .build()
+ val processResult = eelApi.exec.execute(execOptions)
+ return when (processResult) {
+ is EelResult.Ok -> processResult.value.convertToJavaProcess() as PtyProcess
+ is EelResult.Error -> throw ErrnoException(processResult.error)
+ }
+}
+
+internal class ErrnoException(val error: ExecuteProcessError): Exception(error.message)
+
private val log: Logger = logger>()