Skip to content

Commit

Permalink
feat: messaging service (#1004)
Browse files Browse the repository at this point in the history
### Summary of Changes

Add a service that wraps various means to communicate with the language
client.
  • Loading branch information
lars-reimann authored Apr 7, 2024
1 parent 568ee20 commit dcf4ecf
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 1 deletion.
136 changes: 136 additions & 0 deletions packages/safe-ds-lang/src/language/lsp/safe-ds-messaging-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { SafeDsServices } from '../safe-ds-module.js';
import { Connection } from 'vscode-languageserver';
import { Disposable } from 'vscode-languageserver-protocol';

/* c8 ignore start */

/**
* Log or show messages in the language client or otherwise communicate with it.
*/
export class SafeDsMessagingProvider {
private readonly connection: Connection | undefined;

constructor(services: SafeDsServices) {
this.connection = services.shared.lsp.Connection;
}

/**
* Log the given data to the trace log.
*/
trace(tag: string, message: string, verbose?: string): void {
if (this.connection) {
const text = this.formatLogMessage(tag, message);
this.connection.tracer.log(text, verbose);
}
}

/**
* Log a debug message.
*/
debug(tag: string, message: string): void {
if (this.connection) {
const text = this.formatLogMessage(tag, message);
this.connection.console.debug(text);
}
}

/**
* Log an information message.
*/
info(tag: string, message: string): void {
if (this.connection) {
const text = this.formatLogMessage(tag, message);
this.connection.console.info(text);
}
}

/**
* Log a warning message.
*/
warn(tag: string, message: string): void {
if (this.connection) {
const text = this.formatLogMessage(tag, message);
this.connection.console.warn(text);
}
}

/**
* Log an error message.
*/
error(tag: string, message: string): void {
if (this.connection) {
const text = this.formatLogMessage(tag, message);
this.connection.console.error(text);
}
}

private formatLogMessage(tag: string, message: string): string {
return tag ? `[${tag}] ${message}` : message;
}

/**
* Shows an information message in the client's user interface.
*
* Depending on the client this might be a modal dialog with a confirmation button or a notification in a
* notification center.
*/
showInformationMessage(message: string): void {
if (this.connection) {
this.connection.window.showInformationMessage(message);
}
}

/**
* Shows a warning message in the client's user interface.
*
* Depending on the client this might be a modal dialog with a confirmation button or a notification in a
* notification center.
*/
showWarningMessage(message: string): void {
if (this.connection) {
this.connection.window.showWarningMessage(message);
}
}

/**
* Shows an error message in the client's user interface.
*
* Depending on the client this might be a modal dialog with a confirmation button or a notification in a
* notification center.
*/
showErrorMessage(message: string): void {
if (this.connection) {
this.connection.window.showErrorMessage(message);
}
}

/**
* Installs a notification handler for the given method.
*
* @param method The method to register a request handler for.
* @param handler The handler to install.
*/
onNotification(method: string, handler: (...params: any[]) => void): Disposable {
if (this.connection) {
return this.connection.onNotification(method, handler);
}

return {
dispose() {},
};
}

/**
* Send a notification to the client.
*
* @param method The method to invoke on the client.
* @param params The notification's parameters.
*/
async sendNotification(method: string, ...params: any): Promise<void> {
if (this.connection) {
await this.connection.sendNotification(method, params);
}
}
}

/* c8 ignore stop */
3 changes: 3 additions & 0 deletions packages/safe-ds-lang/src/language/safe-ds-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { SafeDsTypeFactory } from './typing/safe-ds-type-factory.js';
import { SafeDsMarkdownGenerator } from './generation/safe-ds-markdown-generator.js';
import { SafeDsCompletionProvider } from './lsp/safe-ds-completion-provider.js';
import { SafeDsFuzzyMatcher } from './lsp/safe-ds-fuzzy-matcher.js';
import { SafeDsMessagingProvider } from './lsp/safe-ds-messaging-provider.js';

/**
* Declaration of custom services - add your own service classes here.
Expand Down Expand Up @@ -73,6 +74,7 @@ export type SafeDsAddedServices = {
NodeMapper: SafeDsNodeMapper;
};
lsp: {
MessagingProvider: SafeDsMessagingProvider;
NodeInfoProvider: SafeDsNodeInfoProvider;
};
purity: {
Expand Down Expand Up @@ -135,6 +137,7 @@ export const SafeDsModule: Module<SafeDsServices, PartialLangiumServices & SafeD
DocumentSymbolProvider: (services) => new SafeDsDocumentSymbolProvider(services),
Formatter: () => new SafeDsFormatter(),
InlayHintProvider: (services) => new SafeDsInlayHintProvider(services),
MessagingProvider: (services) => new SafeDsMessagingProvider(services),
NodeInfoProvider: (services) => new SafeDsNodeInfoProvider(services),
RenameProvider: (services) => new SafeDsRenameProvider(services),
SemanticTokenProvider: (services) => new SafeDsSemanticTokenProvider(services),
Expand Down
11 changes: 11 additions & 0 deletions packages/safe-ds-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@
"type": "string",
"default": "safe-ds-runner"
},
"safe-ds.trace.server": {
"scope": "window",
"type": "string",
"enum": [
"off",
"messages",
"verbose"
],
"default": "off",
"description": "Traces the communication between VS Code and the language server."
},
"safe-ds.validation.codeStyle.enabled": {
"type": "boolean",
"default": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import vscode, { ExtensionContext, Uri } from 'vscode';
import { SafeDsLanguageMetaData } from '../../../../safe-ds-lang/src/language/index.js';

export const dumpDiagnostics = (context: ExtensionContext) => async () => {
// Get the current document
const currentDocument = vscode.window.activeTextEditor?.document;
if (!currentDocument) {
vscode.window.showErrorMessage('No active document.');
return;
} else if (currentDocument.languageId !== 'safe-ds') {
} else if (currentDocument.languageId !== SafeDsLanguageMetaData.languageId) {
vscode.window.showErrorMessage('The active document is not a Safe-DS document.');
return;
}
Expand Down

0 comments on commit dcf4ecf

Please sign in to comment.