Skip to content

Commit

Permalink
feat(vscode): Add completions for Grain Doc comments (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
phated committed Jun 22, 2021
1 parent d2d9f64 commit d34b4ec
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
65 changes: 65 additions & 0 deletions editor-extensions/vscode/client/src/GrainDocCompletionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Based on https://github.com/microsoft/vscode/blob/94c9ea46838a9a619aeafb7e8afd1170c967bb55/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts
import * as vscode from "vscode";
import { LanguageClient } from "vscode-languageclient";

const defaultGrainDoc = new vscode.SnippetString(`/**\n * $0\n */`);

class GrainDocCompletionItem extends vscode.CompletionItem {
constructor(
public readonly document: vscode.TextDocument,
public readonly position: vscode.Position
) {
super("/** */", vscode.CompletionItemKind.Text);
this.detail = "Grain Doc Comment";
this.sortText = "\0";

const line = document.lineAt(position.line).text;
const prefix = line.slice(0, position.character).match(/\/\**\s*$/);
const suffix = line.slice(position.character).match(/^\s*\**\//);
const start = position.translate(0, prefix ? -prefix[0].length : 0);
const range = new vscode.Range(
start,
position.translate(0, suffix ? suffix[0].length : 0)
);
this.range = { inserting: range, replacing: range };
}
}

export class GrainDocCompletionProvider
implements vscode.CompletionItemProvider {
constructor(readonly client: LanguageClient) {}

public async provideCompletionItems(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.CompletionItem[] | undefined> {
if (!this.isPotentiallyValidDocCompletionPosition(document, position)) {
return undefined;
}

const item = new GrainDocCompletionItem(document, position);

// TODO: Get param and returns details from `grain lsp`
item.insertText = defaultGrainDoc;

return [item];
}

private isPotentiallyValidDocCompletionPosition(
document: vscode.TextDocument,
position: vscode.Position
): boolean {
// Only show the GrainDoc completion when the everything before the cursor is whitespace
// or could be the opening of a comment
const line = document.lineAt(position.line).text;
const prefix = line.slice(0, position.character);
if (!/^\s*$|\/\*\*\s*$|^\s*\/\*\*+\s*$/.test(prefix)) {
return false;
}

// And everything after is possibly a closing comment or more whitespace
const suffix = line.slice(position.character);
return /^\s*(\*+\/)?\s*$/.test(suffix);
}
}
9 changes: 9 additions & 0 deletions editor-extensions/vscode/client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import {
} from "vscode-languageclient";

import { CodelensProvider } from "./CodelensProvider";
import { GrainDocCompletionProvider } from "./GrainDocCompletionProvider";

let client: LanguageClient;

let disposables: Disposable[] = [];

let codelensProvider: CodelensProvider;
let grainDocCompletionProvider: GrainDocCompletionProvider;

export function activate(context: ExtensionContext) {
// The server is implemented in node
Expand Down Expand Up @@ -68,6 +70,13 @@ export function activate(context: ExtensionContext) {
codelensProvider = new CodelensProvider(client);
languages.registerCodeLensProvider("grain", codelensProvider);

grainDocCompletionProvider = new GrainDocCompletionProvider(client);
languages.registerCompletionItemProvider(
"grain",
grainDocCompletionProvider,
"*"
);

codelensProvider.triggerRefresh();
client.onNotification("grainlsp/lensesLoaded", (files: Array<String>) => {
codelensProvider.triggerRefresh();
Expand Down

0 comments on commit d34b4ec

Please sign in to comment.