@likec4/language-server 1.43.0 → 1.44.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.
Files changed (299) hide show
  1. package/browser/package.json +1 -1
  2. package/browser-worker/package.json +1 -1
  3. package/dist/LikeC4LanguageServices.d.ts +12 -19
  4. package/dist/LikeC4LanguageServices.js +182 -0
  5. package/dist/Rpc.js +245 -0
  6. package/dist/ast.d.ts +5 -1
  7. package/dist/ast.js +253 -0
  8. package/dist/browser-worker.js +4 -0
  9. package/dist/browser.js +35 -0
  10. package/dist/bundled.js +42 -0
  11. package/dist/bundled.mjs +3542 -3896
  12. package/dist/documentation/documentation-provider.js +51 -0
  13. package/dist/documentation/index.js +1 -0
  14. package/dist/empty.js +2 -0
  15. package/dist/filesystem/ChokidarWatcher.js +97 -0
  16. package/dist/filesystem/FileSystemWatcher.js +14 -0
  17. package/dist/filesystem/LikeC4FileSystem.d.ts +1 -2
  18. package/dist/filesystem/LikeC4FileSystem.js +126 -0
  19. package/dist/filesystem/index.d.ts +26 -0
  20. package/dist/filesystem/index.js +29 -0
  21. package/dist/formatting/LikeC4Formatter.js +637 -0
  22. package/dist/formatting/utils.js +18 -0
  23. package/dist/generated/ast.js +2155 -0
  24. package/dist/generated/{grammar.mjs → grammar.js} +6 -2
  25. package/dist/generated/module.d.ts +6 -1
  26. package/dist/generated/module.js +27 -0
  27. package/dist/generated-lib/{icons.mjs → icons.js} +11 -7
  28. package/dist/index.d.ts +7 -0
  29. package/dist/index.js +53 -0
  30. package/dist/{likec4lib.mjs → likec4lib.js} +3 -3
  31. package/dist/logger.js +81 -0
  32. package/dist/lsp/CodeActionProvider.d.ts +14 -0
  33. package/dist/lsp/CodeActionProvider.js +33 -0
  34. package/dist/lsp/CodeLensProvider.js +44 -0
  35. package/dist/lsp/CompletionProvider.d.ts +3 -1
  36. package/dist/lsp/CompletionProvider.js +200 -0
  37. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  38. package/dist/lsp/DocumentLinkProvider.js +58 -0
  39. package/dist/lsp/DocumentSymbolProvider.js +306 -0
  40. package/dist/lsp/HoverProvider.js +106 -0
  41. package/dist/lsp/RenameProvider.js +6 -0
  42. package/dist/lsp/SemanticTokenProvider.js +257 -0
  43. package/dist/lsp/index.d.ts +1 -0
  44. package/dist/lsp/index.js +9 -0
  45. package/dist/mcp/MCPServerFactory.js +73 -0
  46. package/dist/mcp/NoopLikeC4MCPServer.js +17 -0
  47. package/dist/mcp/interfaces.js +5 -0
  48. package/dist/mcp/server/StdioLikeC4MCPServer.js +47 -0
  49. package/dist/mcp/server/StreamableLikeC4MCPServer.js +145 -0
  50. package/dist/mcp/server/WithMCPServer.js +56 -0
  51. package/dist/mcp/tools/_common.d.ts +8 -7
  52. package/dist/mcp/tools/_common.js +49 -0
  53. package/dist/mcp/tools/find-relationships.d.ts +7 -8
  54. package/dist/mcp/tools/find-relationships.js +150 -0
  55. package/dist/mcp/tools/list-projects.d.ts +3 -3
  56. package/dist/mcp/tools/list-projects.js +62 -0
  57. package/dist/mcp/tools/open-view.d.ts +6 -7
  58. package/dist/mcp/tools/open-view.js +52 -0
  59. package/dist/mcp/tools/read-deployment.d.ts +6 -7
  60. package/dist/mcp/tools/read-deployment.js +132 -0
  61. package/dist/mcp/tools/read-element.d.ts +6 -7
  62. package/dist/mcp/tools/read-element.js +194 -0
  63. package/dist/mcp/tools/read-project-summary.d.ts +5 -6
  64. package/dist/mcp/tools/read-project-summary.js +176 -0
  65. package/dist/mcp/tools/read-view.d.ts +6 -7
  66. package/dist/mcp/tools/read-view.js +203 -0
  67. package/dist/mcp/tools/search-element.d.ts +3 -3
  68. package/dist/mcp/tools/search-element.js +177 -0
  69. package/dist/mcp/utils.d.ts +2 -2
  70. package/dist/mcp/utils.js +48 -0
  71. package/dist/model/builder/MergedExtends.js +74 -0
  72. package/dist/model/builder/MergedSpecification.js +175 -0
  73. package/dist/model/builder/buildModel.js +176 -0
  74. package/dist/model/deployments-index.js +102 -0
  75. package/dist/model/fqn-index.js +250 -0
  76. package/dist/model/index.js +6 -0
  77. package/dist/model/model-builder.d.ts +13 -11
  78. package/dist/model/model-builder.js +234 -0
  79. package/dist/model/model-locator.d.ts +6 -5
  80. package/dist/model/model-locator.js +240 -0
  81. package/dist/model/model-parser-where.js +81 -0
  82. package/dist/model/model-parser.d.ts +309 -304
  83. package/dist/model/model-parser.js +119 -0
  84. package/dist/model/parser/Base.d.ts +2 -2
  85. package/dist/model/parser/Base.js +367 -0
  86. package/dist/model/parser/DeploymentModelParser.d.ts +2 -2
  87. package/dist/model/parser/DeploymentModelParser.js +176 -0
  88. package/dist/model/parser/DeploymentViewParser.d.ts +3 -3
  89. package/dist/model/parser/DeploymentViewParser.js +86 -0
  90. package/dist/model/parser/FqnRefParser.d.ts +2 -2
  91. package/dist/model/parser/FqnRefParser.js +382 -0
  92. package/dist/model/parser/GlobalsParser.d.ts +6 -6
  93. package/dist/model/parser/GlobalsParser.js +84 -0
  94. package/dist/model/parser/ImportsParser.d.ts +11 -12
  95. package/dist/model/parser/ImportsParser.js +24 -0
  96. package/dist/model/parser/ModelParser.d.ts +2 -2
  97. package/dist/model/parser/ModelParser.js +165 -0
  98. package/dist/model/parser/PredicatesParser.d.ts +2 -2
  99. package/dist/model/parser/PredicatesParser.js +45 -0
  100. package/dist/model/parser/SpecificationParser.d.ts +2 -2
  101. package/dist/model/parser/SpecificationParser.js +109 -0
  102. package/dist/model/parser/ValueConverter.js +12 -0
  103. package/dist/model/parser/ViewsParser.d.ts +3 -3
  104. package/dist/model/parser/ViewsParser.js +477 -0
  105. package/dist/model-change/ModelChanges.d.ts +6 -3
  106. package/dist/model-change/ModelChanges.js +102 -0
  107. package/dist/model-change/changeElementStyle.js +134 -0
  108. package/dist/model-change/changeViewLayout.d.ts +2 -2
  109. package/dist/model-change/changeViewLayout.js +28 -0
  110. package/dist/model-change/removeManualLayoutV1.d.ts +7 -0
  111. package/dist/model-change/removeManualLayoutV1.js +27 -0
  112. package/dist/module.d.ts +10 -5
  113. package/dist/module.js +143 -0
  114. package/dist/protocol.d.ts +1 -17
  115. package/dist/protocol.js +114 -0
  116. package/dist/references/index.js +3 -0
  117. package/dist/references/name-provider.js +37 -0
  118. package/dist/references/scope-computation.js +288 -0
  119. package/dist/references/scope-provider.d.ts +3 -3
  120. package/dist/references/scope-provider.js +242 -0
  121. package/dist/shared/NodeKindProvider.js +57 -0
  122. package/dist/shared/{WorkspaceSymbolProvider.mjs → WorkspaceSymbolProvider.js} +1 -1
  123. package/dist/shared/index.js +2 -0
  124. package/dist/test/index.js +1 -0
  125. package/dist/test/testServices.d.ts +16 -16
  126. package/dist/test/testServices.js +210 -0
  127. package/dist/utils/disposable.js +26 -0
  128. package/dist/utils/elementRef.d.ts +1 -1
  129. package/dist/utils/elementRef.js +27 -0
  130. package/dist/utils/fqnRef.js +63 -0
  131. package/dist/utils/index.js +35 -0
  132. package/dist/utils/printDocs.js +1 -0
  133. package/dist/utils/projectId.js +16 -0
  134. package/dist/utils/stringHash.js +5 -0
  135. package/dist/validation/DocumentValidator.js +17 -0
  136. package/dist/validation/_shared.js +26 -0
  137. package/dist/validation/deployment-checks.js +140 -0
  138. package/dist/validation/dynamic-view.js +67 -0
  139. package/dist/validation/element-ref.js +12 -0
  140. package/dist/validation/element.js +49 -0
  141. package/dist/validation/imports.js +46 -0
  142. package/dist/validation/index.d.ts +1 -1
  143. package/dist/validation/index.js +157 -0
  144. package/dist/validation/property-checks.js +108 -0
  145. package/dist/validation/relation.js +55 -0
  146. package/dist/validation/specification.js +190 -0
  147. package/dist/validation/view-predicates/fqn-expr-with.js +43 -0
  148. package/dist/validation/view-predicates/fqn-ref-expr.js +51 -0
  149. package/dist/validation/view-predicates/incoming.js +16 -0
  150. package/dist/validation/view-predicates/index.js +6 -0
  151. package/dist/validation/view-predicates/outgoing.js +20 -0
  152. package/dist/validation/view-predicates/relation-expr.js +46 -0
  153. package/dist/validation/view-predicates/relation-with.js +16 -0
  154. package/dist/validation/view.d.ts +1 -1
  155. package/dist/validation/view.js +42 -0
  156. package/dist/view-utils/assignNavigateTo.js +27 -0
  157. package/dist/view-utils/index.d.ts +1 -0
  158. package/dist/view-utils/index.js +2 -0
  159. package/dist/view-utils/manual-layout.d.ts +6 -0
  160. package/dist/view-utils/manual-layout.js +151 -0
  161. package/dist/views/ConfigurableLayouter.js +51 -0
  162. package/dist/views/LikeC4ManualLayouts.d.ts +28 -0
  163. package/dist/views/LikeC4ManualLayouts.js +132 -0
  164. package/dist/views/{likec4-views.d.ts → LikeC4Views.d.ts} +9 -8
  165. package/dist/views/LikeC4Views.js +200 -0
  166. package/dist/views/index.d.ts +4 -1
  167. package/dist/views/index.js +11 -0
  168. package/dist/workspace/AstNodeDescriptionProvider.js +15 -0
  169. package/dist/workspace/IndexManager.js +21 -0
  170. package/dist/workspace/LangiumDocuments.d.ts +1 -1
  171. package/dist/workspace/LangiumDocuments.js +58 -0
  172. package/dist/workspace/ProjectsManager.d.ts +8 -3
  173. package/dist/workspace/ProjectsManager.js +373 -0
  174. package/dist/workspace/WorkspaceManager.d.ts +3 -2
  175. package/dist/workspace/WorkspaceManager.js +93 -0
  176. package/dist/workspace/index.js +5 -0
  177. package/likec4lib/package.json +1 -1
  178. package/package.json +25 -24
  179. package/protocol/package.json +1 -1
  180. package/dist/LikeC4LanguageServices.mjs +0 -197
  181. package/dist/Rpc.mjs +0 -296
  182. package/dist/ast.mjs +0 -221
  183. package/dist/browser-worker.mjs +0 -2
  184. package/dist/browser.mjs +0 -32
  185. package/dist/documentation/documentation-provider.mjs +0 -48
  186. package/dist/documentation/index.mjs +0 -1
  187. package/dist/empty.mjs +0 -1
  188. package/dist/filesystem/ChokidarWatcher.mjs +0 -68
  189. package/dist/filesystem/FileSystemWatcher.mjs +0 -11
  190. package/dist/filesystem/LikeC4FileSystem.mjs +0 -64
  191. package/dist/filesystem/index.mjs +0 -19
  192. package/dist/formatting/LikeC4Formatter.mjs +0 -511
  193. package/dist/formatting/utils.mjs +0 -15
  194. package/dist/generated/ast.mjs +0 -2150
  195. package/dist/generated/module.mjs +0 -23
  196. package/dist/index.mjs +0 -50
  197. package/dist/logger.mjs +0 -82
  198. package/dist/lsp/CodeLensProvider.mjs +0 -42
  199. package/dist/lsp/CompletionProvider.mjs +0 -208
  200. package/dist/lsp/DocumentHighlightProvider.mjs +0 -10
  201. package/dist/lsp/DocumentLinkProvider.mjs +0 -53
  202. package/dist/lsp/DocumentSymbolProvider.mjs +0 -287
  203. package/dist/lsp/HoverProvider.mjs +0 -104
  204. package/dist/lsp/RenameProvider.mjs +0 -6
  205. package/dist/lsp/SemanticTokenProvider.mjs +0 -276
  206. package/dist/lsp/index.mjs +0 -7
  207. package/dist/mcp/MCPServerFactory.mjs +0 -70
  208. package/dist/mcp/NoopLikeC4MCPServer.mjs +0 -17
  209. package/dist/mcp/interfaces.mjs +0 -4
  210. package/dist/mcp/server/StdioLikeC4MCPServer.mjs +0 -46
  211. package/dist/mcp/server/StreamableLikeC4MCPServer.mjs +0 -153
  212. package/dist/mcp/server/WithMCPServer.mjs +0 -58
  213. package/dist/mcp/tools/_common.mjs +0 -42
  214. package/dist/mcp/tools/find-relationships.mjs +0 -151
  215. package/dist/mcp/tools/list-projects.mjs +0 -62
  216. package/dist/mcp/tools/open-view.mjs +0 -52
  217. package/dist/mcp/tools/read-deployment.mjs +0 -130
  218. package/dist/mcp/tools/read-element.mjs +0 -198
  219. package/dist/mcp/tools/read-project-summary.mjs +0 -178
  220. package/dist/mcp/tools/read-view.mjs +0 -205
  221. package/dist/mcp/tools/search-element.mjs +0 -171
  222. package/dist/mcp/utils.mjs +0 -47
  223. package/dist/model/builder/MergedExtends.mjs +0 -76
  224. package/dist/model/builder/MergedSpecification.mjs +0 -205
  225. package/dist/model/builder/assignTagColors.d.ts +0 -7
  226. package/dist/model/builder/assignTagColors.mjs +0 -51
  227. package/dist/model/builder/buildModel.mjs +0 -226
  228. package/dist/model/deployments-index.mjs +0 -100
  229. package/dist/model/fqn-index.mjs +0 -243
  230. package/dist/model/index.mjs +0 -6
  231. package/dist/model/model-builder.mjs +0 -285
  232. package/dist/model/model-locator.mjs +0 -239
  233. package/dist/model/model-parser-where.mjs +0 -81
  234. package/dist/model/model-parser.mjs +0 -127
  235. package/dist/model/parser/Base.mjs +0 -376
  236. package/dist/model/parser/DeploymentModelParser.mjs +0 -212
  237. package/dist/model/parser/DeploymentViewParser.mjs +0 -95
  238. package/dist/model/parser/FqnRefParser.mjs +0 -398
  239. package/dist/model/parser/GlobalsParser.mjs +0 -82
  240. package/dist/model/parser/ImportsParser.mjs +0 -28
  241. package/dist/model/parser/ModelParser.mjs +0 -190
  242. package/dist/model/parser/PredicatesParser.mjs +0 -45
  243. package/dist/model/parser/SpecificationParser.mjs +0 -120
  244. package/dist/model/parser/ValueConverter.mjs +0 -12
  245. package/dist/model/parser/ViewsParser.mjs +0 -490
  246. package/dist/model-change/ModelChanges.mjs +0 -89
  247. package/dist/model-change/changeElementStyle.mjs +0 -143
  248. package/dist/model-change/changeViewLayout.mjs +0 -32
  249. package/dist/model-change/saveManualLayout.d.ts +0 -11
  250. package/dist/model-change/saveManualLayout.mjs +0 -27
  251. package/dist/module.mjs +0 -180
  252. package/dist/protocol.mjs +0 -65
  253. package/dist/references/index.mjs +0 -3
  254. package/dist/references/name-provider.mjs +0 -39
  255. package/dist/references/scope-computation.mjs +0 -312
  256. package/dist/references/scope-provider.mjs +0 -239
  257. package/dist/shared/NodeKindProvider.mjs +0 -110
  258. package/dist/shared/index.mjs +0 -2
  259. package/dist/test/index.mjs +0 -1
  260. package/dist/test/testServices.mjs +0 -200
  261. package/dist/utils/disposable.mjs +0 -25
  262. package/dist/utils/elementRef.mjs +0 -20
  263. package/dist/utils/fqnRef.mjs +0 -57
  264. package/dist/utils/index.mjs +0 -33
  265. package/dist/utils/printDocs.mjs +0 -1
  266. package/dist/utils/projectId.mjs +0 -16
  267. package/dist/utils/stringHash.mjs +0 -5
  268. package/dist/validation/DocumentValidator.mjs +0 -16
  269. package/dist/validation/_shared.mjs +0 -25
  270. package/dist/validation/deployment-checks.mjs +0 -146
  271. package/dist/validation/dynamic-view.mjs +0 -67
  272. package/dist/validation/element-ref.mjs +0 -12
  273. package/dist/validation/element.mjs +0 -50
  274. package/dist/validation/imports.mjs +0 -25
  275. package/dist/validation/index.mjs +0 -180
  276. package/dist/validation/property-checks.mjs +0 -107
  277. package/dist/validation/relation.mjs +0 -53
  278. package/dist/validation/specification.mjs +0 -173
  279. package/dist/validation/view-predicates/fqn-expr-with.mjs +0 -43
  280. package/dist/validation/view-predicates/fqn-ref-expr.mjs +0 -53
  281. package/dist/validation/view-predicates/incoming.mjs +0 -16
  282. package/dist/validation/view-predicates/index.mjs +0 -6
  283. package/dist/validation/view-predicates/outgoing.mjs +0 -20
  284. package/dist/validation/view-predicates/relation-expr.mjs +0 -39
  285. package/dist/validation/view-predicates/relation-with.mjs +0 -16
  286. package/dist/validation/view.mjs +0 -25
  287. package/dist/view-utils/assignNavigateTo.mjs +0 -25
  288. package/dist/view-utils/index.mjs +0 -1
  289. package/dist/view-utils/manual-layout.mjs +0 -99
  290. package/dist/views/configurable-layouter.mjs +0 -51
  291. package/dist/views/index.mjs +0 -1
  292. package/dist/views/likec4-views.mjs +0 -166
  293. package/dist/workspace/AstNodeDescriptionProvider.mjs +0 -17
  294. package/dist/workspace/IndexManager.mjs +0 -17
  295. package/dist/workspace/LangiumDocuments.mjs +0 -53
  296. package/dist/workspace/ProjectsManager.mjs +0 -360
  297. package/dist/workspace/WorkspaceManager.mjs +0 -83
  298. package/dist/workspace/index.mjs +0 -5
  299. /package/dist/views/{configurable-layouter.d.ts → ConfigurableLayouter.d.ts} +0 -0
@@ -0,0 +1,637 @@
1
+ import { nonexhaustive } from '@likec4/core';
2
+ import { GrammarUtils, } from 'langium';
3
+ import { AbstractFormatter, Formatting, FormattingRegion } from 'langium/lsp';
4
+ import { filter, isTruthy } from 'remeda';
5
+ import * as ast from '../generated/ast';
6
+ import * as utils from './utils';
7
+ import { isMultiline } from './utils';
8
+ const FormattingOptions = {
9
+ newLine: Formatting.newLine({ allowMore: true }),
10
+ oneSpace: Formatting.oneSpace(),
11
+ noSpace: Formatting.noSpace(),
12
+ indent: Formatting.indent({ allowMore: true }),
13
+ noIndent: Formatting.noIndent(),
14
+ };
15
+ export class LikeC4Formatter extends AbstractFormatter {
16
+ options = {
17
+ quoteStyle: 'auto',
18
+ };
19
+ extendedFormattingCommands = [];
20
+ constructor(services) {
21
+ super();
22
+ services.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(update => this.onConfigurationUpdate(update.configuration.formatting));
23
+ }
24
+ doDocumentFormat(document, options, range) {
25
+ this.extendedFormattingCommands = [];
26
+ const edits = super.doDocumentFormat(document, options, range);
27
+ this.doExtendedFormatting(edits);
28
+ return edits;
29
+ }
30
+ format(node) {
31
+ this.removeIndentFromTopLevelStatements(node);
32
+ this.indentContentInBraces(node);
33
+ this.normalizeQuotes(node);
34
+ // Imports
35
+ this.formatImports(node);
36
+ // Specification
37
+ this.formatSpecificationRule(node);
38
+ // Globals
39
+ this.formatGlobals(node);
40
+ // Models
41
+ this.formatElementDeclaration(node);
42
+ this.formatExtendElement(node);
43
+ this.formatRelation(node);
44
+ this.formatMetadataProperty(node);
45
+ // Deployment
46
+ this.formatDeploymentNodeDeclaration(node);
47
+ this.formatDeployedInstance(node);
48
+ this.formatDeploymentRelation(node);
49
+ this.formatExtendDeployment(node);
50
+ // Views
51
+ this.formatView(node);
52
+ this.formatViewRuleGroup(node);
53
+ this.formatViewRuleGlobalStyle(node);
54
+ this.formatViewRuleGlobalPredicate(node);
55
+ this.formatIncludeExcludeExpressions(node);
56
+ this.formatWhereExpression(node);
57
+ this.formatWhereRelationExpression(node);
58
+ this.formatWhereElementExpression(node);
59
+ this.formatRelationExpression(node);
60
+ this.formatAutolayoutProperty(node);
61
+ this.formatWithPredicate(node);
62
+ // Common
63
+ this.formatViewRuleStyle(node);
64
+ this.formatLeafProperty(node);
65
+ this.formatLinkProperty(node);
66
+ this.formatNavigateToProperty(node);
67
+ this.formatTags(node);
68
+ }
69
+ formatTags(node) {
70
+ this.on(node, ast.isTags, (n, f) => {
71
+ const tags = GrammarUtils.findNodesForProperty(n.$cstNode, 'values')
72
+ .filter(isTruthy)
73
+ .slice(1);
74
+ f.cst(tags)
75
+ .prepend(FormattingOptions.oneSpace);
76
+ f.keywords(',')
77
+ .prepend(FormattingOptions.noSpace)
78
+ .append(FormattingOptions.oneSpace);
79
+ });
80
+ }
81
+ formatDeploymentRelation(node) {
82
+ this.on(node, ast.isDeploymentRelation, (n, f) => {
83
+ const sourceNodes = n?.source?.$cstNode ? [n?.source?.$cstNode] : [];
84
+ f.cst(sourceNodes).append(FormattingOptions.oneSpace);
85
+ f.keywords(']->').prepend(FormattingOptions.noSpace);
86
+ f.keywords('-[').append(FormattingOptions.noSpace);
87
+ f.nodes(...filter([
88
+ n.target,
89
+ n.tags,
90
+ ], isTruthy)).prepend(FormattingOptions.oneSpace);
91
+ f.properties('title', 'description', 'technology').prepend(FormattingOptions.oneSpace);
92
+ });
93
+ }
94
+ formatExtendDeployment(node) {
95
+ this.on(node, ast.isExtendDeployment, (n, f) => {
96
+ f.keywords('extend').append(FormattingOptions.oneSpace);
97
+ });
98
+ }
99
+ formatRelation(node) {
100
+ this.on(node, (n) => ast.isRelation(n) || ast.isDeploymentRelation(n), (n, f) => {
101
+ const sourceNodes = n?.source?.$cstNode ? [n?.source?.$cstNode] : [];
102
+ f.cst(sourceNodes).append(FormattingOptions.oneSpace);
103
+ f.keywords(']->').prepend(FormattingOptions.noSpace);
104
+ f.keywords('-[').append(FormattingOptions.noSpace);
105
+ f.nodes(...filter([
106
+ n.target,
107
+ n.tags,
108
+ ], isTruthy)).prepend(FormattingOptions.oneSpace);
109
+ f.properties('title', 'description', 'technology').prepend(FormattingOptions.oneSpace);
110
+ });
111
+ this.on(node, ast.isDynamicViewStep, (n, f) => {
112
+ f.keywords('->', '<-').surround(FormattingOptions.oneSpace);
113
+ f.property('dotKind')
114
+ .prepend(FormattingOptions.oneSpace)
115
+ .append(FormattingOptions.oneSpace);
116
+ f.keywords(']->')
117
+ .prepend(FormattingOptions.noSpace)
118
+ .append(FormattingOptions.oneSpace);
119
+ f.keywords('-[')
120
+ .prepend(FormattingOptions.oneSpace)
121
+ .append(FormattingOptions.noSpace);
122
+ f.properties('title').prepend(FormattingOptions.oneSpace);
123
+ const wrapToNextLine =
124
+ // Dynamic step chain with multiline source
125
+ (ast.isDynamicStepChain(n) && isMultiline(n.$cstNode))
126
+ // This is the beginning of the series
127
+ || (ast.isDynamicStepSingle(n) && ast.isDynamicStepChain(n.$container) && isMultiline(n.$container.$cstNode));
128
+ if (!wrapToNextLine) {
129
+ return;
130
+ }
131
+ f.property('dotKind')
132
+ .prepend(Formatting.indent({ allowLess: false, allowMore: true, priority: 2 }));
133
+ f.keywords('->', '-[')
134
+ .prepend(Formatting.indent({ allowLess: false, allowMore: true, priority: 2 }));
135
+ if (n.custom?.$cstNode && isMultiline(n.custom.$cstNode)) {
136
+ f.property('custom')
137
+ .prepend({
138
+ options: {
139
+ allowLess: false,
140
+ allowMore: true,
141
+ priority: 2,
142
+ },
143
+ moves: [{
144
+ tabs: 1,
145
+ }],
146
+ });
147
+ }
148
+ });
149
+ }
150
+ removeIndentFromTopLevelStatements(node) {
151
+ if (ast.isLikeC4Grammar(node.$container)) {
152
+ const formatter = this.getNodeFormatter(node);
153
+ formatter.keywords('specification', 'model', 'views', 'likec4lib', 'global', 'deployments', 'import')
154
+ .prepend(FormattingOptions.noIndent);
155
+ }
156
+ }
157
+ indentContentInBraces(node) {
158
+ if (ast.isLikeC4Lib(node)
159
+ || ast.isSpecificationRule(node)
160
+ || ast.isSpecificationElementKind(node)
161
+ || ast.isSpecificationRelationshipKind(node)
162
+ || ast.isSpecificationDeploymentNodeKind(node)
163
+ || ast.isGlobals(node)
164
+ || ast.isGlobalStyle(node)
165
+ || ast.isGlobalStyleGroup(node)
166
+ || ast.isGlobalPredicateGroup(node)
167
+ || ast.isGlobalDynamicPredicateGroup(node)
168
+ || ast.isGlobalStyleGroup(node)
169
+ || ast.isModel(node)
170
+ || ast.isElementBody(node)
171
+ || ast.isExtendElementBody(node)
172
+ || ast.isRelationBody(node)
173
+ || ast.isRelationStyleProperty(node)
174
+ || ast.isMetadataBody(node)
175
+ || ast.isModelViews(node)
176
+ || ast.isElementViewBody(node)
177
+ || ast.isDynamicViewBody(node)
178
+ || ast.isDeploymentViewBody(node)
179
+ || ast.isViewRuleStyle(node)
180
+ || ast.isViewRuleGroup(node)
181
+ || ast.isCustomElementProperties(node)
182
+ || ast.isCustomRelationProperties(node)
183
+ || ast.isElementStyleProperty(node)
184
+ || ast.isDynamicViewParallelSteps(node)
185
+ || ast.isModelDeployments(node)
186
+ || ast.isDeploymentNodeBody(node)
187
+ || ast.isDeploymentRelationBody(node)
188
+ || ast.isDeployedInstanceBody(node)
189
+ || ast.isExtendDeploymentBody(node)) {
190
+ const formatter = this.getNodeFormatter(node);
191
+ const openBrace = formatter.keywords('{');
192
+ openBrace
193
+ .prepend(FormattingOptions.noIndent)
194
+ .prepend(FormattingOptions.oneSpace);
195
+ const multiline = isMultiline(node.$cstNode);
196
+ const closeBrace = formatter.keywords('}');
197
+ const interiorNodes = formatter.interior(openBrace, closeBrace);
198
+ // Workaround for tags as they are parsed as overlapping regions.
199
+ // E.g. '#tag1, #tag2' will be parsed as two nodes: '#tag1' and '#tag1, #tag2'
200
+ let previousNode = null;
201
+ for (const interiorNode of interiorNodes.nodes) {
202
+ if (!multiline) {
203
+ formatter.cst([interiorNode])
204
+ .surround(FormattingOptions.oneSpace);
205
+ continue;
206
+ }
207
+ if (!previousNode || !utils.areOverlap(previousNode, interiorNode)) {
208
+ formatter.cst([interiorNode])
209
+ .prepend(Formatting.newLine({ allowMore: true }))
210
+ .prepend(FormattingOptions.indent);
211
+ }
212
+ previousNode = interiorNode;
213
+ }
214
+ if (multiline) {
215
+ closeBrace
216
+ .prepend(FormattingOptions.noIndent)
217
+ .prepend(Formatting.newLine({ allowMore: true }));
218
+ }
219
+ else {
220
+ closeBrace
221
+ .prepend(Formatting.oneSpace({ allowLess: true }));
222
+ }
223
+ }
224
+ }
225
+ appendKeywordsWithSpace(node) {
226
+ this.on(node, ast.isElementKind)
227
+ ?.keywords('element').append(FormattingOptions.oneSpace);
228
+ }
229
+ formatView(node) {
230
+ this.on(node, ast.isElementView, (n, f) => {
231
+ if (n.extends || n.viewOf || n.name) {
232
+ f.keywords('view').append(FormattingOptions.oneSpace);
233
+ }
234
+ f.keywords('of', 'extends').surround(FormattingOptions.oneSpace);
235
+ });
236
+ this.on(node, ast.isDynamicView)
237
+ ?.keywords('dynamic', 'view').append(FormattingOptions.oneSpace);
238
+ this.on(node, ast.isDeploymentView)
239
+ ?.keywords('deployment', 'view').append(FormattingOptions.oneSpace);
240
+ }
241
+ formatLeafProperty(node) {
242
+ if (ast.isElementStringProperty(node)
243
+ || ast.isRelationStringProperty(node)
244
+ || ast.isViewStringProperty(node)
245
+ || ast.isNotationProperty(node)
246
+ || ast.isNotesProperty(node)
247
+ || ast.isSpecificationElementStringProperty(node)
248
+ || ast.isSpecificationRelationshipStringProperty(node)
249
+ || ast.isColorProperty(node)
250
+ || ast.isLineProperty(node)
251
+ || ast.isArrowProperty(node)
252
+ || ast.isIconProperty(node)
253
+ || ast.isShapeProperty(node)
254
+ || ast.isBorderProperty(node)
255
+ || ast.isOpacityProperty(node)
256
+ || ast.isMultipleProperty(node)
257
+ || ast.isShapeSizeProperty(node)
258
+ || ast.isPaddingSizeProperty(node)
259
+ || ast.isTextSizeProperty(node)) {
260
+ const formatter = this.getNodeFormatter(node);
261
+ const colon = formatter.keyword(':');
262
+ const propertyName = formatter.keywords('title', 'description', 'technology', 'summary', 'notation', 'notes', 'color', 'line', 'head', 'tail', 'icon', 'shape', 'border', 'opacity', 'multiple', 'size', 'padding', 'textSize');
263
+ if (colon.nodes.length === 0) {
264
+ propertyName
265
+ .append(FormattingOptions.oneSpace);
266
+ }
267
+ else {
268
+ colon
269
+ .prepend(FormattingOptions.noSpace)
270
+ .append(FormattingOptions.oneSpace);
271
+ }
272
+ formatter.keyword(';')
273
+ .prepend(FormattingOptions.noSpace)
274
+ .append(FormattingOptions.newLine);
275
+ }
276
+ }
277
+ formatLinkProperty(node) {
278
+ this.on(node, ast.isLinkProperty, (n, f) => {
279
+ f.keyword('link').append(FormattingOptions.oneSpace);
280
+ f.property('value').append(FormattingOptions.oneSpace);
281
+ f.keyword(':')
282
+ .prepend(FormattingOptions.noSpace)
283
+ .append(FormattingOptions.oneSpace);
284
+ f.keyword(';')
285
+ .prepend(FormattingOptions.noSpace)
286
+ .append(FormattingOptions.newLine);
287
+ });
288
+ }
289
+ formatNavigateToProperty(node) {
290
+ this.on(node, ast.isNavigateToProperty)
291
+ ?.property('key').append(FormattingOptions.oneSpace);
292
+ }
293
+ formatAutolayoutProperty(node) {
294
+ this.on(node, ast.isViewRuleAutoLayout, (n, f) => {
295
+ f.keyword('autoLayout').append(FormattingOptions.oneSpace);
296
+ f.property('rankSep').prepend(FormattingOptions.oneSpace);
297
+ f.property('nodeSep').prepend(FormattingOptions.oneSpace);
298
+ });
299
+ }
300
+ formatMetadataProperty(node) {
301
+ this.on(node, ast.isMetadataAttribute, (n, f) => {
302
+ f.property('key').append(FormattingOptions.oneSpace);
303
+ f.keyword(':')
304
+ .prepend(FormattingOptions.noSpace)
305
+ .append(FormattingOptions.oneSpace);
306
+ f.keyword(';')
307
+ .prepend(FormattingOptions.noSpace)
308
+ .append(FormattingOptions.newLine);
309
+ });
310
+ }
311
+ formatElementDeclaration(node) {
312
+ this.on(node, ast.isElement, (n, f) => {
313
+ const kind = GrammarUtils.findNodeForProperty(n.$cstNode, 'kind');
314
+ const name = GrammarUtils.findNodeForProperty(n.$cstNode, 'name');
315
+ if (name && kind) {
316
+ // system sys1
317
+ if (utils.compareRanges(name, kind) > 0) {
318
+ f.cst([kind]).append(FormattingOptions.oneSpace);
319
+ }
320
+ // sys1 = system
321
+ else {
322
+ f.cst([name]).append(FormattingOptions.oneSpace);
323
+ f.cst([kind]).prepend(FormattingOptions.oneSpace);
324
+ }
325
+ }
326
+ f.properties('props').prepend(FormattingOptions.oneSpace);
327
+ });
328
+ }
329
+ formatExtendElement(node) {
330
+ this.on(node, ast.isExtendElement, (n, f) => {
331
+ f.keywords('extend').append(FormattingOptions.oneSpace);
332
+ });
333
+ }
334
+ formatGlobals(node) {
335
+ this.on(node, ast.isGlobalStyle, (n, f) => {
336
+ f.keyword('style').append(FormattingOptions.oneSpace);
337
+ f.property('id').append(FormattingOptions.oneSpace);
338
+ });
339
+ this.on(node, ast.isGlobalStyleGroup, (n, f) => {
340
+ f.keyword('styleGroup').append(FormattingOptions.oneSpace);
341
+ });
342
+ this.on(node, ast.isGlobalPredicateGroup, (n, f) => {
343
+ f.keyword('predicateGroup').append(FormattingOptions.oneSpace);
344
+ });
345
+ this.on(node, ast.isGlobalDynamicPredicateGroup, (n, f) => {
346
+ f.keyword('dynamicPredicateGroup').append(FormattingOptions.oneSpace);
347
+ });
348
+ }
349
+ formatImports(node) {
350
+ this.on(node, ast.isImportsFromPoject, (n, f) => {
351
+ f.keyword('import').append(FormattingOptions.oneSpace);
352
+ f.keywords('{', '}', 'from').surround(FormattingOptions.oneSpace);
353
+ });
354
+ this.on(node, ast.isImported, (n, f) => {
355
+ f.keywords(',')
356
+ .prepend(FormattingOptions.noSpace)
357
+ .append(FormattingOptions.oneSpace);
358
+ });
359
+ }
360
+ formatSpecificationRule(node) {
361
+ if (ast.isSpecificationElementKind(node)
362
+ || ast.isSpecificationRelationshipKind(node)
363
+ || ast.isSpecificationTag(node)
364
+ || ast.isSpecificationDeploymentNodeKind(node)) {
365
+ const formatter = this.getNodeFormatter(node);
366
+ formatter.keywords('element', 'relationship', 'tag', 'deploymentNode')
367
+ .append(FormattingOptions.oneSpace);
368
+ }
369
+ if (ast.isSpecificationColor(node)) {
370
+ const formatter = this.getNodeFormatter(node);
371
+ formatter.keyword('color').append(FormattingOptions.oneSpace);
372
+ formatter.property('name').append(FormattingOptions.oneSpace);
373
+ }
374
+ }
375
+ formatWithPredicate(node) {
376
+ if (ast.isFqnExprWith(node)
377
+ || ast.isRelationExprWith(node)) {
378
+ const formatter = this.getNodeFormatter(node);
379
+ formatter.keyword('with').prepend(FormattingOptions.oneSpace);
380
+ }
381
+ }
382
+ formatDeploymentNodeDeclaration(node) {
383
+ this.on(node, ast.isDeploymentNode, (n, f) => {
384
+ const kind = GrammarUtils.findNodeForProperty(n.$cstNode, 'kind');
385
+ const name = GrammarUtils.findNodeForProperty(n.$cstNode, 'name');
386
+ if (name && kind) {
387
+ // system sys1
388
+ if (utils.compareRanges(name, kind) > 0) {
389
+ f.cst([kind]).append(FormattingOptions.oneSpace);
390
+ }
391
+ // sys1 = system
392
+ else {
393
+ f.cst([name]).append(FormattingOptions.oneSpace);
394
+ f.cst([kind]).prepend(FormattingOptions.oneSpace);
395
+ }
396
+ }
397
+ f.properties('title').prepend(FormattingOptions.oneSpace);
398
+ });
399
+ }
400
+ formatDeployedInstance(node) {
401
+ this.on(node, ast.isDeployedInstance, (n, f) => {
402
+ const eqNode = n.$cstNode?.content.find(c => c.text === '=');
403
+ if (eqNode) {
404
+ f.cst([eqNode]).surround(FormattingOptions.oneSpace);
405
+ }
406
+ f.keyword('instanceOf').append(FormattingOptions.oneSpace);
407
+ f.property('title').prepend(FormattingOptions.oneSpace);
408
+ });
409
+ }
410
+ formatViewRuleGlobalStyle(node) {
411
+ this.on(node, ast.isViewRuleGlobalStyle, (n, f) => {
412
+ f.keywords('global', 'style').append(FormattingOptions.oneSpace);
413
+ });
414
+ }
415
+ formatViewRuleGlobalPredicate(node) {
416
+ const formatter = this.getNodeFormatter(node);
417
+ if (ast.isViewRuleGlobalPredicateRef(node)
418
+ || ast.isDynamicViewGlobalPredicateRef(node)) {
419
+ formatter.keywords('global', 'predicate').append(FormattingOptions.oneSpace);
420
+ }
421
+ }
422
+ formatViewRuleGroup(node) {
423
+ this.on(node, ast.isViewRuleGroup, (n, f) => {
424
+ f.keyword('group').append(FormattingOptions.oneSpace);
425
+ });
426
+ }
427
+ formatViewRuleStyle(node) {
428
+ this.on(node, ast.isViewRuleStyle)
429
+ ?.keyword('style').append(FormattingOptions.oneSpace);
430
+ this.on(node, ast.isDeploymentViewRuleStyle)
431
+ ?.keyword('style').append(FormattingOptions.oneSpace);
432
+ this.on(node, ast.isExpressions)
433
+ ?.keyword(',')
434
+ .prepend(FormattingOptions.noSpace)
435
+ .append(FormattingOptions.oneSpace);
436
+ this.on(node, ast.isFqnExpressions)
437
+ ?.keyword(',')
438
+ .prepend(FormattingOptions.noSpace)
439
+ .append(FormattingOptions.oneSpace);
440
+ }
441
+ formatWhereExpression(node) {
442
+ if (ast.isRelationExprWhere(node)
443
+ || ast.isFqnExprWhere(node)) {
444
+ const formatter = this.getNodeFormatter(node);
445
+ formatter.keyword('where').append(FormattingOptions.oneSpace);
446
+ }
447
+ }
448
+ formatWhereRelationExpression(node) {
449
+ this.on(node, ast.isWhereRelationExpression, (n, f) => {
450
+ f.property('operator').surround(FormattingOptions.oneSpace);
451
+ });
452
+ this.on(node, ast.isWhereRelationNegation, (n, f) => {
453
+ f.keyword('not').append(FormattingOptions.oneSpace);
454
+ });
455
+ if (ast.isWhereRelation(node)
456
+ || ast.isWhereRelationTag(node)
457
+ || ast.isWhereRelationKind(node)) {
458
+ const formatter = this.getNodeFormatter(node);
459
+ formatter.property('operator').surround(FormattingOptions.oneSpace);
460
+ formatter.property('not').surround(FormattingOptions.oneSpace);
461
+ }
462
+ }
463
+ formatWhereElementExpression(node) {
464
+ this.on(node, ast.isWhereElementExpression, (n, f) => {
465
+ f.property('operator').surround(FormattingOptions.oneSpace);
466
+ });
467
+ this.on(node, ast.isWhereElementNegation, (n, f) => {
468
+ f.keyword('not').append(FormattingOptions.oneSpace);
469
+ });
470
+ if (ast.isWhereElement(node)
471
+ || ast.isWhereElementTag(node)
472
+ || ast.isWhereElementKind(node)) {
473
+ const formatter = this.getNodeFormatter(node);
474
+ formatter.property('operator').surround(FormattingOptions.oneSpace);
475
+ formatter.property('not').surround(FormattingOptions.oneSpace);
476
+ }
477
+ }
478
+ formatIncludeExcludeExpressions(node) {
479
+ if (ast.isDynamicViewRule(node)
480
+ || ast.isViewRulePredicate(node)
481
+ || ast.isDeploymentViewRulePredicate(node)) {
482
+ const formatter = this.getNodeFormatter(node);
483
+ if (!node.$cstNode || !utils.isMultiline(node.$cstNode)) {
484
+ formatter.keywords('include', 'exclude')
485
+ .append(FormattingOptions.oneSpace);
486
+ }
487
+ }
488
+ if (ast.isExpressions(node)) {
489
+ const formatter = this.getNodeFormatter(node);
490
+ const parent = this.findPredicateExpressionRoot(node);
491
+ const isMultiline = parent?.$cstNode && utils.isMultiline(parent?.$cstNode);
492
+ if (isMultiline) {
493
+ formatter.property('value').prepend(FormattingOptions.indent);
494
+ }
495
+ formatter.keyword(',')
496
+ .prepend(FormattingOptions.noSpace)
497
+ .append(isMultiline ? FormattingOptions.newLine : FormattingOptions.oneSpace);
498
+ }
499
+ }
500
+ formatRelationExpression(node) {
501
+ this.on(node, ast.isIncomingRelationExpr, (n, f) => {
502
+ f.keyword('->').append(FormattingOptions.oneSpace);
503
+ });
504
+ this.on(node, ast.isInOutRelationExpr, (n, f) => {
505
+ f.keyword('->').prepend(FormattingOptions.oneSpace);
506
+ });
507
+ this.on(node, ast.isOutgoingRelationExpr, (n, f) => {
508
+ f.keywords('->', '<->').prepend(FormattingOptions.oneSpace);
509
+ f.keywords('-[')
510
+ .prepend(FormattingOptions.oneSpace)
511
+ .append(FormattingOptions.noSpace);
512
+ f.keywords(']->')
513
+ .prepend(FormattingOptions.noSpace)
514
+ .append(FormattingOptions.oneSpace);
515
+ f.property('dotKind')
516
+ .prepend(FormattingOptions.oneSpace)
517
+ .append(FormattingOptions.oneSpace);
518
+ });
519
+ this.on(node, ast.isDirectedRelationExpr, (n, f) => {
520
+ f.property('target').prepend(FormattingOptions.oneSpace);
521
+ });
522
+ }
523
+ findPredicateExpressionRoot(node) {
524
+ let parent = node.$container;
525
+ while (true) {
526
+ if (!parent
527
+ || ast.isDynamicViewRule(parent)
528
+ || ast.isViewRulePredicate(parent)
529
+ || ast.isDeploymentViewRulePredicate(parent)) {
530
+ return parent;
531
+ }
532
+ parent = parent.$container;
533
+ }
534
+ }
535
+ on(node, predicate, format) {
536
+ const formatter = predicate(node) ? this.getNodeFormatter(node) : undefined;
537
+ format && formatter && format(node, formatter);
538
+ return formatter;
539
+ }
540
+ doExtendedFormatting(edits) {
541
+ const quotesNormalizer = this.quotesNormalizerFactory(this.extendedFormattingCommands);
542
+ for (let command of this.extendedFormattingCommands) {
543
+ switch (command.type) {
544
+ case 'normalizeQuotes':
545
+ quotesNormalizer(command, edits);
546
+ break;
547
+ default:
548
+ nonexhaustive(command.type);
549
+ }
550
+ }
551
+ }
552
+ normalizeQuotes(node) {
553
+ if (this.options.quoteStyle === 'ignore') {
554
+ return;
555
+ }
556
+ let region = null;
557
+ region = region ?? this.on(node, ast.isStringProperty)
558
+ ?.property('value');
559
+ region = region ?? this.on(node, ast.isElement)
560
+ ?.properties('props');
561
+ region = region ?? this.on(node, ast.isImportsFromPoject)
562
+ ?.properties('project');
563
+ region = region ?? this.on(node, ast.isRelation)
564
+ ?.properties('title', 'technology');
565
+ region = region ?? this.on(node, ast.isViewRuleGroup)
566
+ ?.properties('title');
567
+ region = region ?? this.on(node, ast.isDynamicViewStep)
568
+ ?.properties('title');
569
+ region = region ?? this.on(node, ast.isDeploymentNode)
570
+ ?.properties('title');
571
+ region = region ?? this.on(node, ast.isDeployedInstance)
572
+ ?.properties('title');
573
+ region = region ?? this.on(node, ast.isDeploymentRelation)
574
+ ?.properties('title', 'technology');
575
+ region = region ?? this.on(node, ast.isLinkProperty)
576
+ ?.properties('title');
577
+ if (region) {
578
+ this.extendedFormattingCommands.push({ type: 'normalizeQuotes', region });
579
+ }
580
+ }
581
+ quotesNormalizerFactory(commands) {
582
+ const quoteStyle = this.options.quoteStyle != 'auto'
583
+ ? this.options.quoteStyle
584
+ : this.getAutoQuoteStyle(commands);
585
+ return (command, edits) => {
586
+ const quotesToReplace = quoteStyle === 'single' ? '"' : '\'';
587
+ const quotesToInsert = quoteStyle === 'single' ? '\'' : '"';
588
+ const markdownFence = quotesToInsert.repeat(3);
589
+ const plainFence = quotesToInsert;
590
+ const newEdits = command.region.nodes.map(node => {
591
+ const fence = node.text.startsWith(`"""`) || node.text.startsWith(`'''`)
592
+ ? markdownFence
593
+ : plainFence;
594
+ return {
595
+ range: node.range,
596
+ newText: fence +
597
+ this.escapeQuotesInternalQuotes(node.text.slice(fence.length, -fence.length), quotesToReplace, quotesToInsert) +
598
+ fence,
599
+ };
600
+ });
601
+ edits.push(...newEdits);
602
+ };
603
+ }
604
+ escapeQuotesInternalQuotes(text, quotesToReplace, quoteToInsert) {
605
+ let result = '';
606
+ let start = 0;
607
+ while (start >= 0) {
608
+ let pos = text.indexOf(quoteToInsert, start);
609
+ if (pos < 0) {
610
+ result += text.slice(start);
611
+ break;
612
+ }
613
+ result += text.slice(start, pos);
614
+ start = pos + 1;
615
+ let escaped = false;
616
+ while (pos > 0 && text[pos - 1] == '\\') {
617
+ escaped = !escaped;
618
+ pos--;
619
+ }
620
+ result += escaped ? quoteToInsert : `\\${quoteToInsert}`;
621
+ }
622
+ return result;
623
+ }
624
+ getAutoQuoteStyle(commands) {
625
+ const nodes = commands.flatMap(x => x.region.nodes);
626
+ const doubleQuotesCount = nodes.filter(x => x.text[0] == '"').length;
627
+ return doubleQuotesCount * 2 >= nodes.length ? 'double' : 'single';
628
+ }
629
+ onConfigurationUpdate(options) {
630
+ this.options = {
631
+ ...this.options,
632
+ ...options ?? {
633
+ quoteStyle: 'auto',
634
+ },
635
+ };
636
+ }
637
+ }
@@ -0,0 +1,18 @@
1
+ export function areOverlap(a, b) {
2
+ ;
3
+ [a, b] = compareRanges(a, b) > 0 ? [b, a] : [a, b];
4
+ return isInRagne(a.range, b.range.start);
5
+ }
6
+ export function compareRanges(a, b) {
7
+ const lineDiff = a.range.start.line - b.range.start.line;
8
+ return lineDiff !== 0 ? lineDiff : a.range.start.character - b.range.start.character;
9
+ }
10
+ export function isInRagne(range, pos) {
11
+ return !(pos.line < range.start.line
12
+ || pos.line > range.end.line
13
+ || pos.line == range.start.line && pos.character < range.start.character
14
+ || pos.line == range.end.line && pos.character > range.end.character);
15
+ }
16
+ export function isMultiline(node) {
17
+ return !!node && node.range.start.line != node.range.end.line;
18
+ }