@platformos/codemirror-language-client 0.0.7 → 0.0.8

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 (124) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/esm/CodeMirrorLanguageClient.d.ts +60 -0
  3. package/dist/esm/CodeMirrorLanguageClient.js +80 -0
  4. package/dist/esm/CodeMirrorLanguageClient.js.map +1 -0
  5. package/dist/esm/LanguageClient.d.ts +112 -0
  6. package/dist/esm/LanguageClient.js +187 -0
  7. package/dist/esm/LanguageClient.js.map +1 -0
  8. package/dist/esm/extensions/client.d.ts +6 -0
  9. package/dist/esm/extensions/client.js +12 -0
  10. package/dist/esm/extensions/client.js.map +1 -0
  11. package/dist/esm/extensions/complete.d.ts +17 -0
  12. package/dist/esm/extensions/complete.js +202 -0
  13. package/dist/esm/extensions/complete.js.map +1 -0
  14. package/dist/esm/extensions/complete.spec.js +189 -0
  15. package/dist/esm/extensions/complete.spec.js.map +1 -0
  16. package/dist/esm/extensions/documentHighlights.d.ts +14 -0
  17. package/dist/esm/extensions/documentHighlights.js +78 -0
  18. package/dist/esm/extensions/documentHighlights.js.map +1 -0
  19. package/dist/esm/extensions/documentHighlights.spec.d.ts +1 -0
  20. package/dist/esm/extensions/documentHighlights.spec.js +99 -0
  21. package/dist/esm/extensions/documentHighlights.spec.js.map +1 -0
  22. package/dist/esm/extensions/hover.d.ts +18 -0
  23. package/dist/esm/extensions/hover.js +49 -0
  24. package/dist/esm/extensions/hover.js.map +1 -0
  25. package/dist/esm/extensions/hover.spec.d.ts +1 -0
  26. package/dist/esm/extensions/hover.spec.js +59 -0
  27. package/dist/esm/extensions/hover.spec.js.map +1 -0
  28. package/dist/esm/extensions/index.d.ts +6 -0
  29. package/dist/esm/extensions/index.js +7 -0
  30. package/dist/esm/extensions/index.js.map +1 -0
  31. package/dist/esm/extensions/lspLinter.d.ts +23 -0
  32. package/dist/esm/extensions/lspLinter.js +104 -0
  33. package/dist/esm/extensions/lspLinter.js.map +1 -0
  34. package/dist/esm/extensions/lspLinter.spec.d.ts +1 -0
  35. package/dist/esm/extensions/lspLinter.spec.js +141 -0
  36. package/dist/esm/extensions/lspLinter.spec.js.map +1 -0
  37. package/dist/esm/extensions/snippet.d.ts +19 -0
  38. package/dist/esm/extensions/snippet.js +25 -0
  39. package/dist/esm/extensions/snippet.js.map +1 -0
  40. package/dist/esm/extensions/snippet.spec.d.ts +1 -0
  41. package/dist/esm/extensions/snippet.spec.js +23 -0
  42. package/dist/esm/extensions/snippet.spec.js.map +1 -0
  43. package/dist/esm/extensions/textDocumentSync.d.ts +4 -0
  44. package/dist/esm/extensions/textDocumentSync.js +109 -0
  45. package/dist/esm/extensions/textDocumentSync.js.map +1 -0
  46. package/dist/esm/extensions/textDocumentSync.spec.d.ts +1 -0
  47. package/dist/esm/extensions/textDocumentSync.spec.js +163 -0
  48. package/dist/esm/extensions/textDocumentSync.spec.js.map +1 -0
  49. package/dist/esm/index.d.ts +2 -0
  50. package/dist/esm/index.js +3 -0
  51. package/dist/esm/index.js.map +1 -0
  52. package/dist/esm/test/MockClient.d.ts +18 -0
  53. package/dist/esm/test/MockClient.js +63 -0
  54. package/dist/esm/test/MockClient.js.map +1 -0
  55. package/dist/esm/tsconfig.tsbuildInfo +1 -0
  56. package/dist/esm/utils/simpleStateField.d.ts +3 -0
  57. package/dist/esm/utils/simpleStateField.js +17 -0
  58. package/dist/esm/utils/simpleStateField.js.map +1 -0
  59. package/dist/umd/CodeMirrorLanguageClient.d.ts +60 -0
  60. package/dist/umd/CodeMirrorLanguageClient.js +94 -0
  61. package/dist/umd/CodeMirrorLanguageClient.js.map +1 -0
  62. package/dist/umd/LanguageClient.d.ts +112 -0
  63. package/dist/umd/LanguageClient.js +202 -0
  64. package/dist/umd/LanguageClient.js.map +1 -0
  65. package/dist/umd/extensions/client.d.ts +6 -0
  66. package/dist/umd/extensions/client.js +25 -0
  67. package/dist/umd/extensions/client.js.map +1 -0
  68. package/dist/umd/extensions/complete.d.ts +17 -0
  69. package/dist/umd/extensions/complete.js +217 -0
  70. package/dist/umd/extensions/complete.js.map +1 -0
  71. package/dist/umd/extensions/documentHighlights.d.ts +14 -0
  72. package/dist/umd/extensions/documentHighlights.js +93 -0
  73. package/dist/umd/extensions/documentHighlights.js.map +1 -0
  74. package/dist/umd/extensions/hover.d.ts +18 -0
  75. package/dist/umd/extensions/hover.js +64 -0
  76. package/dist/umd/extensions/hover.js.map +1 -0
  77. package/dist/umd/extensions/index.d.ts +6 -0
  78. package/dist/umd/extensions/index.js +36 -0
  79. package/dist/umd/extensions/index.js.map +1 -0
  80. package/dist/umd/extensions/lspLinter.d.ts +23 -0
  81. package/dist/umd/extensions/lspLinter.js +119 -0
  82. package/dist/umd/extensions/lspLinter.js.map +1 -0
  83. package/dist/umd/extensions/snippet.d.ts +19 -0
  84. package/dist/umd/extensions/snippet.js +38 -0
  85. package/dist/umd/extensions/snippet.js.map +1 -0
  86. package/dist/umd/extensions/textDocumentSync.d.ts +4 -0
  87. package/dist/umd/extensions/textDocumentSync.js +122 -0
  88. package/dist/umd/extensions/textDocumentSync.js.map +1 -0
  89. package/dist/umd/index.d.ts +2 -0
  90. package/dist/umd/index.js +29 -0
  91. package/dist/umd/index.js.map +1 -0
  92. package/dist/umd/test/MockClient.d.ts +18 -0
  93. package/dist/umd/test/MockClient.js +77 -0
  94. package/dist/umd/test/MockClient.js.map +1 -0
  95. package/dist/umd/tsconfig.tsbuildInfo +1 -0
  96. package/dist/umd/utils/simpleStateField.d.ts +3 -0
  97. package/dist/umd/utils/simpleStateField.js +30 -0
  98. package/dist/umd/utils/simpleStateField.js.map +1 -0
  99. package/package.json +4 -4
  100. package/playground/src/index.html +2 -2
  101. package/playground/src/language-server-worker.ts +1 -5
  102. package/playground/src/playground.ts +65 -77
  103. package/playground/webpack.config.js +1 -3
  104. package/playground/dist/c79446f35d8df82b1201.7baf47407c339642d100.hot-update.json +0 -1
  105. package/playground/dist/c79446f35d8df82b1201.7e0989b9d82d407d3fa3.hot-update.json +0 -1
  106. package/playground/dist/index.html +0 -10
  107. package/playground/dist/language-server-worker.d.ts +0 -12
  108. package/playground/dist/main.7baf47407c339642d100.hot-update.js +0 -29
  109. package/playground/dist/main.7baf47407c339642d100.hot-update.js.map +0 -1
  110. package/playground/dist/main.7baf47407c339642d100.hot-update.json +0 -1
  111. package/playground/dist/main.7e0989b9d82d407d3fa3.hot-update.js +0 -29
  112. package/playground/dist/main.7e0989b9d82d407d3fa3.hot-update.js.map +0 -1
  113. package/playground/dist/main.7e0989b9d82d407d3fa3.hot-update.json +0 -1
  114. package/playground/dist/main.bundle.js +0 -59960
  115. package/playground/dist/main.bundle.js.map +0 -1
  116. package/playground/dist/src_language-server-worker_ts.7baf47407c339642d100.hot-update.js +0 -11
  117. package/playground/dist/src_language-server-worker_ts.7baf47407c339642d100.hot-update.js.map +0 -1
  118. package/playground/dist/src_language-server-worker_ts.7e0989b9d82d407d3fa3.hot-update.js +0 -11
  119. package/playground/dist/src_language-server-worker_ts.7e0989b9d82d407d3fa3.hot-update.js.map +0 -1
  120. package/playground/dist/src_language-server-worker_ts.bundle.js +0 -27934
  121. package/playground/dist/src_language-server-worker_ts.bundle.js.map +0 -1
  122. package/playground/dist/vendors-node_modules_cross-fetch_dist_browser-ponyfill_js-node_modules_line-column_lib_line-c-6a6d49.bundle.js +0 -100265
  123. package/playground/dist/vendors-node_modules_cross-fetch_dist_browser-ponyfill_js-node_modules_line-column_lib_line-c-6a6d49.bundle.js.map +0 -1
  124. /package/{playground/dist/playground.d.ts → dist/esm/extensions/complete.spec.d.ts} +0 -0
@@ -0,0 +1,202 @@
1
+ import { autocompletion, pickedCompletion, snippet, } from '@codemirror/autocomplete';
2
+ import { CompletionItemKind, CompletionRequest, InsertTextFormat, InsertReplaceEdit, TextEdit, CompletionTriggerKind, } from 'vscode-languageserver-protocol';
3
+ import { clientFacet, fileUriFacet, serverCapabilitiesFacet } from './client';
4
+ import { textDocumentField } from './textDocumentSync';
5
+ import { Facet } from '@codemirror/state';
6
+ import { translateSnippet } from './snippet';
7
+ export const lspComplete = (overrides = {}) => autocompletion({
8
+ activateOnTyping: true,
9
+ override: [complete],
10
+ maxRenderedOptions: 20,
11
+ ...overrides,
12
+ });
13
+ export const infoRendererFacet = Facet.define({
14
+ static: true,
15
+ combine: (values) => values[0] ?? undefined,
16
+ });
17
+ export async function complete(context) {
18
+ const word = context.matchBefore(/\w+/);
19
+ const serverCapabilities = context.state.facet(serverCapabilitiesFacet.reader);
20
+ const triggerCharacters = serverCapabilities.completionProvider?.triggerCharacters ?? [];
21
+ const previousChar = context.state.doc.sliceString(context.pos - 1, context.pos);
22
+ const isTriggerCharacter = triggerCharacters.includes(previousChar);
23
+ const canComplete = isTriggerCharacter || word || context.pos === 0;
24
+ if (!canComplete)
25
+ return null;
26
+ const client = context.state.facet(clientFacet.reader);
27
+ const fileUri = context.state.facet(fileUriFacet.reader);
28
+ const infoRenderer = context.state.facet(infoRendererFacet.reader);
29
+ const textDocument = context.state.field(textDocumentField);
30
+ const lspContext = isTriggerCharacter
31
+ ? { triggerKind: CompletionTriggerKind.TriggerCharacter, triggerCharacter: previousChar }
32
+ : { triggerKind: CompletionTriggerKind.Invoked };
33
+ const results = await client.sendRequest(CompletionRequest.type, {
34
+ textDocument: { uri: fileUri },
35
+ position: textDocument.positionAt(context.pos),
36
+ context: lspContext,
37
+ });
38
+ // No results
39
+ if (results === null || (Array.isArray(results) && results.length === 0))
40
+ return null;
41
+ return {
42
+ from: word?.from ?? context.pos,
43
+ options: items(results).map(toCodeMirrorCompletion(infoRenderer, textDocument)),
44
+ };
45
+ }
46
+ const toCodeMirrorCompletion = (infoRenderer, textDocument) => (completionItem) => {
47
+ switch (completionItem.insertTextFormat) {
48
+ case InsertTextFormat.Snippet:
49
+ return {
50
+ label: completionItem.insertText ?? completionItem.label,
51
+ displayLabel: completionItem.label,
52
+ apply: applySnippet(completionItem, textDocument),
53
+ type: convertLSPKindToCodeMirrorKind(completionItem.kind),
54
+ info: infoRenderer ? (_) => infoRenderer(completionItem) : undefined,
55
+ };
56
+ case InsertTextFormat.PlainText:
57
+ default: {
58
+ return {
59
+ label: completionItem.insertText ?? completionItem.label,
60
+ displayLabel: completionItem.label,
61
+ apply: hasApplicableTextEdit(completionItem)
62
+ ? (view, completion) => applyEdit(view, completion, completionItem, textDocument)
63
+ : undefined,
64
+ type: convertLSPKindToCodeMirrorKind(completionItem.kind),
65
+ info: infoRenderer ? (_) => infoRenderer(completionItem) : undefined,
66
+ };
67
+ }
68
+ }
69
+ };
70
+ function hasApplicableTextEdit(completionItem) {
71
+ return (!!completionItem.textEdit &&
72
+ (TextEdit.is(completionItem.textEdit) || InsertReplaceEdit.is(completionItem.textEdit)));
73
+ }
74
+ const applySnippet = (item, textDocument) => {
75
+ const { textEdit } = item;
76
+ let from = null;
77
+ let to = null;
78
+ let newText = '';
79
+ if (TextEdit.is(textEdit)) {
80
+ from = textDocument.offsetAt(textEdit.range.start);
81
+ to = textDocument.offsetAt(textEdit.range.end);
82
+ newText = textEdit.newText;
83
+ }
84
+ else if (textEdit && InsertReplaceEdit.is(textEdit)) {
85
+ from = textDocument.offsetAt(textEdit.replace.start);
86
+ to = textDocument.offsetAt(textEdit.replace.end);
87
+ newText = textEdit.newText;
88
+ }
89
+ else if (item.insertText) {
90
+ newText = item.insertText;
91
+ }
92
+ else {
93
+ newText = item.label;
94
+ }
95
+ const template = translateSnippet(newText);
96
+ // Because we might replace text with textEdit, we can't use snippet as is.
97
+ // we'll need to infer the from/to from the textEdit.
98
+ const apply = snippet(template);
99
+ return (view, completion, defaultFrom, defaultTo) => {
100
+ apply(view, completion, from ?? defaultFrom, to ?? defaultTo);
101
+ };
102
+ };
103
+ var CMCompletionType;
104
+ (function (CMCompletionType) {
105
+ CMCompletionType["Class"] = "class";
106
+ CMCompletionType["Constant"] = "constant";
107
+ CMCompletionType["Enum"] = "enum";
108
+ CMCompletionType["Function"] = "function";
109
+ CMCompletionType["Interface"] = "interface";
110
+ CMCompletionType["Keyword"] = "keyword";
111
+ CMCompletionType["Method"] = "method";
112
+ CMCompletionType["Namespace"] = "namespace";
113
+ CMCompletionType["Property"] = "property";
114
+ CMCompletionType["Text"] = "text";
115
+ CMCompletionType["Type"] = "type";
116
+ CMCompletionType["Variable"] = "variable";
117
+ })(CMCompletionType || (CMCompletionType = {}));
118
+ function convertLSPKindToCodeMirrorKind(kind) {
119
+ if (!kind)
120
+ return CMCompletionType.Text;
121
+ switch (kind) {
122
+ case CompletionItemKind.Constructor:
123
+ case CompletionItemKind.Class:
124
+ return CMCompletionType.Class;
125
+ case CompletionItemKind.Constant:
126
+ return CMCompletionType.Constant;
127
+ case CompletionItemKind.Enum:
128
+ case CompletionItemKind.EnumMember:
129
+ return CMCompletionType.Enum;
130
+ case CompletionItemKind.Snippet:
131
+ case CompletionItemKind.Function:
132
+ return CMCompletionType.Function;
133
+ case CompletionItemKind.Interface:
134
+ return CMCompletionType.Interface;
135
+ case CompletionItemKind.Operator:
136
+ case CompletionItemKind.Keyword:
137
+ return CMCompletionType.Keyword;
138
+ case CompletionItemKind.Method:
139
+ return CMCompletionType.Method;
140
+ case CompletionItemKind.File:
141
+ case CompletionItemKind.Folder:
142
+ case CompletionItemKind.Module:
143
+ return CMCompletionType.Namespace;
144
+ case CompletionItemKind.Property:
145
+ case CompletionItemKind.Reference:
146
+ case CompletionItemKind.Field:
147
+ return CMCompletionType.Property;
148
+ case CompletionItemKind.Struct:
149
+ case CompletionItemKind.TypeParameter:
150
+ return CMCompletionType.Type;
151
+ case CompletionItemKind.Event:
152
+ case CompletionItemKind.Value:
153
+ case CompletionItemKind.Variable:
154
+ return CMCompletionType.Variable;
155
+ case CompletionItemKind.Color:
156
+ case CompletionItemKind.Unit:
157
+ case CompletionItemKind.Text:
158
+ default:
159
+ return CMCompletionType.Text;
160
+ }
161
+ }
162
+ function applyEdit(view, completion, item, textDocument) {
163
+ const { textEdit } = item;
164
+ let start = 0;
165
+ let end = 0;
166
+ let newText = '';
167
+ if (TextEdit.is(textEdit)) {
168
+ start = textDocument.offsetAt(textEdit.range.start);
169
+ end = textDocument.offsetAt(textEdit.range.end);
170
+ newText = textEdit.newText;
171
+ }
172
+ else if (InsertReplaceEdit.is(textEdit)) {
173
+ start = textDocument.offsetAt(textEdit.replace.start);
174
+ end = textDocument.offsetAt(textEdit.replace.end);
175
+ newText = textEdit.newText;
176
+ }
177
+ view.dispatch({
178
+ // Tell the completion engine which item we chose
179
+ annotations: [pickedCompletion.of(completion)],
180
+ // Move cursor to after the text
181
+ selection: { anchor: start + newText.length, head: start + newText.length },
182
+ // Apply the text edit
183
+ changes: view.state.changes({
184
+ from: start,
185
+ to: end,
186
+ insert: newText,
187
+ }),
188
+ });
189
+ }
190
+ function isCompletionList(results) {
191
+ return results.isIncomplete !== undefined;
192
+ }
193
+ function items(results) {
194
+ if (isCompletionList(results)) {
195
+ return results.items.map((item) => ({
196
+ ...results.itemDefaults,
197
+ ...item,
198
+ }));
199
+ }
200
+ return results;
201
+ }
202
+ //# sourceMappingURL=complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.js","sourceRoot":"","sources":["../../../src/extensions/complete.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAId,gBAAgB,EAEhB,OAAO,GACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,kBAAkB,EAElB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,qBAAqB,GAEtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAK7C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,YAAiC,EAAE,EAAE,EAAE,CACjE,cAAc,CAAC;IACb,gBAAgB,EAAE,IAAI;IACtB,QAAQ,EAAE,CAAC,QAAQ,CAAC;IACpB,kBAAkB,EAAE,EAAE;IACtB,GAAG,SAAS;CACb,CAAC,CAAC;AAWL,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAqD;IAChG,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS;CAC5C,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAA0B;IACvD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC/E,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,kBAAkB,EAAE,iBAAiB,IAAI,EAAE,CAAC;IACzF,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACjF,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACpE,MAAM,WAAW,GAAG,kBAAkB,IAAI,IAAI,IAAI,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IACpE,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAE5D,MAAM,UAAU,GAAyB,kBAAkB;QACzD,CAAC,CAAC,EAAE,WAAW,EAAE,qBAAqB,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,YAAY,EAAE;QACzF,CAAC,CAAC,EAAE,WAAW,EAAE,qBAAqB,CAAC,OAAO,EAAE,CAAC;IAEnD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAC/D,YAAY,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;QAC9B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC;QAC9C,OAAO,EAAE,UAAU;KACpB,CAAC,CAAC;IAEH,aAAa;IACb,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtF,OAAO;QACL,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,CAAC,GAAG;QAC/B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;KAChF,CAAC;AACJ,CAAC;AAED,MAAM,sBAAsB,GAC1B,CAAC,YAAsC,EAAE,YAA0B,EAAE,EAAE,CACvE,CAAC,cAA8B,EAAc,EAAE;IAC7C,QAAQ,cAAc,CAAC,gBAAgB,EAAE,CAAC;QACxC,KAAK,gBAAgB,CAAC,OAAO;YAC3B,OAAO;gBACL,KAAK,EAAE,cAAc,CAAC,UAAU,IAAI,cAAc,CAAC,KAAK;gBACxD,YAAY,EAAE,cAAc,CAAC,KAAK;gBAClC,KAAK,EAAE,YAAY,CAAC,cAAuC,EAAE,YAAY,CAAC;gBAC1E,IAAI,EAAE,8BAA8B,CAAC,cAAc,CAAC,IAAI,CAAC;gBACzD,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;aACrE,CAAC;QAEJ,KAAK,gBAAgB,CAAC,SAAS,CAAC;QAChC,OAAO,CAAC,CAAC,CAAC;YACR,OAAO;gBACL,KAAK,EAAE,cAAc,CAAC,UAAU,IAAI,cAAc,CAAC,KAAK;gBACxD,YAAY,EAAE,cAAc,CAAC,KAAK;gBAClC,KAAK,EAAE,qBAAqB,CAAC,cAAc,CAAC;oBAC1C,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,CAAC;oBACjF,CAAC,CAAC,SAAS;gBACb,IAAI,EAAE,8BAA8B,CAAC,cAAc,CAAC,IAAI,CAAC;gBACzD,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;aACrE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEJ,SAAS,qBAAqB,CAC5B,cAA8B;IAE9B,OAAO,CACL,CAAC,CAAC,cAAc,CAAC,QAAQ;QACzB,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CACxF,CAAC;AACJ,CAAC;AAMD,MAAM,YAAY,GAAG,CAAC,IAA2B,EAAE,YAA0B,EAAE,EAAE;IAC/E,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAC1B,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,EAAE,GAAkB,IAAI,CAAC;IAC7B,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,IAAI,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnD,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC7B,CAAC;SAAM,IAAI,QAAQ,IAAI,iBAAiB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrD,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC7B,CAAC;SAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;IACvB,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE3C,2EAA2E;IAC3E,qDAAqD;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,IAAgB,EAAE,UAAsB,EAAE,WAAmB,EAAE,SAAiB,EAAE,EAAE;QAC1F,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,IAAI,WAAW,EAAE,EAAE,IAAI,SAAS,CAAC,CAAC;IAChE,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,IAAK,gBAaJ;AAbD,WAAK,gBAAgB;IACnB,mCAAe,CAAA;IACf,yCAAqB,CAAA;IACrB,iCAAa,CAAA;IACb,yCAAqB,CAAA;IACrB,2CAAuB,CAAA;IACvB,uCAAmB,CAAA;IACnB,qCAAiB,CAAA;IACjB,2CAAuB,CAAA;IACvB,yCAAqB,CAAA;IACrB,iCAAa,CAAA;IACb,iCAAa,CAAA;IACb,yCAAqB,CAAA;AACvB,CAAC,EAbI,gBAAgB,KAAhB,gBAAgB,QAapB;AAED,SAAS,8BAA8B,CAAC,IAAoC;IAC1E,IAAI,CAAC,IAAI;QAAE,OAAO,gBAAgB,CAAC,IAAI,CAAC;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,kBAAkB,CAAC,WAAW,CAAC;QACpC,KAAK,kBAAkB,CAAC,KAAK;YAC3B,OAAO,gBAAgB,CAAC,KAAK,CAAC;QAEhC,KAAK,kBAAkB,CAAC,QAAQ;YAC9B,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QAEnC,KAAK,kBAAkB,CAAC,IAAI,CAAC;QAC7B,KAAK,kBAAkB,CAAC,UAAU;YAChC,OAAO,gBAAgB,CAAC,IAAI,CAAC;QAE/B,KAAK,kBAAkB,CAAC,OAAO,CAAC;QAChC,KAAK,kBAAkB,CAAC,QAAQ;YAC9B,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QAEnC,KAAK,kBAAkB,CAAC,SAAS;YAC/B,OAAO,gBAAgB,CAAC,SAAS,CAAC;QAEpC,KAAK,kBAAkB,CAAC,QAAQ,CAAC;QACjC,KAAK,kBAAkB,CAAC,OAAO;YAC7B,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAElC,KAAK,kBAAkB,CAAC,MAAM;YAC5B,OAAO,gBAAgB,CAAC,MAAM,CAAC;QAEjC,KAAK,kBAAkB,CAAC,IAAI,CAAC;QAC7B,KAAK,kBAAkB,CAAC,MAAM,CAAC;QAC/B,KAAK,kBAAkB,CAAC,MAAM;YAC5B,OAAO,gBAAgB,CAAC,SAAS,CAAC;QAEpC,KAAK,kBAAkB,CAAC,QAAQ,CAAC;QACjC,KAAK,kBAAkB,CAAC,SAAS,CAAC;QAClC,KAAK,kBAAkB,CAAC,KAAK;YAC3B,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QAEnC,KAAK,kBAAkB,CAAC,MAAM,CAAC;QAC/B,KAAK,kBAAkB,CAAC,aAAa;YACnC,OAAO,gBAAgB,CAAC,IAAI,CAAC;QAE/B,KAAK,kBAAkB,CAAC,KAAK,CAAC;QAC9B,KAAK,kBAAkB,CAAC,KAAK,CAAC;QAC9B,KAAK,kBAAkB,CAAC,QAAQ;YAC9B,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QAEnC,KAAK,kBAAkB,CAAC,KAAK,CAAC;QAC9B,KAAK,kBAAkB,CAAC,IAAI,CAAC;QAC7B,KAAK,kBAAkB,CAAC,IAAI,CAAC;QAC7B;YACE,OAAO,gBAAgB,CAAC,IAAI,CAAC;IACjC,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAChB,IAAgB,EAChB,UAAsB,EACtB,IAA4E,EAC5E,YAA0B;IAE1B,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,IAAI,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpD,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChD,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC7B,CAAC;SAAM,IAAI,iBAAiB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACtD,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC;QACZ,iDAAiD;QACjD,WAAW,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QAC9C,gCAAgC;QAChC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE;QAC3E,sBAAsB;QACtB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAC1B,IAAI,EAAE,KAAK;YACX,EAAE,EAAE,GAAG;YACP,MAAM,EAAE,OAAO;SAChB,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA0C;IAClE,OAAQ,OAA0B,CAAC,YAAY,KAAK,SAAS,CAAC;AAChE,CAAC;AAED,SAAS,KAAK,CAAC,OAA0C;IACvD,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,OAAQ,OAA0B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtD,GAAG,OAAO,CAAC,YAAY;YACvB,GAAG,IAAI;SACR,CAAC,CAAC,CAAC;IACN,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,189 @@
1
+ import { vi, expect, describe, it, beforeEach, assert } from 'vitest';
2
+ import { EditorState } from '@codemirror/state';
3
+ import { CompletionContext } from '@codemirror/autocomplete';
4
+ import { clientFacet, fileUriFacet, serverCapabilitiesFacet } from './client';
5
+ import { MockClient } from '../test/MockClient';
6
+ import { CompletionItemKind } from 'vscode-languageserver-protocol';
7
+ import { textDocumentSync } from './textDocumentSync';
8
+ import { complete, infoRendererFacet, lspComplete } from './complete';
9
+ describe('Module: complete', () => {
10
+ const fileUri = 'browser://input.liquid';
11
+ let client;
12
+ let state;
13
+ let infoRenderer;
14
+ let doc;
15
+ beforeEach(() => {
16
+ doc = 'hello. ;';
17
+ client = new MockClient();
18
+ infoRenderer = vi.fn().mockReturnValue(null);
19
+ state = EditorState.create({
20
+ doc,
21
+ extensions: [
22
+ clientFacet.of(client),
23
+ serverCapabilitiesFacet.of({
24
+ completionProvider: {
25
+ triggerCharacters: ['.'],
26
+ },
27
+ }),
28
+ fileUriFacet.of(fileUri),
29
+ textDocumentSync,
30
+ infoRendererFacet.of(infoRenderer),
31
+ lspComplete(),
32
+ ],
33
+ });
34
+ });
35
+ it('should translate LSP completion responses into CodeMirror completion items', async () => {
36
+ const context = new CompletionContext(state, /* does not matter for mock test */ 0, true);
37
+ const promise = complete(context);
38
+ client.resolveRequest([
39
+ {
40
+ label: 'hello | world',
41
+ insertText: 'hello',
42
+ kind: CompletionItemKind.Text,
43
+ },
44
+ {
45
+ label: 'echo',
46
+ kind: CompletionItemKind.Function,
47
+ documentation: {
48
+ kind: 'markdown',
49
+ value: '### echo',
50
+ },
51
+ },
52
+ {
53
+ label: '"general.greeting" | t',
54
+ insertText: 'greeting',
55
+ textEdit: {
56
+ newText: '"general.greeting" | t',
57
+ range: {
58
+ start: { line: 0, character: 0 },
59
+ end: { line: 0, character: 3 },
60
+ },
61
+ },
62
+ kind: CompletionItemKind.Function,
63
+ documentation: {
64
+ kind: 'markdown',
65
+ value: '### echo',
66
+ },
67
+ },
68
+ ]);
69
+ const results = await promise;
70
+ expect(results).toEqual({
71
+ from: 0,
72
+ options: [
73
+ {
74
+ label: 'hello',
75
+ displayLabel: 'hello | world',
76
+ type: 'text',
77
+ info: expect.any(Function),
78
+ apply: undefined,
79
+ },
80
+ {
81
+ label: 'echo',
82
+ displayLabel: 'echo',
83
+ type: 'function',
84
+ info: expect.any(Function),
85
+ apply: undefined,
86
+ },
87
+ {
88
+ displayLabel: '"general.greeting" | t',
89
+ label: 'greeting',
90
+ type: 'function',
91
+ info: expect.any(Function),
92
+ apply: expect.any(Function),
93
+ },
94
+ ],
95
+ });
96
+ });
97
+ it('should translate LSP completion list responses into CodeMirror completion items', async () => {
98
+ const context = new CompletionContext(state, /* does not matter for mock test */ 0, true);
99
+ const promise = complete(context);
100
+ client.resolveRequest({
101
+ isIncomplete: false,
102
+ items: [
103
+ {
104
+ label: 'hello | world',
105
+ insertText: 'hello',
106
+ kind: CompletionItemKind.Text,
107
+ },
108
+ {
109
+ label: 'echo',
110
+ kind: CompletionItemKind.Function,
111
+ documentation: {
112
+ kind: 'markdown',
113
+ value: '### echo',
114
+ },
115
+ },
116
+ {
117
+ label: '"general.greeting" | t',
118
+ insertText: 'greeting',
119
+ textEdit: {
120
+ newText: '"general.greeting" | t',
121
+ range: {
122
+ start: { line: 0, character: 0 },
123
+ end: { line: 0, character: 3 },
124
+ },
125
+ },
126
+ kind: CompletionItemKind.Function,
127
+ documentation: {
128
+ kind: 'markdown',
129
+ value: '### echo',
130
+ },
131
+ },
132
+ ],
133
+ });
134
+ const results = await promise;
135
+ expect(results).toEqual({
136
+ from: 0,
137
+ options: [
138
+ {
139
+ label: 'hello',
140
+ displayLabel: 'hello | world',
141
+ type: 'text',
142
+ info: expect.any(Function),
143
+ apply: undefined,
144
+ },
145
+ {
146
+ label: 'echo',
147
+ displayLabel: 'echo',
148
+ type: 'function',
149
+ info: expect.any(Function),
150
+ apply: undefined,
151
+ },
152
+ {
153
+ displayLabel: '"general.greeting" | t',
154
+ label: 'greeting',
155
+ type: 'function',
156
+ info: expect.any(Function),
157
+ apply: expect.any(Function),
158
+ },
159
+ ],
160
+ });
161
+ });
162
+ it('should return null if not on a trigger character nor inside a word', async () => {
163
+ const context = new CompletionContext(state, doc.indexOf(';'), true);
164
+ const promise = complete(context);
165
+ assert(!client.pendingRequest);
166
+ const result = await promise;
167
+ expect(result).to.be.null;
168
+ });
169
+ it('should make a request to the backend if after a trigger character', async () => {
170
+ const context = new CompletionContext(state, doc.indexOf('.') + 1, true);
171
+ complete(context);
172
+ assert(client.pendingRequest);
173
+ client.resolveRequest(null);
174
+ });
175
+ it('should make a request to the backend if after a word character', async () => {
176
+ const context = new CompletionContext(state, doc.indexOf('h') + 1, true);
177
+ complete(context);
178
+ assert(client.pendingRequest);
179
+ client.resolveRequest(null);
180
+ });
181
+ it('should return null if nothing comes back', async () => {
182
+ const context = new CompletionContext(state, /* does not matter for mock test */ 0, true);
183
+ const promise = complete(context);
184
+ client.resolveRequest(null);
185
+ const results = await promise;
186
+ expect(results).to.eql(null);
187
+ });
188
+ });
189
+ //# sourceMappingURL=complete.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.spec.js","sourceRoot":"","sources":["../../../src/extensions/complete.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * This extension requests LSP Document Highlights [1] when the user types or
3
+ * change its code selection.
4
+ *
5
+ * Those are then transformed into CodeMirror decorations and applied to the editor.
6
+ *
7
+ * [1]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentHighlight
8
+ */
9
+ import { Extension } from '@codemirror/state';
10
+ import { Decoration, DecorationSet, EditorView } from '@codemirror/view';
11
+ export declare const documentHighlightsClass = "cmlc-document-highlights";
12
+ export declare const highlightDeco: Decoration;
13
+ export declare function getDecorations(view: EditorView): Promise<DecorationSet>;
14
+ export declare function lspDocumentHighlights(): Extension;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * This extension requests LSP Document Highlights [1] when the user types or
3
+ * change its code selection.
4
+ *
5
+ * Those are then transformed into CodeMirror decorations and applied to the editor.
6
+ *
7
+ * [1]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentHighlight
8
+ */
9
+ import { Prec, StateEffect, StateField } from '@codemirror/state';
10
+ import { Decoration, EditorView } from '@codemirror/view';
11
+ import { DocumentHighlightRequest } from 'vscode-languageserver-protocol';
12
+ import { clientFacet, fileUriFacet } from './client';
13
+ import { textDocumentField } from './textDocumentSync';
14
+ // We will use this CSS class to decorate all document highlights
15
+ export const documentHighlightsClass = 'cmlc-document-highlights';
16
+ export const highlightDeco = Decoration.mark({ class: documentHighlightsClass });
17
+ const highlightStyles = Prec.low(EditorView.theme({
18
+ [`.${documentHighlightsClass}`]: {
19
+ // Set background color to a light gray that matches a subtle highlight on
20
+ // a light theme
21
+ 'background-color': 'rgba(0,0,0,0.1)',
22
+ },
23
+ }));
24
+ const setDocumentHighlights = StateEffect.define();
25
+ const documentHighlightsStateField = StateField.define({
26
+ create: () => Decoration.none,
27
+ update(value, tr) {
28
+ let updatedValue = value;
29
+ for (const effect of tr.effects) {
30
+ if (effect.is(setDocumentHighlights)) {
31
+ updatedValue = effect.value;
32
+ }
33
+ }
34
+ return updatedValue;
35
+ },
36
+ // This is some CM obscure API shit that registers this state field
37
+ // into the CM state and makes it so CM will show the decorations
38
+ provide: (f) => EditorView.decorations.from(f),
39
+ });
40
+ export async function getDecorations(view) {
41
+ const client = view.state.facet(clientFacet.reader);
42
+ const uri = view.state.facet(fileUriFacet.reader);
43
+ const textDocument = view.state.field(textDocumentField);
44
+ // If the client doesn't support those requests, don't ask for them.
45
+ if (!client.serverCapabilities?.documentHighlightProvider) {
46
+ return Decoration.none;
47
+ }
48
+ const results = await client.sendRequest(DocumentHighlightRequest.type, {
49
+ textDocument: { uri },
50
+ position: textDocument.positionAt(view.state.selection.main.from),
51
+ });
52
+ if (!results) {
53
+ return Decoration.none;
54
+ }
55
+ const decorations = results
56
+ .map((highlight) => ({
57
+ from: textDocument.offsetAt(highlight.range.start),
58
+ to: textDocument.offsetAt(highlight.range.end),
59
+ }))
60
+ .sort((a, b) => a.from - b.from) // CM wants them sorted ascending or else it freaks out
61
+ .map(({ from, to }) => highlightDeco.range(from, to));
62
+ return Decoration.set(decorations);
63
+ }
64
+ export function lspDocumentHighlights() {
65
+ const decorationHandler = EditorView.updateListener.of((update) => {
66
+ // We only want to query the language server for document highlights
67
+ // the document has changed or the selection has moved
68
+ if (update.docChanged || update.selectionSet) {
69
+ getDecorations(update.view).then((deco) => {
70
+ update.view.dispatch({
71
+ effects: setDocumentHighlights.of(deco),
72
+ });
73
+ });
74
+ }
75
+ });
76
+ return [documentHighlightsStateField, decorationHandler, highlightStyles];
77
+ }
78
+ //# sourceMappingURL=documentHighlights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentHighlights.js","sourceRoot":"","sources":["../../../src/extensions/documentHighlights.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,99 @@
1
+ // @vitest-environment jsdom
2
+ import { EditorState } from '@codemirror/state';
3
+ import { Decoration, EditorView } from '@codemirror/view';
4
+ import { beforeEach, describe, expect, it } from 'vitest';
5
+ import { MockClient } from '../test/MockClient';
6
+ import { clientFacet, fileUriFacet } from './client';
7
+ import { getDecorations, highlightDeco, lspDocumentHighlights } from './documentHighlights';
8
+ import { textDocumentSync } from './textDocumentSync';
9
+ describe('Module: documentHighlights', () => {
10
+ const fileUri = 'browser://input.liquid';
11
+ let client;
12
+ let extensions;
13
+ let view;
14
+ let hoverRenderer;
15
+ beforeEach(() => {
16
+ client = new MockClient({}, { documentHighlightProvider: true });
17
+ extensions = [
18
+ clientFacet.of(client),
19
+ fileUriFacet.of(fileUri),
20
+ textDocumentSync,
21
+ lspDocumentHighlights(),
22
+ ];
23
+ view = new EditorView({
24
+ state: EditorState.create({
25
+ doc: 'hello world',
26
+ extensions,
27
+ }),
28
+ });
29
+ });
30
+ it('should translate LSP Document Highlights into a CodeMirror DecorationSet', async () => {
31
+ const promise = getDecorations(view);
32
+ const highlightsResponse = [
33
+ {
34
+ range: {
35
+ start: { line: 0, character: 0 },
36
+ end: { line: 0, character: 5 },
37
+ },
38
+ },
39
+ ];
40
+ client.resolveRequest(highlightsResponse);
41
+ const result = await promise;
42
+ const actual = toArray(result);
43
+ const expected = toArray(Decoration.set([highlightDeco.range(0, 5)]));
44
+ expect(actual).to.eql(expected);
45
+ });
46
+ it('should sort the decorations', async () => {
47
+ const promise = getDecorations(view);
48
+ const highlightsResponse = [
49
+ {
50
+ range: {
51
+ start: { line: 0, character: 5 },
52
+ end: { line: 0, character: 10 },
53
+ },
54
+ },
55
+ {
56
+ range: {
57
+ start: { line: 0, character: 0 },
58
+ end: { line: 0, character: 5 },
59
+ },
60
+ },
61
+ ];
62
+ client.resolveRequest(highlightsResponse);
63
+ const result = await promise;
64
+ expect(toArray(result)).to.eql(toArray(Decoration.set([highlightDeco.range(0, 5), highlightDeco.range(5, 10)])));
65
+ });
66
+ it('should return a Decoration.none DecorationSet', async () => {
67
+ const promise = getDecorations(view);
68
+ client.resolveRequest(null);
69
+ const result = await promise;
70
+ expect(toArray(result)).to.eql(toArray(Decoration.none));
71
+ });
72
+ /**
73
+ * I wish CM didn't think that their implementation of iterators was better
74
+ * than the built-in one. Makes testing that stuff really hard for what seems
75
+ * like an obscure reason.
76
+ *
77
+ * > A range cursor is an object that moves to the next range every time you
78
+ * > call next on it. Note that, unlike ES6 iterators, these start out pointing
79
+ * > at the first element, so you should call next only after reading the first
80
+ * > range (if any).
81
+ *
82
+ * Also, RangeSet.eq doesn't seem to work. Which is why I decided to take this
83
+ * approach.
84
+ */
85
+ function* toIterator(decoSet) {
86
+ let iter = decoSet.iter();
87
+ if (iter.value === null) {
88
+ return;
89
+ }
90
+ do {
91
+ yield { from: iter.from, to: iter.to, value: iter.value };
92
+ iter.next();
93
+ } while (iter.value !== null);
94
+ }
95
+ function toArray(decoSet) {
96
+ return Array.from(toIterator(decoSet));
97
+ }
98
+ });
99
+ //# sourceMappingURL=documentHighlights.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentHighlights.spec.js","sourceRoot":"","sources":["../../../src/extensions/documentHighlights.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { Hover } from 'vscode-languageserver-protocol';
2
+ import { Facet } from '@codemirror/state';
3
+ import { EditorView, Tooltip, TooltipView, hoverTooltip } from '@codemirror/view';
4
+ type SecondArgType<F> = F extends (_: any, arg: infer A) => any ? A : never;
5
+ export type HoverOptions = Partial<SecondArgType<typeof hoverTooltip>>;
6
+ /**
7
+ * A HoverRenderer would be equivalent to the Hover window in VS Code. It
8
+ * shows the documentation for the symbol under the cursor.
9
+ *
10
+ * Takes a LSP Hover as argument and must return a TooltipView (type {} and autocomplete for required params).
11
+ */
12
+ export type HoverRenderer = (view: EditorView, hover: Hover) => TooltipView;
13
+ export declare const hoverRendererFacet: Facet<HoverRenderer | undefined, HoverRenderer | undefined>;
14
+ export declare const lspHover: (overrides?: HoverOptions) => import("@codemirror/state").Extension & {
15
+ active: import("@codemirror/state").StateField<readonly Tooltip[]>;
16
+ };
17
+ export declare function hover(view: EditorView, pos: number, _side: -1 | 1): Promise<Tooltip | null>;
18
+ export {};