Skip to content

Commit b680e31

Browse files
Merge branch 'topic/issue_gs_#27' into 'master'
Substitute any variable reference when setting process.env See merge request eng/ide/ada_language_server!1178
2 parents d3bce4e + 0720300 commit b680e31

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

integration/vscode/ada/src/extension.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import GnatTaskProvider from './gnatTaskProvider';
2929
import { getSubprogramSymbol } from './gnatTaskProvider';
3030
import { alsCommandExecutor } from './alsExecuteCommand';
3131
import { ALSClientFeatures } from './alsClientFeatures';
32+
import { substituteVariables } from './helpers';
3233

3334
let alsTaskProvider: vscode.Disposable[] = [
3435
vscode.tasks.registerTaskProvider(GnatTaskProvider.gnatType, new GnatTaskProvider()),
@@ -115,7 +116,12 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
115116

116117
if (custom_env) {
117118
for (const var_name in custom_env) {
118-
process.env[var_name] = custom_env[var_name];
119+
let var_value : string = custom_env[var_name];
120+
121+
// Substitute VS Code variable references that might be present
122+
// in the JSON settings configuration (e.g: "PATH": "${workspaceFolder}/obj")
123+
var_value = var_value.replace(/(\$\{.*\})/, substituteVariables)
124+
process.env[var_name] = var_value;
119125
}
120126
}
121127

integration/vscode/ada/src/helpers.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*----------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 2021-2023, AdaCore --
5+
-- --
6+
-- This is free software; you can redistribute it and/or modify it under --
7+
-- terms of the GNU General Public License as published by the Free Soft- --
8+
-- ware Foundation; either version 3, or (at your option) any later ver- --
9+
-- sion. This software is distributed in the hope that it will be useful, --
10+
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
11+
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
12+
-- License for more details. You should have received a copy of the GNU --
13+
-- General Public License distributed with this software; see file --
14+
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
15+
-- of the license. --
16+
----------------------------------------------------------------------------*/
17+
import * as vscode from 'vscode';
18+
import * as path from 'path'
19+
20+
/**
21+
* Substitue any variable reference present in the given string. VS Code
22+
* variable references are listed here:
23+
* https://code.visualstudio.com/docs/editor/variables-reference
24+
* @param str
25+
* @param recursive
26+
* @returns
27+
*/
28+
export function substituteVariables(str: string, recursive = false) {
29+
30+
let workspaces = vscode.workspace.workspaceFolders ?? [];
31+
let workspace = workspaces.length ? workspaces[0] : null;
32+
let activeEditor = vscode.window.activeTextEditor
33+
let activeFile = activeEditor?.document;
34+
let absoluteFilePath = activeFile?.uri.fsPath ?? ""
35+
36+
if (workspace != null) {
37+
str = str.replace(/\${workspaceFolder}/g, workspace?.uri.fsPath);
38+
str = str.replace(/\${workspaceFolderBasename}/g, workspace?.name);
39+
}
40+
41+
str = str.replace(/\${file}/g, absoluteFilePath);
42+
let activeWorkspace = workspace;
43+
let relativeFilePath = absoluteFilePath;
44+
for (let workspace of workspaces) {
45+
if (absoluteFilePath.replace(workspace.uri.fsPath, '') !== absoluteFilePath) {
46+
activeWorkspace = workspace;
47+
relativeFilePath = absoluteFilePath.replace(workspace.uri.fsPath, '').substr(path.sep.length);
48+
break;
49+
}
50+
}
51+
let parsedPath = path.parse(absoluteFilePath);
52+
53+
if (activeWorkspace != null) {
54+
str = str.replace(/\${fileWorkspaceFolder}/g, activeWorkspace?.uri.fsPath);
55+
}
56+
57+
str = str.replace(/\${relativeFile}/g, relativeFilePath);
58+
str = str.replace(/\${relativeFileDirname}/g, relativeFilePath.substr(0, relativeFilePath.lastIndexOf(path.sep)));
59+
str = str.replace(/\${fileBasename}/g, parsedPath.base);
60+
str = str.replace(/\${fileBasenameNoExtension}/g, parsedPath.name);
61+
str = str.replace(/\${fileExtname}/g, parsedPath.ext);
62+
str = str.replace(/\${fileDirname}/g, parsedPath.dir.substr(parsedPath.dir.lastIndexOf(path.sep) + 1));
63+
str = str.replace(/\${cwd}/g, parsedPath.dir);
64+
str = str.replace(/\${pathSeparator}/g, path.sep);
65+
66+
if (activeEditor != null) {
67+
str = str.replace(/\${lineNumber}/g, (activeEditor.selection.start.line + 1).toString());
68+
str = str.replace(/\${selectedText}/g, activeEditor.document.getText(new vscode.Range(activeEditor.selection.start, activeEditor.selection.end)));
69+
}
70+
71+
str = str.replace(/\${env:(.*?)}/g, function (variable) {
72+
return process.env[variable.match(/\${env:(.*?)}/)![1]] || '';
73+
});
74+
75+
str = str.replace(/\${config:(.*?)}/g, function (variable) {
76+
return vscode.workspace.getConfiguration().get(variable.match(/\${config:(.*?)}/)![1], '');
77+
});
78+
79+
if (recursive && str.match(/\${(workspaceFolder|workspaceFolderBasename|fileWorkspaceFolder|relativeFile|fileBasename|fileBasenameNoExtension|fileExtname|fileDirname|cwd|pathSeparator|lineNumber|selectedText|env:(.*?)|config:(.*?))}/)) {
80+
str = substituteVariables(str, recursive);
81+
}
82+
return str;
83+
}

0 commit comments

Comments
 (0)