Skip to content

Commit

Permalink
Configurable folder excludes (#519)
Browse files Browse the repository at this point in the history
Configurable folder excludes #344
  • Loading branch information
dhuebner committed Sep 5, 2022
1 parent f150dbd commit 14eb532
Show file tree
Hide file tree
Showing 14 changed files with 267 additions and 63 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

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

19 changes: 0 additions & 19 deletions packages/langium-vscode/.eslintrc.json

This file was deleted.

15 changes: 13 additions & 2 deletions packages/langium-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,17 @@
"fileMatch": "langium-config.json",
"url": "./data/langium-config-schema.json"
}
]
],
"configuration": {
"title": "Langium",
"properties": {
"langium.build.ignorePatterns": {
"type": "string",
"default": "node_modules, out",
"description": "Specifies the exclusion patterns during initial workspace indexing. You will need to reload your extension afterwards."
}
}
}
},
"activationEvents": [
"onLanguage:langium"
Expand All @@ -55,7 +65,8 @@
"dependencies": {
"langium": "0.4.0",
"vscode-languageclient": "^8.0.1",
"vscode-languageserver": "^8.0.1"
"vscode-languageserver": "^8.0.1",
"ignore":"~5.2.0"
},
"devDependencies": {
"@types/vscode": "^1.53.0",
Expand Down
39 changes: 19 additions & 20 deletions packages/langium-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,40 @@ function startLanguageClient(context: vscode.ExtensionContext): LanguageClient {
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
};

const fileSystemWatcher = vscode.workspace.createFileSystemWatcher('**/*.langium');
context.subscriptions.push(fileSystemWatcher);

// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for langium documents
documentSelector: [{ scheme: 'file', language: 'langium' }],
synchronize: {
// Notify the server about file changes to langium files contained in the workspace
fileEvents: fileSystemWatcher
}
// Register the server for langium documents
documentSelector: [{ scheme: 'file', language: 'langium' }],
synchronize: {
// Notify the server about file changes to langium files contained in the workspace
fileEvents: fileSystemWatcher
}
};

// Create the language client and start the client.
const client = new LanguageClient(
'langium',
'Langium',
serverOptions,
clientOptions
'langium',
'Langium',
serverOptions,
clientOptions
);

// Start the client. This will also launch the server
client.start();
return client;
}


// TODO(@@dd): externalize extension config
const DELAY = 100; // delay in ms until a render can be cancelled on subsequent document changes

Expand All @@ -93,7 +92,7 @@ type CancelableDecorator = () => void;
type TimeoutID = ReturnType<typeof setTimeout>; // NodeJS.Timer (node) or number (browser)

// adds the ability to cancel decoration requests
function cancelableDecorator(decorator: Decorator, delay: number = 500): CancelableDecorator {
function cancelableDecorator(decorator: Decorator, _delay = 500): CancelableDecorator {
let timeout: TimeoutID | undefined; // works for window.setTimeout() & NodeJS
return () => {
const editor = vscode.window.activeTextEditor;
Expand Down Expand Up @@ -137,7 +136,7 @@ function decorateText(document: vscode.TextDocument, decorations: vscode.Decorat
}
}

// TODO(@@dd): find bug
// TODO(@@dd): find bug
function findIndentation(text: string): number {
const indents = text.split(/[\r?\n]/g).map(line => line.trimRight()).filter(line => line.length > 0).map(line => line.search(/\S|$/));
const min = indents.length === 0 ? 0 : Math.min(...indents); // min(...[]) = min() = Infinity
Expand All @@ -146,7 +145,7 @@ function findIndentation(text: string): number {

function isSmartTemplate(name: string, index: number): boolean {
// TODO(@@dd): check if symbol(name)'s type resolves to smart template
return name === "indent" && index !== -1;
return name === 'indent' && index !== -1;
}

// styling of a decorated range
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/

import ignore, { Ignore } from 'ignore';
import { LangiumGrammarLanguageMetaData } from 'langium/src/grammar/generated/module';
import { LangiumSharedServices } from 'langium/src/services';
import { ConfigurationProvider } from 'langium/src/workspace/configuration';
import { FileSystemNode } from 'langium/src/workspace/file-system-provider';
import { DefaultWorkspaceManager } from 'langium/src/workspace/workspace-manager';
import * as path from 'path';
import { CancellationToken, WorkspaceFolder } from 'vscode-languageserver-protocol';
import { URI, Utils } from 'vscode-uri';

const CONFIG_KEY = 'build';

interface WorkspaceManagerConf {
/**
* gitignore-style exclusion patterns, separated by comma
*/
ignorePatterns: string
}

export class LangiumGrammarWorkspaceManager extends DefaultWorkspaceManager {

protected readonly configurationProvider: ConfigurationProvider;
protected matcher: Ignore | undefined;

constructor(services: LangiumSharedServices) {
super(services);
this.configurationProvider = services.workspace.ConfigurationProvider;
}

async initializeWorkspace(folders: WorkspaceFolder[], cancelToken = CancellationToken.None): Promise<void> {
const buildConf: WorkspaceManagerConf = await this.configurationProvider.getConfiguration(LangiumGrammarLanguageMetaData.languageId, CONFIG_KEY);
const ignorePatterns = buildConf.ignorePatterns?.split(',')?.map(pattern => pattern.trim())?.filter(pattern => pattern.length > 0);
this.matcher = ignorePatterns ? ignore().add(ignorePatterns) : undefined;
return super.initializeWorkspace(folders, cancelToken);
}

protected includeEntry(workspaceFolder: WorkspaceFolder, entry: FileSystemNode, fileExtensions: string[]): boolean {
if (this.matcher) {
// create path relative to workspace folder root: /user/foo/workspace/entry.txt -> entry.txt
const relPath = path.relative(URI.parse(workspaceFolder.uri).path, entry.uri.path);
const ignored = this.matcher.ignores(relPath);
return !ignored && (entry.isDirectory || (entry.isFile && fileExtensions.includes(Utils.extname(entry.uri))));
}
return super.includeEntry(workspaceFolder, entry, fileExtensions);
}

}
12 changes: 10 additions & 2 deletions packages/langium-vscode/src/language-server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
* terms of the MIT License, which is available in the project root.
******************************************************************************/

import { createLangiumGrammarServices, startLanguageServer } from 'langium';
import { createLangiumGrammarServices, LangiumSharedServices, Module, PartialLangiumSharedServices, startLanguageServer } from 'langium';
import { NodeFileSystem } from 'langium/node';
import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';
import { LangiumGrammarWorkspaceManager } from './grammar-workspace-manager';

const connection = createConnection(ProposedFeatures.all);
const { shared } = createLangiumGrammarServices({ connection, ...NodeFileSystem });

export const LangiumGrammarSharedModule: Module<LangiumSharedServices, PartialLangiumSharedServices> = {
workspace: {
WorkspaceManager: (services) => new LangiumGrammarWorkspaceManager(services)
}
};

const { shared } = createLangiumGrammarServices({ connection, ...NodeFileSystem }, LangiumGrammarSharedModule);
startLanguageServer(shared);
4 changes: 3 additions & 1 deletion packages/langium/src/default-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { DefaultDocumentValidator } from './validation/document-validator';
import { ValidationRegistry } from './validation/validation-registry';
import { DefaultAstNodeDescriptionProvider, DefaultReferenceDescriptionProvider } from './workspace/ast-descriptions';
import { DefaultAstNodeLocator } from './workspace/ast-node-locator';
import { DefaultConfigurationProvider } from './workspace/configuration';
import { DefaultDocumentBuilder } from './workspace/document-builder';
import { DefaultLangiumDocumentFactory, DefaultLangiumDocuments, DefaultTextDocumentFactory } from './workspace/documents';
import { FileSystemProvider } from './workspace/file-system-provider';
Expand Down Expand Up @@ -132,7 +133,8 @@ export function createDefaultSharedModule(context: DefaultSharedModuleContext):
IndexManager: (services) => new DefaultIndexManager(services),
WorkspaceManager: (services) => new DefaultWorkspaceManager(services),
FileSystemProvider: (services) => context.fileSystemProvider(services),
MutexLock: () => new MutexLock()
MutexLock: () => new MutexLock(),
ConfigurationProvider: (services) => new DefaultConfigurationProvider(services)
}
};
}
20 changes: 11 additions & 9 deletions packages/langium/src/grammar/langium-grammar-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@

import { createDefaultModule, createDefaultSharedModule, DefaultSharedModuleContext } from '../default-module';
import { inject, Module } from '../dependency-injection';
import { LangiumServices, LangiumSharedServices, PartialLangiumServices } from '../services';
import { LangiumServices, LangiumSharedServices, PartialLangiumServices, PartialLangiumSharedServices } from '../services';
import { LangiumGrammarGeneratedModule, LangiumGrammarGeneratedSharedModule } from './generated/module';
import { LangiumGrammarCodeActionProvider } from './lsp/grammar-code-actions';
import { LangiumGrammarScopeComputation, LangiumGrammarScopeProvider } from './langium-grammar-scope';
import { LangiumGrammarSemanticTokenProvider } from './lsp/grammar-semantic-tokens';
import { LangiumGrammarValidationRegistry, LangiumGrammarValidator } from './langium-grammar-validator';
import { LangiumGrammarCodeActionProvider } from './lsp/grammar-code-actions';
import { LangiumGrammarFoldingRangeProvider } from './lsp/grammar-folding-ranges';
import { LangiumGrammarFormatter } from './lsp/grammar-formatter';
import { LangiumGrammarReferences } from './references/grammar-references';
import { LangiumGrammarSemanticTokenProvider } from './lsp/grammar-semantic-tokens';
import { LangiumGrammarNameProvider } from './references/grammar-naming';
import { LangiumGrammarReferences } from './references/grammar-references';
import { LangiumGrammarGoToResolver } from './lsp/grammar-goto';

export type LangiumGrammarAddedServices = {
Expand Down Expand Up @@ -46,13 +46,15 @@ export const LangiumGrammarModule: Module<LangiumGrammarServices, PartialLangium
}
};

export function createLangiumGrammarServices(context: DefaultSharedModuleContext): {
shared: LangiumSharedServices,
grammar: LangiumGrammarServices
} {
export function createLangiumGrammarServices(context: DefaultSharedModuleContext,
sharedModule?: Module<LangiumSharedServices, PartialLangiumSharedServices>): {
shared: LangiumSharedServices,
grammar: LangiumGrammarServices
} {
const shared = inject(
createDefaultSharedModule(context),
LangiumGrammarGeneratedSharedModule
LangiumGrammarGeneratedSharedModule,
sharedModule
);
const grammar = inject(
createDefaultModule({ shared }),
Expand Down
1 change: 1 addition & 0 deletions packages/langium/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ export * from './workspace/documents';
export * from './workspace/index-manager';
export * from './workspace/file-system-provider';
export * from './workspace/workspace-manager';
export * from './workspace/configuration';
8 changes: 8 additions & 0 deletions packages/langium/src/lsp/language-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export function startLanguageServer(services: LangiumSharedServices): void {
addSemanticTokenHandler(connection, services);
addExecuteCommandHandler(connection, services);
addSignatureHelpHandler(connection, services);
addConfigurationChangeHandler(connection, services);

connection.onInitialize(params => {
return services.lsp.LanguageServer.initialize(params);
Expand Down Expand Up @@ -315,6 +316,13 @@ export function addSemanticTokenHandler(connection: Connection, services: Langiu
services
));
}
export function addConfigurationChangeHandler(connection: Connection, services: LangiumSharedServices): void {
connection.onDidChangeConfiguration(change => {
if (change.settings) {
services.workspace.ConfigurationProvider.updateConfiguration(change);
}
});
}

export function addExecuteCommandHandler(connection: Connection, services: LangiumSharedServices): void {
const commandHandler = services.lsp.ExecuteCommandHandler;
Expand Down
2 changes: 2 additions & 0 deletions packages/langium/src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import type { DocumentValidator } from './validation/document-validator';
import type { ValidationRegistry } from './validation/validation-registry';
import type { AstNodeDescriptionProvider, ReferenceDescriptionProvider } from './workspace/ast-descriptions';
import type { AstNodeLocator } from './workspace/ast-node-locator';
import { ConfigurationProvider } from './workspace/configuration';
import type { DocumentBuilder } from './workspace/document-builder';
import type { LangiumDocumentFactory, LangiumDocuments, TextDocumentFactory } from './workspace/documents';
import type { FileSystemProvider } from './workspace/file-system-provider';
Expand Down Expand Up @@ -151,6 +152,7 @@ export type LangiumDefaultSharedServices = {
WorkspaceManager: WorkspaceManager
FileSystemProvider: FileSystemProvider
MutexLock: MutexLock
ConfigurationProvider: ConfigurationProvider
}
}

Expand Down
Loading

0 comments on commit 14eb532

Please sign in to comment.