@difizen/libro-language-client 0.1.18

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 (298) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/es/common/api.d.ts +38 -0
  4. package/es/common/api.d.ts.map +1 -0
  5. package/es/common/api.js +9 -0
  6. package/es/common/callHierarchy.d.ts +39 -0
  7. package/es/common/callHierarchy.d.ts.map +1 -0
  8. package/es/common/callHierarchy.js +139 -0
  9. package/es/common/client.d.ts +482 -0
  10. package/es/common/client.d.ts.map +1 -0
  11. package/es/common/client.js +2731 -0
  12. package/es/common/codeAction.d.ts +22 -0
  13. package/es/common/codeAction.d.ts.map +1 -0
  14. package/es/common/codeAction.js +149 -0
  15. package/es/common/codeConverter.d.ts +81 -0
  16. package/es/common/codeConverter.d.ts.map +1 -0
  17. package/es/common/codeConverter.js +1040 -0
  18. package/es/common/codeLens.d.ts +26 -0
  19. package/es/common/codeLens.d.ts.map +1 -0
  20. package/es/common/codeLens.js +125 -0
  21. package/es/common/colorProvider.d.ts +27 -0
  22. package/es/common/colorProvider.d.ts.map +1 -0
  23. package/es/common/colorProvider.js +104 -0
  24. package/es/common/completion.d.ts +22 -0
  25. package/es/common/completion.d.ts.map +1 -0
  26. package/es/common/completion.js +130 -0
  27. package/es/common/configuration.d.ts +71 -0
  28. package/es/common/configuration.d.ts.map +1 -0
  29. package/es/common/configuration.js +292 -0
  30. package/es/common/declaration.d.ts +18 -0
  31. package/es/common/declaration.d.ts.map +1 -0
  32. package/es/common/declaration.js +88 -0
  33. package/es/common/definition.d.ts +18 -0
  34. package/es/common/definition.d.ts.map +1 -0
  35. package/es/common/definition.js +80 -0
  36. package/es/common/diagnostic.d.ts +125 -0
  37. package/es/common/diagnostic.d.ts.map +1 -0
  38. package/es/common/diagnostic.js +1442 -0
  39. package/es/common/documentHighlight.d.ts +17 -0
  40. package/es/common/documentHighlight.d.ts.map +1 -0
  41. package/es/common/documentHighlight.js +73 -0
  42. package/es/common/documentLink.d.ts +21 -0
  43. package/es/common/documentLink.d.ts.map +1 -0
  44. package/es/common/documentLink.js +90 -0
  45. package/es/common/documentSymbol.d.ts +20 -0
  46. package/es/common/documentSymbol.d.ts.map +1 -0
  47. package/es/common/documentSymbol.js +134 -0
  48. package/es/common/executeCommand.d.ts +22 -0
  49. package/es/common/executeCommand.d.ts.map +1 -0
  50. package/es/common/executeCommand.js +117 -0
  51. package/es/common/features.d.ts +421 -0
  52. package/es/common/features.d.ts.map +1 -0
  53. package/es/common/features.js +576 -0
  54. package/es/common/fileOperations.d.ts +118 -0
  55. package/es/common/fileOperations.d.ts.map +1 -0
  56. package/es/common/fileOperations.js +705 -0
  57. package/es/common/fileSystemWatcher.d.ts +19 -0
  58. package/es/common/fileSystemWatcher.d.ts.map +1 -0
  59. package/es/common/fileSystemWatcher.js +173 -0
  60. package/es/common/foldingRange.d.ts +22 -0
  61. package/es/common/foldingRange.d.ts.map +1 -0
  62. package/es/common/foldingRange.js +127 -0
  63. package/es/common/formatting.d.ts +41 -0
  64. package/es/common/formatting.d.ts.map +1 -0
  65. package/es/common/formatting.js +233 -0
  66. package/es/common/hover.d.ts +18 -0
  67. package/es/common/hover.d.ts.map +1 -0
  68. package/es/common/hover.js +80 -0
  69. package/es/common/implementation.d.ts +18 -0
  70. package/es/common/implementation.d.ts.map +1 -0
  71. package/es/common/implementation.js +88 -0
  72. package/es/common/inlayHint.d.ts +23 -0
  73. package/es/common/inlayHint.d.ts.map +1 -0
  74. package/es/common/inlayHint.js +187 -0
  75. package/es/common/inlineCompletion.d.ts +20 -0
  76. package/es/common/inlineCompletion.d.ts.map +1 -0
  77. package/es/common/inlineCompletion.js +74 -0
  78. package/es/common/inlineValue.d.ts +21 -0
  79. package/es/common/inlineValue.d.ts.map +1 -0
  80. package/es/common/inlineValue.js +124 -0
  81. package/es/common/linkedEditingRange.d.ts +23 -0
  82. package/es/common/linkedEditingRange.d.ts.map +1 -0
  83. package/es/common/linkedEditingRange.js +94 -0
  84. package/es/common/notebook.d.ts +97 -0
  85. package/es/common/notebook.d.ts.map +1 -0
  86. package/es/common/notebook.js +1444 -0
  87. package/es/common/progress.d.ts +12 -0
  88. package/es/common/progress.d.ts.map +1 -0
  89. package/es/common/progress.js +75 -0
  90. package/es/common/progressPart.d.ts +25 -0
  91. package/es/common/progressPart.d.ts.map +1 -0
  92. package/es/common/progressPart.js +147 -0
  93. package/es/common/protocolCallHierarchyItem.d.ts +9 -0
  94. package/es/common/protocolCallHierarchyItem.d.ts.map +1 -0
  95. package/es/common/protocolCallHierarchyItem.js +34 -0
  96. package/es/common/protocolCodeAction.d.ts +7 -0
  97. package/es/common/protocolCodeAction.d.ts.map +1 -0
  98. package/es/common/protocolCodeAction.js +32 -0
  99. package/es/common/protocolCodeLens.d.ts +7 -0
  100. package/es/common/protocolCodeLens.d.ts.map +1 -0
  101. package/es/common/protocolCodeLens.js +29 -0
  102. package/es/common/protocolCompletionItem.d.ts +13 -0
  103. package/es/common/protocolCompletionItem.d.ts.map +1 -0
  104. package/es/common/protocolCompletionItem.js +29 -0
  105. package/es/common/protocolConverter.d.ts +174 -0
  106. package/es/common/protocolConverter.d.ts.map +1 -0
  107. package/es/common/protocolConverter.js +1982 -0
  108. package/es/common/protocolDiagnostic.d.ts +20 -0
  109. package/es/common/protocolDiagnostic.d.ts.map +1 -0
  110. package/es/common/protocolDiagnostic.js +46 -0
  111. package/es/common/protocolDocumentLink.d.ts +8 -0
  112. package/es/common/protocolDocumentLink.d.ts.map +1 -0
  113. package/es/common/protocolDocumentLink.js +29 -0
  114. package/es/common/protocolInlayHint.d.ts +8 -0
  115. package/es/common/protocolInlayHint.d.ts.map +1 -0
  116. package/es/common/protocolInlayHint.js +29 -0
  117. package/es/common/protocolTypeHierarchyItem.d.ts +9 -0
  118. package/es/common/protocolTypeHierarchyItem.d.ts.map +1 -0
  119. package/es/common/protocolTypeHierarchyItem.js +34 -0
  120. package/es/common/protocolWorkspaceSymbol.d.ts +9 -0
  121. package/es/common/protocolWorkspaceSymbol.d.ts.map +1 -0
  122. package/es/common/protocolWorkspaceSymbol.js +36 -0
  123. package/es/common/reference.d.ts +22 -0
  124. package/es/common/reference.d.ts.map +1 -0
  125. package/es/common/reference.js +78 -0
  126. package/es/common/rename.d.ts +29 -0
  127. package/es/common/rename.d.ts.map +1 -0
  128. package/es/common/rename.js +132 -0
  129. package/es/common/selectionRange.d.ts +18 -0
  130. package/es/common/selectionRange.d.ts.map +1 -0
  131. package/es/common/selectionRange.js +108 -0
  132. package/es/common/semanticTokens.d.ts +36 -0
  133. package/es/common/semanticTokens.d.ts.map +1 -0
  134. package/es/common/semanticTokens.js +226 -0
  135. package/es/common/signatureHelp.d.ts +18 -0
  136. package/es/common/signatureHelp.d.ts.map +1 -0
  137. package/es/common/signatureHelp.js +103 -0
  138. package/es/common/textSynchronization.d.ts +104 -0
  139. package/es/common/textSynchronization.d.ts.map +1 -0
  140. package/es/common/textSynchronization.js +771 -0
  141. package/es/common/typeDefinition.d.ts +18 -0
  142. package/es/common/typeDefinition.d.ts.map +1 -0
  143. package/es/common/typeDefinition.js +89 -0
  144. package/es/common/typeHierarchy.d.ts +33 -0
  145. package/es/common/typeHierarchy.d.ts.map +1 -0
  146. package/es/common/typeHierarchy.js +138 -0
  147. package/es/common/utils/async.d.ts +42 -0
  148. package/es/common/utils/async.d.ts.map +1 -0
  149. package/es/common/utils/async.js +441 -0
  150. package/es/common/utils/is.d.ts +13 -0
  151. package/es/common/utils/is.d.ts.map +1 -0
  152. package/es/common/utils/is.js +52 -0
  153. package/es/common/utils/uuid.d.ts +23 -0
  154. package/es/common/utils/uuid.d.ts.map +1 -0
  155. package/es/common/utils/uuid.js +85 -0
  156. package/es/common/vscodeAdaptor/convertor.d.ts +7 -0
  157. package/es/common/vscodeAdaptor/convertor.d.ts.map +1 -0
  158. package/es/common/vscodeAdaptor/convertor.js +66 -0
  159. package/es/common/vscodeAdaptor/diagnosticCollection.d.ts +33 -0
  160. package/es/common/vscodeAdaptor/diagnosticCollection.d.ts.map +1 -0
  161. package/es/common/vscodeAdaptor/diagnosticCollection.js +310 -0
  162. package/es/common/vscodeAdaptor/extHostTypes.d.ts +1496 -0
  163. package/es/common/vscodeAdaptor/extHostTypes.d.ts.map +1 -0
  164. package/es/common/vscodeAdaptor/extHostTypes.js +3825 -0
  165. package/es/common/vscodeAdaptor/fileWatcher.d.ts +19 -0
  166. package/es/common/vscodeAdaptor/fileWatcher.d.ts.map +1 -0
  167. package/es/common/vscodeAdaptor/fileWatcher.js +45 -0
  168. package/es/common/vscodeAdaptor/hostTypeUtil.d.ts +192 -0
  169. package/es/common/vscodeAdaptor/hostTypeUtil.d.ts.map +1 -0
  170. package/es/common/vscodeAdaptor/hostTypeUtil.js +566 -0
  171. package/es/common/vscodeAdaptor/libro-fs.d.ts +21 -0
  172. package/es/common/vscodeAdaptor/libro-fs.d.ts.map +1 -0
  173. package/es/common/vscodeAdaptor/libro-fs.js +64 -0
  174. package/es/common/vscodeAdaptor/libroWindow.d.ts +21 -0
  175. package/es/common/vscodeAdaptor/libroWindow.d.ts.map +1 -0
  176. package/es/common/vscodeAdaptor/libroWindow.js +75 -0
  177. package/es/common/vscodeAdaptor/libroWorkspace.d.ts +33 -0
  178. package/es/common/vscodeAdaptor/libroWorkspace.d.ts.map +1 -0
  179. package/es/common/vscodeAdaptor/libroWorkspace.js +250 -0
  180. package/es/common/vscodeAdaptor/lspEnv.d.ts +8 -0
  181. package/es/common/vscodeAdaptor/lspEnv.d.ts.map +1 -0
  182. package/es/common/vscodeAdaptor/lspEnv.js +31 -0
  183. package/es/common/vscodeAdaptor/monaco-converter.d.ts +229 -0
  184. package/es/common/vscodeAdaptor/monaco-converter.d.ts.map +1 -0
  185. package/es/common/vscodeAdaptor/monaco-converter.js +1613 -0
  186. package/es/common/vscodeAdaptor/monacoLanguages.d.ts +48 -0
  187. package/es/common/vscodeAdaptor/monacoLanguages.d.ts.map +1 -0
  188. package/es/common/vscodeAdaptor/monacoLanguages.js +484 -0
  189. package/es/common/vscodeAdaptor/services.d.ts +85 -0
  190. package/es/common/vscodeAdaptor/services.d.ts.map +1 -0
  191. package/es/common/vscodeAdaptor/services.js +3 -0
  192. package/es/common/vscodeAdaptor/typings.d.ts +10 -0
  193. package/es/common/vscodeAdaptor/util.d.ts +3 -0
  194. package/es/common/vscodeAdaptor/util.d.ts.map +1 -0
  195. package/es/common/vscodeAdaptor/util.js +6 -0
  196. package/es/common/vscodeAdaptor/vscodeAdaptor.d.ts +77 -0
  197. package/es/common/vscodeAdaptor/vscodeAdaptor.d.ts.map +1 -0
  198. package/es/common/vscodeAdaptor/vscodeAdaptor.js +124 -0
  199. package/es/common/workspaceFolder.d.ts +32 -0
  200. package/es/common/workspaceFolder.d.ts.map +1 -0
  201. package/es/common/workspaceFolder.js +204 -0
  202. package/es/common/workspaceSymbol.d.ts +21 -0
  203. package/es/common/workspaceSymbol.d.ts.map +1 -0
  204. package/es/common/workspaceSymbol.js +101 -0
  205. package/es/constants.d.ts +2 -0
  206. package/es/constants.d.ts.map +1 -0
  207. package/es/constants.js +1 -0
  208. package/es/index.d.ts +6 -0
  209. package/es/index.d.ts.map +1 -0
  210. package/es/index.js +5 -0
  211. package/es/libro-language-client-contribution.d.ts +10 -0
  212. package/es/libro-language-client-contribution.d.ts.map +1 -0
  213. package/es/libro-language-client-contribution.js +143 -0
  214. package/es/libro-language-client-manager.d.ts +34 -0
  215. package/es/libro-language-client-manager.d.ts.map +1 -0
  216. package/es/libro-language-client-manager.js +277 -0
  217. package/es/libro-language-client.d.ts +27 -0
  218. package/es/libro-language-client.d.ts.map +1 -0
  219. package/es/libro-language-client.js +141 -0
  220. package/es/module.d.ts +3 -0
  221. package/es/module.d.ts.map +1 -0
  222. package/es/module.js +13 -0
  223. package/package.json +69 -0
  224. package/src/common/api.ts +155 -0
  225. package/src/common/callHierarchy.ts +269 -0
  226. package/src/common/client.ts +3192 -0
  227. package/src/common/codeAction.ts +237 -0
  228. package/src/common/codeConverter.ts +1409 -0
  229. package/src/common/codeLens.ts +188 -0
  230. package/src/common/colorProvider.ts +192 -0
  231. package/src/common/completion.ts +281 -0
  232. package/src/common/configuration.ts +338 -0
  233. package/src/common/declaration.ts +140 -0
  234. package/src/common/definition.ts +138 -0
  235. package/src/common/diagnostic.ts +1408 -0
  236. package/src/common/documentHighlight.ts +140 -0
  237. package/src/common/documentLink.ts +180 -0
  238. package/src/common/documentSymbol.ts +186 -0
  239. package/src/common/executeCommand.ts +129 -0
  240. package/src/common/features.ts +1157 -0
  241. package/src/common/fileOperations.ts +635 -0
  242. package/src/common/fileSystemWatcher.ts +184 -0
  243. package/src/common/foldingRange.ts +160 -0
  244. package/src/common/formatting.ts +465 -0
  245. package/src/common/hover.ts +133 -0
  246. package/src/common/implementation.ts +142 -0
  247. package/src/common/inlayHint.ts +201 -0
  248. package/src/common/inlineCompletion.ts +160 -0
  249. package/src/common/inlineValue.ts +158 -0
  250. package/src/common/linkedEditingRange.ts +141 -0
  251. package/src/common/notebook.ts +1443 -0
  252. package/src/common/progress.ts +61 -0
  253. package/src/common/progressPart.ts +151 -0
  254. package/src/common/protocolCallHierarchyItem.ts +29 -0
  255. package/src/common/protocolCodeAction.ts +17 -0
  256. package/src/common/protocolCodeLens.ts +15 -0
  257. package/src/common/protocolCompletionItem.ts +22 -0
  258. package/src/common/protocolConverter.ts +2627 -0
  259. package/src/common/protocolDiagnostic.ts +47 -0
  260. package/src/common/protocolDocumentLink.ts +17 -0
  261. package/src/common/protocolInlayHint.ts +21 -0
  262. package/src/common/protocolTypeHierarchyItem.ts +29 -0
  263. package/src/common/protocolWorkspaceSymbol.ts +39 -0
  264. package/src/common/reference.ts +144 -0
  265. package/src/common/rename.ts +230 -0
  266. package/src/common/selectionRange.ts +136 -0
  267. package/src/common/semanticTokens.ts +383 -0
  268. package/src/common/signatureHelp.ts +170 -0
  269. package/src/common/textSynchronization.ts +819 -0
  270. package/src/common/typeDefinition.ts +146 -0
  271. package/src/common/typeHierarchy.ts +248 -0
  272. package/src/common/utils/async.ts +354 -0
  273. package/src/common/utils/is.ts +63 -0
  274. package/src/common/utils/uuid.ts +136 -0
  275. package/src/common/vscodeAdaptor/convertor.ts +73 -0
  276. package/src/common/vscodeAdaptor/diagnosticCollection.ts +238 -0
  277. package/src/common/vscodeAdaptor/extHostTypes.ts +4498 -0
  278. package/src/common/vscodeAdaptor/fileWatcher.ts +36 -0
  279. package/src/common/vscodeAdaptor/hostTypeUtil.ts +539 -0
  280. package/src/common/vscodeAdaptor/libro-fs.ts +51 -0
  281. package/src/common/vscodeAdaptor/libroWindow.ts +85 -0
  282. package/src/common/vscodeAdaptor/libroWorkspace.ts +261 -0
  283. package/src/common/vscodeAdaptor/lspEnv.ts +16 -0
  284. package/src/common/vscodeAdaptor/monaco-converter.ts +1800 -0
  285. package/src/common/vscodeAdaptor/monacoLanguages.ts +511 -0
  286. package/src/common/vscodeAdaptor/services.ts +278 -0
  287. package/src/common/vscodeAdaptor/typings.d.ts +10 -0
  288. package/src/common/vscodeAdaptor/util.ts +7 -0
  289. package/src/common/vscodeAdaptor/vscodeAdaptor.ts +122 -0
  290. package/src/common/workspaceFolder.ts +236 -0
  291. package/src/common/workspaceSymbol.ts +166 -0
  292. package/src/constants.ts +1 -0
  293. package/src/index.spec.ts +7 -0
  294. package/src/index.ts +5 -0
  295. package/src/libro-language-client-contribution.ts +49 -0
  296. package/src/libro-language-client-manager.ts +131 -0
  297. package/src/libro-language-client.ts +100 -0
  298. package/src/module.ts +19 -0
@@ -0,0 +1,635 @@
1
+ /* --------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ * ------------------------------------------------------------------------------------------ */
5
+
6
+ import * as proto from '@difizen/vscode-languageserver-protocol';
7
+ import * as minimatch from 'minimatch';
8
+ import type {
9
+ Disposable,
10
+ FileCreateEvent,
11
+ FileRenameEvent,
12
+ FileDeleteEvent,
13
+ FileWillCreateEvent,
14
+ FileWillRenameEvent,
15
+ FileWillDeleteEvent,
16
+ Event as VEvent,
17
+ WorkspaceEdit,
18
+ Uri,
19
+ CancellationToken,
20
+ } from 'vscode';
21
+
22
+ import type {
23
+ DynamicFeature,
24
+ RegistrationData,
25
+ NextSignature,
26
+ FeatureState,
27
+ FeatureClient,
28
+ } from './features.js';
29
+ import * as UUID from './utils/uuid.js';
30
+ import { FileType } from './vscodeAdaptor/vscodeAdaptor.js';
31
+ import { workspace } from './vscodeAdaptor/vscodeAdaptor.js';
32
+
33
+ function ensure<T, K extends keyof T>(target: T, key: K): T[K] {
34
+ if (target[key] === void 0) {
35
+ target[key] = {} as any;
36
+ }
37
+ return target[key];
38
+ }
39
+
40
+ function access<T, K extends keyof T>(target: T, key: K): T[K] {
41
+ return target[key];
42
+ }
43
+
44
+ function assign<T, K extends keyof T>(target: T, key: K, value: T[K]): void {
45
+ target[key] = value;
46
+ }
47
+
48
+ /**
49
+ * File operation middleware
50
+ *
51
+ * @since 3.16.0
52
+ */
53
+ export interface FileOperationsMiddleware {
54
+ didCreateFiles?: NextSignature<FileCreateEvent, Promise<void>>;
55
+ willCreateFiles?: NextSignature<
56
+ FileWillCreateEvent,
57
+ Thenable<WorkspaceEdit | null | undefined>
58
+ >;
59
+ didRenameFiles?: NextSignature<FileRenameEvent, Promise<void>>;
60
+ willRenameFiles?: NextSignature<
61
+ FileWillRenameEvent,
62
+ Thenable<WorkspaceEdit | null | undefined>
63
+ >;
64
+ didDeleteFiles?: NextSignature<FileDeleteEvent, Promise<void>>;
65
+ willDeleteFiles?: NextSignature<
66
+ FileWillDeleteEvent,
67
+ Thenable<WorkspaceEdit | null | undefined>
68
+ >;
69
+ }
70
+
71
+ interface FileOperationsWorkspaceMiddleware {
72
+ workspace?: FileOperationsMiddleware;
73
+ }
74
+
75
+ interface Event<I> {
76
+ readonly files: ReadonlyArray<I>;
77
+ }
78
+
79
+ abstract class FileOperationFeature<I, E extends Event<I>>
80
+ implements DynamicFeature<proto.FileOperationRegistrationOptions>
81
+ {
82
+ protected readonly _client: FeatureClient<FileOperationsWorkspaceMiddleware>;
83
+ private readonly _event: VEvent<E>;
84
+ private readonly _registrationType: proto.RegistrationType<proto.FileOperationRegistrationOptions>;
85
+ private readonly _clientCapability: keyof proto.FileOperationClientCapabilities;
86
+ private readonly _serverCapability: keyof proto.FileOperationOptions;
87
+ private _listener: Disposable | undefined;
88
+ // This property must stay private. Otherwise the type `minimatch.IMinimatch` becomes public and as a consequence we would need to
89
+ // ship the d.ts files for minimatch to make the compiler happy when compiling against the vscode-languageclient library
90
+ private readonly _filters: Map<
91
+ string,
92
+ Array<{
93
+ scheme?: string;
94
+ matcher: minimatch.Minimatch;
95
+ kind?: proto.FileOperationPatternKind;
96
+ }>
97
+ >;
98
+
99
+ constructor(
100
+ client: FeatureClient<FileOperationsWorkspaceMiddleware>,
101
+ event: VEvent<E>,
102
+ registrationType: proto.RegistrationType<proto.FileOperationRegistrationOptions>,
103
+ clientCapability: keyof proto.FileOperationClientCapabilities,
104
+ serverCapability: keyof proto.FileOperationOptions,
105
+ ) {
106
+ this._client = client;
107
+ this._event = event;
108
+ this._registrationType = registrationType;
109
+ this._clientCapability = clientCapability;
110
+ this._serverCapability = serverCapability;
111
+ this._filters = new Map();
112
+ }
113
+
114
+ getState(): FeatureState {
115
+ return {
116
+ kind: 'workspace',
117
+ id: this._registrationType.method,
118
+ registrations: this._filters.size > 0,
119
+ };
120
+ }
121
+
122
+ protected filterSize(): number {
123
+ return this._filters.size;
124
+ }
125
+
126
+ public get registrationType(): proto.RegistrationType<proto.FileOperationRegistrationOptions> {
127
+ return this._registrationType;
128
+ }
129
+
130
+ public fillClientCapabilities(capabilities: proto.ClientCapabilities): void {
131
+ const value = ensure(ensure(capabilities, 'workspace')!, 'fileOperations')!;
132
+ // this happens n times but it is the same value so we tolerate this.
133
+ assign(value, 'dynamicRegistration', true);
134
+ assign(value, this._clientCapability, true);
135
+ }
136
+
137
+ public initialize(capabilities: proto.ServerCapabilities): void {
138
+ const options = capabilities.workspace?.fileOperations;
139
+ const capability =
140
+ options !== undefined ? access(options, this._serverCapability) : undefined;
141
+ if (capability?.filters !== undefined) {
142
+ try {
143
+ this.register({
144
+ id: UUID.generateUuid(),
145
+ registerOptions: { filters: capability.filters },
146
+ });
147
+ } catch (e) {
148
+ this._client.warn(
149
+ `Ignoring invalid glob pattern for ${this._serverCapability} registration: ${e}`,
150
+ );
151
+ }
152
+ }
153
+ }
154
+
155
+ public register(
156
+ data: RegistrationData<proto.FileOperationRegistrationOptions>,
157
+ ): void {
158
+ if (!this._listener) {
159
+ this._listener = this._event(this.send, this);
160
+ }
161
+ const minimatchFilter = data.registerOptions.filters.map((filter) => {
162
+ const matcher = new minimatch.Minimatch(
163
+ filter.pattern.glob,
164
+ FileOperationFeature.asMinimatchOptions(filter.pattern.options),
165
+ );
166
+ if (!matcher.makeRe()) {
167
+ throw new Error(`Invalid pattern ${filter.pattern.glob}!`);
168
+ }
169
+ return { scheme: filter.scheme, matcher, kind: filter.pattern.matches };
170
+ });
171
+ this._filters.set(data.id, minimatchFilter);
172
+ }
173
+
174
+ public abstract send(data: E): Promise<void>;
175
+
176
+ public unregister(id: string): void {
177
+ this._filters.delete(id);
178
+ if (this._filters.size === 0 && this._listener) {
179
+ this._listener.dispose();
180
+ this._listener = undefined;
181
+ }
182
+ }
183
+
184
+ public clear(): void {
185
+ this._filters.clear();
186
+ if (this._listener) {
187
+ this._listener.dispose();
188
+ this._listener = undefined;
189
+ }
190
+ }
191
+
192
+ protected getFileType(uri: Uri): Promise<FileType | undefined> {
193
+ return FileOperationFeature.getFileType(uri);
194
+ }
195
+
196
+ protected async filter(event: E, prop: (i: I) => Uri): Promise<E> {
197
+ // (Asynchronously) map each file onto a boolean of whether it matches
198
+ // any of the globs.
199
+ const fileMatches = await Promise.all(
200
+ event.files.map(async (item) => {
201
+ const uri = prop(item);
202
+ // Use fsPath to make this consistent with file system watchers but help
203
+ // minimatch to use '/' instead of `\\` if present.
204
+ const path = uri.fsPath.replace(/\\/g, '/');
205
+ for (const filters of this._filters.values()) {
206
+ for (const filter of filters) {
207
+ if (filter.scheme !== undefined && filter.scheme !== uri.scheme) {
208
+ continue;
209
+ }
210
+ if (filter.matcher.match(path)) {
211
+ // The pattern matches. If kind is undefined then everything is ok
212
+ if (filter.kind === undefined) {
213
+ return true;
214
+ }
215
+ const fileType = await this.getFileType(uri);
216
+ // If we can't determine the file type than we treat it as a match.
217
+ // Dropping it would be another alternative.
218
+ if (fileType === undefined) {
219
+ this._client.error(
220
+ `Failed to determine file type for ${uri.toString()}.`,
221
+ );
222
+ return true;
223
+ }
224
+ if (
225
+ (fileType === FileType.File &&
226
+ filter.kind === proto.FileOperationPatternKind.file) ||
227
+ (fileType === FileType.Directory &&
228
+ filter.kind === proto.FileOperationPatternKind.folder)
229
+ ) {
230
+ return true;
231
+ }
232
+ } else if (filter.kind === proto.FileOperationPatternKind.folder) {
233
+ const fileType = await FileOperationFeature.getFileType(uri);
234
+ if (fileType === FileType.Directory && filter.matcher.match(`${path}/`)) {
235
+ return true;
236
+ }
237
+ }
238
+ }
239
+ }
240
+ return false;
241
+ }),
242
+ );
243
+
244
+ // Filter the files to those that matched.
245
+ const files = event.files.filter((_, index) => fileMatches[index]);
246
+
247
+ return { ...event, files };
248
+ }
249
+
250
+ protected static async getFileType(uri: Uri): Promise<FileType | undefined> {
251
+ try {
252
+ return (await workspace.fs.stat(uri)).type;
253
+ } catch (e) {
254
+ return undefined;
255
+ }
256
+ }
257
+
258
+ private static asMinimatchOptions(
259
+ options: proto.FileOperationPatternOptions | undefined,
260
+ ): minimatch.MinimatchOptions | undefined {
261
+ // The spec doesn't state that dot files don't match. So we make
262
+ // matching those the default.
263
+ const result: minimatch.MinimatchOptions = { dot: true };
264
+ if (options?.ignoreCase === true) {
265
+ result.nocase = true;
266
+ }
267
+ return result;
268
+ }
269
+ }
270
+
271
+ abstract class NotificationFileOperationFeature<
272
+ I,
273
+ E extends { readonly files: ReadonlyArray<I> },
274
+ P,
275
+ > extends FileOperationFeature<I, E> {
276
+ private _notificationType: proto.ProtocolNotificationType<
277
+ P,
278
+ proto.FileOperationRegistrationOptions
279
+ >;
280
+ private _accessUri: (i: I) => Uri;
281
+ private _createParams: (e: E) => P;
282
+
283
+ constructor(
284
+ client: FeatureClient<FileOperationsWorkspaceMiddleware>,
285
+ event: VEvent<E>,
286
+ notificationType: proto.ProtocolNotificationType<
287
+ P,
288
+ proto.FileOperationRegistrationOptions
289
+ >,
290
+ clientCapability: keyof proto.FileOperationClientCapabilities,
291
+ serverCapability: keyof proto.FileOperationOptions,
292
+ accessUri: (i: I) => Uri,
293
+ createParams: (e: E) => P,
294
+ ) {
295
+ super(client, event, notificationType, clientCapability, serverCapability);
296
+ this._notificationType = notificationType;
297
+ this._accessUri = accessUri;
298
+ this._createParams = createParams;
299
+ }
300
+
301
+ public async send(originalEvent: E): Promise<void> {
302
+ // Create a copy of the event that has the files filtered to match what the
303
+ // server wants.
304
+ const filteredEvent = await this.filter(originalEvent, this._accessUri);
305
+ if (filteredEvent.files.length) {
306
+ const next = async (event: E): Promise<void> => {
307
+ return this._client.sendNotification(
308
+ this._notificationType,
309
+ this._createParams(event),
310
+ );
311
+ };
312
+ return this.doSend(filteredEvent, next);
313
+ }
314
+ }
315
+
316
+ protected abstract doSend(event: E, next: (event: E) => Promise<void>): Promise<void>;
317
+ }
318
+
319
+ abstract class CachingNotificationFileOperationFeature<
320
+ I,
321
+ E extends { readonly files: ReadonlyArray<I> },
322
+ P,
323
+ > extends NotificationFileOperationFeature<I, E, P> {
324
+ protected _willListener: Disposable | undefined;
325
+ private readonly _fsPathFileTypes = new Map<string, FileType>();
326
+
327
+ protected override async getFileType(uri: Uri): Promise<FileType | undefined> {
328
+ const fsPath = uri.fsPath;
329
+ if (this._fsPathFileTypes.has(fsPath)) {
330
+ return this._fsPathFileTypes.get(fsPath);
331
+ }
332
+
333
+ const type = await FileOperationFeature.getFileType(uri);
334
+ if (type) {
335
+ this._fsPathFileTypes.set(fsPath, type);
336
+ }
337
+ return type;
338
+ }
339
+
340
+ protected async cacheFileTypes(event: E, prop: (i: I) => Uri) {
341
+ // Calling filter will force the matching logic to run. For any item
342
+ // that requires a getFileType lookup, the overriden getFileType will
343
+ // be called that will cache the result so that when onDidRename fires,
344
+ // it can still be checked even though the item no longer exists on disk
345
+ // in its original location.
346
+ await this.filter(event, prop);
347
+ }
348
+
349
+ protected clearFileTypeCache() {
350
+ this._fsPathFileTypes.clear();
351
+ }
352
+
353
+ public override unregister(id: string): void {
354
+ super.unregister(id);
355
+ if (this.filterSize() === 0 && this._willListener) {
356
+ this._willListener.dispose();
357
+ this._willListener = undefined;
358
+ }
359
+ }
360
+
361
+ public override clear(): void {
362
+ super.clear();
363
+ if (this._willListener) {
364
+ this._willListener.dispose();
365
+ this._willListener = undefined;
366
+ }
367
+ }
368
+ }
369
+
370
+ export class DidCreateFilesFeature extends NotificationFileOperationFeature<
371
+ Uri,
372
+ FileCreateEvent,
373
+ proto.CreateFilesParams
374
+ > {
375
+ constructor(client: FeatureClient<FileOperationsWorkspaceMiddleware>) {
376
+ super(
377
+ client,
378
+ workspace.onDidCreateFiles,
379
+ proto.DidCreateFilesNotification.type,
380
+ 'didCreate',
381
+ 'didCreate',
382
+ (i: Uri) => i,
383
+ client.code2ProtocolConverter.asDidCreateFilesParams,
384
+ );
385
+ }
386
+
387
+ protected doSend(
388
+ event: FileCreateEvent,
389
+ next: (event: FileCreateEvent) => Promise<void>,
390
+ ): Promise<void> {
391
+ const middleware = this._client.middleware.workspace;
392
+ return middleware?.didCreateFiles
393
+ ? middleware.didCreateFiles(event, next)
394
+ : next(event);
395
+ }
396
+ }
397
+
398
+ export class DidRenameFilesFeature extends CachingNotificationFileOperationFeature<
399
+ { oldUri: Uri; newUri: Uri },
400
+ FileRenameEvent,
401
+ proto.RenameFilesParams
402
+ > {
403
+ constructor(client: FeatureClient<FileOperationsWorkspaceMiddleware>) {
404
+ super(
405
+ client,
406
+ workspace.onDidRenameFiles,
407
+ proto.DidRenameFilesNotification.type,
408
+ 'didRename',
409
+ 'didRename',
410
+ (i: { oldUri: Uri; newUri: Uri }) => i.oldUri,
411
+ client.code2ProtocolConverter.asDidRenameFilesParams,
412
+ );
413
+ }
414
+
415
+ public override register(
416
+ data: RegistrationData<proto.FileOperationRegistrationOptions>,
417
+ ): void {
418
+ if (!this._willListener) {
419
+ this._willListener = workspace.onWillRenameFiles(this.willRename, this);
420
+ }
421
+ super.register(data);
422
+ }
423
+
424
+ private willRename(e: FileWillRenameEvent): void {
425
+ e.waitUntil(this.cacheFileTypes(e, (i) => i.oldUri));
426
+ }
427
+
428
+ protected doSend(
429
+ event: FileRenameEvent,
430
+ next: (event: FileRenameEvent) => Promise<void>,
431
+ ): Promise<void> {
432
+ this.clearFileTypeCache();
433
+ const middleware = this._client.middleware.workspace;
434
+ return middleware?.didRenameFiles
435
+ ? middleware.didRenameFiles(event, next)
436
+ : next(event);
437
+ }
438
+ }
439
+
440
+ export class DidDeleteFilesFeature extends CachingNotificationFileOperationFeature<
441
+ Uri,
442
+ FileDeleteEvent,
443
+ proto.DeleteFilesParams
444
+ > {
445
+ constructor(client: FeatureClient<FileOperationsWorkspaceMiddleware>) {
446
+ super(
447
+ client,
448
+ workspace.onDidDeleteFiles,
449
+ proto.DidDeleteFilesNotification.type,
450
+ 'didDelete',
451
+ 'didDelete',
452
+ (i: Uri) => i,
453
+ client.code2ProtocolConverter.asDidDeleteFilesParams,
454
+ );
455
+ }
456
+
457
+ public override register(
458
+ data: RegistrationData<proto.FileOperationRegistrationOptions>,
459
+ ): void {
460
+ if (!this._willListener) {
461
+ this._willListener = workspace.onWillDeleteFiles(this.willDelete, this);
462
+ }
463
+ super.register(data);
464
+ }
465
+
466
+ private willDelete(e: FileWillDeleteEvent): void {
467
+ e.waitUntil(this.cacheFileTypes(e, (i) => i));
468
+ }
469
+
470
+ protected doSend(
471
+ event: FileCreateEvent,
472
+ next: (event: FileCreateEvent) => Promise<void>,
473
+ ): Promise<void> {
474
+ this.clearFileTypeCache();
475
+ const middleware = this._client.middleware.workspace;
476
+ return middleware?.didDeleteFiles
477
+ ? middleware.didDeleteFiles(event, next)
478
+ : next(event);
479
+ }
480
+ }
481
+
482
+ interface RequestEvent<I> {
483
+ readonly token: CancellationToken;
484
+ readonly files: ReadonlyArray<I>;
485
+ waitUntil(thenable: Thenable<WorkspaceEdit>): void;
486
+ waitUntil(thenable: Thenable<any>): void;
487
+ }
488
+
489
+ abstract class RequestFileOperationFeature<
490
+ I,
491
+ E extends RequestEvent<I>,
492
+ P,
493
+ > extends FileOperationFeature<I, E> {
494
+ private _requestType: proto.ProtocolRequestType<
495
+ P,
496
+ proto.WorkspaceEdit | null,
497
+ never,
498
+ void,
499
+ proto.FileOperationRegistrationOptions
500
+ >;
501
+ private _accessUri: (i: I) => Uri;
502
+ private _createParams: (e: Event<I>) => P;
503
+
504
+ constructor(
505
+ client: FeatureClient<FileOperationsWorkspaceMiddleware>,
506
+ event: VEvent<E>,
507
+ requestType: proto.ProtocolRequestType<
508
+ P,
509
+ proto.WorkspaceEdit | null,
510
+ never,
511
+ void,
512
+ proto.FileOperationRegistrationOptions
513
+ >,
514
+ clientCapability: keyof proto.FileOperationClientCapabilities,
515
+ serverCapability: keyof proto.FileOperationOptions,
516
+ accessUri: (i: I) => Uri,
517
+ createParams: (e: Event<I>) => P,
518
+ ) {
519
+ super(client, event, requestType, clientCapability, serverCapability);
520
+ this._requestType = requestType;
521
+ this._accessUri = accessUri;
522
+ this._createParams = createParams;
523
+ }
524
+
525
+ public async send(originalEvent: E & RequestEvent<I>): Promise<void> {
526
+ const waitUntil = this.waitUntil(originalEvent);
527
+ originalEvent.waitUntil(waitUntil);
528
+ }
529
+
530
+ private async waitUntil(originalEvent: E): Promise<WorkspaceEdit | null | undefined> {
531
+ // Create a copy of the event that has the files filtered to match what the
532
+ // server wants.
533
+ const filteredEvent = await this.filter(originalEvent, this._accessUri);
534
+
535
+ if (filteredEvent.files.length) {
536
+ const next = (event: RequestEvent<I>): Promise<WorkspaceEdit | any> => {
537
+ return this._client
538
+ .sendRequest(this._requestType, this._createParams(event), event.token)
539
+ .then(this._client.protocol2CodeConverter.asWorkspaceEdit);
540
+ };
541
+ return this.doSend(filteredEvent, next);
542
+ } else {
543
+ return undefined;
544
+ }
545
+ }
546
+
547
+ protected abstract doSend(
548
+ event: E,
549
+ next: (event: RequestEvent<I>) => Thenable<WorkspaceEdit> | Thenable<any>,
550
+ ): Thenable<WorkspaceEdit> | Thenable<any>;
551
+ }
552
+
553
+ export class WillCreateFilesFeature extends RequestFileOperationFeature<
554
+ Uri,
555
+ FileWillCreateEvent,
556
+ proto.CreateFilesParams
557
+ > {
558
+ constructor(client: FeatureClient<FileOperationsWorkspaceMiddleware>) {
559
+ super(
560
+ client,
561
+ workspace.onWillCreateFiles,
562
+ proto.WillCreateFilesRequest.type,
563
+ 'willCreate',
564
+ 'willCreate',
565
+ (i: Uri) => i,
566
+ client.code2ProtocolConverter.asWillCreateFilesParams,
567
+ );
568
+ }
569
+
570
+ protected doSend(
571
+ event: FileWillCreateEvent,
572
+ next: (event: FileWillCreateEvent) => Thenable<WorkspaceEdit> | Thenable<any>,
573
+ ): Thenable<WorkspaceEdit> | Thenable<any> {
574
+ const middleware = this._client.middleware.workspace;
575
+ return middleware?.willCreateFiles
576
+ ? middleware.willCreateFiles(event, next)
577
+ : next(event);
578
+ }
579
+ }
580
+
581
+ export class WillRenameFilesFeature extends RequestFileOperationFeature<
582
+ { oldUri: Uri; newUri: Uri },
583
+ FileWillRenameEvent,
584
+ proto.RenameFilesParams
585
+ > {
586
+ constructor(client: FeatureClient<FileOperationsWorkspaceMiddleware>) {
587
+ super(
588
+ client,
589
+ workspace.onWillRenameFiles,
590
+ proto.WillRenameFilesRequest.type,
591
+ 'willRename',
592
+ 'willRename',
593
+ (i: { oldUri: Uri; newUri: Uri }) => i.oldUri,
594
+ client.code2ProtocolConverter.asWillRenameFilesParams,
595
+ );
596
+ }
597
+
598
+ protected doSend(
599
+ event: FileWillRenameEvent,
600
+ next: (event: FileWillRenameEvent) => Thenable<WorkspaceEdit> | Thenable<any>,
601
+ ): Thenable<WorkspaceEdit> | Thenable<any> {
602
+ const middleware = this._client.middleware.workspace;
603
+ return middleware?.willRenameFiles
604
+ ? middleware.willRenameFiles(event, next)
605
+ : next(event);
606
+ }
607
+ }
608
+
609
+ export class WillDeleteFilesFeature extends RequestFileOperationFeature<
610
+ Uri,
611
+ FileWillDeleteEvent,
612
+ proto.DeleteFilesParams
613
+ > {
614
+ constructor(client: FeatureClient<FileOperationsWorkspaceMiddleware>) {
615
+ super(
616
+ client,
617
+ workspace.onWillDeleteFiles,
618
+ proto.WillDeleteFilesRequest.type,
619
+ 'willDelete',
620
+ 'willDelete',
621
+ (i: Uri) => i,
622
+ client.code2ProtocolConverter.asWillDeleteFilesParams,
623
+ );
624
+ }
625
+
626
+ protected doSend(
627
+ event: FileWillDeleteEvent,
628
+ next: (event: FileWillDeleteEvent) => Thenable<WorkspaceEdit> | Thenable<any>,
629
+ ): Thenable<WorkspaceEdit> | Thenable<any> {
630
+ const middleware = this._client.middleware.workspace;
631
+ return middleware?.willDeleteFiles
632
+ ? middleware.willDeleteFiles(event, next)
633
+ : next(event);
634
+ }
635
+ }