@platformos/codemirror-language-client 0.0.2

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 (127) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +91 -0
  3. package/dist/esm/CodeMirrorLanguageClient.d.ts +60 -0
  4. package/dist/esm/CodeMirrorLanguageClient.js +80 -0
  5. package/dist/esm/CodeMirrorLanguageClient.js.map +1 -0
  6. package/dist/esm/LanguageClient.d.ts +112 -0
  7. package/dist/esm/LanguageClient.js +187 -0
  8. package/dist/esm/LanguageClient.js.map +1 -0
  9. package/dist/esm/extensions/client.d.ts +6 -0
  10. package/dist/esm/extensions/client.js +12 -0
  11. package/dist/esm/extensions/client.js.map +1 -0
  12. package/dist/esm/extensions/complete.d.ts +17 -0
  13. package/dist/esm/extensions/complete.js +202 -0
  14. package/dist/esm/extensions/complete.js.map +1 -0
  15. package/dist/esm/extensions/complete.spec.d.ts +1 -0
  16. package/dist/esm/extensions/complete.spec.js +189 -0
  17. package/dist/esm/extensions/complete.spec.js.map +1 -0
  18. package/dist/esm/extensions/documentHighlights.d.ts +14 -0
  19. package/dist/esm/extensions/documentHighlights.js +78 -0
  20. package/dist/esm/extensions/documentHighlights.js.map +1 -0
  21. package/dist/esm/extensions/documentHighlights.spec.d.ts +1 -0
  22. package/dist/esm/extensions/documentHighlights.spec.js +99 -0
  23. package/dist/esm/extensions/documentHighlights.spec.js.map +1 -0
  24. package/dist/esm/extensions/hover.d.ts +16 -0
  25. package/dist/esm/extensions/hover.js +49 -0
  26. package/dist/esm/extensions/hover.js.map +1 -0
  27. package/dist/esm/extensions/hover.spec.d.ts +1 -0
  28. package/dist/esm/extensions/hover.spec.js +59 -0
  29. package/dist/esm/extensions/hover.spec.js.map +1 -0
  30. package/dist/esm/extensions/index.d.ts +6 -0
  31. package/dist/esm/extensions/index.js +7 -0
  32. package/dist/esm/extensions/index.js.map +1 -0
  33. package/dist/esm/extensions/lspLinter.d.ts +23 -0
  34. package/dist/esm/extensions/lspLinter.js +104 -0
  35. package/dist/esm/extensions/lspLinter.js.map +1 -0
  36. package/dist/esm/extensions/lspLinter.spec.d.ts +1 -0
  37. package/dist/esm/extensions/lspLinter.spec.js +141 -0
  38. package/dist/esm/extensions/lspLinter.spec.js.map +1 -0
  39. package/dist/esm/extensions/snippet.d.ts +19 -0
  40. package/dist/esm/extensions/snippet.js +25 -0
  41. package/dist/esm/extensions/snippet.js.map +1 -0
  42. package/dist/esm/extensions/snippet.spec.d.ts +1 -0
  43. package/dist/esm/extensions/snippet.spec.js +23 -0
  44. package/dist/esm/extensions/snippet.spec.js.map +1 -0
  45. package/dist/esm/extensions/textDocumentSync.d.ts +4 -0
  46. package/dist/esm/extensions/textDocumentSync.js +109 -0
  47. package/dist/esm/extensions/textDocumentSync.js.map +1 -0
  48. package/dist/esm/extensions/textDocumentSync.spec.d.ts +1 -0
  49. package/dist/esm/extensions/textDocumentSync.spec.js +163 -0
  50. package/dist/esm/extensions/textDocumentSync.spec.js.map +1 -0
  51. package/dist/esm/index.d.ts +2 -0
  52. package/dist/esm/index.js +3 -0
  53. package/dist/esm/index.js.map +1 -0
  54. package/dist/esm/test/MockClient.d.ts +18 -0
  55. package/dist/esm/test/MockClient.js +63 -0
  56. package/dist/esm/test/MockClient.js.map +1 -0
  57. package/dist/esm/tsconfig.tsbuildInfo +1 -0
  58. package/dist/esm/utils/simpleStateField.d.ts +3 -0
  59. package/dist/esm/utils/simpleStateField.js +17 -0
  60. package/dist/esm/utils/simpleStateField.js.map +1 -0
  61. package/dist/umd/CodeMirrorLanguageClient.d.ts +60 -0
  62. package/dist/umd/CodeMirrorLanguageClient.js +94 -0
  63. package/dist/umd/CodeMirrorLanguageClient.js.map +1 -0
  64. package/dist/umd/LanguageClient.d.ts +112 -0
  65. package/dist/umd/LanguageClient.js +202 -0
  66. package/dist/umd/LanguageClient.js.map +1 -0
  67. package/dist/umd/extensions/client.d.ts +6 -0
  68. package/dist/umd/extensions/client.js +25 -0
  69. package/dist/umd/extensions/client.js.map +1 -0
  70. package/dist/umd/extensions/complete.d.ts +17 -0
  71. package/dist/umd/extensions/complete.js +217 -0
  72. package/dist/umd/extensions/complete.js.map +1 -0
  73. package/dist/umd/extensions/documentHighlights.d.ts +14 -0
  74. package/dist/umd/extensions/documentHighlights.js +93 -0
  75. package/dist/umd/extensions/documentHighlights.js.map +1 -0
  76. package/dist/umd/extensions/hover.d.ts +16 -0
  77. package/dist/umd/extensions/hover.js +64 -0
  78. package/dist/umd/extensions/hover.js.map +1 -0
  79. package/dist/umd/extensions/index.d.ts +6 -0
  80. package/dist/umd/extensions/index.js +36 -0
  81. package/dist/umd/extensions/index.js.map +1 -0
  82. package/dist/umd/extensions/lspLinter.d.ts +23 -0
  83. package/dist/umd/extensions/lspLinter.js +119 -0
  84. package/dist/umd/extensions/lspLinter.js.map +1 -0
  85. package/dist/umd/extensions/snippet.d.ts +19 -0
  86. package/dist/umd/extensions/snippet.js +38 -0
  87. package/dist/umd/extensions/snippet.js.map +1 -0
  88. package/dist/umd/extensions/textDocumentSync.d.ts +4 -0
  89. package/dist/umd/extensions/textDocumentSync.js +122 -0
  90. package/dist/umd/extensions/textDocumentSync.js.map +1 -0
  91. package/dist/umd/index.d.ts +2 -0
  92. package/dist/umd/index.js +29 -0
  93. package/dist/umd/index.js.map +1 -0
  94. package/dist/umd/test/MockClient.d.ts +18 -0
  95. package/dist/umd/test/MockClient.js +77 -0
  96. package/dist/umd/test/MockClient.js.map +1 -0
  97. package/dist/umd/tsconfig.tsbuildInfo +1 -0
  98. package/dist/umd/utils/simpleStateField.d.ts +3 -0
  99. package/dist/umd/utils/simpleStateField.js +30 -0
  100. package/dist/umd/utils/simpleStateField.js.map +1 -0
  101. package/package.json +67 -0
  102. package/playground/src/index.html +10 -0
  103. package/playground/src/language-server-worker.ts +82 -0
  104. package/playground/src/playground.ts +251 -0
  105. package/playground/tsconfig.json +26 -0
  106. package/playground/webpack.config.js +85 -0
  107. package/src/CodeMirrorLanguageClient.ts +179 -0
  108. package/src/LanguageClient.ts +329 -0
  109. package/src/extensions/client.ts +17 -0
  110. package/src/extensions/complete.spec.ts +200 -0
  111. package/src/extensions/complete.ts +274 -0
  112. package/src/extensions/documentHighlights.spec.ts +111 -0
  113. package/src/extensions/documentHighlights.ts +91 -0
  114. package/src/extensions/hover.spec.ts +68 -0
  115. package/src/extensions/hover.ts +66 -0
  116. package/src/extensions/index.ts +19 -0
  117. package/src/extensions/lspLinter.spec.ts +156 -0
  118. package/src/extensions/lspLinter.ts +154 -0
  119. package/src/extensions/snippet.spec.ts +31 -0
  120. package/src/extensions/snippet.ts +42 -0
  121. package/src/extensions/textDocumentSync.spec.ts +188 -0
  122. package/src/extensions/textDocumentSync.ts +138 -0
  123. package/src/index.ts +2 -0
  124. package/src/test/MockClient.ts +96 -0
  125. package/src/utils/simpleStateField.ts +22 -0
  126. package/tsconfig.json +18 -0
  127. package/tsconfig.umd.json +9 -0
@@ -0,0 +1,49 @@
1
+ import { HoverRequest } from 'vscode-languageserver-protocol';
2
+ import { clientFacet, fileUriFacet } from './client';
3
+ import { textDocumentField } from './textDocumentSync';
4
+ import { Facet } from '@codemirror/state';
5
+ import { hoverTooltip } from '@codemirror/view';
6
+ export const hoverRendererFacet = Facet.define({
7
+ static: true,
8
+ combine: (values) => values[0] ?? undefined,
9
+ });
10
+ export const lspHover = (overrides = {}) => hoverTooltip(hover, {
11
+ ...overrides,
12
+ });
13
+ export async function hover(view, pos, _side) {
14
+ const client = view.state.facet(clientFacet.reader);
15
+ const fileUri = view.state.facet(fileUriFacet.reader);
16
+ const hoverRenderer = view.state.facet(hoverRendererFacet.reader);
17
+ const textDocument = view.state.field(textDocumentField);
18
+ if (!hoverRenderer)
19
+ return null;
20
+ const result = await client.sendRequest(HoverRequest.type, {
21
+ textDocument: { uri: fileUri },
22
+ position: textDocument.positionAt(pos),
23
+ });
24
+ // No results
25
+ if (result === null)
26
+ return null;
27
+ let { from, to, text } = view.state.doc.lineAt(pos);
28
+ let start = pos;
29
+ let end = pos;
30
+ if (result.range) {
31
+ start = textDocument.offsetAt(result.range.start);
32
+ end = textDocument.offsetAt(result.range.end);
33
+ }
34
+ else {
35
+ // basic "current word" algo
36
+ while (start > from && /\w/.test(text[start - from - 1]))
37
+ start--;
38
+ while (end < to && /\w/.test(text[end - from]))
39
+ end++;
40
+ }
41
+ return {
42
+ pos: start,
43
+ end: end,
44
+ above: true,
45
+ create: (view) => hoverRenderer(view, result),
46
+ arrow: false,
47
+ };
48
+ }
49
+ //# sourceMappingURL=hover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.js","sourceRoot":"","sources":["../../../src/extensions/hover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAoC,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAalF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAG5C;IACA,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS;CAC5C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,YAA0B,EAAE,EAAE,EAAE,CACvD,YAAY,CAAC,KAAK,EAAE;IAClB,GAAG,SAAS;CACb,CAAC,CAAC;AAEL,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAgB,EAAE,GAAW,EAAE,KAAa;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEzD,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE;QACzD,YAAY,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;QAC9B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;KACvC,CAAC,CAAC;IAEH,aAAa;IACb,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpD,IAAI,KAAK,GAAG,GAAG,CAAC;IAChB,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClD,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,4BAA4B;QAC5B,OAAO,KAAK,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;YAAE,KAAK,EAAE,CAAC;QAClE,OAAO,GAAG,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;YAAE,GAAG,EAAE,CAAC;IACxD,CAAC;IAED,OAAO;QACL,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC;QAC7C,KAAK,EAAE,KAAK;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ // @vitest-environment jsdom
2
+ import { EditorState } from '@codemirror/state';
3
+ import { EditorView } from '@codemirror/view';
4
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
5
+ import { MockClient } from '../test/MockClient';
6
+ import { clientFacet, fileUriFacet } from './client';
7
+ import { hover, hoverRendererFacet, lspHover } from './hover';
8
+ import { textDocumentSync } from './textDocumentSync';
9
+ describe('Module: hover', () => {
10
+ const fileUri = 'browser://input.liquid';
11
+ let client;
12
+ let extensions;
13
+ let view;
14
+ let hoverRenderer;
15
+ beforeEach(() => {
16
+ client = new MockClient();
17
+ hoverRenderer = vi.fn().mockReturnValue(null);
18
+ extensions = [
19
+ clientFacet.of(client),
20
+ fileUriFacet.of(fileUri),
21
+ textDocumentSync,
22
+ hoverRendererFacet.of(hoverRenderer),
23
+ lspHover(),
24
+ ];
25
+ view = new EditorView({
26
+ state: EditorState.create({
27
+ doc: 'hello world',
28
+ extensions,
29
+ }),
30
+ });
31
+ });
32
+ it('should translate LSP hover requests into CodeMirror hover tooltips', async () => {
33
+ const promise = hover(view, /* doesnt matter for unit test */ 0, 1);
34
+ const hoverResponse = {
35
+ contents: {
36
+ kind: 'markdown',
37
+ value: '### echo hello world',
38
+ },
39
+ };
40
+ client.resolveRequest(hoverResponse);
41
+ const result = await promise;
42
+ expect(result).toEqual({
43
+ pos: 0,
44
+ end: 5,
45
+ above: true,
46
+ arrow: false,
47
+ create: expect.any(Function),
48
+ });
49
+ result.create(view);
50
+ expect(hoverRenderer).toHaveBeenCalledWith(view, hoverResponse);
51
+ });
52
+ it('should return null if nothing comes back', async () => {
53
+ const promise = hover(view, 0, 1);
54
+ client.resolveRequest(null);
55
+ const result = await promise;
56
+ expect(result).to.eql(null);
57
+ });
58
+ });
59
+ //# sourceMappingURL=hover.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.spec.js","sourceRoot":"","sources":["../../../src/extensions/hover.spec.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,WAAW,EAAa,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,OAAO,GAAG,wBAAwB,CAAC;IACzC,IAAI,MAAkB,CAAC;IACvB,IAAI,UAAqB,CAAC;IAC1B,IAAI,IAAgB,CAAC;IACrB,IAAI,aAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC1B,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC9C,UAAU,GAAG;YACX,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC;YACtB,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC;YACxB,gBAAgB;YAChB,kBAAkB,CAAC,EAAE,CAAC,aAAa,CAAC;YACpC,QAAQ,EAAE;SACX,CAAC;QACF,IAAI,GAAG,IAAI,UAAU,CAAC;YACpB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;gBACxB,GAAG,EAAE,aAAa;gBAClB,UAAU;aACX,CAAC;SACH,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,iCAAiC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpE,MAAM,aAAa,GAAU;YAC3B,QAAQ,EAAE;gBACR,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,sBAAsB;aAC9B;SACF,CAAC;QAEF,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAE7B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,CAAC;YACN,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SAC7B,CAAC,CAAC;QAEH,MAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAErB,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { clientFacet, fileUriFacet, serverCapabilitiesFacet } from './client';
2
+ export { AutocompleteOptions, InfoRenderer, complete, infoRendererFacet, lspComplete, } from './complete';
3
+ export { documentHighlightsClass, lspDocumentHighlights } from './documentHighlights';
4
+ export { HoverOptions, HoverRenderer, hover, lspHover } from './hover';
5
+ export { DiagnosticRenderer, LinterOptions, diagnosticRendererFacet, diagnosticsFacet, lspDiagnosticsField, lspLinter, } from './lspLinter';
6
+ export { textDocumentField, textDocumentSync } from './textDocumentSync';
@@ -0,0 +1,7 @@
1
+ export { clientFacet, fileUriFacet, serverCapabilitiesFacet } from './client';
2
+ export { complete, infoRendererFacet, lspComplete, } from './complete';
3
+ export { documentHighlightsClass, lspDocumentHighlights } from './documentHighlights';
4
+ export { hover, lspHover } from './hover';
5
+ export { diagnosticRendererFacet, diagnosticsFacet, lspDiagnosticsField, lspLinter, } from './lspLinter';
6
+ export { textDocumentField, textDocumentSync } from './textDocumentSync';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAGL,QAAQ,EACR,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAA+B,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAGL,uBAAuB,EACvB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { Diagnostic as CodeMirrorDiagnostic, linter } from '@codemirror/lint';
2
+ import { Extension, Facet } from '@codemirror/state';
3
+ import { EditorView, PluginValue, ViewPlugin } from '@codemirror/view';
4
+ import { Diagnostic as LSPDiagnostic } from 'vscode-languageserver-protocol';
5
+ declare class DiagnosticsPlugin implements PluginValue {
6
+ private handlers;
7
+ constructor(view: EditorView);
8
+ destroy(): void;
9
+ }
10
+ export declare const setLSPDiagnosticsVersion: import("@codemirror/state").StateEffectType<number | null>;
11
+ export declare const lspDiagnosticsVersionField: import("@codemirror/state").StateField<number | null>;
12
+ export declare const setLSPDiagnostics: import("@codemirror/state").StateEffectType<LSPDiagnostic[]>;
13
+ export declare const lspDiagnosticsField: import("@codemirror/state").StateField<LSPDiagnostic[]>;
14
+ export declare const diagnosticsFacet: Facet<CodeMirrorDiagnostic[], CodeMirrorDiagnostic[]>;
15
+ export type DiagnosticRenderer = (lspDiagnostic: LSPDiagnostic) => Node;
16
+ export declare const diagnosticRendererFacet: Facet<DiagnosticRenderer | undefined, DiagnosticRenderer | undefined>;
17
+ export declare const computedCodeMirrorDiagnosticsValueProvider: Extension;
18
+ type SecondArgType<F> = F extends (_: any, second: infer A) => any ? A : never;
19
+ export type LinterOptions = SecondArgType<typeof linter>;
20
+ export declare const diagnosticsLinter: (overrides: LinterOptions) => Extension;
21
+ export declare const diagnosticsPlugin: ViewPlugin<DiagnosticsPlugin>;
22
+ export declare const lspLinter: (linterOptions?: LinterOptions) => Extension;
23
+ export {};
@@ -0,0 +1,104 @@
1
+ import { linter } from '@codemirror/lint';
2
+ import { Facet, StateEffect } from '@codemirror/state';
3
+ import { ViewPlugin } from '@codemirror/view';
4
+ import { DiagnosticSeverity as LSPSeverity, PublishDiagnosticsNotification, } from 'vscode-languageserver-protocol';
5
+ import { simpleStateField } from '../utils/simpleStateField';
6
+ import { clientFacet, fileUriFacet } from './client';
7
+ import { textDocumentField } from './textDocumentSync';
8
+ class DiagnosticsPlugin {
9
+ constructor(view) {
10
+ const client = view.state.facet(clientFacet.reader);
11
+ const fileUri = view.state.facet(fileUriFacet.reader);
12
+ this.handlers = [];
13
+ this.handlers.push(client.onNotification(PublishDiagnosticsNotification.type, (params) => {
14
+ if (params.uri !== fileUri)
15
+ return;
16
+ view.dispatch({
17
+ effects: [
18
+ setLSPDiagnosticsVersion.of(params.version ?? null),
19
+ setLSPDiagnostics.of(params.diagnostics),
20
+ ],
21
+ });
22
+ }));
23
+ }
24
+ destroy() {
25
+ this.handlers.forEach((disposable) => disposable.dispose());
26
+ }
27
+ }
28
+ export const setLSPDiagnosticsVersion = StateEffect.define();
29
+ export const lspDiagnosticsVersionField = simpleStateField(setLSPDiagnosticsVersion, null);
30
+ export const setLSPDiagnostics = StateEffect.define();
31
+ export const lspDiagnosticsField = simpleStateField(setLSPDiagnostics, []);
32
+ export const diagnosticsFacet = Facet.define({
33
+ combine: (values) => values[0],
34
+ });
35
+ export const diagnosticRendererFacet = Facet.define({
36
+ combine: (values) => (values.length > 0 ? values[0] : undefined),
37
+ });
38
+ export const computedCodeMirrorDiagnosticsValueProvider = diagnosticsFacet.compute([textDocumentField, lspDiagnosticsField, lspDiagnosticsVersionField], (state) => {
39
+ const doc = state.field(textDocumentField);
40
+ const lspDiagnosticsVersion = state.field(lspDiagnosticsVersionField);
41
+ // If the diagnostics version and doc version don't match, it means
42
+ // the diagnostics are stale.
43
+ if (lspDiagnosticsVersion !== doc.version) {
44
+ return [];
45
+ }
46
+ const lspDiagnostics = state.field(lspDiagnosticsField);
47
+ const diagnosticRenderer = state.facet(diagnosticRendererFacet.reader);
48
+ return lspDiagnostics.map((diagnostic) => lspToCodeMirrorDiagnostic(diagnostic, doc, diagnosticRenderer));
49
+ });
50
+ export const diagnosticsLinter = (overrides) => linter((view) => {
51
+ const diagnostics = view.state.facet(diagnosticsFacet.reader);
52
+ return diagnostics;
53
+ }, {
54
+ delay: 100,
55
+ needsRefresh(update) {
56
+ const currVersion = update.state.field(lspDiagnosticsVersionField);
57
+ const prevVersion = update.startState.field(lspDiagnosticsVersionField);
58
+ // Checking against any kind of changes otherwise the squiggly line disappears!!
59
+ return (update.geometryChanged ||
60
+ update.viewportChanged ||
61
+ update.heightChanged ||
62
+ update.focusChanged ||
63
+ update.docChanged ||
64
+ update.transactions[0]?.reconfigured ||
65
+ prevVersion !== currVersion);
66
+ },
67
+ ...overrides,
68
+ });
69
+ export const diagnosticsPlugin = ViewPlugin.fromClass(DiagnosticsPlugin);
70
+ export const lspLinter = (linterOptions = {}) => [
71
+ textDocumentField,
72
+ lspDiagnosticsField,
73
+ lspDiagnosticsVersionField,
74
+ computedCodeMirrorDiagnosticsValueProvider,
75
+ diagnosticsLinter(linterOptions),
76
+ diagnosticsPlugin,
77
+ ];
78
+ function lspToCodeMirrorSeverity(severity) {
79
+ switch (severity) {
80
+ case LSPSeverity.Error: {
81
+ return 'error';
82
+ }
83
+ case LSPSeverity.Warning: {
84
+ return 'warning';
85
+ }
86
+ case LSPSeverity.Hint:
87
+ case LSPSeverity.Information:
88
+ default: {
89
+ return 'info';
90
+ }
91
+ }
92
+ }
93
+ function lspToCodeMirrorDiagnostic(lspDiagnostic, textDocument, diagnosticRenderer) {
94
+ const { range, message, severity } = lspDiagnostic;
95
+ const { start, end } = range;
96
+ return {
97
+ from: textDocument.offsetAt(start),
98
+ to: textDocument.offsetAt(end),
99
+ message,
100
+ severity: lspToCodeMirrorSeverity(severity),
101
+ renderMessage: diagnosticRenderer ? () => diagnosticRenderer(lspDiagnostic) : undefined,
102
+ };
103
+ }
104
+ //# sourceMappingURL=lspLinter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lspLinter.js","sourceRoot":"","sources":["../../../src/extensions/lspLinter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,141 @@
1
+ // @vitest-environment jsdom
2
+ import { expect, describe, it, beforeEach, afterEach } from 'vitest';
3
+ import { EditorState } from '@codemirror/state';
4
+ import { EditorView } from '@codemirror/view';
5
+ import { diagnosticsFacet, lspLinter } from './lspLinter';
6
+ import { clientFacet, fileUriFacet } from './client';
7
+ import { MockClient } from '../test/MockClient';
8
+ import { DiagnosticSeverity, PublishDiagnosticsNotification } from 'vscode-languageserver-protocol';
9
+ describe('Module: lspLinter', () => {
10
+ const fileUri = 'browser://input.liquid';
11
+ let client;
12
+ let extensions;
13
+ let view;
14
+ beforeEach(() => {
15
+ client = new MockClient();
16
+ extensions = [clientFacet.of(client), fileUriFacet.of(fileUri), lspLinter()];
17
+ view = new EditorView({
18
+ state: EditorState.create({
19
+ doc: 'hello world',
20
+ extensions,
21
+ }),
22
+ });
23
+ });
24
+ afterEach(() => {
25
+ view.destroy();
26
+ });
27
+ describe('When it receives up to date diagnostics from the server', () => {
28
+ beforeEach(async () => {
29
+ client.triggerNotification(PublishDiagnosticsNotification.type, {
30
+ uri: fileUri,
31
+ version: 0,
32
+ diagnostics: [
33
+ {
34
+ message: 'hello not accepted',
35
+ severity: DiagnosticSeverity.Error,
36
+ range: {
37
+ start: {
38
+ line: 0,
39
+ character: 0,
40
+ },
41
+ end: {
42
+ line: 0,
43
+ character: 'hello'.length,
44
+ },
45
+ },
46
+ },
47
+ ],
48
+ });
49
+ });
50
+ it('should make them available in the diagnosticState', () => {
51
+ const codeMirrorDiagnostics = view.state.facet(diagnosticsFacet.reader);
52
+ expect(codeMirrorDiagnostics).to.have.lengthOf(1);
53
+ const expectedDiagnostic = {
54
+ from: 0,
55
+ to: 'hello'.length,
56
+ message: 'hello not accepted',
57
+ renderMessage: undefined,
58
+ severity: 'error',
59
+ };
60
+ expect(codeMirrorDiagnostics[0]).to.eql(expectedDiagnostic);
61
+ });
62
+ });
63
+ describe('When it receives out of date diagnostics from the server', () => {
64
+ beforeEach(async () => {
65
+ // Here we dispatch a doc change, this internally increments the
66
+ // version value of the textDocument by 1.
67
+ view.dispatch(view.state.update({
68
+ changes: {
69
+ from: 0,
70
+ to: 'hello world'.indexOf(' '),
71
+ insert: 'hi',
72
+ },
73
+ }));
74
+ // Here we dispatch a set of diagnostics for the old state
75
+ client.triggerNotification(PublishDiagnosticsNotification.type, {
76
+ uri: fileUri,
77
+ version: 0, // Note: since the file was modified, those diagnostics are out of date
78
+ diagnostics: [
79
+ {
80
+ message: 'hello not accepted',
81
+ severity: DiagnosticSeverity.Error,
82
+ range: {
83
+ start: {
84
+ line: 0,
85
+ character: 0,
86
+ },
87
+ end: {
88
+ line: 0,
89
+ character: 'hello'.length,
90
+ },
91
+ },
92
+ },
93
+ ],
94
+ });
95
+ });
96
+ it('should discard the stale diagnostics', () => {
97
+ const codeMirrorDiagnostics = view.state.facet(diagnosticsFacet.reader);
98
+ expect(codeMirrorDiagnostics).to.have.lengthOf(0);
99
+ });
100
+ });
101
+ describe('When it changes the document and the diagnostics are suddenly stale', () => {
102
+ beforeEach(async () => {
103
+ // Here we dispatch a set of diagnostics for the state, they are up to date
104
+ client.triggerNotification(PublishDiagnosticsNotification.type, {
105
+ uri: fileUri,
106
+ version: 0,
107
+ diagnostics: [
108
+ {
109
+ message: 'hello not accepted',
110
+ severity: DiagnosticSeverity.Error,
111
+ range: {
112
+ start: {
113
+ line: 0,
114
+ character: 0,
115
+ },
116
+ end: {
117
+ line: 0,
118
+ character: 'hello'.length,
119
+ },
120
+ },
121
+ },
122
+ ],
123
+ });
124
+ // Here we dispatch a doc change. This internally increments the
125
+ // version value of the textDocument by 1. The diagnostics are now
126
+ // stale.
127
+ view.dispatch(view.state.update({
128
+ changes: {
129
+ from: 0,
130
+ to: 'hello world'.indexOf(' '),
131
+ insert: 'hi',
132
+ },
133
+ }));
134
+ });
135
+ it('should discard the stale diagnostics', () => {
136
+ const codeMirrorDiagnostics = view.state.facet(diagnosticsFacet.reader);
137
+ expect(codeMirrorDiagnostics).to.have.lengthOf(0);
138
+ });
139
+ });
140
+ });
141
+ //# sourceMappingURL=lspLinter.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lspLinter.spec.js","sourceRoot":"","sources":["../../../src/extensions/lspLinter.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Syntax is $1, ${2}, ${3:foo}, $0
3
+ * https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#snippet_syntax
4
+ */
5
+ export type LSPSnippet = string;
6
+ /**
7
+ * Syntax is ${placeholder} or ${1:placeholder} or #{} or ${}
8
+ * https://codemirror.net/docs/ref/#autocomplete.snippet
9
+ */
10
+ export type CodeMirrorSnippet = string;
11
+ /**
12
+ * This function takes a snippet from the language server and transforms it
13
+ * into the format that CodeMirror expects.
14
+ *
15
+ * There are small nuances w.r.t. $0 but that shouldn't be too much of a
16
+ * problem. ($0 is the "end" cursor position in LSP, CM doesn't have that... so
17
+ * we convert $0 to ${99} :D)
18
+ */
19
+ export declare function translateSnippet(snippet: LSPSnippet): CodeMirrorSnippet;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * This function takes a snippet from the language server and transforms it
3
+ * into the format that CodeMirror expects.
4
+ *
5
+ * There are small nuances w.r.t. $0 but that shouldn't be too much of a
6
+ * problem. ($0 is the "end" cursor position in LSP, CM doesn't have that... so
7
+ * we convert $0 to ${99} :D)
8
+ */
9
+ export function translateSnippet(snippet) {
10
+ let fixed = snippet.replace(/\$(\d)+/g, (_match, index) => {
11
+ return '${' + (Number(index) === 0 ? '99' : index) + '}';
12
+ });
13
+ // Remove references to other placeholders in placeholders. CodeMirror doesn't
14
+ // support those and it's a PITA to implement differently.
15
+ fixed = fixed.replace(/\$\{(\d+):([^}$]*)(\$\{\d+\})([^}$]*)\}/g, (_match, index, pre, ref, post) => {
16
+ return '${' + index + ':' + pre + post + '}';
17
+ });
18
+ if (fixed.includes('${99}')) {
19
+ return fixed;
20
+ }
21
+ else {
22
+ return fixed + '${99}';
23
+ }
24
+ }
25
+ //# sourceMappingURL=snippet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snippet.js","sourceRoot":"","sources":["../../../src/extensions/snippet.ts"],"names":[],"mappings":"AAcA;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAmB;IAClD,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACxD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,0DAA0D;IAC1D,KAAK,GAAG,KAAK,CAAC,OAAO,CACnB,0CAA0C,EAC1C,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAChC,OAAO,IAAI,GAAG,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;IAC/C,CAAC,CACF,CAAC;IAEF,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,GAAG,OAAO,CAAC;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { translateSnippet } from './snippet';
3
+ describe('Module: snippets', () => {
4
+ describe('Unit: translateSnippet', () => {
5
+ it('translate $0 to $99', () => {
6
+ expect(translateSnippet('$0')).to.equal('${99}');
7
+ });
8
+ it('handles $1, $2, $3 propertly', () => {
9
+ expect(translateSnippet('def $1, $2, $3, $0 end')).to.equal('def ${1}, ${2}, ${3}, ${99} end');
10
+ });
11
+ it('handles placeholders properly', () => {
12
+ expect(translateSnippet('def ${1:hi}, ${2:hi}, $0 end')).to.equal('def ${1:hi}, ${2:hi}, ${99} end');
13
+ });
14
+ it('appends $99 at the end of the string if $0 is not present', () => {
15
+ expect(translateSnippet('def $1 end')).to.equal('def ${1} end${99}');
16
+ });
17
+ // CodeMirror doesn't support VS Code's ${2:$1} syntax, so we gotta do something about it.
18
+ it('applies a fallback strategy when placeholders refer to other placeholders', () => {
19
+ expect(translateSnippet('${1:hi} ${2:oh$1no}')).to.equal('${1:hi} ${2:ohno}${99}');
20
+ });
21
+ });
22
+ });
23
+ //# sourceMappingURL=snippet.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snippet.spec.js","sourceRoot":"","sources":["../../../src/extensions/snippet.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CACzD,iCAAiC,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAC/D,iCAAiC,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,0FAA0F;QAC1F,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;YACnF,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACrF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { TextDocument } from 'vscode-languageserver-textdocument';
2
+ import { Extension, StateField } from '@codemirror/state';
3
+ export declare const textDocumentField: StateField<TextDocument>;
4
+ export declare const textDocumentSync: Extension;
@@ -0,0 +1,109 @@
1
+ import { TextDocument } from 'vscode-languageserver-textdocument';
2
+ import { DidChangeTextDocumentNotification, DidCloseTextDocumentNotification, DidOpenTextDocumentNotification, } from 'vscode-languageserver-protocol';
3
+ import { StateField } from '@codemirror/state';
4
+ import { ViewPlugin } from '@codemirror/view';
5
+ import { clientFacet, fileUriFacet } from './client';
6
+ class TextDocumentSyncPlugin {
7
+ constructor(view) {
8
+ const doc = view.state.field(textDocumentField);
9
+ this.client = view.state.facet(clientFacet);
10
+ this.uri = doc.uri;
11
+ this.openFile(doc);
12
+ }
13
+ update(update) {
14
+ const doc = update.state.field(textDocumentField);
15
+ const prevFileUri = update.startState.facet(fileUriFacet.reader);
16
+ const currFileUri = update.state.facet(fileUriFacet.reader);
17
+ if (prevFileUri !== currFileUri) {
18
+ this.closeFile(prevFileUri);
19
+ this.openFile(doc);
20
+ this.uri = currFileUri;
21
+ }
22
+ else if (update.docChanged) {
23
+ this.changeFile(doc);
24
+ }
25
+ }
26
+ destroy() {
27
+ this.closeFile(this.uri);
28
+ }
29
+ openFile(doc) {
30
+ // Here we initialize the state in the Language Server by sending a
31
+ // textDocument/didOpen notification.
32
+ this.client.sendNotification(DidOpenTextDocumentNotification.type, {
33
+ textDocument: {
34
+ uri: doc.uri,
35
+ version: doc.version,
36
+ languageId: doc.languageId,
37
+ text: doc.getText(),
38
+ },
39
+ });
40
+ }
41
+ changeFile(doc) {
42
+ // Here we send the textDocument/didChange notification to the server
43
+ // to tell it the file was modified. The version attribute is used to
44
+ // verify if the server and client are in sync (if the versions don't
45
+ // match, they aren't).
46
+ this.client.sendNotification(DidChangeTextDocumentNotification.type, {
47
+ textDocument: {
48
+ uri: doc.uri,
49
+ version: doc.version,
50
+ },
51
+ contentChanges: [
52
+ {
53
+ text: doc.getText(),
54
+ },
55
+ ],
56
+ });
57
+ }
58
+ closeFile(uri) {
59
+ this.client.sendNotification(DidCloseTextDocumentNotification.type, {
60
+ textDocument: {
61
+ uri,
62
+ },
63
+ });
64
+ }
65
+ }
66
+ export const textDocumentField = StateField.define({
67
+ create(state) {
68
+ const fileUri = state.facet(fileUriFacet.reader);
69
+ const version = 0;
70
+ return TextDocument.create(fileUri, languageId(fileUri), version, state.doc.sliceString(0, state.doc.length));
71
+ },
72
+ update(previousValue, tr) {
73
+ const prevFileUri = tr.startState.facet(fileUriFacet.reader);
74
+ const currFileUri = tr.state.facet(fileUriFacet.reader);
75
+ const isNewFile = prevFileUri !== currFileUri;
76
+ const doc = tr.newDoc;
77
+ if (isNewFile) {
78
+ const version = 0;
79
+ return TextDocument.create(currFileUri, languageId(currFileUri), version, doc.sliceString(0, doc.length));
80
+ }
81
+ else if (tr.docChanged) {
82
+ return TextDocument.create(previousValue.uri, previousValue.languageId, previousValue.version + 1, doc.sliceString(0, doc.length));
83
+ }
84
+ return previousValue;
85
+ },
86
+ });
87
+ const textDocumentSyncPlugin = ViewPlugin.fromClass(TextDocumentSyncPlugin);
88
+ // Implicitly depends on the fileUriFacet and clientFacet...
89
+ // Don't know how that's typically handled yet...
90
+ export const textDocumentSync = [textDocumentField, textDocumentSyncPlugin];
91
+ function languageId(uri) {
92
+ const lowerCased = uri.toLowerCase();
93
+ if (lowerCased.endsWith('.liquid')) {
94
+ return 'liquid';
95
+ }
96
+ else if (lowerCased.endsWith('.graphql')) {
97
+ return 'graphql';
98
+ }
99
+ else if (lowerCased.endsWith('.js')) {
100
+ return 'javascript';
101
+ }
102
+ else if (lowerCased.endsWith('.css')) {
103
+ return 'css';
104
+ }
105
+ else {
106
+ return 'unknown';
107
+ }
108
+ }
109
+ //# sourceMappingURL=textDocumentSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textDocumentSync.js","sourceRoot":"","sources":["../../../src/extensions/textDocumentSync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};