diff --git a/bundled/tool/_debug_server.py b/bundled/tool/_debug_server.py index 00a3aae..79d482e 100644 --- a/bundled/tool/_debug_server.py +++ b/bundled/tool/_debug_server.py @@ -15,23 +15,24 @@ def update_sys_path(path_to_add: str) -> None: # Ensure debugger is loaded before we load anything else, to debug initialization. -debugger_path = os.getenv("DEBUGPY_PATH", None) -if debugger_path: - if debugger_path.endswith("debugpy"): - debugger_path = os.fspath(pathlib.Path(debugger_path).parent) +if os.getenv("USE_DEBUGPY", "").strip().lower() in ["true", "1", "t", "yes"]: + debugger_path = os.getenv("DEBUGPY_PATH", None) + if debugger_path: + if debugger_path.endswith("debugpy"): + debugger_path = os.fspath(pathlib.Path(debugger_path).parent) - update_sys_path(debugger_path) + update_sys_path(debugger_path) - import debugpy + import debugpy - # 5678 is the default port, If you need to change it update it here - # and in launch.json. - debugpy.connect(5678) + # 5678 is the default port, If you need to change it update it here + # and in launch.json. + debugpy.connect(5678) - # This will ensure that execution is paused as soon as the debugger - # connects to VS Code. If you don't want to pause here comment this - # line and set breakpoints as appropriate. - debugpy.breakpoint() + # This will ensure that execution is paused as soon as the debugger + # connects to VS Code. If you don't want to pause here comment this + # line and set breakpoints as appropriate. + debugpy.breakpoint() SERVER_PATH = os.fspath(pathlib.Path(__file__).parent / "lsp_server.py") # NOTE: Set breakpoint in `server.py` before continuing. diff --git a/bundled/tool/lsp_jsonrpc.py b/bundled/tool/lsp_jsonrpc.py index 2817d50..35e31ea 100644 --- a/bundled/tool/lsp_jsonrpc.py +++ b/bundled/tool/lsp_jsonrpc.py @@ -6,6 +6,7 @@ import contextlib import io import json +import os import pathlib import subprocess import threading @@ -135,13 +136,23 @@ def stop_all_processes(self): i.send_data({"id": str(uuid.uuid4()), "method": "exit"}) self._thread_pool.shutdown(wait=False) - def start_process(self, workspace: str, args: Sequence[str], cwd: str) -> None: + def start_process( + self, + workspace: str, + args: Sequence[str], + cwd: str, + env: Optional[Dict[str, str]] = None, + ) -> None: """Starts a process and establishes JSON-RPC communication over stdio.""" + _env = os.environ.copy() + if env is not None: + _env.update(env) proc = subprocess.Popen( args, cwd=cwd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, + env=_env, ) self._processes[workspace] = proc self._rpc[workspace] = create_json_rpc(proc.stdout, proc.stdin) @@ -212,7 +223,7 @@ def run_over_json_rpc( """Uses JSON-RPC to execute a command.""" rpc: Union[JsonRpc, None] = get_or_start_json_rpc(workspace, interpreter, cwd) if not rpc: - raise Exception("Failed to run over JSON-RPC.") + raise ConnectionError("Failed to run over JSON-RPC.") msg_id = str(uuid.uuid4()) msg = { diff --git a/bundled/tool/lsp_server.py b/bundled/tool/lsp_server.py index c5d6eea..385337b 100644 --- a/bundled/tool/lsp_server.py +++ b/bundled/tool/lsp_server.py @@ -697,6 +697,23 @@ def _get_settings_by_document(document: TextDocument | None): } +def _get_settings_by_path(file_path: pathlib.Path): + # Note: WORKSPACE_SETTINGS is keyed by normalized workspaceFS path + # (see _update_workspace_settings), so dict lookup by workspaceFS value is correct. + workspaces = {s["workspaceFS"] for s in WORKSPACE_SETTINGS.values()} + + while file_path != file_path.parent: + str_file_path = utils.normalize_path(file_path) + if str_file_path in workspaces: + return WORKSPACE_SETTINGS[str_file_path] + file_path = file_path.parent + + setting_values = list(WORKSPACE_SETTINGS.values()) + if not setting_values: + return {} + return setting_values[0] + + # ***************************************************** # Internal execution APIs. # ***************************************************** diff --git a/src/common/envFile.ts b/src/common/envFile.ts index 9775efd..d49673f 100644 --- a/src/common/envFile.ts +++ b/src/common/envFile.ts @@ -8,8 +8,9 @@ import { WorkspaceFolder } from 'vscode'; import { traceInfo, traceWarn } from './logging'; import { getConfiguration } from './vscodeapi'; -function expandTilde(value: string): string { - const home = process.env.HOME || process.env.USERPROFILE || ''; +export function expandTilde(value: string): string { + const home = process.env.HOME || process.env.USERPROFILE; + if (!home) return value; if (value === '~') { return home; } diff --git a/src/common/settings.ts b/src/common/settings.ts index 7b1b0fa..e5bbaf9 100644 --- a/src/common/settings.ts +++ b/src/common/settings.ts @@ -6,6 +6,7 @@ import { traceLog, traceWarn } from './logging'; import { getInterpreterDetails } from './python'; import { getConfiguration, getWorkspaceFolders } from './vscodeapi'; import { getInterpreterFromSetting } from './utilities'; +import { expandTilde } from './envFile'; /* eslint-disable @typescript-eslint/naming-convention */ const DEFAULT_SEVERITY: Record = { @@ -149,13 +150,6 @@ export async function getWorkspaceSettings( return workspaceSetting; } -function expandTilde(value: string): string { - const home = process.env.HOME || process.env.USERPROFILE || ''; - if (value === '~') return home; - if (value.startsWith('~/') || value.startsWith('~\\')) return home + value.slice(1); - return value; -} - function getGlobalValue(config: WorkspaceConfiguration, key: string, defaultValue: T): T { const inspect = config.inspect(key); return inspect?.globalValue ?? inspect?.defaultValue ?? defaultValue;