@eclipse-lyra/core 0.0.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 (281) hide show
  1. package/dist/api/base-classes.d.ts +7 -0
  2. package/dist/api/base-classes.d.ts.map +1 -0
  3. package/dist/api/constants.d.ts +2 -0
  4. package/dist/api/constants.d.ts.map +1 -0
  5. package/dist/api/index.d.ts +6 -0
  6. package/dist/api/index.d.ts.map +1 -0
  7. package/dist/api/index.js +84 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/api/services.d.ts +28 -0
  10. package/dist/api/services.d.ts.map +1 -0
  11. package/dist/api/types.d.ts +11 -0
  12. package/dist/api/types.d.ts.map +1 -0
  13. package/dist/commands/editor.d.ts +1 -0
  14. package/dist/commands/editor.d.ts.map +1 -0
  15. package/dist/commands/files.d.ts +2 -0
  16. package/dist/commands/files.d.ts.map +1 -0
  17. package/dist/commands/global.d.ts +1 -0
  18. package/dist/commands/global.d.ts.map +1 -0
  19. package/dist/commands/index.d.ts +1 -0
  20. package/dist/commands/index.d.ts.map +1 -0
  21. package/dist/commands/open-view-as-editor.d.ts +2 -0
  22. package/dist/commands/open-view-as-editor.d.ts.map +1 -0
  23. package/dist/commands/version-info.d.ts +2 -0
  24. package/dist/commands/version-info.d.ts.map +1 -0
  25. package/dist/components/app-selector.d.ts +17 -0
  26. package/dist/components/app-selector.d.ts.map +1 -0
  27. package/dist/components/app-switcher.d.ts +13 -0
  28. package/dist/components/app-switcher.d.ts.map +1 -0
  29. package/dist/components/command.d.ts +31 -0
  30. package/dist/components/command.d.ts.map +1 -0
  31. package/dist/components/extensions.d.ts +32 -0
  32. package/dist/components/extensions.d.ts.map +1 -0
  33. package/dist/components/fastviews.d.ts +34 -0
  34. package/dist/components/fastviews.d.ts.map +1 -0
  35. package/dist/components/filebrowser.d.ts +45 -0
  36. package/dist/components/filebrowser.d.ts.map +1 -0
  37. package/dist/components/index.d.ts +1 -0
  38. package/dist/components/index.d.ts.map +1 -0
  39. package/dist/components/language-selector.d.ts +12 -0
  40. package/dist/components/language-selector.d.ts.map +1 -0
  41. package/dist/components/log-terminal.d.ts +36 -0
  42. package/dist/components/log-terminal.d.ts.map +1 -0
  43. package/dist/components/part-name.d.ts +12 -0
  44. package/dist/components/part-name.d.ts.map +1 -0
  45. package/dist/components/tasks.d.ts +13 -0
  46. package/dist/components/tasks.d.ts.map +1 -0
  47. package/dist/contributions/default-ui-contributions.d.ts +2 -0
  48. package/dist/contributions/default-ui-contributions.d.ts.map +1 -0
  49. package/dist/contributions/index.d.ts +1 -0
  50. package/dist/contributions/index.d.ts.map +1 -0
  51. package/dist/contributions/marketplace-catalog-contributions.d.ts +2 -0
  52. package/dist/contributions/marketplace-catalog-contributions.d.ts.map +1 -0
  53. package/dist/core/app-host-config.d.ts +7 -0
  54. package/dist/core/app-host-config.d.ts.map +1 -0
  55. package/dist/core/apploader.d.ts +214 -0
  56. package/dist/core/apploader.d.ts.map +1 -0
  57. package/dist/core/appstate.d.ts +12 -0
  58. package/dist/core/appstate.d.ts.map +1 -0
  59. package/dist/core/commandregistry.d.ts +79 -0
  60. package/dist/core/commandregistry.d.ts.map +1 -0
  61. package/dist/core/config.d.ts +15 -0
  62. package/dist/core/config.d.ts.map +1 -0
  63. package/dist/core/constants.d.ts +22 -0
  64. package/dist/core/constants.d.ts.map +1 -0
  65. package/dist/core/contributionregistry.d.ts +53 -0
  66. package/dist/core/contributionregistry.d.ts.map +1 -0
  67. package/dist/core/di.d.ts +18 -0
  68. package/dist/core/di.d.ts.map +1 -0
  69. package/dist/core/dialogservice.d.ts +33 -0
  70. package/dist/core/dialogservice.d.ts.map +1 -0
  71. package/dist/core/editorregistry.d.ts +87 -0
  72. package/dist/core/editorregistry.d.ts.map +1 -0
  73. package/dist/core/esmsh-service.d.ts +40 -0
  74. package/dist/core/esmsh-service.d.ts.map +1 -0
  75. package/dist/core/events.d.ts +7 -0
  76. package/dist/core/events.d.ts.map +1 -0
  77. package/dist/core/events.js +63 -0
  78. package/dist/core/events.js.map +1 -0
  79. package/dist/core/extensionregistry.d.ts +98 -0
  80. package/dist/core/extensionregistry.d.ts.map +1 -0
  81. package/dist/core/filesys/common.d.ts +122 -0
  82. package/dist/core/filesys/common.d.ts.map +1 -0
  83. package/dist/core/filesys/fs-access.d.ts +31 -0
  84. package/dist/core/filesys/fs-access.d.ts.map +1 -0
  85. package/dist/core/filesys/index.d.ts +5 -0
  86. package/dist/core/filesys/index.d.ts.map +1 -0
  87. package/dist/core/filesys/indexeddb.d.ts +41 -0
  88. package/dist/core/filesys/indexeddb.d.ts.map +1 -0
  89. package/dist/core/filesys/opfs.d.ts +14 -0
  90. package/dist/core/filesys/opfs.d.ts.map +1 -0
  91. package/dist/core/i18n.d.ts +50 -0
  92. package/dist/core/i18n.d.ts.map +1 -0
  93. package/dist/core/index.d.ts +1 -0
  94. package/dist/core/index.d.ts.map +1 -0
  95. package/dist/core/keybindings.d.ts +67 -0
  96. package/dist/core/keybindings.d.ts.map +1 -0
  97. package/dist/core/logger.d.ts +44 -0
  98. package/dist/core/logger.d.ts.map +1 -0
  99. package/dist/core/marketplaceregistry.d.ts +25 -0
  100. package/dist/core/marketplaceregistry.d.ts.map +1 -0
  101. package/dist/core/packageinfoservice.d.ts +16 -0
  102. package/dist/core/packageinfoservice.d.ts.map +1 -0
  103. package/dist/core/persistenceservice.d.ts +6 -0
  104. package/dist/core/persistenceservice.d.ts.map +1 -0
  105. package/dist/core/settingsservice.d.ts +54 -0
  106. package/dist/core/settingsservice.d.ts.map +1 -0
  107. package/dist/core/signals.d.ts +3 -0
  108. package/dist/core/signals.d.ts.map +1 -0
  109. package/dist/core/taskservice.d.ts +20 -0
  110. package/dist/core/taskservice.d.ts.map +1 -0
  111. package/dist/core/toast.d.ts +4 -0
  112. package/dist/core/toast.d.ts.map +1 -0
  113. package/dist/core/tree-utils.d.ts +16 -0
  114. package/dist/core/tree-utils.d.ts.map +1 -0
  115. package/dist/dialogs/confirm-dialog.d.ts +14 -0
  116. package/dist/dialogs/confirm-dialog.d.ts.map +1 -0
  117. package/dist/dialogs/index.d.ts +5 -0
  118. package/dist/dialogs/index.d.ts.map +1 -0
  119. package/dist/dialogs/info-dialog.d.ts +13 -0
  120. package/dist/dialogs/info-dialog.d.ts.map +1 -0
  121. package/dist/dialogs/navigable-info-dialog.d.ts +33 -0
  122. package/dist/dialogs/navigable-info-dialog.d.ts.map +1 -0
  123. package/dist/dialogs/prompt-dialog.d.ts +21 -0
  124. package/dist/dialogs/prompt-dialog.d.ts.map +1 -0
  125. package/dist/externals/lit.d.ts +21 -0
  126. package/dist/externals/lit.d.ts.map +1 -0
  127. package/dist/externals/lit.js +24 -0
  128. package/dist/externals/lit.js.map +1 -0
  129. package/dist/externals/third-party.d.ts +7 -0
  130. package/dist/externals/third-party.d.ts.map +1 -0
  131. package/dist/externals/third-party.js +7 -0
  132. package/dist/externals/third-party.js.map +1 -0
  133. package/dist/externals/webawesome.d.ts +1 -0
  134. package/dist/externals/webawesome.d.ts.map +1 -0
  135. package/dist/externals/webawesome.js +75 -0
  136. package/dist/externals/webawesome.js.map +1 -0
  137. package/dist/i18n/extensions.json.d.ts +42 -0
  138. package/dist/i18n/fastviews.json.d.ts +13 -0
  139. package/dist/i18n/filebrowser.json.d.ts +29 -0
  140. package/dist/i18n/index.d.ts +2 -0
  141. package/dist/i18n/index.d.ts.map +1 -0
  142. package/dist/i18n/logterminal.json.d.ts +45 -0
  143. package/dist/i18n/partname.json.d.ts +15 -0
  144. package/dist/i18n/tasks.json.d.ts +15 -0
  145. package/dist/i18n/workspace.json.d.ts +15 -0
  146. package/dist/icon-DN6fp0dg.js +487 -0
  147. package/dist/icon-DN6fp0dg.js.map +1 -0
  148. package/dist/index.d.ts +2 -0
  149. package/dist/index.d.ts.map +1 -0
  150. package/dist/index.js +84 -0
  151. package/dist/index.js.map +1 -0
  152. package/dist/layouts/standard-layout.d.ts +16 -0
  153. package/dist/layouts/standard-layout.d.ts.map +1 -0
  154. package/dist/nocontent-BhrN6yxJ.js +48 -0
  155. package/dist/nocontent-BhrN6yxJ.js.map +1 -0
  156. package/dist/parts/container.d.ts +4 -0
  157. package/dist/parts/container.d.ts.map +1 -0
  158. package/dist/parts/contextmenu.d.ts +50 -0
  159. package/dist/parts/contextmenu.d.ts.map +1 -0
  160. package/dist/parts/dialog-content.d.ts +9 -0
  161. package/dist/parts/dialog-content.d.ts.map +1 -0
  162. package/dist/parts/element.d.ts +36 -0
  163. package/dist/parts/element.d.ts.map +1 -0
  164. package/dist/parts/index.d.ts +1 -0
  165. package/dist/parts/index.d.ts.map +1 -0
  166. package/dist/parts/index.js +3 -0
  167. package/dist/parts/index.js.map +1 -0
  168. package/dist/parts/part.d.ts +96 -0
  169. package/dist/parts/part.d.ts.map +1 -0
  170. package/dist/parts/resizable-grid.d.ts +31 -0
  171. package/dist/parts/resizable-grid.d.ts.map +1 -0
  172. package/dist/parts/tabs.d.ts +75 -0
  173. package/dist/parts/tabs.d.ts.map +1 -0
  174. package/dist/parts/toolbar.d.ts +35 -0
  175. package/dist/parts/toolbar.d.ts.map +1 -0
  176. package/dist/resizable-grid-BRH3MyZK.js +3813 -0
  177. package/dist/resizable-grid-BRH3MyZK.js.map +1 -0
  178. package/dist/standard-layout-BSGa06lP.js +4907 -0
  179. package/dist/standard-layout-BSGa06lP.js.map +1 -0
  180. package/dist/widgets/icon.d.ts +10 -0
  181. package/dist/widgets/icon.d.ts.map +1 -0
  182. package/dist/widgets/index.d.ts +1 -0
  183. package/dist/widgets/index.d.ts.map +1 -0
  184. package/dist/widgets/index.js +3 -0
  185. package/dist/widgets/index.js.map +1 -0
  186. package/dist/widgets/nocontent.d.ts +13 -0
  187. package/dist/widgets/nocontent.d.ts.map +1 -0
  188. package/dist/widgets/widget.d.ts +25 -0
  189. package/dist/widgets/widget.d.ts.map +1 -0
  190. package/package.json +81 -0
  191. package/src/api/base-classes.ts +10 -0
  192. package/src/api/constants.ts +3 -0
  193. package/src/api/index.ts +31 -0
  194. package/src/api/services.ts +58 -0
  195. package/src/api/types.ts +46 -0
  196. package/src/commands/editor.ts +1 -0
  197. package/src/commands/files.ts +425 -0
  198. package/src/commands/global.ts +198 -0
  199. package/src/commands/index.ts +6 -0
  200. package/src/commands/open-view-as-editor.ts +28 -0
  201. package/src/commands/version-info.ts +214 -0
  202. package/src/components/app-selector.ts +233 -0
  203. package/src/components/app-switcher.ts +126 -0
  204. package/src/components/command.ts +236 -0
  205. package/src/components/extensions.ts +615 -0
  206. package/src/components/fastviews.ts +314 -0
  207. package/src/components/filebrowser.ts +518 -0
  208. package/src/components/index.ts +9 -0
  209. package/src/components/language-selector.ts +166 -0
  210. package/src/components/log-terminal.ts +337 -0
  211. package/src/components/part-name.ts +54 -0
  212. package/src/components/tasks.ts +275 -0
  213. package/src/contributions/default-ui-contributions.ts +44 -0
  214. package/src/contributions/index.ts +3 -0
  215. package/src/contributions/marketplace-catalog-contributions.ts +6 -0
  216. package/src/core/app-host-config.ts +23 -0
  217. package/src/core/apploader.ts +630 -0
  218. package/src/core/appstate.ts +15 -0
  219. package/src/core/commandregistry.ts +210 -0
  220. package/src/core/config.ts +29 -0
  221. package/src/core/constants.ts +29 -0
  222. package/src/core/contributionregistry.ts +81 -0
  223. package/src/core/di.ts +54 -0
  224. package/src/core/dialogservice.ts +266 -0
  225. package/src/core/editorregistry.ts +347 -0
  226. package/src/core/esmsh-service.ts +404 -0
  227. package/src/core/events.ts +68 -0
  228. package/src/core/extensionregistry.ts +399 -0
  229. package/src/core/filesys/common.ts +474 -0
  230. package/src/core/filesys/fs-access.ts +339 -0
  231. package/src/core/filesys/index.ts +5 -0
  232. package/src/core/filesys/indexeddb.ts +596 -0
  233. package/src/core/filesys/opfs.ts +95 -0
  234. package/src/core/i18n.ts +221 -0
  235. package/src/core/index.ts +51 -0
  236. package/src/core/keybindings.ts +274 -0
  237. package/src/core/logger.ts +187 -0
  238. package/src/core/marketplaceregistry.ts +197 -0
  239. package/src/core/packageinfoservice.ts +56 -0
  240. package/src/core/persistenceservice.ts +46 -0
  241. package/src/core/settingsservice.ts +191 -0
  242. package/src/core/signals.ts +18 -0
  243. package/src/core/taskservice.ts +72 -0
  244. package/src/core/toast.ts +21 -0
  245. package/src/core/tree-utils.ts +24 -0
  246. package/src/dialogs/confirm-dialog.ts +72 -0
  247. package/src/dialogs/index.ts +4 -0
  248. package/src/dialogs/info-dialog.ts +67 -0
  249. package/src/dialogs/navigable-info-dialog.ts +256 -0
  250. package/src/dialogs/prompt-dialog.ts +123 -0
  251. package/src/externals/lit.ts +36 -0
  252. package/src/externals/third-party.ts +10 -0
  253. package/src/externals/webawesome.ts +76 -0
  254. package/src/i18n/extensions.json +39 -0
  255. package/src/i18n/fastviews.json +10 -0
  256. package/src/i18n/filebrowser.json +27 -0
  257. package/src/i18n/index.ts +25 -0
  258. package/src/i18n/logterminal.json +42 -0
  259. package/src/i18n/partname.json +12 -0
  260. package/src/i18n/tasks.json +12 -0
  261. package/src/i18n/workspace.json +12 -0
  262. package/src/icons/icons.txt +3 -0
  263. package/src/icons/js.svg +6 -0
  264. package/src/icons/jupyter.svg +18 -0
  265. package/src/icons/python.svg +15 -0
  266. package/src/index.ts +3 -0
  267. package/src/layouts/standard-layout.ts +174 -0
  268. package/src/parts/container.ts +4 -0
  269. package/src/parts/contextmenu.ts +266 -0
  270. package/src/parts/dialog-content.ts +31 -0
  271. package/src/parts/element.ts +100 -0
  272. package/src/parts/index.ts +5 -0
  273. package/src/parts/part.ts +158 -0
  274. package/src/parts/resizable-grid.ts +366 -0
  275. package/src/parts/tabs.ts +581 -0
  276. package/src/parts/toolbar.ts +260 -0
  277. package/src/vite-env.d.ts +16 -0
  278. package/src/widgets/icon.ts +38 -0
  279. package/src/widgets/index.ts +2 -0
  280. package/src/widgets/nocontent.ts +40 -0
  281. package/src/widgets/widget.ts +92 -0
@@ -0,0 +1,347 @@
1
+ import { EDITOR_AREA_MAIN } from "./constants";
2
+ import { LyraPart } from "../parts/part";
3
+ import { activePartSignal, activeEditorSignal, partDirtySignal } from "./appstate";
4
+ import { watchSignal } from "./signals";
5
+ import { subscribe } from "./events";
6
+ import { TOPIC_WORKSPACE_CONNECTED } from "./filesys";
7
+ import { LyraTabs } from "../parts/tabs";
8
+ import { TabContribution, IconContribution, contributionRegistry, TOPIC_CONTRIBUTEIONS_CHANGED } from "./contributionregistry";
9
+ import { rootContext } from "./di";
10
+
11
+ export const EVENT_SHOW_EDITOR = "editors/showEditor";
12
+
13
+ export interface EditorInput {
14
+ key: string;
15
+ title: string;
16
+ icon?: string;
17
+ data: any;
18
+ noOverflow?: boolean;
19
+ widgetFactory: (container: any, tab: HTMLElement) => any;
20
+ state: { [key: string]: any };
21
+ }
22
+
23
+ export interface EditorInputHandler {
24
+ editorId: string;
25
+ label: string;
26
+ icon?: string;
27
+ canHandle: (input: any) => boolean;
28
+ handle: (input: any) => Promise<EditorInput>;
29
+ lazyInit?: () => Promise<void> | void;
30
+ ranking?: number;
31
+ }
32
+
33
+ interface RegisteredEditorInputHandler {
34
+ definition: EditorInputHandler;
35
+ initialized: boolean;
36
+ lazyInitPromise?: Promise<void>;
37
+ }
38
+
39
+ /**
40
+ * Interface for editors that can provide content, selection, and snippets.
41
+ * Implement this interface to make editor content accessible via commands.
42
+ */
43
+ export interface EditorContentProvider {
44
+ /**
45
+ * Gets the complete contents of the editor.
46
+ * @returns The full content as a string, or null if not available.
47
+ */
48
+ getContent(): string | null;
49
+
50
+ /**
51
+ * Gets the currently selected text in the editor.
52
+ * @returns The selected text, or null if no selection exists.
53
+ */
54
+ getSelection(): string | null;
55
+
56
+ /**
57
+ * Gets a code snippet with n lines before and after the cursor position.
58
+ * @param lines Number of lines before and after the cursor (default: 5).
59
+ * @returns An object containing the snippet, cursor line number, or null if not available.
60
+ */
61
+ getSnippet(lines?: number): { snippet: string; cursorLine: number } | null;
62
+
63
+ /**
64
+ * Gets the programming language of the editor content.
65
+ * @returns The language identifier (e.g., 'python', 'javascript'), or null if not available.
66
+ */
67
+ getLanguage(): string | null;
68
+
69
+ /**
70
+ * Returns whether the editor content is in the given language (case-insensitive).
71
+ * Default implementation can use getLanguage() === lang.toLowerCase().
72
+ */
73
+ isLanguage?(lang: string): boolean;
74
+
75
+ /**
76
+ * Gets the workspace path of the file being edited.
77
+ * @returns The file path relative to the workspace, or null if not available.
78
+ */
79
+ getFilePath(): string | null;
80
+ }
81
+
82
+ class EditorRegistry {
83
+ private editorInputHandlers: RegisteredEditorInputHandler[] = [];
84
+ private listenersAttached = false;
85
+ private cachedIconContributions: IconContribution[] | null = null;
86
+ private signalCleanup?: () => void;
87
+
88
+ constructor() {
89
+ subscribe(TOPIC_WORKSPACE_CONNECTED, () => {
90
+ // TODO close all editors
91
+ });
92
+
93
+ subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event: any) => {
94
+ if (event.target === 'system.icons') {
95
+ this.cachedIconContributions = null;
96
+ }
97
+ });
98
+ }
99
+
100
+ private getSortedIconContributions(): IconContribution[] {
101
+ if (this.cachedIconContributions !== null) {
102
+ return this.cachedIconContributions;
103
+ }
104
+
105
+ const contributions = contributionRegistry.getContributions('system.icons') as IconContribution[];
106
+
107
+ // Sort by priority (higher priority first), then by label for tie-breaking
108
+ this.cachedIconContributions = [...contributions].sort((a, b) => {
109
+ const priorityA = a.priority ?? 0;
110
+ const priorityB = b.priority ?? 0;
111
+ if (priorityB !== priorityA) {
112
+ // Higher priority comes first (descending order)
113
+ return priorityB - priorityA;
114
+ }
115
+ return a.label.localeCompare(b.label);
116
+ });
117
+
118
+ return this.cachedIconContributions;
119
+ }
120
+
121
+ private setupEventListeners(editorArea: LyraTabs) {
122
+ if (this.listenersAttached) {
123
+ return;
124
+ }
125
+ this.listenersAttached = true;
126
+
127
+ const handler = (event: CustomEvent) => {
128
+ const tabPanel = event.detail
129
+ if (tabPanel) {
130
+ const parts = Array.from(tabPanel.querySelectorAll(`*`)).filter((element): element is LyraPart => element instanceof LyraPart)
131
+ parts.forEach((part) => {
132
+ activePartSignal.set(part)
133
+ // Only update activeEditorSignal if this is an editor part
134
+ if ((part as LyraPart).isEditor) {
135
+ activeEditorSignal.set(part)
136
+ }
137
+ })
138
+ }
139
+ }
140
+ // @ts-ignore
141
+ editorArea.addEventListener("tab-shown", handler)
142
+
143
+ const closed = (event: CustomEvent) => {
144
+ const tabPanel: HTMLElement = event.detail
145
+ const parts = Array.from(tabPanel.querySelectorAll(`*`)).filter((element): element is LyraPart => element instanceof LyraPart)
146
+ parts.forEach((part) => {
147
+ // part.close() will be automatically called by disconnected callback of part
148
+ if (activePartSignal.get() == part) {
149
+ activePartSignal.set(null as unknown as LyraPart)
150
+ }
151
+ if (activeEditorSignal.get() == part) {
152
+ activeEditorSignal.set(null as unknown as LyraPart)
153
+ }
154
+ })
155
+ }
156
+ // @ts-ignore
157
+ editorArea.addEventListener("tab-closed", closed)
158
+
159
+ const dirtyHandler = (targetPart: LyraPart) => {
160
+ const tabPanel = targetPart.closest("wa-tab-panel") as HTMLElement
161
+ const name = tabPanel.getAttribute("name") as string
162
+ editorArea.markDirty(name, targetPart.isDirty())
163
+ }
164
+ this.signalCleanup = watchSignal(partDirtySignal, dirtyHandler)
165
+ }
166
+
167
+ registerEditorInputHandler(editorInputHandler: EditorInputHandler) {
168
+ this.editorInputHandlers.push({
169
+ definition: editorInputHandler,
170
+ initialized: false
171
+ });
172
+ // Sort by ranking (higher ranking first), default ranking is 0
173
+ this.editorInputHandlers.sort((a, b) => {
174
+ const rankA = a.definition.ranking ?? 0;
175
+ const rankB = b.definition.ranking ?? 0;
176
+ return rankB - rankA;
177
+ });
178
+ }
179
+
180
+ private async ensureHandlerInitialized(entry: RegisteredEditorInputHandler): Promise<void> {
181
+ const handler = entry.definition;
182
+ if (!handler.lazyInit || entry.initialized) {
183
+ return;
184
+ }
185
+
186
+ if (!entry.lazyInitPromise) {
187
+ entry.lazyInitPromise = Promise.resolve(handler.lazyInit()).then(() => {
188
+ entry.initialized = true;
189
+ entry.lazyInitPromise = undefined;
190
+ }).catch(error => {
191
+ entry.lazyInitPromise = undefined;
192
+ throw error;
193
+ });
194
+ }
195
+
196
+ await entry.lazyInitPromise;
197
+ }
198
+
199
+ getEditorOptionsForInput(input: any): Array<{ editorId: string; title: string; icon?: string }> {
200
+ const seen = new Set<string>();
201
+ const options: Array<{ editorId: string; title: string; icon?: string }> = [];
202
+ for (const entry of this.editorInputHandlers) {
203
+ const handler = entry.definition;
204
+ if (!handler.canHandle(input) || seen.has(handler.editorId)) continue;
205
+ seen.add(handler.editorId);
206
+ options.push({
207
+ editorId: handler.editorId,
208
+ title: handler.label,
209
+ icon: handler.icon
210
+ });
211
+ }
212
+ return options;
213
+ }
214
+
215
+ async handleInput(input: any, preferredEditorId?: string) {
216
+ if (preferredEditorId !== undefined) {
217
+ const entry = this.editorInputHandlers.find(
218
+ e => e.definition.editorId === preferredEditorId
219
+ );
220
+ if (entry) {
221
+ await this.ensureHandlerInitialized(entry);
222
+ const result = await entry.definition.handle(input);
223
+ if (result) (result as unknown as Record<string, unknown>).editorId = entry.definition.editorId;
224
+ return result;
225
+ }
226
+ return undefined;
227
+ }
228
+ for (let i = 0; i < this.editorInputHandlers.length; i++) {
229
+ const entry = this.editorInputHandlers[i];
230
+ const editorInputHandler = entry.definition;
231
+ if (editorInputHandler.canHandle(input)) {
232
+ await this.ensureHandlerInitialized(entry);
233
+ const result = await editorInputHandler.handle(input);
234
+ if (result) (result as unknown as Record<string, unknown>).editorId = editorInputHandler.editorId;
235
+ return result;
236
+ }
237
+ }
238
+ }
239
+
240
+ getEditorArea(): LyraTabs | null {
241
+ return document.querySelector(`lyra-tabs#${EDITOR_AREA_MAIN}`) as LyraTabs | null
242
+ }
243
+
244
+ async loadEditor(editorInput: EditorInput | any, preferredEditorId?: string) {
245
+ if (!editorInput) {
246
+ return
247
+ }
248
+
249
+ if (!("widgetFactory" in editorInput)) {
250
+ editorInput = await this.handleInput(editorInput, preferredEditorId)
251
+ }
252
+
253
+ if (!editorInput || !("widgetFactory" in editorInput)) {
254
+ return
255
+ }
256
+
257
+ const editorId = (editorInput as Record<string, unknown>).editorId as string | undefined ?? preferredEditorId;
258
+ if (editorId) (editorInput as Record<string, unknown>).editorId = editorId;
259
+
260
+ await this.openTab({
261
+ name: editorInput.key,
262
+ editorId,
263
+ label: editorInput.title,
264
+ icon: editorInput.icon,
265
+ closable: true,
266
+ noOverflow: editorInput.noOverflow,
267
+ component: editorInput.widgetFactory
268
+ } as TabContribution)
269
+ }
270
+
271
+ async openTab(tabContribution: TabContribution) {
272
+ const editorArea = this.getEditorArea();
273
+
274
+ if (!editorArea) {
275
+ console.error("Editor area not found. The split pane system may not be initialized yet.");
276
+ return;
277
+ }
278
+
279
+ this.setupEventListeners(editorArea);
280
+
281
+ if (editorArea.has(tabContribution.name)) {
282
+ editorArea.activate(tabContribution.name)
283
+ return
284
+ }
285
+
286
+ editorArea.open(tabContribution)
287
+ }
288
+
289
+ getFileIcon(fileNameOrType: string): string {
290
+ const extension = fileNameOrType.includes('.')
291
+ ? fileNameOrType.split('.').pop()?.toLowerCase() || ''
292
+ : fileNameOrType.toLowerCase();
293
+
294
+ const sortedContributions = this.getSortedIconContributions();
295
+
296
+ if (sortedContributions.length === 0) {
297
+ return 'file';
298
+ }
299
+
300
+ for (const contribution of sortedContributions) {
301
+ if (contribution.mappings && contribution.mappings[extension]) {
302
+ return contribution.mappings[extension];
303
+ }
304
+ }
305
+
306
+ return 'file';
307
+ }
308
+ }
309
+
310
+ export const editorRegistry = new EditorRegistry();
311
+ rootContext.put("editorRegistry", editorRegistry);
312
+
313
+ contributionRegistry.registerContribution<IconContribution>('system.icons', {
314
+ label: 'Default File Icons',
315
+ mappings: {
316
+ 'pdf': 'file-pdf',
317
+ 'md': 'book',
318
+ 'txt': 'file-lines',
319
+ 'ts': 'code',
320
+ 'tsx': 'code',
321
+ 'js': 'code',
322
+ 'jsx': 'code',
323
+ 'json': 'file-code',
324
+ 'geojson': 'file-code',
325
+ 'py': 'python',
326
+ 'html': 'code',
327
+ 'htm': 'code',
328
+ 'css': 'code',
329
+ 'scss': 'code',
330
+ 'sass': 'code',
331
+ 'xml': 'file-code',
332
+ 'yaml': 'file-code',
333
+ 'yml': 'file-code',
334
+ 'sql': 'database',
335
+ 'kml': 'file-code',
336
+ 'gpx': 'file-code',
337
+ 'jpg': 'image',
338
+ 'jpeg': 'image',
339
+ 'png': 'image',
340
+ 'gif': 'image',
341
+ 'svg': 'image',
342
+ 'webp': 'image',
343
+ 'bmp': 'image',
344
+ 'ico': 'image',
345
+ },
346
+ priority: 0
347
+ });