Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable folder excludes #519

Merged
merged 1 commit into from
Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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