Skip to content

Commit af91463

Browse files
committed
[Qute] Add language support for qute
Fixes #178 Signed-off-by: azerr <azerr@redhat.com>
1 parent 2d5e1a9 commit af91463

File tree

9 files changed

+441
-11
lines changed

9 files changed

+441
-11
lines changed

gulpfile.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ const quarkusServerExt = 'com.redhat.quarkus.ls';
2121
const quarkusExtensionDir = '../quarkus-ls/quarkus.jdt.ext';
2222
const quarkusExtension = 'com.redhat.microprofile.jdt.quarkus';
2323

24+
const quteServerDir = '../quarkus-ls/qute.ls/com.redhat.qute.ls'
25+
const quteServer = 'com.redhat.qute.ls-uber.jar';
26+
27+
const quteExtensionDir = '../quarkus-ls/qute.jdt';
28+
const quteExtension = 'com.redhat.qute.jdt';
29+
2430
gulp.task('buildServer', (done) => {
2531
cp.execSync(mvnw() + ' clean verify -DskipTests', { cwd: quarkusServerExtDir , stdio: 'inherit' });
2632
gulp.src(quarkusServerExtDir + '/target/' + quarkusServerExt + '-!(*sources).jar')
@@ -41,7 +47,22 @@ gulp.task('buildExtension', (done) => {
4147
done();
4248
});
4349

44-
gulp.task('build', gulp.series('buildServer', 'buildExtension'));
50+
gulp.task('buildQuteServer', (done) => {
51+
cp.execSync(mvnw() + ' clean install -DskipTests', { cwd: quteServerDir , stdio: 'inherit' });
52+
gulp.src(quteServerDir + '/target/' + quteServer)
53+
.pipe(gulp.dest('./server'));
54+
done();
55+
});
56+
57+
gulp.task('buildQuteExtension', (done) => {
58+
cp.execSync(mvnw() + ' -pl "' + quteExtension + '" clean verify -DskipTests', { cwd: quteExtensionDir, stdio: 'inherit' });
59+
gulp.src(quteExtensionDir + '/' + quteExtension + '/target/' + quteExtension + '-!(*sources).jar')
60+
.pipe(rename(quteExtension + '.jar'))
61+
.pipe(gulp.dest('./jars'));
62+
done();
63+
});
64+
65+
gulp.task('build', gulp.series('buildServer', 'buildExtension','buildQuteServer', 'buildQuteExtension'));
4566

4667
function mvnw() {
4768
return isWin() ? 'mvnw.cmd' : './mvnw';

package-lock.json

Lines changed: 78 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@
5757
],
5858
"contributes": {
5959
"javaExtensions": [
60-
"./jars/com.redhat.microprofile.jdt.quarkus.jar"
60+
"./jars/com.redhat.microprofile.jdt.quarkus.jar",
61+
"./jars/com.redhat.qute.jdt.jar"
6162
],
6263
"microprofile": {
6364
"jarExtensions": [
64-
"./server/com.redhat.quarkus.ls.jar"
65+
"./server/com.redhat.quarkus.ls.jar",
66+
"./server/com.redhat.qute.ls.jar"
6567
],
6668
"documentSelector": [
6769
{
@@ -290,6 +292,8 @@
290292
"build": "./node_modules/.bin/gulp build",
291293
"build-server": "./node_modules/.bin/gulp buildServer",
292294
"build-ext": "./node_modules/.bin/gulp buildExtension",
295+
"build-qute-server": "./node_modules/.bin/gulp buildQuteServer",
296+
"build-qute-ext": "./node_modules/.bin/gulp buildQuteExtension",
293297
"test-ui": "rm -rf out && npm run test-compile && npm run test-ui-run",
294298
"test-ui-run": "extest setup-and-run 'out/test/vscodeUiTest/suite/*.js' -u -e 'out/test/vscodeUiTest/extensions'",
295299
"test-all": "npm test && npm run test-ui-run"
@@ -334,13 +338,15 @@
334338
"@redhat-developer/vscode-redhat-telemetry": "^0.4.2",
335339
"ejs": "^2.7.1",
336340
"expand-home-dir": "0.0.3",
341+
"find-java-home": "^1.0.0",
337342
"find-up": "^4.1.0",
338343
"fs-extra": "^8.0.1",
339344
"glob": "^7.1.4",
340345
"js-yaml": "^4.0.0",
341346
"lodash": "^4.17.21",
342347
"request": "^2.88.0",
343348
"request-promise": "^4.2.4",
349+
"vscode-languageclient": "^7.0.0",
344350
"which": "^2.0.2",
345351
"yauzl": "^2.10.0"
346352
}

src/extension.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { ProjectLabelInfo } from './definitions/ProjectLabelInfo';
2020
import { PropertiesLanguageMismatch, QuarkusConfig } from './QuarkusConfig';
2121
import { QuarkusContext } from './QuarkusContext';
2222
import quarkusProjectListener from './QuarkusProjectListener';
23+
import { connectToQuteLS } from './qute/languageServer/client';
2324
import { terminalCommandRunner } from './terminal/terminalCommandRunner';
2425
import { initTelemetryService } from './utils/telemetryUtils';
2526
import { WelcomeWebview } from './webviews/WelcomeWebview';
@@ -64,6 +65,14 @@ export async function activate(context: ExtensionContext) {
6465
);
6566

6667
registerVSCodeCommands(context);
68+
69+
connectToQuteLS(context).catch((error) => {
70+
window.showErrorMessage(error.message, error.label).then((selection) => {
71+
if (error.label && error.label === selection && error.openUrl) {
72+
commands.executeCommand('vscode.open', error.openUrl);
73+
}
74+
});
75+
});
6776
}
6877

6978
export function deactivate() {

src/qute/languageServer/client.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import * as requirements from './requirements';
2+
3+
import { DidChangeConfigurationNotification, LanguageClientOptions } from 'vscode-languageclient';
4+
import { LanguageClient } from 'vscode-languageclient/node';
5+
import { ExtensionContext, commands, window, workspace, Uri } from 'vscode';
6+
import { prepareExecutable } from './javaServerStarter';
7+
import { TextEncoder } from 'util';
8+
9+
export function connectToQuteLS(context: ExtensionContext) {
10+
registerVSCodeCommands(context);
11+
12+
return requirements.resolveRequirements().then(requirements => {
13+
const clientOptions: LanguageClientOptions = {
14+
documentSelector: [
15+
{ scheme: 'file', language: 'qute-html' },
16+
{ scheme: 'file', language: 'qute-json' },
17+
{ scheme: 'file', language: 'qute-yaml' },
18+
{ scheme: 'file', language: 'qute-txt' },
19+
{ scheme: 'untitled', language: 'qute-html' },
20+
{ scheme: 'vscode-notebook-cell', language: 'qute-html' },
21+
{ scheme: 'file', language: 'java' }
22+
],
23+
// wrap with key 'settings' so it can be handled same a DidChangeConfiguration
24+
initializationOptions: {
25+
settings: getQuteSettings()
26+
},
27+
synchronize: {
28+
// preferences starting with these will trigger didChangeConfiguration
29+
configurationSection: ['quarkus', '[qute]']
30+
},
31+
middleware: {
32+
workspace: {
33+
didChangeConfiguration: () => {
34+
quteLanguageClient.sendNotification(DidChangeConfigurationNotification.type, { settings: getQuteSettings() });
35+
}
36+
}
37+
}
38+
};
39+
40+
function bindQuteRequest(request: string) {
41+
quteLanguageClient.onRequest(request, async (params: any) =>
42+
<any>await commands.executeCommand("java.execute.workspaceCommand", request, params)
43+
);
44+
}
45+
46+
function bindQuteNotification(notification: string) {
47+
context.subscriptions.push(commands.registerCommand(notification, (event: any) => {
48+
quteLanguageClient.sendNotification(notification, event);
49+
}));
50+
}
51+
52+
const serverOptions = prepareExecutable(requirements);
53+
const quteLanguageClient = new LanguageClient('qute', 'Qute Support', serverOptions, clientOptions);
54+
context.subscriptions.push(quteLanguageClient.start());
55+
return quteLanguageClient.onReady().then(() => {
56+
bindQuteRequest('qute/template/project');
57+
bindQuteRequest('qute/template/projectDataModel');
58+
bindQuteRequest('qute/template/javaClasses');
59+
bindQuteRequest('qute/template/resolvedJavaClass');
60+
bindQuteRequest('qute/template/javaDefinition');
61+
bindQuteNotification('qute/dataModelChanged');
62+
bindQuteRequest('qute/java/codeLens');
63+
}
64+
)
65+
});
66+
}
67+
68+
/**
69+
* Returns a json object with key 'quarkus' and a json object value that
70+
* holds all quarkus. settings.
71+
*
72+
* Returns: {
73+
* 'quarkus': {...}
74+
* }
75+
*/
76+
function getQuteSettings(): JSON {
77+
const configQuarkus = workspace.getConfiguration().get('quarkus');
78+
let quarkus;
79+
if (!configQuarkus) { // Set default preferences if not provided
80+
const defaultValue =
81+
{
82+
qute: {
83+
84+
}
85+
};
86+
quarkus = defaultValue;
87+
} else {
88+
const x = JSON.stringify(configQuarkus); // configQuarkus is not a JSON type
89+
quarkus = { quarkus: JSON.parse(x) };
90+
}
91+
return quarkus;
92+
}
93+
94+
function registerVSCodeCommands(context: ExtensionContext) {
95+
registerOpenUriCommand(context);
96+
registerGenerateTemplateFileCommand(context);
97+
}
98+
99+
100+
function registerOpenUriCommand(context: ExtensionContext) {
101+
context.subscriptions.push(commands.registerCommand('qute.command.open.uri', async (uri?: string) => {
102+
commands.executeCommand('vscode.open', Uri.parse(uri));
103+
}));
104+
}
105+
106+
function registerGenerateTemplateFileCommand(context: ExtensionContext) {
107+
context.subscriptions.push(commands.registerCommand('qute.command.generate.template.file', async (info?) => {
108+
const templateContent: string = await commands.executeCommand('qute.command.generate.template.content', info);
109+
const uri = info.templateFileUri;
110+
const fileUri = Uri.parse(uri);
111+
await workspace.fs.writeFile(fileUri, new TextEncoder().encode(templateContent));
112+
window.showTextDocument(fileUri, { preview: false });
113+
}));
114+
}

0 commit comments

Comments
 (0)