Skip to content

Commit 5cd3a2f

Browse files
committed
Add variables for xml.fileAssociations
Adds three variables that can be used in `xml.fileAssociations`: * ${workspaceFolder} * ${fileDirname} * ${fileBasenameNoExtension} These variables can be used for both the `pattern` and the `systemId`. Closes #307 Signed-off-by: David Thompson <davthomp@redhat.com>
1 parent b44ceb9 commit 5cd3a2f

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

docs/Validation.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,18 @@ Please note that you can use wildcards in the pattern (ex: `foo*.xml`):
199199

200200
In this case, all XML files that start with foo and end with .xml will be associated with the XSD (foo1.xml, foo2.xml, etc)
201201

202+
You can also use the following three variables in either the `pattern` or `systemId`:
203+
204+
| Variable | Meaning |
205+
| --------------------------- | ------------------------------------------------------------------------ |
206+
| ${workspaceFolder} | The absolute path to root folder of the workspace that is currently open |
207+
| ${fileDirname} | The absolute path to the folder of the file that is currently opened |
208+
| ${fileBasenameNoExtension} | The current opened file's basename with no file extension |
209+
210+
If one of the variables for an association can't be expanded (eg. because vscode is opened in rootless mode),
211+
the association is ignored.
212+
This feature is specific to the VSCode client.
213+
202214
## Validation with DTD grammar
203215

204216
To associate your XML with a DTD grammar you can use several strategies:
@@ -322,7 +334,17 @@ Please note that you can use wildcards in the pattern (ex: `foo*.xml`):
322334

323335
In this case, all XML files that start with foo and end with .xml will be associated with the DTD (foo1.xml, foo2.xml, etc)
324336

337+
You can also use the following three variables in either the `pattern` or `systemId`:
338+
339+
| Variable | Meaning |
340+
| --------------------------- | ------------------------------------------------------------------------ |
341+
| ${workspaceFolder} | The absolute path to root folder of the workspace that is currently open |
342+
| ${fileDirname} | The absolute path to the folder of the file that is currently opened |
343+
| ${fileBasenameNoExtension} | The current opened file's basename with no file extension |
325344

345+
If one of the variables for an association can't be expanded (eg. because vscode is opened in rootless mode),
346+
the association is ignored.
347+
This feature is specific to the VSCode client.
326348

327349
# Other Validation Settings
328350

src/extension.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
import { prepareExecutable } from './javaServerStarter';
14-
import { LanguageClientOptions, RevealOutputChannelOn, LanguageClient, DidChangeConfigurationNotification, RequestType, TextDocumentPositionParams, ReferencesRequest, NotificationType, MessageType } from 'vscode-languageclient';
14+
import { LanguageClientOptions, RevealOutputChannelOn, LanguageClient, DidChangeConfigurationNotification, RequestType, TextDocumentPositionParams, ReferencesRequest, NotificationType, MessageType, ShowMessageNotification } from 'vscode-languageclient';
1515
import * as requirements from './requirements';
1616
import { languages, IndentAction, workspace, window, commands, ExtensionContext, TextDocument, Position, LanguageConfiguration, Uri, extensions, Command } from "vscode";
1717
import * as path from 'path';
@@ -249,6 +249,13 @@ export function activate(context: ExtensionContext) {
249249
}));
250250
}
251251

252+
// When the current document changes, update ${fileDirname} and ${fileBasenameNoExtension}
253+
// for the file associations, and send the updated settings to the server
254+
context.subscriptions.push(window.onDidChangeActiveTextEditor(() => {
255+
languageClient.sendNotification(DidChangeConfigurationNotification.type, { settings: getXMLSettings(requirements.java_home) });
256+
onConfigurationChange();
257+
}));
258+
252259
const api: XMLExtensionApi = {
253260
// add API set catalogs to internal memory
254261
addXMLCatalogs: (catalogs: string[]) => {
@@ -349,11 +356,50 @@ export function activate(context: ExtensionContext) {
349356
xml['xml']['catalogs'].push(catalog);
350357
}
351358
})
352-
externalXmlSettings.xmlFileAssociations.forEach(element => {
353-
if (!xml['xml']['fileAssociations'].some(fileAssociation => fileAssociation.systemId === element.systemId)) {
354-
xml['xml']['fileAssociations'].push(element);
359+
const variableSubstitutedAssociations: XMLFileAssociation[] =
360+
xml['xml']['fileAssociations'].map((association: XMLFileAssociation): XMLFileAssociation => {
361+
362+
const currentFile: string = window.activeTextEditor.document.uri.fsPath;
363+
let currentWorkspace: string = workspace.getWorkspaceFolder(window.activeTextEditor.document.uri).uri.fsPath
364+
|| workspace.workspaceFolders[0].uri.fsPath;
365+
366+
if (!currentWorkspace
367+
&& (association.pattern.indexOf('&{workspaceFolder}') >= 0
368+
|| association.systemId.indexOf('&{workspaceFolder}') >= 0)) {
369+
return;
370+
}
371+
372+
if (!currentFile
373+
&& (association.pattern.indexOf('&{fileDirname}') >= 0
374+
|| association.systemId.indexOf('&{fileDirname}') >= 0
375+
|| association.pattern.indexOf('&{fileBasenameNoExtension}') >= 0
376+
|| association.systemId.indexOf('&{fileBasenameNoExtension}') >= 0)) {
377+
return;
378+
}
379+
380+
/**
381+
* Returns the string with the values for:
382+
* * ${workspaceFolder}
383+
* * ${fileDirname}
384+
* * ${fileBasenameNoExtension}
385+
* substituted into the string
386+
*
387+
* @param val the value to substitute the variables into
388+
* @return the string with values for the variables subtituted into the string
389+
*/
390+
const subVars = (val: string): string => {
391+
let newVal: string = val.replace(/\$\{workspaceFolder\}/g, currentWorkspace);
392+
newVal = newVal.replace(/\$\{fileDirname\}/g, path.dirname(currentFile));
393+
newVal = newVal.replace(/\$\{fileBasenameNoExtension\}/g, path.basename(currentFile, path.extname(currentFile)));
394+
return newVal;
355395
}
396+
397+
return {
398+
pattern: subVars(association.pattern),
399+
systemId: subVars(association.systemId)
400+
};
356401
});
402+
xml['xml']['fileAssociations'] = [...variableSubstitutedAssociations];
357403

358404
return xml;
359405
}

0 commit comments

Comments
 (0)