Skip to content

Commit

Permalink
Enable client snippet before the language server is ready (#1101)
Browse files Browse the repository at this point in the history
Signed-off-by: Sheng Chen <[email protected]>
  • Loading branch information
jdneo authored and fbricon committed Dec 3, 2019
1 parent 236632e commit a44000b
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 11 deletions.
60 changes: 49 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@
"tslint": "tslint -p ."
},
"devDependencies": {
"@types/fs-extra": "^8.0.0",
"@types/glob": "5.0.30",
"@types/lodash.findindex": "^4.6.6",
"@types/mocha": "^5.2.5",
Expand All @@ -571,6 +572,7 @@
"tmp": "^0.0.33",
"path-exists": "^3.0.0",
"expand-home-dir": "^0.0.3",
"fs-extra": "^8.1.0",
"glob": "^7.1.3",
"winston": "^3.2.1",
"winston-daily-rotate-file": "^3.10.0"
Expand Down
90 changes: 90 additions & 0 deletions snippets/server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"sysout": {
"prefix": "sysout",
"body": [
"System.out.println($0);"
],
"description": "Print to standard out"
},
"syserr": {
"prefix": "syserr",
"body": [
"System.err.println($0);"
],
"description": "Print to standard err"
},
"fori": {
"prefix": "fori",
"body": [
"for (${1:int} ${2:i} = ${3:0}; ${2:i} < ${4:max}; ${2:i}++) {",
"\t$0",
"}"
],
"description": "Indexed for loop"
},
"foreach": {
"prefix": "foreach",
"body": [
"for (${1:type} ${2:var} : ${3:iterable}) {",
"\t$0",
"}"
],
"description": "Enhanced for loop"
},
"if": {
"prefix": "if",
"body": [
"if (${1:condition}) {",
"\t$0",
"}"
],
"description": "if statement"
},
"ifelse": {
"prefix": "ifelse",
"body": [
"if (${1:condition}) {",
"\t$2",
"} else {",
"\t$0",
"}"
],
"description": "if/else statement"
},
"ifnull": {
"prefix": "ifnull",
"body": [
"if (${1:condition} == null) {",
"\t$0",
"}"
],
"description": "if statement checking for null"
},
"ifnotnull": {
"prefix": "ifnotnull",
"body": [
"if (${1:condition} != null) {",
"\t$0",
"}"
],
"description": "if statement checking for not null"
},
"While Statement": {
"prefix": "while",
"body": [
"while (${1:condition}) {",
"\t$0",
"}"
],
"description": "While Statement"
},
"Do-While Statement": {
"prefix": "dowhile",
"body": [
"do {",
"\t$0",
"} while (${1:condition});"
],
"description": "Do-While Statement"
}
}
5 changes: 5 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { getJavaConfiguration } from './utils';
import { onConfigurationChange, excludeProjectSettingsFiles } from './settings';
import { logger, initializeLogFile } from './log';
import glob = require('glob');
import { SnippetCompletionProvider } from './snippetCompletionProvider';
import { serverTasks } from './serverTasks';
import { serverTaskPresenter } from './serverTaskPresenter';
import { serverStatus, ServerStatusKind } from './serverStatus';
Expand Down Expand Up @@ -224,6 +225,9 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
const registerHoverCommand = hoverAction.registerClientHoverProvider(languageClient, context);
const getDocumentSymbols: getDocumentSymbolsCommand = getDocumentSymbolsProvider(languageClient);

const snippetProvider: SnippetCompletionProvider = new SnippetCompletionProvider();
context.subscriptions.push(languages.registerCompletionItemProvider({ scheme: 'file', language: 'java' }, snippetProvider));

languageClient.onReady().then(() => {
languageClient.onNotification(StatusNotification.type, (report) => {
switch (report.type) {
Expand All @@ -237,6 +241,7 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
registerHoverCommand,
getDocumentSymbols
});
snippetProvider.setActivation(false);
break;
case 'Error':
serverStatus.updateServerStatus(ServerStatusKind.Error);
Expand Down
44 changes: 44 additions & 0 deletions src/snippetCompletionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

import { CompletionItemProvider, TextDocument, Position, CancellationToken, CompletionContext, CompletionItem, CompletionItemKind, SnippetString, MarkdownString } from "vscode";
import * as fse from 'fs-extra';
import * as path from 'path';

export class SnippetCompletionProvider implements CompletionItemProvider {

private snippets: {};
private activation: boolean;

public constructor() {
this.activation = true;
this.snippets = fse.readJSONSync(path.join(__dirname, '..', 'snippets', 'server.json'));
}

public async provideCompletionItems(_document: TextDocument, _position: Position, _token: CancellationToken, _context: CompletionContext): Promise<CompletionItem[]> {
if (!this.activation) {
return [];
}

const snippetItems: CompletionItem[] = [];
for (const label of Object.keys(this.snippets)) {
const snippetContent = this.snippets[label];
const snippetItem: CompletionItem = new CompletionItem(snippetContent.prefix);
snippetItem.kind = CompletionItemKind.Snippet;
snippetItem.detail = snippetContent.description;
const insertText: string = (snippetContent.body as String[]).join('\n');
snippetItem.insertText = new SnippetString(insertText);
snippetItem.documentation = beautifyDocument(insertText);
snippetItems.push(snippetItem);
}
return snippetItems;
}

public setActivation(activation: boolean): void {
this.activation = activation;
}
}

export function beautifyDocument(raw: string): MarkdownString {
const escapedString = raw.replace(/\$\{\d:?(.*?)\}/gm, '$1').replace(/\$\d/gm, '');
return new MarkdownString().appendCodeblock(escapedString, "java");
}
14 changes: 14 additions & 0 deletions test/snippetCompletionProvider.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as assert from 'assert';
import { beautifyDocument } from '../src/snippetCompletionProvider';
import { MarkdownString } from 'vscode';

suite('Snippet Completion Provider', () => {

test('should render document correctly', () => {
// tslint:disable: prefer-template
const raw = "for (${1:int} ${2:i} = ${3:0}; ${2:i} < ${4:max}; ${2:i}++) {\n" + "\t$0\n" + "}";
const markdownString: MarkdownString = beautifyDocument(raw);
const expected: string = "\n```java\n" + "for (int i = 0; i < max; i++) {\n" + "\t\n" + "}\n" + "```\n";
assert.equal(markdownString.value, expected);
});
});

0 comments on commit a44000b

Please sign in to comment.