mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 08:52:12 +00:00
The remote server read the login shell's PATH once and cached it, had no project-level environment, and changed environment variables only took effect after reinstalling or a manual restart.
- Every openidea-server start re-reads the remote login shell's full environment (`$SHELL -ilc env -0`), with the cached PATH only as a fallback when the shell doesn't answer.
- A project's `.devcontainer/devcontainer.json` (or `.devcontainer.json`) applies on remote hosts: `remoteEnv` (with `${localEnv|containerEnv|env:X[:default]}`, workspace variables and `null` to unset) reaches every child process through one environment overlay (terminals, run configurations, language servers, debuggers, build tools, git), and `postStartCommand` (string, array or parallel object) runs once per server start in the project root as a cancellable background task; a failure raises a notification with the exit code and the last output lines without blocking the project.
- Reload Environment (`remote.reloadEnvironment`, File menu and Find Action) re-resolves the login shell and `remoteEnv` without restarting the server, starting from the process's original environment so prepended PATH entries don't pile up; it lists the changed variables, notes that running processes keep their environment, and offers to restart language servers.
- The JSONC reader moves to `ide_core::jsonc` and is shared with ide-run.
Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
/**
|
|
* Reload Environment: new terminals, runs, language servers and tools get the login
|
|
* shell's current environment (and, on a remote host, the project's `devcontainer.json`
|
|
* `remoteEnv`) without restarting the backend. What is already running keeps its own.
|
|
*/
|
|
import { tx } from "@/platform/i18n";
|
|
import { call, commands, type EnvReloaded } from "@/platform/ipc";
|
|
import { notifications } from "@/workbench/contributions";
|
|
|
|
const KEY = "remote.reloadEnvironment";
|
|
/** Variable names listed in the notification before "and N more". */
|
|
const LISTED = 8;
|
|
|
|
/** The notification text for a reload result. */
|
|
export function reloadSummary(r: EnvReloaded): string {
|
|
const names = r.changed.slice(0, LISTED).join(", ");
|
|
const more = r.changed.length - LISTED;
|
|
const changed =
|
|
r.changed.length === 0
|
|
? tx("No variables changed.")
|
|
: more > 0
|
|
? tx`Changed: ${names} and ${more} more.`
|
|
: tx`Changed: ${names}.`;
|
|
const keep = tx("Terminals and processes already running keep their old environment; new ones get the new one.");
|
|
return [changed, keep].join(" ");
|
|
}
|
|
|
|
async function restartLanguageServers() {
|
|
try {
|
|
const servers = await call(commands.lspServers());
|
|
await Promise.all(servers.map((s) => call(commands.lspRestart(s.id))));
|
|
} catch (e) {
|
|
notifications().notify({
|
|
group: "lsp",
|
|
level: "error",
|
|
title: "Failed to restart language server",
|
|
body: e instanceof Error ? e.message : String(e),
|
|
});
|
|
}
|
|
}
|
|
|
|
export async function reloadEnvironment() {
|
|
let result: EnvReloaded;
|
|
try {
|
|
result = await call(commands.envReload());
|
|
} catch (e) {
|
|
notifications().notify({
|
|
key: KEY,
|
|
level: "error",
|
|
title: "Could not reload the environment",
|
|
body: e instanceof Error ? e.message : String(e),
|
|
});
|
|
return;
|
|
}
|
|
notifications().notify({
|
|
key: KEY,
|
|
level: "info",
|
|
title: "Environment reloaded",
|
|
body: reloadSummary(result),
|
|
actions: result.changed.length
|
|
? [{ label: "Restart Language Servers", run: () => void restartLanguageServers() }]
|
|
: [],
|
|
});
|
|
}
|