Skip to content

Commit c315d20

Browse files
committed
Add support for linux terminals
1 parent 448763e commit c315d20

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

Extension/src/Debugger/runWithoutDebuggingAdapter.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import * as cp from 'child_process';
77
import * as os from 'os';
88
import * as path from 'path';
99
import * as vscode from 'vscode';
10+
import * as nls from 'vscode-nls';
1011
import { sessionIsWsl } from '../common';
1112

13+
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
14+
const localize = nls.loadMessageBundle();
15+
1216
/**
1317
* A minimal inline Debug Adapter that runs the target program directly without a debug adapter
1418
* when the user invokes "Run Without Debugging".
@@ -117,11 +121,48 @@ export class RunWithoutDebuggingAdapter implements vscode.DebugAdapter {
117121
} else if (platform === 'linux' && sessionIsWsl()) {
118122
cp.spawn('/mnt/c/Windows/System32/cmd.exe', ['/c', 'start', 'bash', '-c', `${cmdLine};read -p 'Press enter to continue...'`], { env, detached: true, stdio: 'ignore' }).unref();
119123
} else { // platform === 'linux'
120-
cp.spawn('bash', ['-c', `${cmdLine};read -p 'Press enter to continue...'`], { cwd, env, detached: true, stdio: 'ignore' }).unref();
124+
this.launchLinuxExternalTerminal(cmdLine, cwd, env);
121125
}
122126
this.sendEvent('terminated');
123127
}
124128

129+
/**
130+
* On Linux, find and launch an available terminal emulator to run the command.
131+
*/
132+
private launchLinuxExternalTerminal(cmdLine: string, cwd: string | undefined, env: NodeJS.ProcessEnv): void {
133+
const bashCmd = `${cmdLine}; echo; read -p 'Press enter to continue...'`;
134+
const bashArgs = ['bash', '-c', bashCmd];
135+
136+
// Terminal emulators in order of preference, with the correct flag style for each.
137+
const candidates: { cmd: string; buildArgs: () => string[] }[] = [
138+
{ cmd: 'x-terminal-emulator', buildArgs: () => ['-e', ...bashArgs] },
139+
{ cmd: 'gnome-terminal', buildArgs: () => ['-e', ...bashArgs] },
140+
{ cmd: 'konsole', buildArgs: () => ['-e', ...bashArgs] },
141+
{ cmd: 'xterm', buildArgs: () => ['-e', ...bashArgs] }
142+
];
143+
144+
// Honor the $TERMINAL environment variable if set.
145+
const terminalEnv = process.env['TERMINAL'];
146+
if (terminalEnv) {
147+
candidates.unshift({ cmd: terminalEnv, buildArgs: () => ['-e', ...bashArgs] });
148+
}
149+
150+
for (const candidate of candidates) {
151+
try {
152+
const result = cp.spawnSync('which', [candidate.cmd], { stdio: 'pipe' });
153+
if (result.status === 0) {
154+
cp.spawn(candidate.cmd, candidate.buildArgs(), { cwd, env, detached: true, stdio: 'ignore' }).unref();
155+
return;
156+
}
157+
} catch {
158+
continue;
159+
}
160+
}
161+
162+
const message = localize('no.terminal.emulator', 'No terminal emulator found. Please set the $TERMINAL environment variable to your terminal emulator of choice, or install one of the following: x-terminal-emulator, gnome-terminal, konsole, xterm.');
163+
vscode.window.showErrorMessage(message);
164+
}
165+
125166
/**
126167
* Spawn the process and forward stdout/stderr as DAP output events.
127168
*/

0 commit comments

Comments
 (0)