@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.
- package/dist/api/base-classes.d.ts +7 -0
- package/dist/api/base-classes.d.ts.map +1 -0
- package/dist/api/constants.d.ts +2 -0
- package/dist/api/constants.d.ts.map +1 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +84 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/services.d.ts +28 -0
- package/dist/api/services.d.ts.map +1 -0
- package/dist/api/types.d.ts +11 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/commands/editor.d.ts +1 -0
- package/dist/commands/editor.d.ts.map +1 -0
- package/dist/commands/files.d.ts +2 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/global.d.ts +1 -0
- package/dist/commands/global.d.ts.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/open-view-as-editor.d.ts +2 -0
- package/dist/commands/open-view-as-editor.d.ts.map +1 -0
- package/dist/commands/version-info.d.ts +2 -0
- package/dist/commands/version-info.d.ts.map +1 -0
- package/dist/components/app-selector.d.ts +17 -0
- package/dist/components/app-selector.d.ts.map +1 -0
- package/dist/components/app-switcher.d.ts +13 -0
- package/dist/components/app-switcher.d.ts.map +1 -0
- package/dist/components/command.d.ts +31 -0
- package/dist/components/command.d.ts.map +1 -0
- package/dist/components/extensions.d.ts +32 -0
- package/dist/components/extensions.d.ts.map +1 -0
- package/dist/components/fastviews.d.ts +34 -0
- package/dist/components/fastviews.d.ts.map +1 -0
- package/dist/components/filebrowser.d.ts +45 -0
- package/dist/components/filebrowser.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/language-selector.d.ts +12 -0
- package/dist/components/language-selector.d.ts.map +1 -0
- package/dist/components/log-terminal.d.ts +36 -0
- package/dist/components/log-terminal.d.ts.map +1 -0
- package/dist/components/part-name.d.ts +12 -0
- package/dist/components/part-name.d.ts.map +1 -0
- package/dist/components/tasks.d.ts +13 -0
- package/dist/components/tasks.d.ts.map +1 -0
- package/dist/contributions/default-ui-contributions.d.ts +2 -0
- package/dist/contributions/default-ui-contributions.d.ts.map +1 -0
- package/dist/contributions/index.d.ts +1 -0
- package/dist/contributions/index.d.ts.map +1 -0
- package/dist/contributions/marketplace-catalog-contributions.d.ts +2 -0
- package/dist/contributions/marketplace-catalog-contributions.d.ts.map +1 -0
- package/dist/core/app-host-config.d.ts +7 -0
- package/dist/core/app-host-config.d.ts.map +1 -0
- package/dist/core/apploader.d.ts +214 -0
- package/dist/core/apploader.d.ts.map +1 -0
- package/dist/core/appstate.d.ts +12 -0
- package/dist/core/appstate.d.ts.map +1 -0
- package/dist/core/commandregistry.d.ts +79 -0
- package/dist/core/commandregistry.d.ts.map +1 -0
- package/dist/core/config.d.ts +15 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/constants.d.ts +22 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/contributionregistry.d.ts +53 -0
- package/dist/core/contributionregistry.d.ts.map +1 -0
- package/dist/core/di.d.ts +18 -0
- package/dist/core/di.d.ts.map +1 -0
- package/dist/core/dialogservice.d.ts +33 -0
- package/dist/core/dialogservice.d.ts.map +1 -0
- package/dist/core/editorregistry.d.ts +87 -0
- package/dist/core/editorregistry.d.ts.map +1 -0
- package/dist/core/esmsh-service.d.ts +40 -0
- package/dist/core/esmsh-service.d.ts.map +1 -0
- package/dist/core/events.d.ts +7 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +63 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/extensionregistry.d.ts +98 -0
- package/dist/core/extensionregistry.d.ts.map +1 -0
- package/dist/core/filesys/common.d.ts +122 -0
- package/dist/core/filesys/common.d.ts.map +1 -0
- package/dist/core/filesys/fs-access.d.ts +31 -0
- package/dist/core/filesys/fs-access.d.ts.map +1 -0
- package/dist/core/filesys/index.d.ts +5 -0
- package/dist/core/filesys/index.d.ts.map +1 -0
- package/dist/core/filesys/indexeddb.d.ts +41 -0
- package/dist/core/filesys/indexeddb.d.ts.map +1 -0
- package/dist/core/filesys/opfs.d.ts +14 -0
- package/dist/core/filesys/opfs.d.ts.map +1 -0
- package/dist/core/i18n.d.ts +50 -0
- package/dist/core/i18n.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/keybindings.d.ts +67 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/logger.d.ts +44 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/marketplaceregistry.d.ts +25 -0
- package/dist/core/marketplaceregistry.d.ts.map +1 -0
- package/dist/core/packageinfoservice.d.ts +16 -0
- package/dist/core/packageinfoservice.d.ts.map +1 -0
- package/dist/core/persistenceservice.d.ts +6 -0
- package/dist/core/persistenceservice.d.ts.map +1 -0
- package/dist/core/settingsservice.d.ts +54 -0
- package/dist/core/settingsservice.d.ts.map +1 -0
- package/dist/core/signals.d.ts +3 -0
- package/dist/core/signals.d.ts.map +1 -0
- package/dist/core/taskservice.d.ts +20 -0
- package/dist/core/taskservice.d.ts.map +1 -0
- package/dist/core/toast.d.ts +4 -0
- package/dist/core/toast.d.ts.map +1 -0
- package/dist/core/tree-utils.d.ts +16 -0
- package/dist/core/tree-utils.d.ts.map +1 -0
- package/dist/dialogs/confirm-dialog.d.ts +14 -0
- package/dist/dialogs/confirm-dialog.d.ts.map +1 -0
- package/dist/dialogs/index.d.ts +5 -0
- package/dist/dialogs/index.d.ts.map +1 -0
- package/dist/dialogs/info-dialog.d.ts +13 -0
- package/dist/dialogs/info-dialog.d.ts.map +1 -0
- package/dist/dialogs/navigable-info-dialog.d.ts +33 -0
- package/dist/dialogs/navigable-info-dialog.d.ts.map +1 -0
- package/dist/dialogs/prompt-dialog.d.ts +21 -0
- package/dist/dialogs/prompt-dialog.d.ts.map +1 -0
- package/dist/externals/lit.d.ts +21 -0
- package/dist/externals/lit.d.ts.map +1 -0
- package/dist/externals/lit.js +24 -0
- package/dist/externals/lit.js.map +1 -0
- package/dist/externals/third-party.d.ts +7 -0
- package/dist/externals/third-party.d.ts.map +1 -0
- package/dist/externals/third-party.js +7 -0
- package/dist/externals/third-party.js.map +1 -0
- package/dist/externals/webawesome.d.ts +1 -0
- package/dist/externals/webawesome.d.ts.map +1 -0
- package/dist/externals/webawesome.js +75 -0
- package/dist/externals/webawesome.js.map +1 -0
- package/dist/i18n/extensions.json.d.ts +42 -0
- package/dist/i18n/fastviews.json.d.ts +13 -0
- package/dist/i18n/filebrowser.json.d.ts +29 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/logterminal.json.d.ts +45 -0
- package/dist/i18n/partname.json.d.ts +15 -0
- package/dist/i18n/tasks.json.d.ts +15 -0
- package/dist/i18n/workspace.json.d.ts +15 -0
- package/dist/icon-DN6fp0dg.js +487 -0
- package/dist/icon-DN6fp0dg.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts/standard-layout.d.ts +16 -0
- package/dist/layouts/standard-layout.d.ts.map +1 -0
- package/dist/nocontent-BhrN6yxJ.js +48 -0
- package/dist/nocontent-BhrN6yxJ.js.map +1 -0
- package/dist/parts/container.d.ts +4 -0
- package/dist/parts/container.d.ts.map +1 -0
- package/dist/parts/contextmenu.d.ts +50 -0
- package/dist/parts/contextmenu.d.ts.map +1 -0
- package/dist/parts/dialog-content.d.ts +9 -0
- package/dist/parts/dialog-content.d.ts.map +1 -0
- package/dist/parts/element.d.ts +36 -0
- package/dist/parts/element.d.ts.map +1 -0
- package/dist/parts/index.d.ts +1 -0
- package/dist/parts/index.d.ts.map +1 -0
- package/dist/parts/index.js +3 -0
- package/dist/parts/index.js.map +1 -0
- package/dist/parts/part.d.ts +96 -0
- package/dist/parts/part.d.ts.map +1 -0
- package/dist/parts/resizable-grid.d.ts +31 -0
- package/dist/parts/resizable-grid.d.ts.map +1 -0
- package/dist/parts/tabs.d.ts +75 -0
- package/dist/parts/tabs.d.ts.map +1 -0
- package/dist/parts/toolbar.d.ts +35 -0
- package/dist/parts/toolbar.d.ts.map +1 -0
- package/dist/resizable-grid-BRH3MyZK.js +3813 -0
- package/dist/resizable-grid-BRH3MyZK.js.map +1 -0
- package/dist/standard-layout-BSGa06lP.js +4907 -0
- package/dist/standard-layout-BSGa06lP.js.map +1 -0
- package/dist/widgets/icon.d.ts +10 -0
- package/dist/widgets/icon.d.ts.map +1 -0
- package/dist/widgets/index.d.ts +1 -0
- package/dist/widgets/index.d.ts.map +1 -0
- package/dist/widgets/index.js +3 -0
- package/dist/widgets/index.js.map +1 -0
- package/dist/widgets/nocontent.d.ts +13 -0
- package/dist/widgets/nocontent.d.ts.map +1 -0
- package/dist/widgets/widget.d.ts +25 -0
- package/dist/widgets/widget.d.ts.map +1 -0
- package/package.json +81 -0
- package/src/api/base-classes.ts +10 -0
- package/src/api/constants.ts +3 -0
- package/src/api/index.ts +31 -0
- package/src/api/services.ts +58 -0
- package/src/api/types.ts +46 -0
- package/src/commands/editor.ts +1 -0
- package/src/commands/files.ts +425 -0
- package/src/commands/global.ts +198 -0
- package/src/commands/index.ts +6 -0
- package/src/commands/open-view-as-editor.ts +28 -0
- package/src/commands/version-info.ts +214 -0
- package/src/components/app-selector.ts +233 -0
- package/src/components/app-switcher.ts +126 -0
- package/src/components/command.ts +236 -0
- package/src/components/extensions.ts +615 -0
- package/src/components/fastviews.ts +314 -0
- package/src/components/filebrowser.ts +518 -0
- package/src/components/index.ts +9 -0
- package/src/components/language-selector.ts +166 -0
- package/src/components/log-terminal.ts +337 -0
- package/src/components/part-name.ts +54 -0
- package/src/components/tasks.ts +275 -0
- package/src/contributions/default-ui-contributions.ts +44 -0
- package/src/contributions/index.ts +3 -0
- package/src/contributions/marketplace-catalog-contributions.ts +6 -0
- package/src/core/app-host-config.ts +23 -0
- package/src/core/apploader.ts +630 -0
- package/src/core/appstate.ts +15 -0
- package/src/core/commandregistry.ts +210 -0
- package/src/core/config.ts +29 -0
- package/src/core/constants.ts +29 -0
- package/src/core/contributionregistry.ts +81 -0
- package/src/core/di.ts +54 -0
- package/src/core/dialogservice.ts +266 -0
- package/src/core/editorregistry.ts +347 -0
- package/src/core/esmsh-service.ts +404 -0
- package/src/core/events.ts +68 -0
- package/src/core/extensionregistry.ts +399 -0
- package/src/core/filesys/common.ts +474 -0
- package/src/core/filesys/fs-access.ts +339 -0
- package/src/core/filesys/index.ts +5 -0
- package/src/core/filesys/indexeddb.ts +596 -0
- package/src/core/filesys/opfs.ts +95 -0
- package/src/core/i18n.ts +221 -0
- package/src/core/index.ts +51 -0
- package/src/core/keybindings.ts +274 -0
- package/src/core/logger.ts +187 -0
- package/src/core/marketplaceregistry.ts +197 -0
- package/src/core/packageinfoservice.ts +56 -0
- package/src/core/persistenceservice.ts +46 -0
- package/src/core/settingsservice.ts +191 -0
- package/src/core/signals.ts +18 -0
- package/src/core/taskservice.ts +72 -0
- package/src/core/toast.ts +21 -0
- package/src/core/tree-utils.ts +24 -0
- package/src/dialogs/confirm-dialog.ts +72 -0
- package/src/dialogs/index.ts +4 -0
- package/src/dialogs/info-dialog.ts +67 -0
- package/src/dialogs/navigable-info-dialog.ts +256 -0
- package/src/dialogs/prompt-dialog.ts +123 -0
- package/src/externals/lit.ts +36 -0
- package/src/externals/third-party.ts +10 -0
- package/src/externals/webawesome.ts +76 -0
- package/src/i18n/extensions.json +39 -0
- package/src/i18n/fastviews.json +10 -0
- package/src/i18n/filebrowser.json +27 -0
- package/src/i18n/index.ts +25 -0
- package/src/i18n/logterminal.json +42 -0
- package/src/i18n/partname.json +12 -0
- package/src/i18n/tasks.json +12 -0
- package/src/i18n/workspace.json +12 -0
- package/src/icons/icons.txt +3 -0
- package/src/icons/js.svg +6 -0
- package/src/icons/jupyter.svg +18 -0
- package/src/icons/python.svg +15 -0
- package/src/index.ts +3 -0
- package/src/layouts/standard-layout.ts +174 -0
- package/src/parts/container.ts +4 -0
- package/src/parts/contextmenu.ts +266 -0
- package/src/parts/dialog-content.ts +31 -0
- package/src/parts/element.ts +100 -0
- package/src/parts/index.ts +5 -0
- package/src/parts/part.ts +158 -0
- package/src/parts/resizable-grid.ts +366 -0
- package/src/parts/tabs.ts +581 -0
- package/src/parts/toolbar.ts +260 -0
- package/src/vite-env.d.ts +16 -0
- package/src/widgets/icon.ts +38 -0
- package/src/widgets/index.ts +2 -0
- package/src/widgets/nocontent.ts +40 -0
- package/src/widgets/widget.ts +92 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import {registerAll, type ExecutionContext} from "../core/commandregistry";
|
|
2
|
+
import {File, workspaceService, Directory} from "../core/filesys";
|
|
3
|
+
import {toastError, toastInfo} from "../core/toast";
|
|
4
|
+
import {activeSelectionSignal} from "../core/appstate";
|
|
5
|
+
import {editorRegistry, EditorContentProvider} from "../core/editorregistry";
|
|
6
|
+
import logger from "../core/logger";
|
|
7
|
+
|
|
8
|
+
async function getWorkspaceAndPath(params: any, requirePath: boolean = true): Promise<{workspace: Directory, path: string} | null> {
|
|
9
|
+
const workspace = await workspaceService.getWorkspace()
|
|
10
|
+
if (!workspace) {
|
|
11
|
+
return null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const path = params?.path
|
|
15
|
+
if (requirePath && !path) {
|
|
16
|
+
return null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return { workspace, path: path || '' }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Type guard to check if an editor implements EditorContentProvider
|
|
24
|
+
*/
|
|
25
|
+
function isEditorContentProvider(editor: any): editor is EditorContentProvider {
|
|
26
|
+
return editor &&
|
|
27
|
+
typeof editor.getContent === 'function' &&
|
|
28
|
+
typeof editor.getSelection === 'function' &&
|
|
29
|
+
typeof editor.getSnippet === 'function' &&
|
|
30
|
+
typeof editor.getLanguage === 'function' &&
|
|
31
|
+
typeof editor.getFilePath === 'function';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Helper to get a resource from path or active selection
|
|
36
|
+
*/
|
|
37
|
+
async function getResourceFromContext(context: ExecutionContext, params?: any): Promise<any> {
|
|
38
|
+
let resource = undefined
|
|
39
|
+
const path = params?.path || context.params?.["path"]
|
|
40
|
+
|
|
41
|
+
if (path) {
|
|
42
|
+
const workspaceDir = await workspaceService.getWorkspace()
|
|
43
|
+
if (workspaceDir) {
|
|
44
|
+
resource = await workspaceDir.getResource(path)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!resource) {
|
|
49
|
+
resource = activeSelectionSignal.get()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return resource
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Helper to read text file contents with error handling
|
|
57
|
+
*/
|
|
58
|
+
async function readTextFile(file: File): Promise<string | null> {
|
|
59
|
+
try {
|
|
60
|
+
const contents = await file.getContents()
|
|
61
|
+
if (typeof contents !== 'string') {
|
|
62
|
+
toastError("File is not a text file")
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
return contents
|
|
66
|
+
} catch (err: any) {
|
|
67
|
+
toastError(`Failed to read file: ${err.message}`)
|
|
68
|
+
return null
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Helper to create null editor response
|
|
74
|
+
*/
|
|
75
|
+
function createNullEditorResponse(includeCursorLine: boolean = false) {
|
|
76
|
+
const base = {
|
|
77
|
+
filePath: null,
|
|
78
|
+
language: null
|
|
79
|
+
}
|
|
80
|
+
if (includeCursorLine) {
|
|
81
|
+
return { ...base, snippet: null, cursorLine: null }
|
|
82
|
+
}
|
|
83
|
+
return base
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function getWorkspaceAndFile(params: any, requirePath: boolean = true): Promise<{workspace: Directory, path: string, file: File} | null> {
|
|
87
|
+
const result = await getWorkspaceAndPath(params, requirePath)
|
|
88
|
+
if (!result) {
|
|
89
|
+
return null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { workspace, path } = result
|
|
93
|
+
|
|
94
|
+
if (!path) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const resource = await workspace.getResource(path)
|
|
100
|
+
if (!resource || !(resource instanceof File)) {
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { workspace, path, file: resource }
|
|
105
|
+
} catch (err: any) {
|
|
106
|
+
return null
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
registerAll({
|
|
111
|
+
command: {
|
|
112
|
+
"id": "disconnect_folder",
|
|
113
|
+
"name": "Disconnect folder",
|
|
114
|
+
"description": "Disconnects a folder from the workspace"
|
|
115
|
+
},
|
|
116
|
+
handler: {
|
|
117
|
+
execute: async () => {
|
|
118
|
+
const selection = activeSelectionSignal.get()
|
|
119
|
+
if (!(selection instanceof Directory && selection.getParent() === undefined)) {
|
|
120
|
+
toastError("Select a folder root to disconnect.")
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
await workspaceService.disconnectFolder(selection)
|
|
125
|
+
} catch (err: any) {
|
|
126
|
+
toastError(err.message)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
contribution: {
|
|
131
|
+
target: "contextmenu:filebrowser",
|
|
132
|
+
label: "Disconnect folder",
|
|
133
|
+
icon: "folder-minus",
|
|
134
|
+
disabled: () => {
|
|
135
|
+
const selection = activeSelectionSignal.get();
|
|
136
|
+
return !(selection instanceof Directory && selection.getParent() === undefined);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Register local filesystem workspace contribution
|
|
142
|
+
registerAll({
|
|
143
|
+
command: {
|
|
144
|
+
"id": "load_workspace",
|
|
145
|
+
"name": "Local Folder",
|
|
146
|
+
"description": "Connect to a local folder using File System Access API",
|
|
147
|
+
"parameters": []
|
|
148
|
+
},
|
|
149
|
+
handler: {
|
|
150
|
+
execute: async _context => {
|
|
151
|
+
// @ts-ignore
|
|
152
|
+
await window.showDirectoryPicker({
|
|
153
|
+
mode: "readwrite"
|
|
154
|
+
}).then((dirHandle: FileSystemDirectoryHandle) => {
|
|
155
|
+
return workspaceService.connectWorkspace(dirHandle);
|
|
156
|
+
}).catch((err: Error) => {
|
|
157
|
+
toastError(err.message)
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
contribution: {
|
|
162
|
+
target: "filebrowser.connections",
|
|
163
|
+
label: "Local Folder",
|
|
164
|
+
icon: "folder-open"
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
registerAll({
|
|
169
|
+
command: {
|
|
170
|
+
"id": "connect_opfs",
|
|
171
|
+
"name": "OPFS",
|
|
172
|
+
"description": "Connect to Origin Private File System (browser storage)",
|
|
173
|
+
"parameters": []
|
|
174
|
+
},
|
|
175
|
+
handler: {
|
|
176
|
+
execute: async () => {
|
|
177
|
+
try {
|
|
178
|
+
await workspaceService.connectFolder({ opfs: true });
|
|
179
|
+
} catch (err: any) {
|
|
180
|
+
toastError(err.message);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
contribution: {
|
|
185
|
+
target: "filebrowser.connections",
|
|
186
|
+
label: "OPFS (Browser Storage)",
|
|
187
|
+
icon: "database"
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
registerAll({
|
|
192
|
+
command: {
|
|
193
|
+
"id": "connect_indexeddb",
|
|
194
|
+
"name": "IndexedDB",
|
|
195
|
+
"description": "Connect to IndexedDB-backed workspace (browser storage)",
|
|
196
|
+
"parameters": [
|
|
197
|
+
{
|
|
198
|
+
"name": "name",
|
|
199
|
+
"description": "Optional display name for this IndexedDB workspace root",
|
|
200
|
+
"required": false
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
handler: {
|
|
205
|
+
execute: async (context: ExecutionContext) => {
|
|
206
|
+
const nameParam = context.params?.["name"];
|
|
207
|
+
try {
|
|
208
|
+
await workspaceService.connectFolder({ indexeddb: true, name: nameParam });
|
|
209
|
+
} catch (err: any) {
|
|
210
|
+
toastError(err.message);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
contribution: {
|
|
215
|
+
target: "filebrowser.connections",
|
|
216
|
+
label: "IndexedDB (Browser Storage)",
|
|
217
|
+
icon: "database"
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
registerAll({
|
|
222
|
+
command: {
|
|
223
|
+
"id": "refresh_resource",
|
|
224
|
+
"name": "Refresh resource",
|
|
225
|
+
"description": "Refreshes the connected folder of the selected resource, or the whole workspace if nothing is selected",
|
|
226
|
+
"parameters": []
|
|
227
|
+
},
|
|
228
|
+
handler: {
|
|
229
|
+
execute: async () => {
|
|
230
|
+
const selection = activeSelectionSignal.get()
|
|
231
|
+
if (selection) {
|
|
232
|
+
selection.getWorkspace().touch()
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
const workspace = await workspaceService.getWorkspace()
|
|
236
|
+
if (!workspace) {
|
|
237
|
+
toastError("No workspace selected.")
|
|
238
|
+
return
|
|
239
|
+
}
|
|
240
|
+
workspace.touch()
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
registerAll({
|
|
246
|
+
command: {
|
|
247
|
+
"id": "open_editor",
|
|
248
|
+
"name": "Open editor",
|
|
249
|
+
"description": "Opens a file in an editor",
|
|
250
|
+
"parameters": [
|
|
251
|
+
{
|
|
252
|
+
"name": "path",
|
|
253
|
+
"description": "The path of the file to open within the workspace; if omitted, the active selection is opened",
|
|
254
|
+
"required": false
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"name": "editorId",
|
|
258
|
+
"description": "Open with this editor id; if omitted, use default editor",
|
|
259
|
+
"required": false
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
handler: {
|
|
264
|
+
execute: async context => {
|
|
265
|
+
const path = context.params?.["path"]
|
|
266
|
+
const editorId = context.params?.["editorId"]
|
|
267
|
+
let file: File | null = null
|
|
268
|
+
if (path) {
|
|
269
|
+
const result = await getWorkspaceAndFile({ path })
|
|
270
|
+
file = result?.file ?? null
|
|
271
|
+
} else {
|
|
272
|
+
const selection = activeSelectionSignal.get()
|
|
273
|
+
file = selection instanceof File ? selection : null
|
|
274
|
+
}
|
|
275
|
+
if (!file) return
|
|
276
|
+
await editorRegistry.loadEditor(file, editorId)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
registerAll({
|
|
282
|
+
command: {
|
|
283
|
+
"id": "get_active_editor_content",
|
|
284
|
+
"name": "Get active editor content",
|
|
285
|
+
"description": "Gets the complete contents of the currently active editor. Returns null if no editor is active or if the editor is not a code editor.",
|
|
286
|
+
"parameters": [],
|
|
287
|
+
"output": [
|
|
288
|
+
{
|
|
289
|
+
"name": "content",
|
|
290
|
+
"description": "the complete contents of the active editor, or null if no editor is active"
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"name": "filePath",
|
|
294
|
+
"description": "the workspace path of the file in the active editor, or null if no editor is active"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"name": "language",
|
|
298
|
+
"description": "the programming language of the active editor, or null if no editor is active"
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
handler: {
|
|
303
|
+
execute: async (context: ExecutionContext) => {
|
|
304
|
+
const activeEditor = context.activeEditor as any
|
|
305
|
+
if (!isEditorContentProvider(activeEditor)) {
|
|
306
|
+
return { ...createNullEditorResponse(), content: null }
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
return {
|
|
311
|
+
content: activeEditor.getContent(),
|
|
312
|
+
filePath: activeEditor.getFilePath(),
|
|
313
|
+
language: activeEditor.getLanguage()
|
|
314
|
+
}
|
|
315
|
+
} catch (err: any) {
|
|
316
|
+
return { ...createNullEditorResponse(), content: null }
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
registerAll({
|
|
323
|
+
command: {
|
|
324
|
+
"id": "get_active_editor_selection",
|
|
325
|
+
"name": "Get active editor selection",
|
|
326
|
+
"description": "Gets the currently selected text in the active editor. Returns null if no editor is active, no selection exists, or if the editor is not a code editor.",
|
|
327
|
+
"parameters": [],
|
|
328
|
+
"output": [
|
|
329
|
+
{
|
|
330
|
+
"name": "selection",
|
|
331
|
+
"description": "the selected text in the active editor, or null if no selection exists or no editor is active"
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"name": "filePath",
|
|
335
|
+
"description": "the workspace path of the file in the active editor, or null if no editor is active"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"name": "language",
|
|
339
|
+
"description": "the programming language of the active editor, or null if no editor is active"
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
},
|
|
343
|
+
handler: {
|
|
344
|
+
execute: async (context: ExecutionContext) => {
|
|
345
|
+
const activeEditor = context.activeEditor as any
|
|
346
|
+
if (!isEditorContentProvider(activeEditor)) {
|
|
347
|
+
return { ...createNullEditorResponse(), selection: null }
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
try {
|
|
351
|
+
return {
|
|
352
|
+
selection: activeEditor.getSelection(),
|
|
353
|
+
filePath: activeEditor.getFilePath(),
|
|
354
|
+
language: activeEditor.getLanguage()
|
|
355
|
+
}
|
|
356
|
+
} catch (err: any) {
|
|
357
|
+
return { ...createNullEditorResponse(), selection: null }
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
registerAll({
|
|
364
|
+
command: {
|
|
365
|
+
"id": "get_active_editor_snippet",
|
|
366
|
+
"name": "Get active editor snippet around cursor",
|
|
367
|
+
"description": "Gets a code snippet from the active editor with n lines before and n lines after the cursor position. Useful for getting context around the cursor without loading the entire file.",
|
|
368
|
+
"parameters": [
|
|
369
|
+
{
|
|
370
|
+
"name": "lines",
|
|
371
|
+
"description": "number of lines to include before and after the cursor position (default: 5)",
|
|
372
|
+
"type": "number",
|
|
373
|
+
"required": false
|
|
374
|
+
}
|
|
375
|
+
],
|
|
376
|
+
"output": [
|
|
377
|
+
{
|
|
378
|
+
"name": "snippet",
|
|
379
|
+
"description": "the code snippet with n lines before and after the cursor, or null if no editor is active"
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"name": "filePath",
|
|
383
|
+
"description": "the workspace path of the file in the active editor, or null if no editor is active"
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
"name": "language",
|
|
387
|
+
"description": "the programming language of the active editor, or null if no editor is active"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"name": "cursorLine",
|
|
391
|
+
"description": "the line number where the cursor is positioned (1-based), or null if no editor is active"
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
},
|
|
395
|
+
handler: {
|
|
396
|
+
execute: async (context: ExecutionContext) => {
|
|
397
|
+
const activeEditor = context.activeEditor as any
|
|
398
|
+
if (!isEditorContentProvider(activeEditor)) {
|
|
399
|
+
return createNullEditorResponse(true)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
const numLines = context.params?.lines ? parseInt(context.params.lines, 10) : 5
|
|
404
|
+
if (isNaN(numLines) || numLines < 0) {
|
|
405
|
+
return createNullEditorResponse(true)
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const snippetResult = activeEditor.getSnippet(numLines)
|
|
409
|
+
if (!snippetResult) {
|
|
410
|
+
return createNullEditorResponse(true)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return {
|
|
414
|
+
snippet: snippetResult.snippet,
|
|
415
|
+
filePath: activeEditor.getFilePath(),
|
|
416
|
+
language: activeEditor.getLanguage(),
|
|
417
|
+
cursorLine: snippetResult.cursorLine
|
|
418
|
+
}
|
|
419
|
+
} catch (err: any) {
|
|
420
|
+
return createNullEditorResponse(true)
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
})
|
|
425
|
+
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { registerAll } from "../core/commandregistry";
|
|
2
|
+
import { CommandContribution } from "../core/contributionregistry";
|
|
3
|
+
import { TOOLBAR_MAIN_RIGHT } from "../core/constants";
|
|
4
|
+
import { EditorInput, editorRegistry } from "../core/editorregistry";
|
|
5
|
+
import { html } from "lit";
|
|
6
|
+
import { toastError, toastInfo } from "../core/toast";
|
|
7
|
+
import { activeEditorSignal, activePartSignal } from "../core/appstate";
|
|
8
|
+
import { appSettings } from "../core/settingsservice";
|
|
9
|
+
import { extensionRegistry } from "../core/extensionregistry";
|
|
10
|
+
import type { Extension } from "../core/extensionregistry";
|
|
11
|
+
import { marketplaceRegistry } from "../core/marketplaceregistry";
|
|
12
|
+
import "./files";
|
|
13
|
+
import "./version-info";
|
|
14
|
+
|
|
15
|
+
registerAll({
|
|
16
|
+
command: {
|
|
17
|
+
"id": "save",
|
|
18
|
+
"name": "Save editor",
|
|
19
|
+
"description": "Saves the active/focused editor",
|
|
20
|
+
"keyBinding": "CTRL+S",
|
|
21
|
+
"parameters": []
|
|
22
|
+
},
|
|
23
|
+
handler: {
|
|
24
|
+
execute: async _context => {
|
|
25
|
+
const part = activeEditorSignal.get() || activePartSignal.get()
|
|
26
|
+
if (part && part.isDirty()) {
|
|
27
|
+
part.save()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
contribution: {
|
|
32
|
+
target: "toolbar:.system.editors",
|
|
33
|
+
icon: "floppy-disk",
|
|
34
|
+
label: "Save active editor",
|
|
35
|
+
slot: "start",
|
|
36
|
+
disabled: () => {
|
|
37
|
+
const part = activePartSignal.get()
|
|
38
|
+
return !part || !part.isDirty()
|
|
39
|
+
}
|
|
40
|
+
} as CommandContribution
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const THEME_SETTINGS_KEY = "theme"
|
|
44
|
+
|
|
45
|
+
async function applyTheme(themeClass: 'wa-dark' | 'wa-light'): Promise<void> {
|
|
46
|
+
const root = document.documentElement
|
|
47
|
+
root.classList.remove('wa-dark', 'wa-light')
|
|
48
|
+
root.classList.add(themeClass)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function loadTheme(): Promise<void> {
|
|
52
|
+
const theme = await appSettings.get(THEME_SETTINGS_KEY)
|
|
53
|
+
await applyTheme(theme || 'wa-dark')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function saveTheme(themeClass: 'wa-dark' | 'wa-light'): Promise<void> {
|
|
57
|
+
await appSettings.set(THEME_SETTINGS_KEY, themeClass)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
registerAll({
|
|
61
|
+
command: {
|
|
62
|
+
"id": "switch_theme",
|
|
63
|
+
"name": "Switch theme",
|
|
64
|
+
"description": "Switches between dark and light theme",
|
|
65
|
+
"parameters": []
|
|
66
|
+
},
|
|
67
|
+
handler: {
|
|
68
|
+
execute: async _context => {
|
|
69
|
+
const isDark = document.documentElement.classList.contains("wa-dark")
|
|
70
|
+
const newTheme = isDark ? 'wa-light' : 'wa-dark'
|
|
71
|
+
await applyTheme(newTheme)
|
|
72
|
+
await saveTheme(newTheme)
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
contribution: {
|
|
76
|
+
target: TOOLBAR_MAIN_RIGHT,
|
|
77
|
+
icon: "circle-half-stroke",
|
|
78
|
+
label: "Theme Switcher",
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Load theme on module initialization
|
|
83
|
+
loadTheme().catch(err => {
|
|
84
|
+
console.error('Failed to load theme preference:', err)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
registerAll({
|
|
88
|
+
command: {
|
|
89
|
+
"id": "fullscreen",
|
|
90
|
+
"name": "Toggle fullscreen",
|
|
91
|
+
"description": "Toggles fullscreen mode",
|
|
92
|
+
"parameters": []
|
|
93
|
+
},
|
|
94
|
+
handler: {
|
|
95
|
+
execute: async _context => {
|
|
96
|
+
if (document.fullscreenElement === document.body) {
|
|
97
|
+
await document.exitFullscreen()
|
|
98
|
+
} else {
|
|
99
|
+
await document.body.requestFullscreen()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
contribution: {
|
|
104
|
+
target: TOOLBAR_MAIN_RIGHT,
|
|
105
|
+
icon: "expand",
|
|
106
|
+
label: "Fullscreen",
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
registerAll({
|
|
111
|
+
command: {
|
|
112
|
+
"id": "open_extensions",
|
|
113
|
+
"name": "Open Extensions",
|
|
114
|
+
"description": "Opens the extensions registry",
|
|
115
|
+
"parameters": []
|
|
116
|
+
},
|
|
117
|
+
handler: {
|
|
118
|
+
execute: _context => {
|
|
119
|
+
const editorInput: EditorInput = {
|
|
120
|
+
title: "Extensions",
|
|
121
|
+
data: {},
|
|
122
|
+
key: "system.extensions",
|
|
123
|
+
icon: "puzzle-piece",
|
|
124
|
+
state: {},
|
|
125
|
+
noOverflow: true,
|
|
126
|
+
widgetFactory: () => html`<lyra-extensions></lyra-extensions>`,
|
|
127
|
+
}
|
|
128
|
+
editorRegistry.loadEditor(editorInput, "extensions-editor").then()
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
contribution: {
|
|
132
|
+
target: TOOLBAR_MAIN_RIGHT,
|
|
133
|
+
icon: "puzzle-piece",
|
|
134
|
+
label: "Open Extensions",
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
registerAll({
|
|
139
|
+
command: {
|
|
140
|
+
"id": "list_extensions",
|
|
141
|
+
"name": "List extensions",
|
|
142
|
+
"description": "Lists all available extensions with their status (enabled/disabled)",
|
|
143
|
+
"parameters": [],
|
|
144
|
+
"output": [
|
|
145
|
+
{
|
|
146
|
+
"name": "extensions",
|
|
147
|
+
"description": "array of extension objects with id, name, description, experimental flag, and enabled status"
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
handler: {
|
|
152
|
+
execute: async (_context: any) => {
|
|
153
|
+
const extensions = extensionRegistry.getExtensions().map((e: Extension) => {
|
|
154
|
+
return {
|
|
155
|
+
id: e.id,
|
|
156
|
+
name: e.name,
|
|
157
|
+
description: e.description,
|
|
158
|
+
experimental: e.experimental,
|
|
159
|
+
enabled: extensionRegistry.isEnabled(e.id)
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return extensions;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
registerAll({
|
|
168
|
+
command: {
|
|
169
|
+
"id": "toast_message",
|
|
170
|
+
"name": "Toast message to user",
|
|
171
|
+
"description": "Shows a toast message",
|
|
172
|
+
"parameters": [
|
|
173
|
+
{
|
|
174
|
+
"name": "message",
|
|
175
|
+
"description": "the message to toast",
|
|
176
|
+
"required": true
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "type",
|
|
180
|
+
"description": "the toast type: info (default), or error",
|
|
181
|
+
"required": false
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
handler: {
|
|
186
|
+
execute: ({ params: { message, type } }: any) => {
|
|
187
|
+
if (!message) {
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
if (type === "error") {
|
|
191
|
+
toastError(message)
|
|
192
|
+
} else {
|
|
193
|
+
toastInfo(message)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { registerAll } from "../core/commandregistry";
|
|
2
|
+
import { SYSTEM_VIEWS } from "../core/constants";
|
|
3
|
+
import type { TabContribution } from "../core/contributionregistry";
|
|
4
|
+
import { contributionRegistry } from "../core/contributionregistry";
|
|
5
|
+
import { editorRegistry } from "../core/editorregistry";
|
|
6
|
+
|
|
7
|
+
registerAll({
|
|
8
|
+
command: {
|
|
9
|
+
id: "open_view_as_editor",
|
|
10
|
+
name: "Open view as editor",
|
|
11
|
+
description: "Opens a dashboard view in the editor area",
|
|
12
|
+
parameters: [
|
|
13
|
+
{ name: "name", description: "View contribution name", required: true },
|
|
14
|
+
{ name: "sourceContributionSlot", description: "source contribution slot (default: SYSTEM_VIEWS)", required: false }
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
handler: {
|
|
18
|
+
execute: async ({ params }: { params?: { name?: string, sourceContributionSlot?: string } }) => {
|
|
19
|
+
const name = params?.name;
|
|
20
|
+
if (!name) return;
|
|
21
|
+
const slot = params?.sourceContributionSlot ?? SYSTEM_VIEWS
|
|
22
|
+
const contributions = contributionRegistry.getContributions(slot) as TabContribution[];
|
|
23
|
+
const contribution = contributions.find(c => c.name === name);
|
|
24
|
+
if (!contribution?.component) return;
|
|
25
|
+
await editorRegistry.openTab(contribution as TabContribution);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|