| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import * as vscode from 'vscode';
- import { createDiagnostics } from './diagnostics';
- import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient/node';
- const KEYWORDS = new Set([
- 'ARRAY', 'BEGIN', 'BY', 'CASE', 'CONST', 'DEFINITION', 'DIV', 'DO',
- 'ELSE', 'ELSIF', 'END', 'EXIT', 'FOR', 'IF', 'IMPORT', 'IN', 'IS',
- 'LOOP', 'MOD', 'MODULE', 'NIL', 'OF', 'OR', 'POINTER', 'PROCEDURE',
- 'RECORD', 'REPEAT', 'RETURN', 'THEN', 'TO', 'TYPE', 'UNTIL', 'VAR',
- 'WHILE', 'WITH'
- ]);
- let applyingEdit = false;
- function isIdentifierCharacter(ch: string | undefined): boolean {
- return !!ch && /[A-Za-z0-9_]/.test(ch);
- }
- export function activate(context: vscode.ExtensionContext): void {
- createDiagnostics(context);
- const serverModule = context.asAbsolutePath('out/server.js');
- const serverOptions: ServerOptions = {
- run: { module: serverModule, transport: TransportKind.ipc },
- debug: { module: serverModule, transport: TransportKind.ipc }
- };
- const cfg = vscode.workspace.getConfiguration('modula2');
- const clientOptions: LanguageClientOptions = {
- documentSelector: [
- { scheme: 'file', language: 'oberon' }
- ],
- synchronize: { configurationSection: 'modula2' },
- initializationOptions: {
- oberonDialect: cfg.get<string>('oberon.dialect', 'oberon2'),
- oberonValidators: cfg.get<object>('oberon.validators', {}),
- format: {
- indentSize: cfg.get<number>('oberon.format.indentSize', 2),
- useTabs: cfg.get<boolean>('oberon.format.useTabs', false),
- keywordCase: cfg.get<string>('oberon.format.keywordCase', 'upper'),
- spaceAroundOperators: cfg.get<boolean>('oberon.format.spaceAroundOperators', true),
- spaceAfterComma: cfg.get<boolean>('oberon.format.spaceAfterComma', true),
- spaceBeforeColon: cfg.get<boolean>('oberon.format.spaceBeforeColon', false),
- spaceAroundRange: cfg.get<boolean>('oberon.format.spaceAroundRange', true),
- emptyLineLimit: cfg.get<number>('oberon.format.emptyLineLimit', 1),
- trimTrailingWhitespace: cfg.get<boolean>('oberon.format.trimTrailingWhitespace', true),
- insertFinalNewline: cfg.get<boolean>('oberon.format.insertFinalNewline', true)
- }
- }
- };
- const client = new LanguageClient('oberonCocoR', 'Oberon Coco/R Language Server', serverOptions, clientOptions);
- context.subscriptions.push(client);
- void client.start();
- context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(async event => {
- if (applyingEdit || event.document.languageId !== 'oberon' ||
- !vscode.workspace.getConfiguration('modula2').get<boolean>('oberon.uppercaseKeywords', true)) {
- return;
- }
- const editor = vscode.window.activeTextEditor;
- if (!editor || editor.document.uri.toString() !== event.document.uri.toString()) {
- return;
- }
- for (const change of event.contentChanges) {
- const position = change.range.start.translate(0, change.text.length);
- const line = event.document.lineAt(position.line).text;
- let start = position.character;
- while (start > 0 && isIdentifierCharacter(line[start - 1])) {
- start--;
- }
- let end = position.character;
- while (end < line.length && isIdentifierCharacter(line[end])) {
- end++;
- }
- // Do not modify a token while it is still being typed.
- if (end >= line.length || isIdentifierCharacter(line[end])) {
- continue;
- }
- const token = line.slice(start, end);
- const upper = token.toUpperCase();
- if (!KEYWORDS.has(upper) || token === upper) {
- continue;
- }
- applyingEdit = true;
- try {
- await editor.edit(builder => {
- builder.replace(
- new vscode.Range(position.line, start, position.line, end),
- upper
- );
- });
- } finally {
- applyingEdit = false;
- }
- }
- }));
- }
- export function deactivate(): void {}
|