Skip to content

Commit

Permalink
Merge pull request #22 from 4d/workspace_command
Browse files Browse the repository at this point in the history
Workspace command
  • Loading branch information
guillaume-kotulski authored Mar 7, 2024
2 parents c88f465 + 0f3409d commit fc58818
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 90 deletions.
8 changes: 7 additions & 1 deletion editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,13 @@
"markdownDescription": "Precise the scope of the diagnostics. If 'workspace' is selected, every methods will be checked. If 'Document' is selected, only the current document will be checked"
}
}
}
},
"commands": [
{
"command": "4d-analyzer.checkWorkspaceSyntax",
"title": "4D Analyzer: Check workspace syntax"
}
]
},
"scripts": {
"vscode:prepublish": "npm run esbuild-base -- --minify",
Expand Down
50 changes: 32 additions & 18 deletions editor/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,36 +43,50 @@ export function filesStatus(ctx: Ctx): Cmd {
}));
};
}
let id = 0;
export function checkSyntax(ctx: Ctx): Cmd {
return async()=> {
id++;

export function checkWorkspaceSyntax(ctx: Ctx): Cmd {
if(ctx.config.diagnosticEnabled && ctx.config.diagnosticScope === "Workspace")
{
return async()=>{
const userResponse = await vscode.window.showErrorMessage(
`Workspace syntax checking is already running`
);
}
}

return async()=> {vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Workspace syntax check running",
cancellable: false
}, async (progress, token) => {
const client = ctx.client;
const params = client.code2ProtocolConverter.asTextDocumentIdentifier(
vscode.window.activeTextEditor.document
);
const response = await client.sendRequest(ext.checkSyntax, params);
let currentItem : WorkspaceFullDocumentDiagnosticReport;
const diagnosticName : string = client.diagnostics.name;
console.log("NAME" + diagnosticName);
//.
const diagnosticCollection = client.diagnostics;
diagnosticCollection.clear();
const diagnostics : vscode.Diagnostic[] = [];
const response = await client.sendRequest(ext.checkWorkspaceSyntax, params);

let diagnosticCollection = ctx.workspaceDiagnostic;
diagnosticCollection.clear()
for(const diagWorkspace of response.items)
{
currentItem = diagWorkspace as WorkspaceFullDocumentDiagnosticReport;
const diagnostics : vscode.Diagnostic[] = [];
let currentItem = diagWorkspace as WorkspaceFullDocumentDiagnosticReport;
let currentDiagnostics = vscode.languages.getDiagnostics(vscode.Uri.parse(currentItem.uri))
for(const diag of currentItem.items)
{
const range : vscode.Range = new vscode.Range(diag.range.start.line, diag.range.start.character, diag.range.end.line, diag.range.end.character);
const diagnostic = new vscode.Diagnostic(range, diag.message, diag.severity - 1);
diagnostics.push(diagnostic);
if(!currentDiagnostics.find((cdiagnostic =>{
return cdiagnostic.range.isEqual(diagnostic.range) && cdiagnostic.message === diagnostic.message
})))
{
diagnostics.push(diagnostic);
}

}

diagnosticCollection.set(vscode.Uri.parse(currentItem.uri), diagnostics);
}

ctx.extensionContext.subscriptions.push(diagnosticCollection);

};
});}
}

10 changes: 9 additions & 1 deletion editor/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class Config {

readonly rootSection = "4D-Analyzer";

_ctx : Ctx;
private _ctx : Ctx;
private readonly requiresReloadOpts = [
"server.path",
"diagnostics.enable",
Expand All @@ -29,6 +29,14 @@ export class Config {
return vscode.workspace.getConfiguration(this.rootSection);
}

public get diagnosticScope() : string{
return this.get<string>("diagnostics.scope");
}

public get diagnosticEnabled() : string{
return this.get<string>("diagnostics.enable");
}

private get<T>(path: string): T {
return this.cfg.get<T>(path)!;
}
Expand Down
146 changes: 77 additions & 69 deletions editor/src/ctx.ts
Original file line number Diff line number Diff line change
@@ -1,95 +1,97 @@
import * as vscode from 'vscode';
import * as Commands from "./commands";
import {Config} from "./config";
import { Config } from "./config";
import {
LanguageClient,
LanguageClientOptions,
StreamInfo
LanguageClient,
LanguageClientOptions,
StreamInfo
} from 'vscode-languageclient/node';

import { workspace } from 'vscode';
import * as child_process from 'child_process';
import * as net from 'net';


export type CommandCallback = {
call: (ctx: Ctx) => Commands.Cmd;
};

export class Ctx
{
private _client : LanguageClient;
private _extensionContext : vscode.ExtensionContext;
private _commands : Record<string, CommandCallback>;
private _config : Config;
export class Ctx {
private _client: LanguageClient;
private _extensionContext: vscode.ExtensionContext;
private _commands: Record<string, CommandCallback>;
private _config: Config;
private _workspaceDiagnostic : vscode.DiagnosticCollection;

constructor(ctx : vscode.ExtensionContext) {
constructor(ctx: vscode.ExtensionContext) {
this._client = null;
this._extensionContext = ctx;
this._commands = {};
this._config = null;
this._workspaceDiagnostic = vscode.languages.createDiagnosticCollection("4d_workspace");
}

public get config(): Config {
return this._config;
}

public get workspaceDiagnostic(): vscode.DiagnosticCollection {
return this._workspaceDiagnostic;
}

public get extensionContext() : vscode.ExtensionContext
{
public get extensionContext(): vscode.ExtensionContext {
return this._extensionContext;
}

public get client() : LanguageClient
{
public get client(): LanguageClient {
return this._client;
}

public set client(inClient : LanguageClient) {
public set client(inClient: LanguageClient) {
this._client = inClient;
}

private _getServerPath(isDebug : boolean) : string {
let serverPath : string = this._config.serverPath;
private _getServerPath(isDebug: boolean): string {
let serverPath: string = this._config.serverPath;

if(process.env.ANALYZER_4D_PATH)
{
if (process.env.ANALYZER_4D_PATH) {
serverPath = process.env.ANALYZER_4D_PATH;
}
if(isDebug) {

if (isDebug) {
serverPath = '';//debug
}

return serverPath;
}

private _getPort(isDebug : boolean) : number {
private _getPort(isDebug: boolean): number {
let port = 0;
if(process.env.ANALYZER_4D_PORT)
{
if (process.env.ANALYZER_4D_PORT) {
port = parseInt(process.env.ANALYZER_4D_PORT);
}

if(isDebug) {
if (isDebug) {
port = 1800;
}

return port;
}

public start()
{
public start() {
this._config = new Config(this._extensionContext);
this._config.setContext(this);
this._config.checkSettings();
let isDebug : boolean;
let isDebug: boolean;
isDebug = false;
if(process.env.ANALYZER_4D_DEBUG)
{
if (process.env.ANALYZER_4D_DEBUG) {
isDebug = true;
}
const serverPath : string = this._getServerPath(isDebug);
const port : number= this._getPort(isDebug);

const serverPath: string = this._getServerPath(isDebug);
const port: number = this._getPort(isDebug);

console.log("SERVER PATH", serverPath);

// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
const serverOptions = () =>
Expand All @@ -111,24 +113,24 @@ export class Ctx
server.close();
});
//server.close()
resolve({ reader: socket, writer: socket, detached : false });
resolve({ reader: socket, writer: socket, detached: false });
});

// Listen on random port
server.listen(port, '127.0.0.1', () => {
console.log(`Listens on port: ${(server.address() as net.AddressInfo).port}`);
if(serverPath != '') {

if (serverPath != '') {
const childProcess = child_process.spawn(serverPath, [
'--lsp=' + (server.address() as net.AddressInfo).port,
]);

childProcess.stderr.on('data', (chunk: Buffer) => {
const str = chunk.toString();
console.log('4D Language Server:', str);
this._client.outputChannel.appendLine(str);
});

childProcess.on('exit', (code, signal) => {
this._client.outputChannel.appendLine(
`Language server exited ` + (signal ? `from signal ${signal}` : `with exit code ${code}`)
Expand All @@ -137,30 +139,38 @@ export class Ctx
this._client.outputChannel.show();
}
});
server.on('close', function() {


server.on('close', function () {
console.log("KILL");
childProcess.kill();
});

return childProcess;
}

});
});

// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{ scheme: 'file', language: '4d' }],
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/.4DSettings')
},
initializationOptions: this._config.cfg,
diagnosticCollectionName:"4d"
};

// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{ scheme: 'file', language: '4d' }],
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/.4DSettings')
},
initializationOptions: this._config.cfg,
diagnosticCollectionName: "4d",
middleware: {
provideDiagnostics: (document, previousResultId, token, next) => {
console.log(document instanceof vscode.Uri ? document : document.uri)
if(this._config.diagnosticEnabled)
this._workspaceDiagnostic.set(document instanceof vscode.Uri ? document : document.uri, undefined)
return next(document, previousResultId, token);
}
}
};
// Create the language client and start the client.
this._client = new LanguageClient(
'4D-Analyzer',
Expand All @@ -172,17 +182,16 @@ export class Ctx
this._client.start();
}

public registerCommands()
{
public registerCommands() {
this._commands = {
filesStatus:{call:Commands.filesStatus},
checkSyntax:{call:Commands.checkSyntax}
};
filesStatus: { call: Commands.filesStatus },
checkWorkspaceSyntax: { call: Commands.checkWorkspaceSyntax }
};

for (const [name, command] of Object.entries(this._commands)) {
for (const [name, command] of Object.entries(this._commands)) {
const fullName = `4d-analyzer.${name}`;
const callback = command.call(this);

this._extensionContext.subscriptions.push(vscode.commands.registerCommand(fullName, callback));
}
}
Expand All @@ -191,12 +200,11 @@ export class Ctx
this._extensionContext.subscriptions.push(d);
}

stop() : undefined | Promise<void>
{
stop(): undefined | Promise<void> {
if (!this._client) {
return undefined;
}

return this._client.stop();
}
}
Expand Down
2 changes: 1 addition & 1 deletion editor/src/lsp_ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export const filesStatus = new lc.RequestType0<object, void>(
"experimental/filesStatus"
);

export const checkSyntax = new lc.RequestType<lc.TextDocumentIdentifier, WorkspaceDiagnosticReport, void>(
export const checkWorkspaceSyntax = new lc.RequestType<lc.TextDocumentIdentifier, WorkspaceDiagnosticReport, void>(
"experimental/checkSyntax"
);

0 comments on commit fc58818

Please sign in to comment.