Skip to content

Commit 6a44787

Browse files
committed
feat: add crude filepath detection to flag errors
Update the extension client to specify it's Name and reveal output channels. Update language server, reenable text document sync and basic validation methods. Create a simple config service to share server props across imports. Implement a simple filepath validator that currently marks all filepaths as invalid (and unresolved)
1 parent 4b79237 commit 6a44787

File tree

4 files changed

+127
-49
lines changed

4 files changed

+127
-49
lines changed

packages/client/src/extension.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@ export function activate(context: ExtensionContext): void {
3333

3434
const clientOptions: LanguageClientOptions = {
3535
documentSelector: [{ scheme: 'file', language: 'ccini' }],
36-
diagnosticCollectionName: 'sample',
37-
revealOutputChannelOn: RevealOutputChannelOn.Never,
36+
revealOutputChannelOn: RevealOutputChannelOn.Error,
3837
progressOnInitialization: true,
3938
};
4039

4140
let client: LanguageClient;
4241
try {
43-
client = new LanguageClient('UI Sample', serverOptions, clientOptions);
42+
client = new LanguageClient(
43+
'Cortex Command Client',
44+
serverOptions,
45+
clientOptions
46+
);
4447
} catch (err) {
4548
Window.showErrorMessage(
4649
`The extension couldn't be started. See the output channel for details.`

packages/server/src/sampleServer.ts

Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,49 @@ import {
1111
createConnection,
1212
Diagnostic,
1313
DiagnosticSeverity,
14+
InitializeParams,
1415
Position,
16+
ProposedFeatures,
1517
Range,
1618
TextDocumentEdit,
1719
TextDocuments,
1820
TextDocumentSyncKind,
1921
TextEdit,
2022
} from 'vscode-languageserver/node';
2123
import { TextDocument } from 'vscode-languageserver-textdocument';
24+
import { configService } from './services/configuration.service';
25+
import { validateFilePaths } from './validations/validate';
2226

23-
const connection = createConnection();
24-
connection.console.info(`Sample server running in node ${process.version}`);
27+
const connection = createConnection(ProposedFeatures.all);
28+
29+
connection.console.info(
30+
`CC Language server running in node ${process.version}`
31+
);
2532

2633
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
2734
documents.listen(connection);
2835

29-
connection.onInitialize(() => {
36+
connection.onInitialize((params: InitializeParams) => {
37+
const capabilities = params.capabilities;
38+
39+
// Does the client support the `workspace/configuration` request?
40+
// If not, we fall back using global settings.
41+
configService.hasConfigurationCapability = !!(
42+
capabilities.workspace && !!capabilities.workspace.configuration
43+
);
44+
configService.hasWorkspaceFolderCapability = !!(
45+
capabilities.workspace && !!capabilities.workspace.workspaceFolders
46+
);
47+
configService.hasDiagnosticRelatedInformationCapability =
48+
!!capabilities.textDocument?.publishDiagnostics?.relatedInformation;
49+
3050
return {
3151
capabilities: {
3252
// codeActionProvider: true,
33-
// textDocumentSync: {
34-
// openClose: true,
35-
// change: TextDocumentSyncKind.Incremental,
36-
// },
53+
textDocumentSync: {
54+
openClose: true,
55+
change: TextDocumentSyncKind.Incremental,
56+
},
3757
// executeCommandProvider: {
3858
// commands: ['sample.fixMe'],
3959
// },
@@ -42,53 +62,52 @@ connection.onInitialize(() => {
4262
});
4363

4464
function validate(document: TextDocument): void {
65+
const diagnostics = validateFilePaths(document);
66+
4567
connection.sendDiagnostics({
4668
uri: document.uri,
4769
version: document.version,
48-
diagnostics: [
49-
Diagnostic.create(
50-
Range.create(0, 0, 0, 10),
51-
'Something is wrong here',
52-
DiagnosticSeverity.Warning
53-
),
54-
],
70+
diagnostics,
5571
});
5672
}
5773

58-
// documents.onDidOpen((event) => {
59-
// validate(event.document);
60-
// });
61-
62-
// documents.onDidChangeContent((event) => {
63-
// validate(event.document);
64-
// });
74+
documents.onDidOpen((event) => {
75+
validate(event.document);
76+
});
6577

66-
// connection.onCodeAction((params) => {
67-
// const textDocument = documents.get(params.textDocument.uri);
68-
// if (textDocument === undefined) {
69-
// return undefined;
70-
// }
71-
// const title = 'With User Input';
72-
// return [CodeAction.create(title, Command.create(title, 'sample.fixMe', textDocument.uri), CodeActionKind.QuickFix)];
73-
// });
78+
documents.onDidChangeContent((event) => {
79+
validate(event.document);
80+
});
7481

75-
// connection.onExecuteCommand(async (params) => {
76-
// if (params.command !== 'sample.fixMe' || params.arguments === undefined) {
77-
// return;
78-
// }
82+
/*
83+
connection.onCodeAction((params) => {
84+
const textDocument = documents.get(params.textDocument.uri);
85+
if (textDocument === undefined) {
86+
return undefined;
87+
}
88+
const title = 'With User Input';
89+
return [CodeAction.create(title, Command.create(title, 'sample.fixMe', textDocument.uri), CodeActionKind.QuickFix)];
90+
});
91+
*/
7992

80-
// const textDocument = documents.get(params.arguments[0]);
81-
// if (textDocument === undefined) {
82-
// return;
83-
// }
84-
// const newText = typeof params.arguments[1] === 'string' ? params.arguments[1] : 'Eclipse';
85-
// connection.workspace.applyEdit({
86-
// documentChanges: [
87-
// TextDocumentEdit.create({ uri: textDocument.uri, version: textDocument.version }, [
88-
// TextEdit.insert(Position.create(0, 0), newText)
89-
// ])
90-
// ]
91-
// });
92-
// });
93+
/*
94+
connection.onExecuteCommand(async (params) => {
95+
if (params.command !== 'sample.fixMe' || params.arguments === undefined) {
96+
return;
97+
}
9398
99+
const textDocument = documents.get(params.arguments[0]);
100+
if (textDocument === undefined) {
101+
return;
102+
}
103+
const newText = typeof params.arguments[1] === 'string' ? params.arguments[1] : 'Eclipse';
104+
connection.workspace.applyEdit({
105+
documentChanges: [
106+
TextDocumentEdit.create({ uri: textDocument.uri, version: textDocument.version }, [
107+
TextEdit.insert(Position.create(0, 0), newText)
108+
])
109+
]
110+
});
111+
});
112+
*/
94113
connection.listen();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class ConfigurationService {
2+
public hasConfigurationCapability = false;
3+
public hasWorkspaceFolderCapability = false;
4+
public hasDiagnosticRelatedInformationCapability = false;
5+
}
6+
7+
export const configService = new ConfigurationService();
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver';
2+
import { TextDocument } from 'vscode-languageserver-textdocument';
3+
import { configService } from '../services/configuration.service';
4+
5+
const settings = {
6+
maxNumberOfProblems: 100,
7+
};
8+
9+
export function validateFilePaths(textDocument: TextDocument): Diagnostic[] {
10+
// In this simple example we get the settings for every validate run.
11+
// const settings = await getDocumentSettings(textDocument.uri);
12+
13+
// The validator creates diagnostics for all uppercase words length 2 and more
14+
const text = textDocument.getText();
15+
const pattern = /(\t*(?:FilePath|IncludeFile)\s*=\s*)(.*)/dg;
16+
let m: RegExpExecArray | null;
17+
18+
let problems = 0;
19+
const diagnostics: Diagnostic[] = [];
20+
21+
while ((m = pattern.exec(text)) && problems < settings.maxNumberOfProblems) {
22+
problems++;
23+
const diagnostic: Diagnostic = {
24+
severity: DiagnosticSeverity.Error,
25+
range: {
26+
start: textDocument.positionAt(m.index + m[1].length),
27+
end: textDocument.positionAt(m.index + m[0].length),
28+
},
29+
message: `Cannot find the file ${m[2]}`,
30+
source: 'CC Language Features',
31+
};
32+
if (configService.hasDiagnosticRelatedInformationCapability) {
33+
diagnostic.relatedInformation = [
34+
{
35+
location: {
36+
uri: textDocument.uri,
37+
range: Object.assign({}, diagnostic.range),
38+
},
39+
message:
40+
'This may be due to a bad file extension/path, or incorrect capitalization.',
41+
},
42+
];
43+
}
44+
diagnostics.push(diagnostic);
45+
}
46+
47+
// Send the computed diagnostics to VSCode.
48+
return diagnostics;
49+
}

0 commit comments

Comments
 (0)