implementing completion

This commit is contained in:
CismonX 2020-10-08 22:31:54 +08:00
parent e47d92f2a9
commit 36b8ae0279
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
2 changed files with 88 additions and 54 deletions

View File

@ -7,64 +7,31 @@
import * as vscode from 'vscode';
/**
* Texinfo language completion item provider.
*/
export class CompletionItemProvider implements vscode.CompletionItemProvider {
private readonly completionItems: vscode.CompletionItem[] = [
{
label: 'header',
kind: vscode.CompletionItemKind.Snippet,
detail: 'Start/end of header',
sortText: 'c1',
filterText: 'c',
insertText: 'c %**',
},
{
label: '@setfilename',
kind: vscode.CompletionItemKind.Function,
detail: 'Set output file name',
sortText: 'setfilename',
filterText: 'setfilename',
insertText: 'setfilename ',
},
{
label: '@settitle',
kind: vscode.CompletionItemKind.Function,
detail: 'Set document title',
sortText: 'settitle',
filterText: 'settitle',
insertText: 'settitle ',
},
{
label: '@copying',
kind: vscode.CompletionItemKind.Function,
detail: 'declare copying permissions',
sortText: 'copying1',
filterText: 'copying',
insertText: 'copying',
},
{
label: 'copying',
kind: vscode.CompletionItemKind.Snippet,
detail: 'declare copying permissions',
sortText: 'copying0',
filterText: 'copying',
insertText: new vscode.SnippetString('copying\n$1\n@end copying\n'),
},
{
label: '@copyright',
kind: vscode.CompletionItemKind.Function,
detail: 'The \'©\' symbol',
sortText: 'copyright',
filterText: 'copyright',
insertText: 'copyright{} '
},
private readonly completionItems = [
command('c', 'Line comment'),
snippet('header', 'c', 'Declare header block', 1,
'@c %**start of header\n\n@c %**end of header',
'c %**${1:start of header}\n$2\n@c %**${3:end of header}'),
command('setfilename', 'Set output file name'),
command('settitle', 'Set document title'),
command('copying', 'Declare copying permissions', { sortOrder: 1 }),
blockSnippet('copying', 'Declare copying permissions'),
command('copyright', 'The \'©\' symbol', { hasEmptyArguments: true }),
command('insertcopying', 'Include permissions text'),
command('titlepage', 'Declare title page', { sortOrder: 1 }),
blockSnippet('titlepage', 'Declare title page'),
];
provideCompletionItems(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken,
context: vscode.CompletionContext
context: vscode.CompletionContext,
) {
if (context.triggerKind === vscode.CompletionTriggerKind.Invoke) {
const wordRange = document.getWordRangeAtPosition(position);
@ -73,12 +40,10 @@ export class CompletionItemProvider implements vscode.CompletionItemProvider {
}
position = wordRange.start;
if (document.getText(new vscode.Range(position.translate(0, -1), position)) !== '@') {
// Current word is not a command.
return undefined;
}
}
if (position.character === 1) {
// Start of line.
return this.completionItems;
}
if (document.getText(new vscode.Range(position.translate(0, -2), position.translate(0, -1))) === '@') {
@ -89,3 +54,72 @@ export class CompletionItemProvider implements vscode.CompletionItemProvider {
}
}
}
/**
* Build the completion item for a Texinfo command.
*
* @param name The command name.
* @param detail The command description.
* @param extraArgs Extra arguments.
*/
function command(name: string, detail: string, extraArgs?: {
/**
* Sort order for this completion item when names collide.
*/
sortOrder?: number,
/**
* Whether this command takes no arguments and braces are required.
*/
hasEmptyArguments?: boolean,
}): vscode.CompletionItem {
return {
label: '@' + name,
kind: vscode.CompletionItemKind.Function,
detail: detail,
sortText: name + extraArgs?.sortOrder?.toString() ?? '',
filterText: name,
insertText: name + extraArgs?.hasEmptyArguments ? '{}' : '',
}
}
function blockSnippet(name: string, detail: string): vscode.CompletionItem {
return snippet(name, name, detail, 0, `@${name}\n\n@end ${name}`, `${name}\n$1\n@end ${name}`);
}
/**
* Build the completion item for a generic snippet.
*
* @param label The string showing up in the completion list.
* @param keyword The word typed by the user.
* @param detail The snippet description.
* @param sortOrder Sort order for this completion item when names collide.
* @param documentation The Markdown documentation for this snippet.
* @param insertText The text to replace current word when the item is selected.
*/
function snippet(
label: string,
keyword: string,
detail: string,
sortOrder: number,
documentation: string,
insertText: string,
): vscode.CompletionItem {
return {
label: label,
kind: vscode.CompletionItemKind.Snippet,
detail: detail + ' (snippet)',
documentation: snippetDocumentation(documentation),
sortText: keyword + sortOrder.toString(),
filterText: keyword,
insertText: new vscode.SnippetString(insertText),
}
}
/**
* Wraps Texinfo snippet code into a Markdown code block for documentation.
*
* @param snippet The snippet code
*/
function snippetDocumentation(snippet: string) {
return new vscode.MarkdownString(`\`\`\`texinfo\n${snippet}\n\`\`\``);
}

View File

@ -1,10 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"target": "ES2019",
"outDir": "out",
"lib": [
"es6"
"ES2019"
],
"sourceMap": true,
"rootDir": "src",