Skip to content

Commit 49de257

Browse files
Copilotedvilme
andauthored
Add configurable cwd setting to extension template (#260)
* Initial plan * Add configurable cwd setting to extension template Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> * Improve get_cwd docstring and add call-site comment Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com>
1 parent c1c4f80 commit 49de257

3 files changed

Lines changed: 33 additions & 3 deletions

File tree

bundled/tool/lsp_server.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,23 @@ def on_shutdown(_params: Optional[Any] = None) -> None:
289289
jsonrpc.shutdown_json_rpc()
290290

291291

292+
def get_cwd(settings: dict, document: Optional[workspace.Document]) -> str:
293+
"""Returns the working directory for running the tool.
294+
295+
Resolves ``${fileDirname}`` to the directory of the current document.
296+
If no document is available, falls back to the workspace root.
297+
298+
Examples of supported patterns: ``${fileDirname}``, ``${fileDirname}/subdir``.
299+
"""
300+
cwd = settings.get("cwd", settings["workspaceFS"])
301+
if "${fileDirname}" in cwd:
302+
if document and document.path:
303+
cwd = cwd.replace("${fileDirname}", os.path.dirname(document.path))
304+
else:
305+
cwd = settings["workspaceFS"]
306+
return cwd
307+
308+
292309
def _get_global_defaults():
293310
return {
294311
"path": GLOBAL_SETTINGS.get("path", []),
@@ -393,7 +410,8 @@ def _run_tool_on_document(
393410
settings = copy.deepcopy(_get_settings_by_document(document))
394411

395412
code_workspace = settings["workspaceFS"]
396-
cwd = settings["cwd"]
413+
# Pass document so get_cwd can resolve ${fileDirname} to this file's directory.
414+
cwd = get_cwd(settings, document)
397415

398416
use_path = False
399417
use_rpc = False
@@ -498,7 +516,7 @@ def _run_tool(extra_args: Sequence[str]) -> utils.RunResult:
498516
settings = copy.deepcopy(_get_settings_by_document(None))
499517

500518
code_workspace = settings["workspaceFS"]
501-
cwd = settings["workspaceFS"]
519+
cwd = get_cwd(settings, None)
502520

503521
use_path = False
504522
use_rpc = False

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@
6464
"contributes": {
6565
"configuration": {
6666
"properties": {
67+
"<pytool-module>.cwd": {
68+
"default": "${workspaceFolder}",
69+
"description": "Sets the working directory for <pytool-module>. Supported variables: `${workspaceFolder}` (workspace root) and `${fileDirname}` (directory of the current file).",
70+
"scope": "resource",
71+
"type": "string"
72+
},
6773
"<pytool-module>.args": {
6874
"default": [],
6975
"description": "Arguments passed in. Each argument is a separate item in the array.",

src/common/settings.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ export function getInterpreterFromSetting(namespace: string, scope?: Configurati
4646
return config.get<string[]>('interpreter');
4747
}
4848

49+
function getCwd(config: WorkspaceConfiguration, workspace: WorkspaceFolder): string {
50+
const cwd = config.get<string>('cwd', '${workspaceFolder}');
51+
return resolveVariables([cwd], workspace)[0];
52+
}
53+
4954
export async function getWorkspaceSettings(
5055
namespace: string,
5156
workspace: WorkspaceFolder,
@@ -62,7 +67,7 @@ export async function getWorkspaceSettings(
6267
}
6368

6469
const workspaceSetting = {
65-
cwd: workspace.uri.fsPath,
70+
cwd: getCwd(config, workspace),
6671
workspace: workspace.uri.toString(),
6772
args: resolveVariables(config.get<string[]>(`args`) ?? [], workspace),
6873
path: resolveVariables(config.get<string[]>(`path`) ?? [], workspace),
@@ -104,6 +109,7 @@ export async function getGlobalSettings(namespace: string, includeInterpreter?:
104109
export function checkIfConfigurationChanged(e: ConfigurationChangeEvent, namespace: string): boolean {
105110
const settings = [
106111
`${namespace}.args`,
112+
`${namespace}.cwd`,
107113
`${namespace}.path`,
108114
`${namespace}.interpreter`,
109115
`${namespace}.importStrategy`,

0 commit comments

Comments
 (0)