yaml-language-server 1.11.1-dcdfa10.0 → 1.11.1-e8be2e1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +9 -0
  3. package/eslint-result.sarif +4397 -0
  4. package/lib/esm/languageserver/handlers/languageHandlers.js +4 -1
  5. package/lib/esm/languageserver/handlers/languageHandlers.js.map +1 -1
  6. package/lib/esm/languageserver/handlers/schemaSelectionHandlers.js +44 -60
  7. package/lib/esm/languageserver/handlers/schemaSelectionHandlers.js.map +1 -1
  8. package/lib/esm/languageserver/handlers/settingsHandlers.d.ts +1 -1
  9. package/lib/esm/languageserver/handlers/settingsHandlers.js +161 -183
  10. package/lib/esm/languageserver/handlers/settingsHandlers.js.map +1 -1
  11. package/lib/esm/languageserver/telemetry.d.ts +2 -12
  12. package/lib/esm/languageserver/telemetry.js +1 -1
  13. package/lib/esm/languageserver/telemetry.js.map +1 -1
  14. package/lib/esm/languageservice/jsonSchema.d.ts +1 -0
  15. package/lib/esm/languageservice/parser/jsonParser07.d.ts +2 -0
  16. package/lib/esm/languageservice/parser/jsonParser07.js +44 -19
  17. package/lib/esm/languageservice/parser/jsonParser07.js.map +1 -1
  18. package/lib/esm/languageservice/parser/yaml-documents.js +6 -5
  19. package/lib/esm/languageservice/parser/yaml-documents.js.map +1 -1
  20. package/lib/esm/languageservice/parser/yamlParser07.js +1 -2
  21. package/lib/esm/languageservice/parser/yamlParser07.js.map +1 -1
  22. package/lib/esm/languageservice/services/documentSymbols.d.ts +1 -1
  23. package/lib/esm/languageservice/services/validation/yaml-style.js +2 -3
  24. package/lib/esm/languageservice/services/validation/yaml-style.js.map +1 -1
  25. package/lib/esm/languageservice/services/yamlCodeActions.js +2 -3
  26. package/lib/esm/languageservice/services/yamlCodeActions.js.map +1 -1
  27. package/lib/esm/languageservice/services/yamlCodeLens.d.ts +1 -1
  28. package/lib/esm/languageservice/services/yamlCodeLens.js +23 -34
  29. package/lib/esm/languageservice/services/yamlCodeLens.js.map +1 -1
  30. package/lib/esm/languageservice/services/yamlCommands.js +3 -12
  31. package/lib/esm/languageservice/services/yamlCommands.js.map +1 -1
  32. package/lib/esm/languageservice/services/yamlCompletion.d.ts +3 -2
  33. package/lib/esm/languageservice/services/yamlCompletion.js +439 -414
  34. package/lib/esm/languageservice/services/yamlCompletion.js.map +1 -1
  35. package/lib/esm/languageservice/services/yamlDefinition.d.ts +1 -1
  36. package/lib/esm/languageservice/services/yamlFolding.js +1 -2
  37. package/lib/esm/languageservice/services/yamlFolding.js.map +1 -1
  38. package/lib/esm/languageservice/services/yamlHover.d.ts +1 -1
  39. package/lib/esm/languageservice/services/yamlLinks.d.ts +1 -1
  40. package/lib/esm/languageservice/services/yamlOnTypeFormatting.js +0 -1
  41. package/lib/esm/languageservice/services/yamlOnTypeFormatting.js.map +1 -1
  42. package/lib/esm/languageservice/services/yamlSchemaService.js +202 -218
  43. package/lib/esm/languageservice/services/yamlSchemaService.js.map +1 -1
  44. package/lib/esm/languageservice/services/yamlValidation.d.ts +1 -1
  45. package/lib/esm/languageservice/services/yamlValidation.js +61 -71
  46. package/lib/esm/languageservice/services/yamlValidation.js.map +1 -1
  47. package/lib/esm/languageservice/telemetry.d.ts +16 -0
  48. package/lib/esm/languageservice/telemetry.js +6 -0
  49. package/lib/esm/languageservice/telemetry.js.map +1 -0
  50. package/lib/esm/languageservice/utils/astUtils.js +2 -6
  51. package/lib/esm/languageservice/utils/astUtils.js.map +1 -1
  52. package/lib/esm/languageservice/utils/indentationGuesser.js +0 -1
  53. package/lib/esm/languageservice/utils/indentationGuesser.js.map +1 -1
  54. package/lib/esm/languageservice/utils/objects.js +1 -2
  55. package/lib/esm/languageservice/utils/objects.js.map +1 -1
  56. package/lib/esm/languageservice/utils/schemaUrls.d.ts +1 -1
  57. package/lib/esm/languageservice/utils/schemaUrls.js +2 -4
  58. package/lib/esm/languageservice/utils/schemaUrls.js.map +1 -1
  59. package/lib/esm/languageservice/utils/schemaUtils.d.ts +2 -0
  60. package/lib/esm/languageservice/utils/schemaUtils.js +9 -6
  61. package/lib/esm/languageservice/utils/schemaUtils.js.map +1 -1
  62. package/lib/esm/languageservice/yamlLanguageService.d.ts +2 -3
  63. package/lib/esm/languageservice/yamlLanguageService.js +0 -1
  64. package/lib/esm/languageservice/yamlLanguageService.js.map +1 -1
  65. package/lib/esm/server.js +5 -14
  66. package/lib/esm/server.js.map +1 -1
  67. package/lib/esm/webworker/yamlServerMain.js +2 -2
  68. package/lib/esm/webworker/yamlServerMain.js.map +1 -1
  69. package/lib/esm/yamlServerInit.d.ts +1 -1
  70. package/lib/umd/languageserver/handlers/languageHandlers.js +4 -1
  71. package/lib/umd/languageserver/handlers/languageHandlers.js.map +1 -1
  72. package/lib/umd/languageserver/handlers/schemaSelectionHandlers.js +44 -60
  73. package/lib/umd/languageserver/handlers/schemaSelectionHandlers.js.map +1 -1
  74. package/lib/umd/languageserver/handlers/settingsHandlers.d.ts +1 -1
  75. package/lib/umd/languageserver/handlers/settingsHandlers.js +161 -183
  76. package/lib/umd/languageserver/handlers/settingsHandlers.js.map +1 -1
  77. package/lib/umd/languageserver/telemetry.d.ts +2 -12
  78. package/lib/umd/languageserver/telemetry.js +3 -3
  79. package/lib/umd/languageserver/telemetry.js.map +1 -1
  80. package/lib/umd/languageservice/jsonSchema.d.ts +1 -0
  81. package/lib/umd/languageservice/parser/jsonParser07.d.ts +2 -0
  82. package/lib/umd/languageservice/parser/jsonParser07.js +45 -20
  83. package/lib/umd/languageservice/parser/jsonParser07.js.map +1 -1
  84. package/lib/umd/languageservice/parser/yaml-documents.js +6 -5
  85. package/lib/umd/languageservice/parser/yaml-documents.js.map +1 -1
  86. package/lib/umd/languageservice/parser/yamlParser07.js +1 -2
  87. package/lib/umd/languageservice/parser/yamlParser07.js.map +1 -1
  88. package/lib/umd/languageservice/services/documentSymbols.d.ts +1 -1
  89. package/lib/umd/languageservice/services/validation/yaml-style.js +2 -3
  90. package/lib/umd/languageservice/services/validation/yaml-style.js.map +1 -1
  91. package/lib/umd/languageservice/services/yamlCodeActions.js +2 -3
  92. package/lib/umd/languageservice/services/yamlCodeActions.js.map +1 -1
  93. package/lib/umd/languageservice/services/yamlCodeLens.d.ts +1 -1
  94. package/lib/umd/languageservice/services/yamlCodeLens.js +23 -34
  95. package/lib/umd/languageservice/services/yamlCodeLens.js.map +1 -1
  96. package/lib/umd/languageservice/services/yamlCommands.js +3 -12
  97. package/lib/umd/languageservice/services/yamlCommands.js.map +1 -1
  98. package/lib/umd/languageservice/services/yamlCompletion.d.ts +3 -2
  99. package/lib/umd/languageservice/services/yamlCompletion.js +438 -413
  100. package/lib/umd/languageservice/services/yamlCompletion.js.map +1 -1
  101. package/lib/umd/languageservice/services/yamlDefinition.d.ts +1 -1
  102. package/lib/umd/languageservice/services/yamlFolding.js +1 -2
  103. package/lib/umd/languageservice/services/yamlFolding.js.map +1 -1
  104. package/lib/umd/languageservice/services/yamlHover.d.ts +1 -1
  105. package/lib/umd/languageservice/services/yamlLinks.d.ts +1 -1
  106. package/lib/umd/languageservice/services/yamlOnTypeFormatting.js +0 -1
  107. package/lib/umd/languageservice/services/yamlOnTypeFormatting.js.map +1 -1
  108. package/lib/umd/languageservice/services/yamlSchemaService.js +202 -218
  109. package/lib/umd/languageservice/services/yamlSchemaService.js.map +1 -1
  110. package/lib/umd/languageservice/services/yamlValidation.d.ts +1 -1
  111. package/lib/umd/languageservice/services/yamlValidation.js +61 -71
  112. package/lib/umd/languageservice/services/yamlValidation.js.map +1 -1
  113. package/lib/umd/languageservice/telemetry.d.ts +16 -0
  114. package/lib/umd/languageservice/telemetry.js +17 -0
  115. package/lib/umd/languageservice/telemetry.js.map +1 -0
  116. package/lib/umd/languageservice/utils/astUtils.js +2 -6
  117. package/lib/umd/languageservice/utils/astUtils.js.map +1 -1
  118. package/lib/umd/languageservice/utils/indentationGuesser.js +0 -1
  119. package/lib/umd/languageservice/utils/indentationGuesser.js.map +1 -1
  120. package/lib/umd/languageservice/utils/objects.js +1 -2
  121. package/lib/umd/languageservice/utils/objects.js.map +1 -1
  122. package/lib/umd/languageservice/utils/schemaUrls.d.ts +1 -1
  123. package/lib/umd/languageservice/utils/schemaUrls.js +2 -4
  124. package/lib/umd/languageservice/utils/schemaUrls.js.map +1 -1
  125. package/lib/umd/languageservice/utils/schemaUtils.d.ts +2 -0
  126. package/lib/umd/languageservice/utils/schemaUtils.js +12 -7
  127. package/lib/umd/languageservice/utils/schemaUtils.js.map +1 -1
  128. package/lib/umd/languageservice/yamlLanguageService.d.ts +2 -3
  129. package/lib/umd/languageservice/yamlLanguageService.js +0 -1
  130. package/lib/umd/languageservice/yamlLanguageService.js.map +1 -1
  131. package/lib/umd/server.js +4 -13
  132. package/lib/umd/server.js.map +1 -1
  133. package/lib/umd/webworker/yamlServerMain.js +1 -1
  134. package/lib/umd/webworker/yamlServerMain.js.map +1 -1
  135. package/lib/umd/yamlServerInit.d.ts +1 -1
  136. package/out/server/src/languageserver/handlers/languageHandlers.js +4 -1
  137. package/out/server/src/languageserver/handlers/languageHandlers.js.map +1 -1
  138. package/out/server/src/languageserver/handlers/schemaSelectionHandlers.js +44 -60
  139. package/out/server/src/languageserver/handlers/schemaSelectionHandlers.js.map +1 -1
  140. package/out/server/src/languageserver/handlers/settingsHandlers.d.ts +1 -1
  141. package/out/server/src/languageserver/handlers/settingsHandlers.js +161 -183
  142. package/out/server/src/languageserver/handlers/settingsHandlers.js.map +1 -1
  143. package/out/server/src/languageserver/telemetry.d.ts +2 -12
  144. package/out/server/src/languageserver/telemetry.js +3 -3
  145. package/out/server/src/languageserver/telemetry.js.map +1 -1
  146. package/out/server/src/languageservice/jsonSchema.d.ts +1 -0
  147. package/out/server/src/languageservice/parser/jsonParser07.d.ts +2 -0
  148. package/out/server/src/languageservice/parser/jsonParser07.js +44 -19
  149. package/out/server/src/languageservice/parser/jsonParser07.js.map +1 -1
  150. package/out/server/src/languageservice/parser/yaml-documents.js +6 -5
  151. package/out/server/src/languageservice/parser/yaml-documents.js.map +1 -1
  152. package/out/server/src/languageservice/parser/yamlParser07.js +1 -2
  153. package/out/server/src/languageservice/parser/yamlParser07.js.map +1 -1
  154. package/out/server/src/languageservice/services/documentSymbols.d.ts +1 -1
  155. package/out/server/src/languageservice/services/validation/yaml-style.js +2 -3
  156. package/out/server/src/languageservice/services/validation/yaml-style.js.map +1 -1
  157. package/out/server/src/languageservice/services/yamlCodeActions.js +2 -3
  158. package/out/server/src/languageservice/services/yamlCodeActions.js.map +1 -1
  159. package/out/server/src/languageservice/services/yamlCodeLens.d.ts +1 -1
  160. package/out/server/src/languageservice/services/yamlCodeLens.js +23 -34
  161. package/out/server/src/languageservice/services/yamlCodeLens.js.map +1 -1
  162. package/out/server/src/languageservice/services/yamlCommands.js +3 -12
  163. package/out/server/src/languageservice/services/yamlCommands.js.map +1 -1
  164. package/out/server/src/languageservice/services/yamlCompletion.d.ts +3 -2
  165. package/out/server/src/languageservice/services/yamlCompletion.js +438 -413
  166. package/out/server/src/languageservice/services/yamlCompletion.js.map +1 -1
  167. package/out/server/src/languageservice/services/yamlDefinition.d.ts +1 -1
  168. package/out/server/src/languageservice/services/yamlFolding.js +1 -2
  169. package/out/server/src/languageservice/services/yamlFolding.js.map +1 -1
  170. package/out/server/src/languageservice/services/yamlHover.d.ts +1 -1
  171. package/out/server/src/languageservice/services/yamlLinks.d.ts +1 -1
  172. package/out/server/src/languageservice/services/yamlOnTypeFormatting.js +0 -1
  173. package/out/server/src/languageservice/services/yamlOnTypeFormatting.js.map +1 -1
  174. package/out/server/src/languageservice/services/yamlSchemaService.js +202 -218
  175. package/out/server/src/languageservice/services/yamlSchemaService.js.map +1 -1
  176. package/out/server/src/languageservice/services/yamlValidation.d.ts +1 -1
  177. package/out/server/src/languageservice/services/yamlValidation.js +61 -71
  178. package/out/server/src/languageservice/services/yamlValidation.js.map +1 -1
  179. package/out/server/src/languageservice/telemetry.d.ts +16 -0
  180. package/out/server/src/languageservice/telemetry.js +7 -0
  181. package/out/server/src/languageservice/telemetry.js.map +1 -0
  182. package/out/server/src/languageservice/utils/astUtils.js +2 -6
  183. package/out/server/src/languageservice/utils/astUtils.js.map +1 -1
  184. package/out/server/src/languageservice/utils/indentationGuesser.js +0 -1
  185. package/out/server/src/languageservice/utils/indentationGuesser.js.map +1 -1
  186. package/out/server/src/languageservice/utils/objects.js +1 -2
  187. package/out/server/src/languageservice/utils/objects.js.map +1 -1
  188. package/out/server/src/languageservice/utils/schemaUrls.d.ts +1 -1
  189. package/out/server/src/languageservice/utils/schemaUrls.js +2 -4
  190. package/out/server/src/languageservice/utils/schemaUrls.js.map +1 -1
  191. package/out/server/src/languageservice/utils/schemaUtils.d.ts +2 -0
  192. package/out/server/src/languageservice/utils/schemaUtils.js +12 -7
  193. package/out/server/src/languageservice/utils/schemaUtils.js.map +1 -1
  194. package/out/server/src/languageservice/yamlLanguageService.d.ts +2 -3
  195. package/out/server/src/languageservice/yamlLanguageService.js +0 -1
  196. package/out/server/src/languageservice/yamlLanguageService.js.map +1 -1
  197. package/out/server/src/server.js +4 -13
  198. package/out/server/src/server.js.map +1 -1
  199. package/out/server/src/webworker/yamlServerMain.js +1 -1
  200. package/out/server/src/webworker/yamlServerMain.js.map +1 -1
  201. package/out/server/src/yamlServerInit.d.ts +1 -1
  202. package/out/server/test/autoCompletion.test.js +267 -178
  203. package/out/server/test/autoCompletion.test.js.map +1 -1
  204. package/out/server/test/autoCompletionFix.test.js +222 -134
  205. package/out/server/test/autoCompletionFix.test.js.map +1 -1
  206. package/out/server/test/code-action-schema.test.js +6 -15
  207. package/out/server/test/code-action-schema.test.js.map +1 -1
  208. package/out/server/test/defaultSnippets.test.js +11 -19
  209. package/out/server/test/defaultSnippets.test.js.map +1 -1
  210. package/out/server/test/findLinks.test.js +3 -12
  211. package/out/server/test/findLinks.test.js.map +1 -1
  212. package/out/server/test/hover.test.js +64 -73
  213. package/out/server/test/hover.test.js.map +1 -1
  214. package/out/server/test/integration.test.js +3 -12
  215. package/out/server/test/integration.test.js.map +1 -1
  216. package/out/server/test/jsonParser.test.js +15 -26
  217. package/out/server/test/jsonParser.test.js.map +1 -1
  218. package/out/server/test/multipleDocuments.test.js +3 -12
  219. package/out/server/test/multipleDocuments.test.js.map +1 -1
  220. package/out/server/test/schema.test.js +71 -85
  221. package/out/server/test/schema.test.js.map +1 -1
  222. package/out/server/test/schemaRequestHandler.test.js +9 -18
  223. package/out/server/test/schemaRequestHandler.test.js.map +1 -1
  224. package/out/server/test/schemaSelectionHandlers.test.js +12 -21
  225. package/out/server/test/schemaSelectionHandlers.test.js.map +1 -1
  226. package/out/server/test/schemaValidation.test.js +216 -97
  227. package/out/server/test/schemaValidation.test.js.map +1 -1
  228. package/out/server/test/settingsHandlers.test.js +44 -55
  229. package/out/server/test/settingsHandlers.test.js.map +1 -1
  230. package/out/server/test/telemetry.test.js +1 -1
  231. package/out/server/test/telemetry.test.js.map +1 -1
  232. package/out/server/test/utils/testsTypes.d.ts +3 -2
  233. package/out/server/test/utils/testsTypes.js +1 -1
  234. package/out/server/test/utils/testsTypes.js.map +1 -1
  235. package/out/server/test/utils/verifyError.d.ts +1 -1
  236. package/out/server/test/utils/verifyError.js +22 -20
  237. package/out/server/test/utils/verifyError.js.map +1 -1
  238. package/out/server/test/yamlCodeLens.test.js +25 -34
  239. package/out/server/test/yamlCodeLens.test.js.map +1 -1
  240. package/out/server/test/yamlCommands.test.js +6 -15
  241. package/out/server/test/yamlCommands.test.js.map +1 -1
  242. package/out/server/test/yamlSchema.test.js +9 -18
  243. package/out/server/test/yamlSchema.test.js.map +1 -1
  244. package/out/server/test/yamlSchemaService.test.js +9 -18
  245. package/out/server/test/yamlSchemaService.test.js.map +1 -1
  246. package/out/server/test/yamlValidation.test.js +30 -39
  247. package/out/server/test/yamlValidation.test.js.map +1 -1
  248. package/package.json +3 -2
@@ -2,15 +2,6 @@
2
2
  * Copyright (c) Red Hat, Inc. All rights reserved.
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
5
  import { CompletionItem as CompletionItemBase, CompletionItemKind, CompletionList, InsertTextFormat, InsertTextMode, MarkupKind, Position, Range, TextEdit, } from 'vscode-languageserver-types';
15
6
  import { isPair, isScalar, isMap, isSeq, isNode } from 'yaml';
16
7
  import { filterInvalidCustomTags, matchOffsetToDocument } from '../utils/arrUtils';
@@ -23,7 +14,7 @@ import { setKubernetesParserOption } from '../parser/isKubernetes';
23
14
  import { asSchema } from '../parser/jsonParser07';
24
15
  import { indexOf, isInComment, isMapContainsEmptyPair } from '../utils/astUtils';
25
16
  import { isModeline } from './modelineUtil';
26
- import { getSchemaTypeName } from '../utils/schemaUtils';
17
+ import { getSchemaTypeName, isAnyOfAllOfOneOfType, isPrimitiveType } from '../utils/schemaUtils';
27
18
  const localize = nls.loadMessageBundle();
28
19
  const doubleQuotesEscapeRegExp = /[\\]+"/g;
29
20
  const parentCompletionKind = CompletionItemKind.Class;
@@ -46,409 +37,438 @@ export class YamlCompletion {
46
37
  this.disableDefaultProperties = languageSettings.disableDefaultProperties;
47
38
  this.parentSkeletonSelectedFirst = languageSettings.parentSkeletonSelectedFirst;
48
39
  }
49
- doComplete(document, position, isKubernetes = false, doComplete = true) {
50
- return __awaiter(this, void 0, void 0, function* () {
51
- const result = CompletionList.create([], false);
52
- if (!this.completionEnabled) {
53
- return result;
54
- }
55
- const doc = this.yamlDocument.getYamlDocument(document, { customTags: this.customTags, yamlVersion: this.yamlVersion }, true);
56
- const textBuffer = new TextBuffer(document);
57
- if (!this.configuredIndentation) {
58
- const indent = guessIndentation(textBuffer, 2, true);
59
- this.indentation = indent.insertSpaces ? ' '.repeat(indent.tabSize) : '\t';
60
- }
61
- else {
62
- this.indentation = this.configuredIndentation;
63
- }
64
- setKubernetesParserOption(doc.documents, isKubernetes);
65
- const offset = document.offsetAt(position);
66
- const text = document.getText();
67
- if (text.charAt(offset - 1) === ':') {
68
- return Promise.resolve(result);
69
- }
70
- let currentDoc = matchOffsetToDocument(offset, doc);
71
- if (currentDoc === null) {
72
- return Promise.resolve(result);
73
- }
74
- // as we modify AST for completion, we need to use copy of original document
75
- currentDoc = currentDoc.clone();
76
- let [node, foundByClosest] = currentDoc.getNodeFromPosition(offset, textBuffer, this.indentation.length);
77
- const currentWord = this.getCurrentWord(document, offset);
78
- let lineContent = textBuffer.getLineContent(position.line);
79
- const lineAfterPosition = lineContent.substring(position.character);
80
- const areOnlySpacesAfterPosition = /^[ ]+\n?$/.test(lineAfterPosition);
81
- this.arrayPrefixIndentation = '';
82
- let overwriteRange = null;
83
- if (areOnlySpacesAfterPosition) {
84
- overwriteRange = Range.create(position, Position.create(position.line, lineContent.length));
85
- const isOnlyWhitespace = lineContent.trim().length === 0;
86
- const isOnlyDash = lineContent.match(/^\s*(-)\s*$/);
87
- if (node && isScalar(node) && !isOnlyWhitespace && !isOnlyDash) {
88
- // line contains part of a key with trailing spaces, adjust the overwrite range to include only the text
89
- const matches = lineContent.match(/^([\s-]*)[^:]+[ \t]+\n?$/);
90
- if (matches === null || matches === void 0 ? void 0 : matches.length) {
91
- overwriteRange = Range.create(Position.create(position.line, matches[1].length), Position.create(position.line, lineContent.length));
92
- }
93
- }
94
- }
95
- else if (node && isScalar(node) && node.value === 'null') {
96
- const nodeStartPos = document.positionAt(node.range[0]);
97
- nodeStartPos.character += 1;
98
- const nodeEndPos = document.positionAt(node.range[2]);
99
- nodeEndPos.character += 1;
100
- overwriteRange = Range.create(nodeStartPos, nodeEndPos);
101
- }
102
- else if (node && isScalar(node) && node.value) {
103
- const start = document.positionAt(node.range[0]);
104
- if (offset > 0 && start.character > 0 && text.charAt(offset - 1) === '-') {
105
- start.character -= 1;
40
+ async doComplete(document, position, isKubernetes = false, doComplete = true) {
41
+ const result = CompletionList.create([], false);
42
+ if (!this.completionEnabled) {
43
+ return result;
44
+ }
45
+ const doc = this.yamlDocument.getYamlDocument(document, { customTags: this.customTags, yamlVersion: this.yamlVersion }, true);
46
+ const textBuffer = new TextBuffer(document);
47
+ if (!this.configuredIndentation) {
48
+ const indent = guessIndentation(textBuffer, 2, true);
49
+ this.indentation = indent.insertSpaces ? ' '.repeat(indent.tabSize) : '\t';
50
+ }
51
+ else {
52
+ this.indentation = this.configuredIndentation;
53
+ }
54
+ setKubernetesParserOption(doc.documents, isKubernetes);
55
+ // set parser options
56
+ for (const jsonDoc of doc.documents) {
57
+ jsonDoc.uri = document.uri;
58
+ }
59
+ const offset = document.offsetAt(position);
60
+ const text = document.getText();
61
+ if (text.charAt(offset - 1) === ':') {
62
+ return Promise.resolve(result);
63
+ }
64
+ let currentDoc = matchOffsetToDocument(offset, doc);
65
+ if (currentDoc === null) {
66
+ return Promise.resolve(result);
67
+ }
68
+ // as we modify AST for completion, we need to use copy of original document
69
+ currentDoc = currentDoc.clone();
70
+ let [node, foundByClosest] = currentDoc.getNodeFromPosition(offset, textBuffer, this.indentation.length);
71
+ const currentWord = this.getCurrentWord(document, offset);
72
+ let lineContent = textBuffer.getLineContent(position.line);
73
+ const lineAfterPosition = lineContent.substring(position.character);
74
+ const areOnlySpacesAfterPosition = /^[ ]+\n?$/.test(lineAfterPosition);
75
+ this.arrayPrefixIndentation = '';
76
+ let overwriteRange = null;
77
+ if (areOnlySpacesAfterPosition) {
78
+ overwriteRange = Range.create(position, Position.create(position.line, lineContent.length));
79
+ const isOnlyWhitespace = lineContent.trim().length === 0;
80
+ const isOnlyDash = lineContent.match(/^\s*(-)\s*$/);
81
+ if (node && isScalar(node) && !isOnlyWhitespace && !isOnlyDash) {
82
+ // line contains part of a key with trailing spaces, adjust the overwrite range to include only the text
83
+ const matches = lineContent.match(/^([\s-]*)[^:]+[ \t]+\n?$/);
84
+ if (matches?.length) {
85
+ overwriteRange = Range.create(Position.create(position.line, matches[1].length), Position.create(position.line, lineContent.length));
106
86
  }
107
- overwriteRange = Range.create(start, document.positionAt(node.range[1]));
108
87
  }
109
- else if (node && isScalar(node) && node.value === null && currentWord === '-') {
110
- overwriteRange = Range.create(position, position);
111
- this.arrayPrefixIndentation = ' ';
88
+ }
89
+ else if (node && isScalar(node) && node.value === 'null') {
90
+ const nodeStartPos = document.positionAt(node.range[0]);
91
+ nodeStartPos.character += 1;
92
+ const nodeEndPos = document.positionAt(node.range[2]);
93
+ nodeEndPos.character += 1;
94
+ overwriteRange = Range.create(nodeStartPos, nodeEndPos);
95
+ }
96
+ else if (node && isScalar(node) && node.value) {
97
+ const start = document.positionAt(node.range[0]);
98
+ if (offset > 0 && start.character > 0 && text.charAt(offset - 1) === '-') {
99
+ start.character -= 1;
112
100
  }
113
- else {
114
- let overwriteStart = document.offsetAt(position) - currentWord.length;
115
- if (overwriteStart > 0 && text[overwriteStart - 1] === '"') {
116
- overwriteStart--;
117
- }
118
- overwriteRange = Range.create(document.positionAt(overwriteStart), position);
101
+ overwriteRange = Range.create(start, document.positionAt(node.range[1]));
102
+ }
103
+ else if (node && isScalar(node) && node.value === null && currentWord === '-') {
104
+ overwriteRange = Range.create(position, position);
105
+ this.arrayPrefixIndentation = ' ';
106
+ }
107
+ else {
108
+ let overwriteStart = document.offsetAt(position) - currentWord.length;
109
+ if (overwriteStart > 0 && text[overwriteStart - 1] === '"') {
110
+ overwriteStart--;
119
111
  }
120
- const proposed = {};
121
- const existingProposeItem = '__';
122
- const collector = {
123
- add: (completionItem) => {
124
- const addSuggestionForParent = function (completionItem) {
125
- var _a;
126
- const existsInYaml = ((_a = proposed[completionItem.label]) === null || _a === void 0 ? void 0 : _a.label) === existingProposeItem;
127
- //don't put to parent suggestion if already in yaml
128
- if (existsInYaml) {
129
- return;
130
- }
131
- const schema = completionItem.parent.schema;
132
- const schemaType = getSchemaTypeName(schema);
133
- const schemaDescription = schema.markdownDescription || schema.description;
134
- let parentCompletion = result.items.find((item) => { var _a; return ((_a = item.parent) === null || _a === void 0 ? void 0 : _a.schema) === schema && item.kind === parentCompletionKind; });
135
- if (parentCompletion && parentCompletion.parent.insertTexts.includes(completionItem.insertText)) {
136
- // already exists in the parent
137
- return;
138
- }
139
- else if (!parentCompletion) {
140
- // create a new parent
141
- parentCompletion = Object.assign(Object.assign({}, completionItem), { label: schemaType, documentation: schemaDescription, sortText: '_' + schemaType, kind: parentCompletionKind });
142
- parentCompletion.parent.insertTexts = [completionItem.insertText];
143
- result.items.push(parentCompletion);
144
- }
145
- else {
146
- // add to the existing parent
147
- parentCompletion.parent.insertTexts.push(completionItem.insertText);
148
- }
149
- };
150
- const isForParentCompletion = !!completionItem.parent;
151
- let label = completionItem.label;
152
- if (!label) {
153
- // we receive not valid CompletionItem as `label` is mandatory field, so just ignore it
154
- console.warn(`Ignoring CompletionItem without label: ${JSON.stringify(completionItem)}`);
112
+ overwriteRange = Range.create(document.positionAt(overwriteStart), position);
113
+ }
114
+ const proposed = {};
115
+ const existingProposeItem = '__';
116
+ const collector = {
117
+ add: (completionItem, oneOfSchema) => {
118
+ const addSuggestionForParent = function (completionItem) {
119
+ const existsInYaml = proposed[completionItem.label]?.label === existingProposeItem;
120
+ //don't put to parent suggestion if already in yaml
121
+ if (existsInYaml) {
155
122
  return;
156
123
  }
157
- if (!isString(label)) {
158
- label = String(label);
159
- }
160
- label = label.replace(/[\n]/g, '↵');
161
- if (label.length > 60) {
162
- const shortendedLabel = label.substr(0, 57).trim() + '...';
163
- if (!proposed[shortendedLabel]) {
164
- label = shortendedLabel;
165
- }
124
+ const schema = completionItem.parent.schema;
125
+ const schemaType = getSchemaTypeName(schema);
126
+ const schemaDescription = schema.markdownDescription || schema.description;
127
+ let parentCompletion = result.items.find((item) => item.parent?.schema === schema && item.kind === parentCompletionKind);
128
+ if (parentCompletion && parentCompletion.parent.insertTexts.includes(completionItem.insertText)) {
129
+ // already exists in the parent
130
+ return;
166
131
  }
167
- // trim $1 from end of completion
168
- if (completionItem.insertText.endsWith('$1') && !isForParentCompletion) {
169
- completionItem.insertText = completionItem.insertText.substr(0, completionItem.insertText.length - 2);
132
+ else if (!parentCompletion) {
133
+ // create a new parent
134
+ parentCompletion = {
135
+ ...completionItem,
136
+ label: schemaType,
137
+ documentation: schemaDescription,
138
+ sortText: '_' + schemaType,
139
+ kind: parentCompletionKind,
140
+ };
141
+ parentCompletion.label = parentCompletion.label || completionItem.label;
142
+ parentCompletion.parent.insertTexts = [completionItem.insertText];
143
+ result.items.push(parentCompletion);
170
144
  }
171
- if (overwriteRange && overwriteRange.start.line === overwriteRange.end.line) {
172
- completionItem.textEdit = TextEdit.replace(overwriteRange, completionItem.insertText);
145
+ else {
146
+ // add to the existing parent
147
+ parentCompletion.parent.insertTexts.push(completionItem.insertText);
173
148
  }
174
- completionItem.label = label;
175
- if (isForParentCompletion) {
176
- addSuggestionForParent(completionItem);
177
- return;
149
+ };
150
+ const isForParentCompletion = !!completionItem.parent;
151
+ let label = completionItem.label;
152
+ if (!label) {
153
+ // we receive not valid CompletionItem as `label` is mandatory field, so just ignore it
154
+ console.warn(`Ignoring CompletionItem without label: ${JSON.stringify(completionItem)}`);
155
+ return;
156
+ }
157
+ if (!isString(label)) {
158
+ label = String(label);
159
+ }
160
+ label = label.replace(/[\n]/g, '↵');
161
+ if (label.length > 60) {
162
+ const shortendedLabel = label.substr(0, 57).trim() + '...';
163
+ if (!proposed[shortendedLabel]) {
164
+ label = shortendedLabel;
178
165
  }
179
- if (this.arrayPrefixIndentation) {
180
- this.updateCompletionText(completionItem, this.arrayPrefixIndentation + completionItem.insertText);
166
+ }
167
+ // trim $1 from end of completion
168
+ if (completionItem.insertText.endsWith('$1') && !isForParentCompletion) {
169
+ completionItem.insertText = completionItem.insertText.substr(0, completionItem.insertText.length - 2);
170
+ }
171
+ if (overwriteRange && overwriteRange.start.line === overwriteRange.end.line) {
172
+ completionItem.textEdit = TextEdit.replace(overwriteRange, completionItem.insertText);
173
+ }
174
+ completionItem.label = label;
175
+ if (isForParentCompletion) {
176
+ addSuggestionForParent(completionItem);
177
+ return;
178
+ }
179
+ if (this.arrayPrefixIndentation) {
180
+ this.updateCompletionText(completionItem, this.arrayPrefixIndentation + completionItem.insertText);
181
+ }
182
+ const existing = proposed[label];
183
+ const isInsertTextDifferent = existing?.label !== existingProposeItem && existing?.insertText !== completionItem.insertText;
184
+ if (!existing) {
185
+ proposed[label] = completionItem;
186
+ result.items.push(completionItem);
187
+ }
188
+ else if (isInsertTextDifferent) {
189
+ // try to merge simple insert values
190
+ const mergedText = this.mergeSimpleInsertTexts(label, existing.insertText, completionItem.insertText, oneOfSchema);
191
+ if (mergedText) {
192
+ this.updateCompletionText(existing, mergedText);
181
193
  }
182
- const existing = proposed[label];
183
- const isInsertTextDifferent = (existing === null || existing === void 0 ? void 0 : existing.label) !== existingProposeItem && (existing === null || existing === void 0 ? void 0 : existing.insertText) !== completionItem.insertText;
184
- if (!existing) {
194
+ else {
195
+ // add to result when it wasn't able to merge (even if the item is already there but with a different value)
185
196
  proposed[label] = completionItem;
186
197
  result.items.push(completionItem);
187
198
  }
188
- else if (isInsertTextDifferent) {
189
- // try to merge simple insert values
190
- const mergedText = this.mergeSimpleInsertTexts(label, existing.insertText, completionItem.insertText);
191
- if (mergedText) {
192
- this.updateCompletionText(existing, mergedText);
193
- }
194
- else {
195
- // add to result when it wasn't able to merge (even if the item is already there but with a different value)
196
- proposed[label] = completionItem;
197
- result.items.push(completionItem);
198
- }
199
- }
200
- if (existing && !existing.documentation && completionItem.documentation) {
201
- existing.documentation = completionItem.documentation;
202
- }
203
- },
204
- error: (message) => {
205
- this.telemetry.sendError('yaml.completion.error', { error: convertErrorToTelemetryMsg(message) });
206
- },
207
- log: (message) => {
208
- console.log(message);
209
- },
210
- getNumberOfProposals: () => {
211
- return result.items.length;
212
- },
213
- };
214
- if (this.customTags.length > 0) {
215
- this.getCustomTagValueCompletions(collector);
216
- }
217
- if (lineContent.endsWith('\n')) {
218
- lineContent = lineContent.substr(0, lineContent.length - 1);
199
+ }
200
+ if (existing && !existing.documentation && completionItem.documentation) {
201
+ existing.documentation = completionItem.documentation;
202
+ }
203
+ },
204
+ error: (message) => {
205
+ this.telemetry.sendError('yaml.completion.error', { error: convertErrorToTelemetryMsg(message) });
206
+ },
207
+ log: (message) => {
208
+ console.log(message);
209
+ },
210
+ getNumberOfProposals: () => {
211
+ return result.items.length;
212
+ },
213
+ result,
214
+ };
215
+ if (this.customTags.length > 0) {
216
+ this.getCustomTagValueCompletions(collector);
217
+ }
218
+ if (lineContent.endsWith('\n')) {
219
+ lineContent = lineContent.substr(0, lineContent.length - 1);
220
+ }
221
+ try {
222
+ const schema = await this.schemaService.getSchemaForResource(document.uri, currentDoc);
223
+ if (!schema || schema.errors.length) {
224
+ if (position.line === 0 && position.character === 0 && !isModeline(lineContent)) {
225
+ const inlineSchemaCompletion = {
226
+ kind: CompletionItemKind.Text,
227
+ label: 'Inline schema',
228
+ insertText: '# yaml-language-server: $schema=',
229
+ insertTextFormat: InsertTextFormat.PlainText,
230
+ };
231
+ result.items.push(inlineSchemaCompletion);
232
+ }
219
233
  }
220
- try {
221
- const schema = yield this.schemaService.getSchemaForResource(document.uri, currentDoc);
222
- if (!schema || schema.errors.length) {
223
- if (position.line === 0 && position.character === 0 && !isModeline(lineContent)) {
224
- const inlineSchemaCompletion = {
225
- kind: CompletionItemKind.Text,
226
- label: 'Inline schema',
227
- insertText: '# yaml-language-server: $schema=',
234
+ if (isModeline(lineContent) || isInComment(doc.tokens, offset)) {
235
+ const schemaIndex = lineContent.indexOf('$schema=');
236
+ if (schemaIndex !== -1 && schemaIndex + '$schema='.length <= position.character) {
237
+ this.schemaService.getAllSchemas().forEach((schema) => {
238
+ const schemaIdCompletion = {
239
+ kind: CompletionItemKind.Constant,
240
+ label: schema.name ?? schema.uri,
241
+ detail: schema.description,
242
+ insertText: schema.uri,
228
243
  insertTextFormat: InsertTextFormat.PlainText,
244
+ insertTextMode: InsertTextMode.asIs,
229
245
  };
230
- result.items.push(inlineSchemaCompletion);
231
- }
246
+ result.items.push(schemaIdCompletion);
247
+ });
232
248
  }
233
- if (isModeline(lineContent) || isInComment(doc.tokens, offset)) {
234
- const schemaIndex = lineContent.indexOf('$schema=');
235
- if (schemaIndex !== -1 && schemaIndex + '$schema='.length <= position.character) {
236
- this.schemaService.getAllSchemas().forEach((schema) => {
237
- var _a;
238
- const schemaIdCompletion = {
239
- kind: CompletionItemKind.Constant,
240
- label: (_a = schema.name) !== null && _a !== void 0 ? _a : schema.uri,
241
- detail: schema.description,
242
- insertText: schema.uri,
243
- insertTextFormat: InsertTextFormat.PlainText,
244
- insertTextMode: InsertTextMode.asIs,
245
- };
246
- result.items.push(schemaIdCompletion);
247
- });
248
- }
249
- return result;
249
+ return result;
250
+ }
251
+ if (!schema || schema.errors.length) {
252
+ return result;
253
+ }
254
+ let currentProperty = null;
255
+ if (!node) {
256
+ if (!currentDoc.internalDocument.contents || isScalar(currentDoc.internalDocument.contents)) {
257
+ const map = currentDoc.internalDocument.createNode({});
258
+ map.range = [offset, offset + 1, offset + 1];
259
+ currentDoc.internalDocument.contents = map;
260
+ // eslint-disable-next-line no-self-assign
261
+ currentDoc.internalDocument = currentDoc.internalDocument;
262
+ node = map;
250
263
  }
251
- if (!schema || schema.errors.length) {
252
- return result;
264
+ else {
265
+ node = currentDoc.findClosestNode(offset, textBuffer);
266
+ foundByClosest = true;
253
267
  }
254
- let currentProperty = null;
255
- if (!node) {
256
- if (!currentDoc.internalDocument.contents || isScalar(currentDoc.internalDocument.contents)) {
257
- const map = currentDoc.internalDocument.createNode({});
258
- map.range = [offset, offset + 1, offset + 1];
259
- currentDoc.internalDocument.contents = map;
260
- // eslint-disable-next-line no-self-assign
261
- currentDoc.internalDocument = currentDoc.internalDocument;
262
- node = map;
263
- }
264
- else {
265
- node = currentDoc.findClosestNode(offset, textBuffer);
266
- foundByClosest = true;
267
- }
268
+ }
269
+ const originalNode = node;
270
+ if (node) {
271
+ if (lineContent.length === 0) {
272
+ node = currentDoc.internalDocument.contents;
268
273
  }
269
- const originalNode = node;
270
- if (node) {
271
- if (lineContent.length === 0) {
272
- node = currentDoc.internalDocument.contents;
273
- }
274
- else {
275
- const parent = currentDoc.getParent(node);
276
- if (parent) {
277
- if (isScalar(node)) {
278
- if (node.value) {
279
- if (isPair(parent)) {
280
- if (parent.value === node) {
281
- if (lineContent.trim().length > 0 && lineContent.indexOf(':') < 0) {
282
- const map = this.createTempObjNode(currentWord, node, currentDoc);
283
- const parentParent = currentDoc.getParent(parent);
284
- if (isSeq(currentDoc.internalDocument.contents)) {
285
- const index = indexOf(currentDoc.internalDocument.contents, parent);
286
- if (typeof index === 'number') {
287
- currentDoc.internalDocument.set(index, map);
288
- // eslint-disable-next-line no-self-assign
289
- currentDoc.internalDocument = currentDoc.internalDocument;
290
- }
291
- }
292
- else if (parentParent && (isMap(parentParent) || isSeq(parentParent))) {
293
- parentParent.set(parent.key, map);
294
- // eslint-disable-next-line no-self-assign
295
- currentDoc.internalDocument = currentDoc.internalDocument;
296
- }
297
- else {
298
- currentDoc.internalDocument.set(parent.key, map);
274
+ else {
275
+ const parent = currentDoc.getParent(node);
276
+ if (parent) {
277
+ if (isScalar(node)) {
278
+ if (node.value) {
279
+ if (isPair(parent)) {
280
+ if (parent.value === node) {
281
+ if (lineContent.trim().length > 0 && lineContent.indexOf(':') < 0) {
282
+ const map = this.createTempObjNode(currentWord, node, currentDoc);
283
+ const parentParent = currentDoc.getParent(parent);
284
+ if (isSeq(currentDoc.internalDocument.contents)) {
285
+ const index = indexOf(currentDoc.internalDocument.contents, parent);
286
+ if (typeof index === 'number') {
287
+ currentDoc.internalDocument.set(index, map);
299
288
  // eslint-disable-next-line no-self-assign
300
289
  currentDoc.internalDocument = currentDoc.internalDocument;
301
290
  }
302
- currentProperty = map.items[0];
303
- node = map;
304
291
  }
305
- else if (lineContent.trim().length === 0) {
306
- const parentParent = currentDoc.getParent(parent);
307
- if (parentParent) {
308
- node = parentParent;
309
- }
292
+ else if (parentParent && (isMap(parentParent) || isSeq(parentParent))) {
293
+ parentParent.set(parent.key, map);
294
+ // eslint-disable-next-line no-self-assign
295
+ currentDoc.internalDocument = currentDoc.internalDocument;
296
+ }
297
+ else {
298
+ currentDoc.internalDocument.set(parent.key, map);
299
+ // eslint-disable-next-line no-self-assign
300
+ currentDoc.internalDocument = currentDoc.internalDocument;
310
301
  }
302
+ currentProperty = map.items[0];
303
+ node = map;
311
304
  }
312
- else if (parent.key === node) {
305
+ else if (lineContent.trim().length === 0) {
313
306
  const parentParent = currentDoc.getParent(parent);
314
- currentProperty = parent;
315
307
  if (parentParent) {
316
308
  node = parentParent;
317
309
  }
318
310
  }
319
311
  }
320
- else if (isSeq(parent)) {
321
- if (lineContent.trim().length > 0) {
322
- const map = this.createTempObjNode(currentWord, node, currentDoc);
323
- parent.delete(node);
324
- parent.add(map);
325
- // eslint-disable-next-line no-self-assign
326
- currentDoc.internalDocument = currentDoc.internalDocument;
327
- node = map;
328
- }
329
- else {
330
- node = parent;
312
+ else if (parent.key === node) {
313
+ const parentParent = currentDoc.getParent(parent);
314
+ currentProperty = parent;
315
+ if (parentParent) {
316
+ node = parentParent;
331
317
  }
332
318
  }
333
319
  }
334
- else if (node.value === null) {
335
- if (isPair(parent)) {
336
- if (parent.key === node) {
337
- node = parent;
338
- }
339
- else {
340
- if (isNode(parent.key) && parent.key.range) {
341
- const parentParent = currentDoc.getParent(parent);
342
- if (foundByClosest && parentParent && isMap(parentParent) && isMapContainsEmptyPair(parentParent)) {
343
- node = parentParent;
344
- }
345
- else {
346
- const parentPosition = document.positionAt(parent.key.range[0]);
347
- //if cursor has bigger indentation that parent key, then we need to complete new empty object
348
- if (position.character > parentPosition.character && position.line !== parentPosition.line) {
349
- const map = this.createTempObjNode(currentWord, node, currentDoc);
350
- if (parentParent && (isMap(parentParent) || isSeq(parentParent))) {
351
- parentParent.set(parent.key, map);
352
- // eslint-disable-next-line no-self-assign
353
- currentDoc.internalDocument = currentDoc.internalDocument;
354
- }
355
- else {
356
- currentDoc.internalDocument.set(parent.key, map);
357
- // eslint-disable-next-line no-self-assign
358
- currentDoc.internalDocument = currentDoc.internalDocument;
359
- }
360
- currentProperty = map.items[0];
361
- node = map;
320
+ else if (isSeq(parent)) {
321
+ if (lineContent.trim().length > 0) {
322
+ const map = this.createTempObjNode(currentWord, node, currentDoc);
323
+ parent.delete(node);
324
+ parent.add(map);
325
+ // eslint-disable-next-line no-self-assign
326
+ currentDoc.internalDocument = currentDoc.internalDocument;
327
+ node = map;
328
+ }
329
+ else {
330
+ node = parent;
331
+ }
332
+ }
333
+ }
334
+ else if (node.value === null) {
335
+ if (isPair(parent)) {
336
+ if (parent.key === node) {
337
+ node = parent;
338
+ }
339
+ else {
340
+ if (isNode(parent.key) && parent.key.range) {
341
+ const parentParent = currentDoc.getParent(parent);
342
+ if (foundByClosest && parentParent && isMap(parentParent) && isMapContainsEmptyPair(parentParent)) {
343
+ node = parentParent;
344
+ }
345
+ else {
346
+ const parentPosition = document.positionAt(parent.key.range[0]);
347
+ //if cursor has bigger indentation that parent key, then we need to complete new empty object
348
+ if (position.character > parentPosition.character && position.line !== parentPosition.line) {
349
+ const map = this.createTempObjNode(currentWord, node, currentDoc);
350
+ if (parentParent && (isMap(parentParent) || isSeq(parentParent))) {
351
+ parentParent.set(parent.key, map);
352
+ // eslint-disable-next-line no-self-assign
353
+ currentDoc.internalDocument = currentDoc.internalDocument;
362
354
  }
363
- else if (parentPosition.character === position.character) {
364
- if (parentParent) {
365
- node = parentParent;
366
- }
355
+ else {
356
+ currentDoc.internalDocument.set(parent.key, map);
357
+ // eslint-disable-next-line no-self-assign
358
+ currentDoc.internalDocument = currentDoc.internalDocument;
359
+ }
360
+ currentProperty = map.items[0];
361
+ node = map;
362
+ }
363
+ else if (parentPosition.character === position.character) {
364
+ if (parentParent) {
365
+ node = parentParent;
367
366
  }
368
367
  }
369
368
  }
370
369
  }
371
370
  }
372
- else if (isSeq(parent)) {
373
- if (lineContent.charAt(position.character - 1) !== '-') {
374
- const map = this.createTempObjNode(currentWord, node, currentDoc);
375
- parent.delete(node);
376
- parent.add(map);
377
- // eslint-disable-next-line no-self-assign
378
- currentDoc.internalDocument = currentDoc.internalDocument;
379
- node = map;
380
- }
381
- else if (lineContent.charAt(position.character - 1) === '-') {
382
- const map = this.createTempObjNode('', node, currentDoc);
383
- parent.delete(node);
384
- parent.add(map);
385
- // eslint-disable-next-line no-self-assign
386
- currentDoc.internalDocument = currentDoc.internalDocument;
387
- node = map;
388
- }
389
- else {
390
- node = parent;
391
- }
392
- }
393
371
  }
394
- }
395
- else if (isMap(node)) {
396
- if (!foundByClosest && lineContent.trim().length === 0 && isSeq(parent)) {
397
- const nextLine = textBuffer.getLineContent(position.line + 1);
398
- if (textBuffer.getLineCount() === position.line + 1 || nextLine.trim().length === 0) {
372
+ else if (isSeq(parent)) {
373
+ if (lineContent.charAt(position.character - 1) !== '-') {
374
+ const map = this.createTempObjNode(currentWord, node, currentDoc);
375
+ parent.delete(node);
376
+ parent.add(map);
377
+ // eslint-disable-next-line no-self-assign
378
+ currentDoc.internalDocument = currentDoc.internalDocument;
379
+ node = map;
380
+ }
381
+ else if (lineContent.charAt(position.character - 1) === '-') {
382
+ const map = this.createTempObjNode('', node, currentDoc);
383
+ parent.delete(node);
384
+ parent.add(map);
385
+ // eslint-disable-next-line no-self-assign
386
+ currentDoc.internalDocument = currentDoc.internalDocument;
387
+ node = map;
388
+ }
389
+ else {
399
390
  node = parent;
400
391
  }
401
392
  }
402
393
  }
403
394
  }
404
- else if (isScalar(node)) {
395
+ else if (isMap(node)) {
396
+ if (!foundByClosest && lineContent.trim().length === 0 && isSeq(parent)) {
397
+ const nextLine = textBuffer.getLineContent(position.line + 1);
398
+ if (textBuffer.getLineCount() === position.line + 1 || nextLine.trim().length === 0) {
399
+ node = parent;
400
+ }
401
+ }
402
+ }
403
+ }
404
+ else if (isScalar(node)) {
405
+ const map = this.createTempObjNode(currentWord, node, currentDoc);
406
+ currentDoc.internalDocument.contents = map;
407
+ // eslint-disable-next-line no-self-assign
408
+ currentDoc.internalDocument = currentDoc.internalDocument;
409
+ currentProperty = map.items[0];
410
+ node = map;
411
+ }
412
+ else if (isMap(node)) {
413
+ for (const pair of node.items) {
414
+ if (isNode(pair.value) && pair.value.range && pair.value.range[0] === offset + 1) {
415
+ node = pair.value;
416
+ }
417
+ }
418
+ }
419
+ else if (isSeq(node)) {
420
+ if (lineContent.charAt(position.character - 1) !== '-') {
405
421
  const map = this.createTempObjNode(currentWord, node, currentDoc);
406
- currentDoc.internalDocument.contents = map;
422
+ map.items = [];
407
423
  // eslint-disable-next-line no-self-assign
408
424
  currentDoc.internalDocument = currentDoc.internalDocument;
409
- currentProperty = map.items[0];
410
- node = map;
411
- }
412
- else if (isMap(node)) {
413
425
  for (const pair of node.items) {
414
- if (isNode(pair.value) && pair.value.range && pair.value.range[0] === offset + 1) {
415
- node = pair.value;
426
+ if (isMap(pair)) {
427
+ pair.items.forEach((value) => {
428
+ map.items.push(value);
429
+ });
416
430
  }
417
431
  }
432
+ node = map;
418
433
  }
419
434
  }
420
435
  }
421
- // completion for object keys
422
- if (node && isMap(node)) {
423
- // don't suggest properties that are already present
424
- const properties = node.items;
425
- for (const p of properties) {
426
- if (!currentProperty || currentProperty !== p) {
427
- if (isScalar(p.key)) {
428
- proposed[p.key.value + ''] = CompletionItemBase.create(existingProposeItem);
429
- }
436
+ }
437
+ // completion for object keys
438
+ if (node && isMap(node)) {
439
+ // don't suggest properties that are already present
440
+ const properties = node.items;
441
+ for (const p of properties) {
442
+ if (!currentProperty || currentProperty !== p) {
443
+ if (isScalar(p.key)) {
444
+ proposed[p.key.value + ''] = CompletionItemBase.create(existingProposeItem);
430
445
  }
431
446
  }
432
- this.addPropertyCompletions(schema, currentDoc, node, originalNode, '', collector, textBuffer, overwriteRange, doComplete);
433
- if (!schema && currentWord.length > 0 && text.charAt(offset - currentWord.length - 1) !== '"') {
434
- collector.add({
435
- kind: CompletionItemKind.Property,
436
- label: currentWord,
437
- insertText: this.getInsertTextForProperty(currentWord, null, ''),
438
- insertTextFormat: InsertTextFormat.Snippet,
439
- });
440
- }
441
447
  }
442
- // proposals for values
443
- const types = {};
444
- this.getValueCompletions(schema, currentDoc, node, offset, document, collector, types, doComplete);
445
- }
446
- catch (err) {
447
- this.telemetry.sendError('yaml.completion.error', { error: convertErrorToTelemetryMsg(err) });
448
+ this.addPropertyCompletions(schema, currentDoc, node, originalNode, '', collector, textBuffer, overwriteRange, doComplete);
449
+ if (!schema && currentWord.length > 0 && text.charAt(offset - currentWord.length - 1) !== '"') {
450
+ collector.add({
451
+ kind: CompletionItemKind.Property,
452
+ label: currentWord,
453
+ insertText: this.getInsertTextForProperty(currentWord, null, ''),
454
+ insertTextFormat: InsertTextFormat.Snippet,
455
+ });
456
+ }
448
457
  }
449
- this.finalizeParentCompletion(result);
450
- return result;
451
- });
458
+ // proposals for values
459
+ const types = {};
460
+ this.getValueCompletions(schema, currentDoc, node, offset, document, collector, types, doComplete);
461
+ }
462
+ catch (err) {
463
+ this.telemetry.sendError('yaml.completion.error', { error: convertErrorToTelemetryMsg(err) });
464
+ }
465
+ this.finalizeParentCompletion(result);
466
+ const uniqueItems = result.items.filter((arr, index, self) => index ===
467
+ self.findIndex((item) => item.label === arr.label && item.insertText === arr.insertText && item.kind === arr.kind));
468
+ if (uniqueItems?.length > 0) {
469
+ result.items = uniqueItems;
470
+ }
471
+ return result;
452
472
  }
453
473
  updateCompletionText(completionItem, text) {
454
474
  completionItem.insertText = text;
@@ -456,11 +476,22 @@ export class YamlCompletion {
456
476
  completionItem.textEdit.newText = text;
457
477
  }
458
478
  }
459
- mergeSimpleInsertTexts(label, existingText, addingText) {
479
+ mergeSimpleInsertTexts(label, existingText, addingText, oneOfSchema) {
460
480
  const containsNewLineAfterColon = (value) => {
461
481
  return value.includes('\n');
462
482
  };
483
+ const startWithNewLine = (value) => {
484
+ return value.startsWith('\n');
485
+ };
486
+ const isNullObject = (value) => {
487
+ const index = value.indexOf('\n');
488
+ return index > 0 && value.substring(index, value.length).trim().length === 0;
489
+ };
463
490
  if (containsNewLineAfterColon(existingText) || containsNewLineAfterColon(addingText)) {
491
+ //if the exisiting object null one then replace with the non-null object
492
+ if (oneOfSchema && isNullObject(existingText) && !isNullObject(addingText) && !startWithNewLine(addingText)) {
493
+ return addingText;
494
+ }
464
495
  return undefined;
465
496
  }
466
497
  const existingValues = this.getValuesFromInsertText(existingText);
@@ -541,7 +572,6 @@ export class YamlCompletion {
541
572
  return map;
542
573
  }
543
574
  addPropertyCompletions(schema, doc, node, originalNode, separatorAfter, collector, textBuffer, overwriteRange, doComplete) {
544
- var _a, _b;
545
575
  const matchingSchemas = doc.getMatchingSchemas(schema.schema, -1, null, doComplete);
546
576
  const existingKey = textBuffer.getText(overwriteRange);
547
577
  const lineContent = textBuffer.getLineContent(overwriteRange.start.line);
@@ -550,8 +580,19 @@ export class YamlCompletion {
550
580
  const isInArray = lineContent.trimLeft().indexOf('-') === 0;
551
581
  const nodeParent = doc.getParent(node);
552
582
  const matchOriginal = matchingSchemas.find((it) => it.node.internalNode === originalNode && it.schema.properties);
583
+ const oneOfSchema = matchingSchemas.filter((schema) => schema.schema.oneOf).map((oneOfSchema) => oneOfSchema.schema.oneOf)[0];
584
+ let didOneOfSchemaMatches = false;
585
+ if (oneOfSchema?.length < matchingSchemas.length) {
586
+ oneOfSchema?.forEach((property, index) => {
587
+ if (!matchingSchemas[index]?.schema.oneOf && matchingSchemas[index]?.schema.properties === property.properties) {
588
+ didOneOfSchemaMatches = true;
589
+ }
590
+ });
591
+ }
553
592
  for (const schema of matchingSchemas) {
554
- if (((schema.node.internalNode === node && !matchOriginal) || (schema.node.internalNode === originalNode && !hasColon)) &&
593
+ if (((schema.node.internalNode === node && !matchOriginal) ||
594
+ (schema.node.internalNode === originalNode && !hasColon) ||
595
+ (schema.node.parent?.internalNode === originalNode && !hasColon)) &&
555
596
  !schema.inverted) {
556
597
  this.collectDefaultSnippets(schema.schema, separatorAfter, collector, {
557
598
  newLineFirst: false,
@@ -594,18 +635,10 @@ export class YamlCompletion {
594
635
  textBuffer.getPosition(it.key.range[2]).line === overwriteRange.end.line - 1)) &&
595
636
  pair) {
596
637
  if (Array.isArray(propertySchema.items)) {
597
- this.addSchemaValueCompletions(propertySchema.items[0], separatorAfter, collector, {});
638
+ this.addSchemaValueCompletions(propertySchema.items[0], separatorAfter, collector, {}, 'property');
598
639
  }
599
640
  else if (typeof propertySchema.items === 'object' && propertySchema.items.type === 'object') {
600
- const insertText = `- ${this.getInsertTextForObject(propertySchema.items, separatorAfter, ' ').insertText.trimLeft()}`;
601
- const documentation = this.getDocumentationWithMarkdownText(`Create an item of an array${propertySchema.description ? ' (' + propertySchema.description + ')' : ''}`, insertText);
602
- collector.add({
603
- kind: this.getSuggestionKind(propertySchema.items.type),
604
- label: '- (array item)',
605
- documentation,
606
- insertText,
607
- insertTextFormat: InsertTextFormat.Snippet,
608
- });
641
+ this.addArrayItemValueCompletion(propertySchema.items, separatorAfter, collector);
609
642
  }
610
643
  }
611
644
  let insertText = key;
@@ -614,7 +647,7 @@ export class YamlCompletion {
614
647
  }
615
648
  const isNodeNull = (isScalar(originalNode) && originalNode.value === null) ||
616
649
  (isMap(originalNode) && originalNode.items.length === 0);
617
- const existsParentCompletion = ((_a = schema.schema.required) === null || _a === void 0 ? void 0 : _a.length) > 0;
650
+ const existsParentCompletion = schema.schema.required?.length > 0;
618
651
  if (!this.parentSkeletonSelectedFirst || !isNodeNull || !existsParentCompletion) {
619
652
  collector.add({
620
653
  kind: CompletionItemKind.Property,
@@ -622,10 +655,10 @@ export class YamlCompletion {
622
655
  insertText,
623
656
  insertTextFormat: InsertTextFormat.Snippet,
624
657
  documentation: this.fromMarkup(propertySchema.markdownDescription) || propertySchema.description || '',
625
- });
658
+ }, didOneOfSchemaMatches);
626
659
  }
627
660
  // if the prop is required add it also to parent suggestion
628
- if ((_b = schema.schema.required) === null || _b === void 0 ? void 0 : _b.includes(key)) {
661
+ if (schema.schema.required?.includes(key)) {
629
662
  collector.add({
630
663
  label: key,
631
664
  insertText: this.getInsertTextForProperty(key, propertySchema, separatorAfter, identCompensation + this.indentation),
@@ -647,8 +680,8 @@ export class YamlCompletion {
647
680
  // test:
648
681
  // - item1
649
682
  // it will treated as a property key since `:` has been appended
650
- if (nodeParent && isSeq(nodeParent) && schema.schema.type !== 'object') {
651
- this.addSchemaValueCompletions(schema.schema, separatorAfter, collector, {}, Array.isArray(nodeParent.items));
683
+ if (nodeParent && isSeq(nodeParent) && isPrimitiveType(schema.schema)) {
684
+ this.addSchemaValueCompletions(schema.schema, separatorAfter, collector, {}, 'property', Array.isArray(nodeParent.items));
652
685
  }
653
686
  if (schema.schema.propertyNames && schema.schema.additionalProperties && schema.schema.type === 'object') {
654
687
  const propertyNameSchema = asSchema(schema.schema.propertyNames);
@@ -688,7 +721,7 @@ export class YamlCompletion {
688
721
  node = doc.getParent(node);
689
722
  }
690
723
  if (!node) {
691
- this.addSchemaValueCompletions(schema.schema, '', collector, types);
724
+ this.addSchemaValueCompletions(schema.schema, '', collector, types, 'value');
692
725
  return;
693
726
  }
694
727
  if (isPair(node)) {
@@ -714,54 +747,26 @@ export class YamlCompletion {
714
747
  if (Array.isArray(s.schema.items)) {
715
748
  const index = this.findItemAtOffset(node, document, offset);
716
749
  if (index < s.schema.items.length) {
717
- this.addSchemaValueCompletions(s.schema.items[index], separatorAfter, collector, types);
750
+ this.addSchemaValueCompletions(s.schema.items[index], separatorAfter, collector, types, 'value');
718
751
  }
719
752
  }
720
- else if (typeof s.schema.items === 'object' && s.schema.items.type === 'object') {
721
- const insertText = `- ${this.getInsertTextForObject(s.schema.items, separatorAfter, ' ').insertText.trimLeft()}`;
722
- const documentation = this.getDocumentationWithMarkdownText(`Create an item of an array${s.schema.description ? ' (' + s.schema.description + ')' : ''}`, insertText);
723
- collector.add({
724
- kind: this.getSuggestionKind(s.schema.items.type),
725
- label: '- (array item)',
726
- documentation,
727
- insertText,
728
- insertTextFormat: InsertTextFormat.Snippet,
729
- });
730
- this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
731
- }
732
- else if (typeof s.schema.items === 'object' && s.schema.items.anyOf) {
733
- s.schema.items.anyOf
734
- .filter((i) => typeof i === 'object')
735
- .forEach((i, index) => {
736
- const schemaType = getSchemaTypeName(i);
737
- const insertText = `- ${this.getInsertTextForObject(i, separatorAfter).insertText.trimLeft()}`;
738
- //append insertText to documentation
739
- const schemaTypeTitle = schemaType ? ' type `' + schemaType + '`' : '';
740
- const schemaDescription = s.schema.description ? ' (' + s.schema.description + ')' : '';
741
- const documentation = this.getDocumentationWithMarkdownText(`Create an item of an array${schemaTypeTitle}${schemaDescription}`, insertText);
742
- collector.add({
743
- kind: this.getSuggestionKind(i.type),
744
- label: '- (array item) ' + (schemaType || index + 1),
745
- documentation: documentation,
746
- insertText: insertText,
747
- insertTextFormat: InsertTextFormat.Snippet,
748
- });
749
- });
750
- this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
753
+ else if (typeof s.schema.items === 'object' &&
754
+ (s.schema.items.type === 'object' || isAnyOfAllOfOneOfType(s.schema.items))) {
755
+ this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types, 'value', true);
751
756
  }
752
757
  else {
753
- this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
758
+ this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types, 'value');
754
759
  }
755
760
  }
756
761
  }
757
762
  if (s.schema.properties) {
758
763
  const propertySchema = s.schema.properties[parentKey];
759
764
  if (propertySchema) {
760
- this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
765
+ this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types, 'value');
761
766
  }
762
767
  }
763
768
  else if (s.schema.additionalProperties) {
764
- this.addSchemaValueCompletions(s.schema.additionalProperties, separatorAfter, collector, types);
769
+ this.addSchemaValueCompletions(s.schema.additionalProperties, separatorAfter, collector, types, 'value');
765
770
  }
766
771
  }
767
772
  }
@@ -774,6 +779,21 @@ export class YamlCompletion {
774
779
  }
775
780
  }
776
781
  }
782
+ addArrayItemValueCompletion(schema, separatorAfter, collector, index) {
783
+ const schemaType = getSchemaTypeName(schema);
784
+ const insertText = `- ${this.getInsertTextForObject(schema, separatorAfter).insertText.trimLeft()}`;
785
+ //append insertText to documentation
786
+ const schemaTypeTitle = schemaType ? ' type `' + schemaType + '`' : '';
787
+ const schemaDescription = schema.description ? ' (' + schema.description + ')' : '';
788
+ const documentation = this.getDocumentationWithMarkdownText(`Create an item of an array${schemaTypeTitle}${schemaDescription}`, insertText);
789
+ collector.add({
790
+ kind: this.getSuggestionKind(schema.type),
791
+ label: '- (array item) ' + (schemaType || index),
792
+ documentation: documentation,
793
+ insertText: insertText,
794
+ insertTextFormat: InsertTextFormat.Snippet,
795
+ });
796
+ }
777
797
  getInsertTextForProperty(key, propertySchema, separatorAfter, indent = this.indentation) {
778
798
  const propertyText = this.getInsertTextForValue(key, '', 'string');
779
799
  const resultText = propertyText + ':';
@@ -944,7 +964,9 @@ export class YamlCompletion {
944
964
  case 'boolean':
945
965
  case 'number':
946
966
  case 'integer':
947
- insertText += `${indent}${key}: \${${insertIndex++}:${propertySchema.default}}\n`;
967
+ insertText += `${indent}${
968
+ //added quote if key is null
969
+ key === 'null' ? this.getInsertTextForValue(key, '', 'string') : key}: \${${insertIndex++}:${propertySchema.default}}\n`;
948
970
  break;
949
971
  case 'string':
950
972
  insertText += `${indent}${key}: \${${insertIndex++}:${convertToStringValue(propertySchema.default)}}\n`;
@@ -1073,24 +1095,28 @@ export class YamlCompletion {
1073
1095
  }
1074
1096
  return this.getInsertTextForPlainText(value + separatorAfter);
1075
1097
  }
1076
- addSchemaValueCompletions(schema, separatorAfter, collector, types, isArray) {
1098
+ addSchemaValueCompletions(schema, separatorAfter, collector, types, completionType, isArray) {
1077
1099
  if (typeof schema === 'object') {
1078
1100
  this.addEnumValueCompletions(schema, separatorAfter, collector, isArray);
1079
1101
  this.addDefaultValueCompletions(schema, separatorAfter, collector);
1080
1102
  this.collectTypes(schema, types);
1103
+ if (isArray && completionType === 'value' && !isAnyOfAllOfOneOfType(schema)) {
1104
+ // add array only for final types (no anyOf, allOf, oneOf)
1105
+ this.addArrayItemValueCompletion(schema, separatorAfter, collector);
1106
+ }
1081
1107
  if (Array.isArray(schema.allOf)) {
1082
1108
  schema.allOf.forEach((s) => {
1083
- return this.addSchemaValueCompletions(s, separatorAfter, collector, types);
1109
+ return this.addSchemaValueCompletions(s, separatorAfter, collector, types, completionType, isArray);
1084
1110
  });
1085
1111
  }
1086
1112
  if (Array.isArray(schema.anyOf)) {
1087
1113
  schema.anyOf.forEach((s) => {
1088
- return this.addSchemaValueCompletions(s, separatorAfter, collector, types);
1114
+ return this.addSchemaValueCompletions(s, separatorAfter, collector, types, completionType, isArray);
1089
1115
  });
1090
1116
  }
1091
1117
  if (Array.isArray(schema.oneOf)) {
1092
1118
  schema.oneOf.forEach((s) => {
1093
- return this.addSchemaValueCompletions(s, separatorAfter, collector, types);
1119
+ return this.addSchemaValueCompletions(s, separatorAfter, collector, types, completionType, isArray);
1094
1120
  });
1095
1121
  }
1096
1122
  }
@@ -1263,7 +1289,7 @@ export class YamlCompletion {
1263
1289
  }
1264
1290
  return value;
1265
1291
  };
1266
- return stringifyObject(value, '', replacer, Object.assign(Object.assign({}, settings), { indentation: this.indentation }), depth) + separatorAfter;
1292
+ return stringifyObject(value, '', replacer, { ...settings, indentation: this.indentation }, depth) + separatorAfter;
1267
1293
  }
1268
1294
  addBooleanValueCompletion(value, separatorAfter, collector) {
1269
1295
  collector.add({
@@ -1430,8 +1456,7 @@ function convertToStringValue(param) {
1430
1456
  * simplify `{$1:value}` to `value`
1431
1457
  */
1432
1458
  function evaluateTab1Symbol(value) {
1433
- const result = value.replace(/\$\{1:(.*)\}/, '$1');
1434
- return result;
1459
+ return value.replace(/\$\{1:(.*)\}/, '$1');
1435
1460
  }
1436
1461
  function isParentCompletionItem(item) {
1437
1462
  return 'parent' in item;