Skip to content

Commit 4f002c9

Browse files
datho7561angelozerr
authored andcommitted
xml.extension.jars to add LemMinX extension jars
Adds a new setting `xml.extension.jars`, where you can list jars to contribute to the LemMinX classpath. You can use this feature to test LemMinX extensions in VSCode. Closes #251 Signed-off-by: David Thompson <davthomp@redhat.com>
1 parent b44ceb9 commit 4f002c9

File tree

7 files changed

+67
-42
lines changed

7 files changed

+67
-42
lines changed

README.md

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -93,41 +93,8 @@ Since 0.13.0:
9393

9494
## Custom XML Extensions
9595

96-
The [LemMinX - XML Language Server](https://github.com/eclipse/lemminx) can be extended to support custom completion, hover, validation, rename, etc by using the [Java Service Provider Interface (SPI)](https://www.baeldung.com/java-spi) mechanism. vscode-xml provides the ability use your custom XML support provider, by adding external jars to the XML language server's classpath.
97-
98-
To do that:
99-
100-
* create a Java project which provides a custom XML extension providing your custom completion, hover, validation, rename, etc:
101-
* create the XML extension like [MavenPlugin](https://github.com/angelozerr/lsp4xml-extensions-maven/blob/master/org.eclipse.lsp4xml.extensions.maven/src/main/java/org/eclipse/lsp4xml/extensions/maven/MavenPlugin.java).
102-
* register your custom completion participant in the XML extension like [MavenCompletionParticipant](https://github.com/angelozerr/lsp4xml-extensions-maven/blob/master/org.eclipse.lsp4xml.extensions.maven/src/main/java/org/eclipse/lsp4xml/extensions/maven/MavenCompletionParticipant.java#L28)
103-
* register your custom XML extension with [Java Service Provider Interface (SPI)](https://www.baeldung.com/java-spi) mechanism in the [/META-INF/services/org.eclipse.lemminx.services.extensions.IXMLExtension](https://github.com/angelozerr/lsp4xml-extensions-maven/blob/master/org.eclipse.lsp4xml.extensions.maven/src/main/resources/META-INF/services/org.eclipse.lsp4xml.services.extensions.IXMLExtension) file.
104-
* build a JAR `your-custom-xml-extension.jar`.
105-
106-
* create a `vscode extension` which embeds the `your-custom-xml-extension.jar` JAR and declares this JAR path in the `package.json`:
107-
108-
```json
109-
"contributes": {
110-
"xml.javaExtensions": [
111-
"./jar/your-custom-xml-extension.jar"
112-
]
113-
}
114-
```
115-
116-
* You can also list multiple jars or use glob patterns to specify the jars:
117-
118-
```json
119-
"contributes": {
120-
"xml.javaExtensions": [
121-
"./jar/dependencies/*.jar",
122-
"./jar/my-xml-extension.jar"
123-
]
124-
}
125-
```
126-
127-
128-
You can see the [vscode-xml-maven](https://github.com/angelozerr/vscode-xml-maven) sample which registers custom maven completion [MavenCompletionParticipant](https://github.com/angelozerr/lsp4xml-extensions-maven/blob/master/org.eclipse.lsp4xml.extensions.maven/src/main/java/org/eclipse/lsp4xml/extensions/maven/MavenCompletionParticipant.java#L28) for scope:
129-
130-
![VScode XML Maven](images/vscode-xml-maven.gif)
96+
The [LemMinX - XML Language Server](https://github.com/eclipse/lemminx) can be extended to support custom completion, hover, validation, rename, etc.
97+
Please see the [extensions documentation](./docs/Extensions#custom-xml-extensions) for more information.
13198

13299
## Contributing
133100

docs/Extensions.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Custom XML Extensions
2+
3+
The [LemMinX - XML Language Server](https://github.com/eclipse/lemminx) can be extended to support custom completion, hover, validation, rename, etc by using the [Java Service Provider Interface (SPI)](https://www.baeldung.com/java-spi) mechanism.
4+
vscode-xml provides the ability to use your custom XML support provider, by adding external jars to the XML language server's classpath.
5+
6+
To do that:
7+
8+
* create a Java project which provides a custom XML extension providing your custom completion, hover, validation, rename, etc:
9+
* create the XML extension like [MavenLemminxExtension](https://github.com/eclipse/lemminx-maven/blob/master/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenLemminxExtension.java).
10+
* register your custom completion participant in the XML extension like [MavenCompletionParticipant](https://github.com/eclipse/lemminx-maven/blob/master/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenCompletionParticipant.java#L75)
11+
* register your custom XML extension with [Java Service Provider Interface (SPI)](https://www.baeldung.com/java-spi) mechanism in the [/META-INF/services/org.eclipse.lemminx.services.extensions.IXMLExtension](https://github.com/eclipse/lemminx-maven/blob/master/lemminx-maven/src/main/resources/META-INF/services/org.eclipse.lemminx.services.extensions.IXMLExtension) file.
12+
* build a JAR `your-custom-xml-extension.jar`.
13+
* create a `vscode extension` which embeds the `your-custom-xml-extension.jar` JAR and declares this JAR path in the `package.json`:
14+
15+
```json
16+
"contributes": {
17+
"xml.javaExtensions": [
18+
"./jar/your-custom-xml-extension.jar"
19+
]
20+
}
21+
```
22+
23+
* You can also list multiple jars or use glob patterns to specify the jars:
24+
25+
```json
26+
"contributes": {
27+
"xml.javaExtensions": [
28+
"./jar/dependencies/*.jar",
29+
"./jar/my-xml-extension.jar"
30+
]
31+
}
32+
```
33+
34+
You can see the [vscode-xml-maven](https://github.com/angelozerr/vscode-xml-maven) sample which registers custom maven completion [MavenCompletionParticipant](https://github.com/eclipse/lemminx-maven/blob/master/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenCompletionParticipant.java#L210) for scope:
35+
36+
![demo of vscode xml maven suggesting different scopes for a dependency](./images/vscode-xml-maven.gif)

docs/Preferences.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,16 @@ The different options are:
161161
Here is a demonstration of the effects of the setting on hovering. The above schema is used in the example:
162162

163163
![Changing the documentation type setting changes which text the hover shows when hovering over an element that is in a schema document](./images/Preferences/HoverDocumentationQuickDemo.gif)
164+
165+
## Extension JARs
166+
167+
The LemMinX XML Language Server can be extended with custom plugins to provide additional validation and assistance.
168+
Typically this is done for specific files or contexts.
169+
External extensions are are contributed via an external JAR.
170+
Please see [the extension development documentation](https://github.com/eclipse/lemminx/blob/master/docs/LemMinX-Extensions.md) for more information on how this works.
171+
172+
JARs can be contributed to the LemMinX classpath using the `xml.extension.jars` preference.
173+
These paths can include globs.
174+
This feature is only intended to be used for LemMinX extension development purposes.
175+
Distributing vscode-xml extensions is best done through the mechanism described in the
176+
[vscode-xml extension development documentation](Extensions#custom-xml-extensions).

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,13 @@
355355
"xml.symbols.showReferencedGrammars": {
356356
"type": "boolean",
357357
"default": true,
358-
"markdownDescription": "Show referenced grammars in the Outline. Default is `true.",
358+
"markdownDescription": "Show referenced grammars in the Outline. Default is `true`.",
359+
"scope": "window"
360+
},
361+
"xml.extension.jars": {
362+
"type": "array",
363+
"default": [],
364+
"markdownDescription": "An array of paths to JARs that should be contributed to the LemMinX classpath. The paths can include glob patterns. This is intended to be used as a tool for developing extensions to vscode-xml. Please see [here](command:xml.open.docs?%5B%7B%22page%22%3A%22Preferences%22%2C%22section%22%3A%22extension-jars%22%7D%5D) for more information",
359365
"scope": "window"
360366
}
361367
}

src/extension.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import * as path from 'path';
1818
import * as os from 'os';
1919
import { activateTagClosing, AutoCloseResult } from './tagClosing';
2020
import { Commands } from './commands';
21-
import { onConfigurationChange, subscribeJDKChangeConfiguration } from './settings';
21+
import { getXMLConfiguration, onConfigurationChange, subscribeJDKChangeConfiguration } from './settings';
2222
import { collectXmlJavaExtensions, onExtensionChange } from './plugin';
2323
import { markdownPreviewProvider } from "./markdownPreviewProvider";
2424

@@ -203,7 +203,7 @@ export function activate(context: ExtensionContext) {
203203
}
204204
}
205205

206-
let serverOptions = prepareExecutable(requirements, collectXmlJavaExtensions(extensions.all), context);
206+
let serverOptions = prepareExecutable(requirements, collectXmlJavaExtensions(extensions.all, getXMLConfiguration().get("extension.jars", [])), context);
207207
languageClient = new LanguageClient('xml', 'XML Support', serverOptions, clientOptions);
208208
let toDispose = context.subscriptions;
209209
let disposable = languageClient.start();
@@ -245,7 +245,7 @@ export function activate(context: ExtensionContext) {
245245

246246
if (extensions.onDidChange) {// Theia doesn't support this API yet
247247
context.subscriptions.push(extensions.onDidChange(() => {
248-
onExtensionChange(extensions.all);
248+
onExtensionChange(extensions.all, getXMLConfiguration().get("extension.jars", []));
249249
}));
250250
}
251251

src/plugin.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const glob = require('glob');
77

88
let existingExtensions: Array<string>;
99

10-
export function collectXmlJavaExtensions(extensions: readonly vscode.Extension<any>[]): string[] {
10+
export function collectXmlJavaExtensions(extensions: readonly vscode.Extension<any>[], jars: string[]): string[] {
1111
const result = [];
1212
if (extensions && extensions.length) {
1313
for (const extension of extensions) {
@@ -22,17 +22,20 @@ export function collectXmlJavaExtensions(extensions: readonly vscode.Extension<a
2222
}
2323
}
2424
}
25+
for (const extension of jars) {
26+
result.push(...glob.sync(extension));
27+
}
2528
// Make a copy of extensions:
2629
existingExtensions = result.slice();
2730
return result;
2831
}
2932

30-
export function onExtensionChange(extensions: readonly vscode.Extension<any>[]) {
33+
export function onExtensionChange(extensions: readonly vscode.Extension<any>[], jars: string[]) {
3134
if (!existingExtensions) {
3235
return;
3336
}
3437
const oldExtensions = new Set(existingExtensions.slice());
35-
const newExtensions = collectXmlJavaExtensions(extensions);
38+
const newExtensions = collectXmlJavaExtensions(extensions, jars);
3639
let hasChanged = ( oldExtensions.size !== newExtensions.length);
3740
if (!hasChanged) {
3841
for (const newExtension of newExtensions) {

0 commit comments

Comments
 (0)