@likec4/language-server 1.30.0 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundled.mjs +2167 -2160
- package/dist/formatting/LikeC4Formatter.d.ts +26 -2
- package/dist/formatting/LikeC4Formatter.js +99 -2
- package/dist/generated/ast.d.ts +147 -148
- package/dist/generated/ast.js +2 -2
- package/dist/generated/grammar.d.ts +1 -1
- package/dist/generated/module.d.ts +1 -1
- package/dist/test/testServices.js +3 -0
- package/dist/workspace/WorkspaceManager.d.ts +2 -2
- package/dist/workspace/WorkspaceManager.js +2 -2
- package/package.json +16 -16
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import { type AstNode } from 'langium';
|
|
2
|
-
import { AbstractFormatter } from 'langium/lsp';
|
|
1
|
+
import { type AstNode, type LangiumDocument } from 'langium';
|
|
2
|
+
import { AbstractFormatter, FormattingRegion } from 'langium/lsp';
|
|
3
|
+
import type { FormattingOptions as LSFormattingOptions, Range, TextEdit } from 'vscode-languageserver-types';
|
|
4
|
+
import type { LikeC4Services } from '../module';
|
|
5
|
+
type QuoteStyle = 'single' | 'double' | 'ignore' | 'auto';
|
|
6
|
+
interface LikeC4FormatterOptions {
|
|
7
|
+
quoteStyle: QuoteStyle;
|
|
8
|
+
}
|
|
9
|
+
type ExtendedFormattingCommandType = 'normalizeQuotes';
|
|
10
|
+
interface ExtendedFormattingCommand {
|
|
11
|
+
type: ExtendedFormattingCommandType;
|
|
12
|
+
region: FormattingRegion;
|
|
13
|
+
}
|
|
3
14
|
export declare class LikeC4Formatter extends AbstractFormatter {
|
|
15
|
+
protected options: LikeC4FormatterOptions;
|
|
16
|
+
extendedFormattingCommands: ExtendedFormattingCommand[];
|
|
17
|
+
constructor(services: LikeC4Services);
|
|
18
|
+
protected doDocumentFormat(document: LangiumDocument, options: LSFormattingOptions, range?: Range): TextEdit[];
|
|
4
19
|
protected format(node: AstNode): void;
|
|
5
20
|
protected formatTags(node: AstNode): void;
|
|
6
21
|
protected formatDeploymentRelation(node: AstNode): void;
|
|
22
|
+
protected formatExtendDeployment(node: AstNode): void;
|
|
7
23
|
protected formatRelation(node: AstNode): void;
|
|
8
24
|
protected removeIndentFromTopLevelStatements(node: AstNode): void;
|
|
9
25
|
protected indentContentInBraces(node: AstNode): void;
|
|
@@ -15,7 +31,9 @@ export declare class LikeC4Formatter extends AbstractFormatter {
|
|
|
15
31
|
protected formatAutolayoutProperty(node: AstNode): void;
|
|
16
32
|
protected formatMetadataProperty(node: AstNode): void;
|
|
17
33
|
protected formatElementDeclaration(node: AstNode): void;
|
|
34
|
+
protected formatExtendElement(node: AstNode): void;
|
|
18
35
|
protected formatGlobals(node: AstNode): void;
|
|
36
|
+
protected formatImports(node: AstNode): void;
|
|
19
37
|
protected formatSpecificationRule(node: AstNode): void;
|
|
20
38
|
protected formatWithPredicate(node: AstNode): void;
|
|
21
39
|
protected formatDeploymentNodeDeclaration(node: AstNode): void;
|
|
@@ -31,4 +49,10 @@ export declare class LikeC4Formatter extends AbstractFormatter {
|
|
|
31
49
|
protected formatRelationExpression(node: AstNode): void;
|
|
32
50
|
private findPredicateExpressionRoot;
|
|
33
51
|
private on;
|
|
52
|
+
private doExtendedFormatting;
|
|
53
|
+
protected normalizeQuotes(node: AstNode): void;
|
|
54
|
+
private quotesNormalizerFactory;
|
|
55
|
+
private getAutoQuoteStyle;
|
|
56
|
+
private onConfigurationUpdate;
|
|
34
57
|
}
|
|
58
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { nonexhaustive } from "@likec4/core";
|
|
1
2
|
import { GrammarUtils } from "langium";
|
|
2
3
|
import { AbstractFormatter, Formatting } from "langium/lsp";
|
|
3
4
|
import { filter, isTruthy } from "remeda";
|
|
@@ -11,17 +12,37 @@ const FormattingOptions = {
|
|
|
11
12
|
noIndent: Formatting.noIndent()
|
|
12
13
|
};
|
|
13
14
|
export class LikeC4Formatter extends AbstractFormatter {
|
|
15
|
+
options = {
|
|
16
|
+
quoteStyle: "auto"
|
|
17
|
+
};
|
|
18
|
+
extendedFormattingCommands = [];
|
|
19
|
+
constructor(services) {
|
|
20
|
+
super();
|
|
21
|
+
services.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(
|
|
22
|
+
(update) => this.onConfigurationUpdate(update.configuration.formatting)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
doDocumentFormat(document, options, range) {
|
|
26
|
+
this.extendedFormattingCommands = [];
|
|
27
|
+
const edits = super.doDocumentFormat(document, options, range);
|
|
28
|
+
this.doExtendedFormatting(edits);
|
|
29
|
+
return edits;
|
|
30
|
+
}
|
|
14
31
|
format(node) {
|
|
15
32
|
this.removeIndentFromTopLevelStatements(node);
|
|
16
33
|
this.indentContentInBraces(node);
|
|
34
|
+
this.normalizeQuotes(node);
|
|
35
|
+
this.formatImports(node);
|
|
17
36
|
this.formatSpecificationRule(node);
|
|
18
37
|
this.formatGlobals(node);
|
|
19
38
|
this.formatElementDeclaration(node);
|
|
39
|
+
this.formatExtendElement(node);
|
|
20
40
|
this.formatRelation(node);
|
|
21
41
|
this.formatMetadataProperty(node);
|
|
22
42
|
this.formatDeploymentNodeDeclaration(node);
|
|
23
43
|
this.formatDeployedInstance(node);
|
|
24
44
|
this.formatDeploymentRelation(node);
|
|
45
|
+
this.formatExtendDeployment(node);
|
|
25
46
|
this.formatView(node);
|
|
26
47
|
this.formatViewRuleGroup(node);
|
|
27
48
|
this.formatViewRuleGlobalStyle(node);
|
|
@@ -58,6 +79,11 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
58
79
|
f.properties("title", "technology").prepend(FormattingOptions.oneSpace);
|
|
59
80
|
});
|
|
60
81
|
}
|
|
82
|
+
formatExtendDeployment(node) {
|
|
83
|
+
this.on(node, ast.isExtendDeployment, (n, f) => {
|
|
84
|
+
f.keywords("extend").append(FormattingOptions.oneSpace);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
61
87
|
formatRelation(node) {
|
|
62
88
|
this.on(
|
|
63
89
|
node,
|
|
@@ -90,7 +116,7 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
90
116
|
}
|
|
91
117
|
}
|
|
92
118
|
indentContentInBraces(node) {
|
|
93
|
-
if (ast.isLikeC4Lib(node) || ast.isSpecificationRule(node) || ast.isSpecificationElementKind(node) || ast.isSpecificationRelationshipKind(node) || ast.isSpecificationDeploymentNodeKind(node) || ast.isGlobals(node) || ast.isGlobalStyle(node) || ast.isGlobalStyleGroup(node) || ast.isGlobalPredicateGroup(node) || ast.isGlobalDynamicPredicateGroup(node) || ast.isGlobalStyleGroup(node) || ast.isModel(node) || ast.isElementBody(node) || ast.isExtendElementBody(node) || ast.isRelationBody(node) || ast.isRelationStyleProperty(node) || ast.isMetadataBody(node) || ast.isModelViews(node) || ast.isElementViewBody(node) || ast.isDynamicViewBody(node) || ast.isDeploymentViewBody(node) || ast.isViewRuleStyle(node) || ast.isViewRuleGroup(node) || ast.isCustomElementProperties(node) || ast.isCustomRelationProperties(node) || ast.isElementStyleProperty(node) || ast.isDynamicViewParallelSteps(node) || ast.isModelDeployments(node) || ast.isDeploymentNodeBody(node) || ast.isDeploymentRelationBody(node) || ast.isDeployedInstanceBody(node)) {
|
|
119
|
+
if (ast.isLikeC4Lib(node) || ast.isSpecificationRule(node) || ast.isSpecificationElementKind(node) || ast.isSpecificationRelationshipKind(node) || ast.isSpecificationDeploymentNodeKind(node) || ast.isGlobals(node) || ast.isGlobalStyle(node) || ast.isGlobalStyleGroup(node) || ast.isGlobalPredicateGroup(node) || ast.isGlobalDynamicPredicateGroup(node) || ast.isGlobalStyleGroup(node) || ast.isModel(node) || ast.isElementBody(node) || ast.isExtendElementBody(node) || ast.isRelationBody(node) || ast.isRelationStyleProperty(node) || ast.isMetadataBody(node) || ast.isModelViews(node) || ast.isElementViewBody(node) || ast.isDynamicViewBody(node) || ast.isDeploymentViewBody(node) || ast.isViewRuleStyle(node) || ast.isViewRuleGroup(node) || ast.isCustomElementProperties(node) || ast.isCustomRelationProperties(node) || ast.isElementStyleProperty(node) || ast.isDynamicViewParallelSteps(node) || ast.isModelDeployments(node) || ast.isDeploymentNodeBody(node) || ast.isDeploymentRelationBody(node) || ast.isDeployedInstanceBody(node) || ast.isExtendDeploymentBody(node)) {
|
|
94
120
|
const formatter = this.getNodeFormatter(node);
|
|
95
121
|
const openBrace = formatter.keywords("{");
|
|
96
122
|
const closeBrace = formatter.keywords("}");
|
|
@@ -120,7 +146,7 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
120
146
|
this.on(node, ast.isDeploymentView)?.keywords("deployment", "view").append(FormattingOptions.oneSpace);
|
|
121
147
|
}
|
|
122
148
|
formatLeafProperty(node) {
|
|
123
|
-
if (ast.isElementStringProperty(node) || ast.isRelationStringProperty(node) || ast.isViewStringProperty(node) || ast.isNotationProperty(node) || ast.isSpecificationElementStringProperty(node) || ast.isSpecificationRelationshipStringProperty(node) || ast.isColorProperty(node) || ast.isLineProperty(node) || ast.isArrowProperty(node) || ast.isIconProperty(node) || ast.isShapeProperty(node) || ast.isBorderProperty(node) || ast.isOpacityProperty(node) || ast.isMultipleProperty(node) || ast.isShapeSizeProperty(node) || ast.isPaddingSizeProperty(node) || ast.isTextSizeProperty(node)) {
|
|
149
|
+
if (ast.isElementStringProperty(node) || ast.isRelationStringProperty(node) || ast.isViewStringProperty(node) || ast.isNotationProperty(node) || ast.isNotesProperty(node) || ast.isSpecificationElementStringProperty(node) || ast.isSpecificationRelationshipStringProperty(node) || ast.isColorProperty(node) || ast.isLineProperty(node) || ast.isArrowProperty(node) || ast.isIconProperty(node) || ast.isShapeProperty(node) || ast.isBorderProperty(node) || ast.isOpacityProperty(node) || ast.isMultipleProperty(node) || ast.isShapeSizeProperty(node) || ast.isPaddingSizeProperty(node) || ast.isTextSizeProperty(node)) {
|
|
124
150
|
const formatter = this.getNodeFormatter(node);
|
|
125
151
|
const colon = formatter.keyword(":");
|
|
126
152
|
const propertyName = formatter.keywords(
|
|
@@ -128,6 +154,7 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
128
154
|
"description",
|
|
129
155
|
"technology",
|
|
130
156
|
"notation",
|
|
157
|
+
"notes",
|
|
131
158
|
"color",
|
|
132
159
|
"line",
|
|
133
160
|
"head",
|
|
@@ -189,6 +216,11 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
189
216
|
f.properties("props").prepend(FormattingOptions.oneSpace);
|
|
190
217
|
});
|
|
191
218
|
}
|
|
219
|
+
formatExtendElement(node) {
|
|
220
|
+
this.on(node, ast.isExtendElement, (n, f) => {
|
|
221
|
+
f.keywords("extend").append(FormattingOptions.oneSpace);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
192
224
|
formatGlobals(node) {
|
|
193
225
|
this.on(node, ast.isGlobalStyle, (n, f) => {
|
|
194
226
|
f.keyword("style").append(FormattingOptions.oneSpace);
|
|
@@ -204,6 +236,15 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
204
236
|
f.keyword("dynamicPredicateGroup").append(FormattingOptions.oneSpace);
|
|
205
237
|
});
|
|
206
238
|
}
|
|
239
|
+
formatImports(node) {
|
|
240
|
+
this.on(node, ast.isImportsFromPoject, (n, f) => {
|
|
241
|
+
f.keyword("import").append(FormattingOptions.oneSpace);
|
|
242
|
+
f.keywords("{", "}", "from").surround(FormattingOptions.oneSpace);
|
|
243
|
+
});
|
|
244
|
+
this.on(node, ast.isImported, (n, f) => {
|
|
245
|
+
f.keywords(",").prepend(FormattingOptions.noSpace).append(FormattingOptions.oneSpace);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
207
248
|
formatSpecificationRule(node) {
|
|
208
249
|
if (ast.isSpecificationElementKind(node) || ast.isSpecificationRelationshipKind(node) || ast.isSpecificationTag(node) || ast.isSpecificationDeploymentNodeKind(node)) {
|
|
209
250
|
const formatter = this.getNodeFormatter(node);
|
|
@@ -349,4 +390,60 @@ export class LikeC4Formatter extends AbstractFormatter {
|
|
|
349
390
|
format && formatter && format(node, formatter);
|
|
350
391
|
return formatter;
|
|
351
392
|
}
|
|
393
|
+
doExtendedFormatting(edits) {
|
|
394
|
+
const quotesNormalizer = this.quotesNormalizerFactory(this.extendedFormattingCommands);
|
|
395
|
+
for (let command of this.extendedFormattingCommands) {
|
|
396
|
+
switch (command.type) {
|
|
397
|
+
case "normalizeQuotes":
|
|
398
|
+
quotesNormalizer(command, edits);
|
|
399
|
+
break;
|
|
400
|
+
default:
|
|
401
|
+
nonexhaustive(command.type);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
normalizeQuotes(node) {
|
|
406
|
+
if (this.options.quoteStyle === "ignore") {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
let region = null;
|
|
410
|
+
region = region ?? this.on(node, ast.isStringProperty)?.property("value");
|
|
411
|
+
region = region ?? this.on(node, ast.isElement)?.properties("props");
|
|
412
|
+
region = region ?? this.on(node, ast.isImportsFromPoject)?.properties("project");
|
|
413
|
+
region = region ?? this.on(node, ast.isRelation)?.properties("title", "technology");
|
|
414
|
+
region = region ?? this.on(node, ast.isViewRuleGroup)?.properties("title");
|
|
415
|
+
region = region ?? this.on(node, ast.isDynamicViewStep)?.properties("title");
|
|
416
|
+
region = region ?? this.on(node, ast.isDeploymentNode)?.properties("title");
|
|
417
|
+
region = region ?? this.on(node, ast.isDeployedInstance)?.properties("title");
|
|
418
|
+
region = region ?? this.on(node, ast.isDeploymentRelation)?.properties("title", "technology");
|
|
419
|
+
region = region ?? this.on(node, ast.isLinkProperty)?.properties("title");
|
|
420
|
+
if (region) {
|
|
421
|
+
this.extendedFormattingCommands.push({ type: "normalizeQuotes", region });
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
quotesNormalizerFactory(commands) {
|
|
425
|
+
const quoteStyle = this.options.quoteStyle != "auto" ? this.options.quoteStyle : this.getAutoQuoteStyle(commands);
|
|
426
|
+
return (command, edits) => {
|
|
427
|
+
const quotesToReplace = quoteStyle === "single" ? '"' : "'";
|
|
428
|
+
const quotesToInsert = quoteStyle === "single" ? "'" : '"';
|
|
429
|
+
const newEdits = command.region.nodes.map((node) => ({
|
|
430
|
+
range: node.range,
|
|
431
|
+
newText: node.text.replaceAll(quotesToReplace, quotesToInsert)
|
|
432
|
+
}));
|
|
433
|
+
edits.push(...newEdits);
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
getAutoQuoteStyle(commands) {
|
|
437
|
+
const nodes = commands.flatMap((x) => x.region.nodes);
|
|
438
|
+
const doubleQuotesCount = nodes.filter((x) => x.text[0] == '"').length;
|
|
439
|
+
return doubleQuotesCount * 2 >= nodes.length ? "double" : "single";
|
|
440
|
+
}
|
|
441
|
+
onConfigurationUpdate(options) {
|
|
442
|
+
this.options = {
|
|
443
|
+
...this.options,
|
|
444
|
+
...options ?? {
|
|
445
|
+
quoteStyle: "auto"
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
}
|
|
352
449
|
}
|