@lvce-editor/shared-process 0.0.2

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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -0
  3. package/bin/sharedProcess.js +3 -0
  4. package/index.js +6 -0
  5. package/package.json +96 -0
  6. package/src/parts/Assert/Assert.js +57 -0
  7. package/src/parts/Callback/Callback.js +48 -0
  8. package/src/parts/ChildProcess/ChildProcess.js +98 -0
  9. package/src/parts/ClipBoard/ClipBoard.ipc.js +7 -0
  10. package/src/parts/ClipBoard/ClipBoard.js +23 -0
  11. package/src/parts/ClipBoard/ClipBoardGnome.js +78 -0
  12. package/src/parts/ClipBoard/ClipBoardNoop.js +14 -0
  13. package/src/parts/ClipBoard/ClipBoardWindows.js +22 -0
  14. package/src/parts/Command/Command.js +264 -0
  15. package/src/parts/Configuration/Configuration.ipc.js +7 -0
  16. package/src/parts/Configuration/Configuration.js +39 -0
  17. package/src/parts/Credentials/Credentials.ipc.js +10 -0
  18. package/src/parts/Credentials/Credentials.js +69 -0
  19. package/src/parts/Debug/Debug.js +3 -0
  20. package/src/parts/Developer/Developer.ipc.js +20 -0
  21. package/src/parts/Developer/Developer.js +132 -0
  22. package/src/parts/Download/Download.js +33 -0
  23. package/src/parts/Electron/Electron.ipc.js +19 -0
  24. package/src/parts/Electron/Electron.js +99 -0
  25. package/src/parts/Env/Env.js +3 -0
  26. package/src/parts/Error/Error.js +30 -0
  27. package/src/parts/ErrorHandling/ErrorHandling.js +40 -0
  28. package/src/parts/Exec/Exec.js +16 -0
  29. package/src/parts/Extension/Extension.js +7 -0
  30. package/src/parts/ExtensionHost/ExtensionHost.ipc.js +80 -0
  31. package/src/parts/ExtensionHost/ExtensionHost.js +163 -0
  32. package/src/parts/ExtensionHost/ExtensionHostBraceCompletion.js +14 -0
  33. package/src/parts/ExtensionHost/ExtensionHostClosingTag.js +14 -0
  34. package/src/parts/ExtensionHost/ExtensionHostColorTheme.js +60 -0
  35. package/src/parts/ExtensionHost/ExtensionHostCommand.js +19 -0
  36. package/src/parts/ExtensionHost/ExtensionHostCompletion.js +12 -0
  37. package/src/parts/ExtensionHost/ExtensionHostDefinition.js +12 -0
  38. package/src/parts/ExtensionHost/ExtensionHostDiagnostic.js +7 -0
  39. package/src/parts/ExtensionHost/ExtensionHostFileSystem.js +23 -0
  40. package/src/parts/ExtensionHost/ExtensionHostFormatting.js +4 -0
  41. package/src/parts/ExtensionHost/ExtensionHostHover.js +12 -0
  42. package/src/parts/ExtensionHost/ExtensionHostIconTheme.js +35 -0
  43. package/src/parts/ExtensionHost/ExtensionHostImplementation.js +12 -0
  44. package/src/parts/ExtensionHost/ExtensionHostKeyBindings.js +23 -0
  45. package/src/parts/ExtensionHost/ExtensionHostLanguages.js +84 -0
  46. package/src/parts/ExtensionHost/ExtensionHostManagement.js +26 -0
  47. package/src/parts/ExtensionHost/ExtensionHostOutput.js +3 -0
  48. package/src/parts/ExtensionHost/ExtensionHostQuickPick.js +6 -0
  49. package/src/parts/ExtensionHost/ExtensionHostReference.js +12 -0
  50. package/src/parts/ExtensionHost/ExtensionHostRename.js +27 -0
  51. package/src/parts/ExtensionHost/ExtensionHostSemanticTokens.js +10 -0
  52. package/src/parts/ExtensionHost/ExtensionHostSourceControl.js +15 -0
  53. package/src/parts/ExtensionHost/ExtensionHostStats.js +3 -0
  54. package/src/parts/ExtensionHost/ExtensionHostStatusBar.js +7 -0
  55. package/src/parts/ExtensionHost/ExtensionHostTabCompletion.js +12 -0
  56. package/src/parts/ExtensionHost/ExtensionHostTextDocument.js +35 -0
  57. package/src/parts/ExtensionHost/ExtensionHostTypeDefinition.js +12 -0
  58. package/src/parts/ExtensionHost/ExtensionHostWorkspace.js +3 -0
  59. package/src/parts/ExtensionManagement/ExtensionManagement.ipc.js +11 -0
  60. package/src/parts/ExtensionManagement/ExtensionManagement.js +319 -0
  61. package/src/parts/FileSystem/FileSystem.ipc.js +32 -0
  62. package/src/parts/FileSystem/FileSystem.js +228 -0
  63. package/src/parts/Git/Git.js +58 -0
  64. package/src/parts/Json/Json.js +67 -0
  65. package/src/parts/JsonFile/JsonFile.js +14 -0
  66. package/src/parts/JsonRpc/JsonRpc.js +22 -0
  67. package/src/parts/Native/Native.ipc.js +6 -0
  68. package/src/parts/Native/Native.js +14 -0
  69. package/src/parts/OutputChannel/OutputChannel.ipc.js +51 -0
  70. package/src/parts/OutputChannel/OutputChannel.js +37 -0
  71. package/src/parts/ParentIpc/ParentIpc.js +203 -0
  72. package/src/parts/Path/Path.js +17 -0
  73. package/src/parts/Platform/Platform.ipc.js +18 -0
  74. package/src/parts/Platform/Platform.js +165 -0
  75. package/src/parts/Preferences/Preferences.ipc.js +6 -0
  76. package/src/parts/Preferences/Preferences.js +75 -0
  77. package/src/parts/PrettyError/PrettyError.js +86 -0
  78. package/src/parts/Process/Process.ipc.js +7 -0
  79. package/src/parts/Process/Process.js +7 -0
  80. package/src/parts/Queue/Queue.js +35 -0
  81. package/src/parts/RequiresSocket/RequiresSocket.js +11 -0
  82. package/src/parts/RgPath/RgPath.js +1 -0
  83. package/src/parts/Root/Root.js +6 -0
  84. package/src/parts/Search/Search.ipc.js +6 -0
  85. package/src/parts/Search/Search.js +101 -0
  86. package/src/parts/SearchFile/SearchFile.ipc.js +6 -0
  87. package/src/parts/SearchFile/SearchFile.js +51 -0
  88. package/src/parts/Socket/Socket.js +132 -0
  89. package/src/parts/Stats/Stats.js +45 -0
  90. package/src/parts/Terminal/Terminal.ipc.js +45 -0
  91. package/src/parts/Terminal/Terminal.js +161 -0
  92. package/src/parts/TextDocument/TextDocument.ipc.js +6 -0
  93. package/src/parts/TextDocument/TextDocument.js +37 -0
  94. package/src/parts/Trace/Trace.js +15 -0
  95. package/src/parts/Trash/Trash.js +11 -0
  96. package/src/parts/WebSocketServer/WebSocketServer.ipc.js +6 -0
  97. package/src/parts/WebSocketServer/WebSocketServer.js +43 -0
  98. package/src/parts/Workspace/Workspace.ipc.js +7 -0
  99. package/src/parts/Workspace/Workspace.js +107 -0
  100. package/src/sharedProcessMain.js +61 -0
  101. package/test/Callback.test.js +42 -0
  102. package/test/ClipBoard.test.js +105 -0
  103. package/test/Credentials.test.js +147 -0
  104. package/test/Developer.test.js +34 -0
  105. package/test/Electron.test.js +93 -0
  106. package/test/Error.test.js +16 -0
  107. package/test/Exec.test.js +25 -0
  108. package/test/ExtensionHost.test.js +127 -0
  109. package/test/ExtensionHostColorTheme.test.js +141 -0
  110. package/test/ExtensionHostCommand.test.js +27 -0
  111. package/test/ExtensionHostCompletion.test.js +45 -0
  112. package/test/ExtensionHostDefinition.test.js +35 -0
  113. package/test/ExtensionHostDiagnostic.test.js +23 -0
  114. package/test/ExtensionHostFileSystem.test.js +91 -0
  115. package/test/ExtensionHostFormatting.test.js +27 -0
  116. package/test/ExtensionHostIconTheme.test.js +73 -0
  117. package/test/ExtensionHostLanguages.test.js +212 -0
  118. package/test/ExtensionHostOutput.test.js +23 -0
  119. package/test/ExtensionHostRename.test.js +59 -0
  120. package/test/ExtensionHostSemanticTokens.test.js +26 -0
  121. package/test/ExtensionHostTabCompletion.test.js +35 -0
  122. package/test/ExtensionHostTextDocument.test.js +61 -0
  123. package/test/ExtensionHostTypeDefinition.test.js +35 -0
  124. package/test/ExtensionHostWorkspace.test.js +21 -0
  125. package/test/ExtensionManagement.test.js +408 -0
  126. package/test/FileSystem.test.js +294 -0
  127. package/test/Json.test.js +25 -0
  128. package/test/Native.test.js +31 -0
  129. package/test/OutputChannel.test.js +68 -0
  130. package/test/Path.test.js +17 -0
  131. package/test/Platform.test.js +61 -0
  132. package/test/Preferences.test.js +140 -0
  133. package/test/Process.test.js +9 -0
  134. package/test/RgPath.test.js +5 -0
  135. package/test/Search.test.js +45 -0
  136. package/test/SearchFile.test.js +80 -0
  137. package/test/Terminal.test.js +53 -0
  138. package/test/Trash.test.js +34 -0
  139. package/test/WebSocketServer.test.js +98 -0
  140. package/test/fixture-search-1/index.html +10 -0
  141. package/test/fixture-search-file-1/fileA +0 -0
  142. package/test/fixture-search-file-1/fileB +0 -0
  143. package/test/fixture-search-file-1/nested/fileC +0 -0
@@ -0,0 +1,99 @@
1
+ import * as Callback from '../Callback/Callback.js'
2
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js'
3
+
4
+ export const state = {
5
+ send(message) {
6
+ ParentIpc.electronSend(message)
7
+ },
8
+ }
9
+
10
+ const send = (method, ...params) => {
11
+ state.send({
12
+ jsonrpc: '2.0',
13
+ method,
14
+ params,
15
+ })
16
+ }
17
+
18
+ const invoke = async (method, ...params) => {
19
+ return new Promise((resolve, reject) => {
20
+ // TODO use one map instead of two
21
+ const callbackId = Callback.register(resolve, reject)
22
+ state.send({
23
+ jsonrpc: '2.0',
24
+ method,
25
+ params,
26
+ id: callbackId,
27
+ })
28
+ })
29
+ }
30
+
31
+ export const toggleDevtools = () => {
32
+ send(/* Window.toggleDevtools */ 6523)
33
+ }
34
+
35
+ export const windowMinimize = () => {
36
+ send(/* Window.minimize */ 6521)
37
+ }
38
+
39
+ export const windowMaximize = () => {
40
+ send(/* Window.maximize */ 6522)
41
+ }
42
+
43
+ export const windowUnmaximize = () => {
44
+ send(/* Window.unmaximize */ 6524)
45
+ }
46
+
47
+ export const windowClose = () => {
48
+ send(/* Window.close */ 6525)
49
+ }
50
+
51
+ export const windowReload = () => {
52
+ send(/* Window.reload */ 6526)
53
+ }
54
+
55
+ // TODO move these into separate files like done extension host
56
+
57
+ export const windowOpenNew = () => {
58
+ send(/* AppWindow.openNew */ 8527)
59
+ }
60
+
61
+ export const about = () => {
62
+ send(/* About.open */ 20001)
63
+ }
64
+
65
+ export const showOpenDialog = async () => {
66
+ const result = await invoke(/* Dialog.showOpenDialog */ 20100)
67
+ return result
68
+ }
69
+
70
+ export const showMessageBox = async (message, buttons) => {
71
+ const result = await invoke(
72
+ /* Dialog.showMessageBox */ 20101,
73
+ message,
74
+ buttons
75
+ )
76
+ return result
77
+ }
78
+
79
+ export const crashMainProcess = () => {
80
+ send(/* Developer.crashMainProcess */ 7723)
81
+ }
82
+
83
+ export const getPerformanceEntries = async () => {
84
+ const result = await invoke(/* Developer.getPerformanceEntries */ 7722)
85
+ return result
86
+ }
87
+
88
+ export const beep = async () => {
89
+ // TODO when is remote should send to renderer worker
90
+ await invoke(/* Beep.beep */ 50000)
91
+ }
92
+
93
+ export const exit = async () => {
94
+ await invoke(/* App.exit */ 2211)
95
+ }
96
+
97
+ export const openProcessExplorer = async () => {
98
+ await invoke(/* ProcessExplorer.openProcessExplorer */ 8822)
99
+ }
@@ -0,0 +1,3 @@
1
+ export const getFolder = () => {
2
+ return process.env.FOLDER
3
+ }
@@ -0,0 +1,30 @@
1
+ import VError from 'verror'
2
+
3
+ /**
4
+ *
5
+ * @param {unknown} cause
6
+ * @returns {cause is Error}
7
+ */
8
+ const isError = (cause) => {
9
+ // @ts-ignore
10
+ return cause && cause.stack && cause.message
11
+ }
12
+
13
+ export class OperationalError extends VError {
14
+ /**
15
+ *
16
+ * @param {{cause?:unknown, message:string, code:string, stack?:any, codeFrame?:any, category?:string, stderr?:string }} param0
17
+ */
18
+ constructor({ cause, message, code, stack, codeFrame, category, stderr }) {
19
+ if (isError(cause)) {
20
+ super(cause, message)
21
+ } else {
22
+ super(message)
23
+ }
24
+ this.code = code
25
+ this.originalStack = stack
26
+ this.originalCodeFrame = codeFrame
27
+ this.category = category
28
+ this.stderr = stderr
29
+ }
30
+ }
@@ -0,0 +1,40 @@
1
+ import * as Socket from '../Socket/Socket.js'
2
+
3
+ export const state = {
4
+ seenErrors: [],
5
+ }
6
+
7
+ const preparePrettyError = (error) => {
8
+ const cause = error.cause()
9
+ return {
10
+ message: error.message,
11
+ codeFrame: cause.codeFrame,
12
+ stack: cause.stack,
13
+ }
14
+ }
15
+
16
+ const printPrettyError = (prettyError) => {
17
+ console.error(
18
+ `${prettyError.message}\n${prettyError.codeFrame}\n${prettyError.stack}`
19
+ )
20
+ }
21
+
22
+ export const handleError = (error) => {
23
+ if (state.seenErrors.includes(error.message)) {
24
+ return
25
+ }
26
+ state.seenErrors.push(error.message)
27
+ const prettyError = preparePrettyError(error)
28
+ Socket.send({
29
+ jsonrpc: '2.0',
30
+ method: /* Dialog.showErrorDialogWithOptions */ 1494,
31
+ params: [
32
+ {
33
+ message: prettyError.message,
34
+ codeFrame: prettyError.codeFrame,
35
+ stack: prettyError.stack,
36
+ },
37
+ ],
38
+ })
39
+ printPrettyError(prettyError)
40
+ }
@@ -0,0 +1,16 @@
1
+ import { execa } from 'execa'
2
+
3
+ /**
4
+ *
5
+ * @param {string} command
6
+ * @param {string[]} args
7
+ * @param {import('execa').Options} options
8
+ * @returns
9
+ */
10
+ export const exec = async (command, args, options) => {
11
+ const { stdout, stderr } = await execa(command, args, options)
12
+ return {
13
+ stdout,
14
+ stderr,
15
+ }
16
+ }
@@ -0,0 +1,7 @@
1
+ export const install = (id) => {}
2
+
3
+ export const uninstall = (id) => {}
4
+
5
+ export const enable = (id) => {}
6
+
7
+ export const disable = (id) => {}
@@ -0,0 +1,80 @@
1
+ import * as Command from '../Command/Command.js'
2
+ import * as ExtensionHost from './ExtensionHost.js'
3
+ import * as ExtensionHostCommand from './ExtensionHostCommand.js'
4
+ import * as ExtensionHostCompletion from './ExtensionHostCompletion.js'
5
+ import * as ExtensionHostSourceControl from './ExtensionHostSourceControl.js'
6
+ import * as ExtensionHostTabCompletion from './ExtensionHostTabCompletion.js'
7
+ import * as ExtensionHostStats from './ExtensionHostStats.js'
8
+ import * as ExtensionHostFormatting from './ExtensionHostFormatting.js'
9
+ import * as ExtensionHostTextDocument from './ExtensionHostTextDocument.js'
10
+ import * as ExtensionHostHover from './ExtensionHostHover.js'
11
+ import * as ExtensionHostDiagnostic from './ExtensionHostDiagnostic.js'
12
+ import * as ExtensionHostRename from './ExtensionHostRename.js'
13
+ import * as ExtensionHostDefinition from './ExtensionHostDefinition.js'
14
+ import * as ExtensionHostFileSystem from './ExtensionHostFileSystem.js'
15
+ import * as ExtensionHostManagement from './ExtensionHostManagement.js'
16
+ import * as ExtensionHostWorkspace from './ExtensionHostWorkspace.js'
17
+ import * as ExtensionHostOutput from './ExtensionHostOutput.js'
18
+ import * as ExtensionHostLanguages from './ExtensionHostLanguages.js'
19
+ import * as ExtensionHostColorTheme from './ExtensionHostColorTheme.js'
20
+ import * as ExtensionHostKeyBindings from './ExtensionHostKeyBindings.js'
21
+ import * as ExtensionHostIconTheme from './ExtensionHostIconTheme.js'
22
+ import * as ExtensionHostStatusBar from './ExtensionHostStatusBar.js'
23
+ import * as ExtensionHostQuickPick from './ExtensionHostQuickPick.js'
24
+ import * as ExtensionHostBraceCompletion from './ExtensionHostBraceCompletion.js'
25
+ import * as ExtensionHostReferences from './ExtensionHostReference.js'
26
+ import * as ExtensionHostImplementation from './ExtensionHostImplementation.js'
27
+ import * as ExtensionHostTypeDefinition from './ExtensionHostTypeDefinition.js'
28
+ import * as ExtensionHostClosingTag from './ExtensionHostClosingTag.js'
29
+ import * as ExtensionHostSemanticTokens from './ExtensionHostSemanticTokens.js'
30
+
31
+ export const __initialize__ = () => {
32
+ Command.register('ExtensionHost.getCommands', ExtensionHostCommand.getCommandsIpc)
33
+ Command.register('ExtensionHostCompletion.execute', ExtensionHost.wrapExtensionHostCommand(ExtensionHostCompletion.executeCompletionProvider))
34
+ // Command.register(385, ExtensionHost.textDocumentSync)
35
+ Command.register('ExtensionHost.executeTabCompletionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTabCompletion.executeTabCompletionProvider))
36
+ Command.register('ExtensionHost.getLanguages', ExtensionHostLanguages.getLanguages)
37
+ Command.register('ExtensionHost.getIconThemeJson', ExtensionHostIconTheme.getIconTheme)
38
+ Command.register('ExtensionHostKeyBindings.getKeyBindings', ExtensionHostKeyBindings.getKeyBindings)
39
+ Command.register('ExtensionHost.executeCommand', ExtensionHost.wrapExtensionHostCommand(ExtensionHostCommand.executeCommand))
40
+ Command.register('ExtensionHost.getColorThemeJson', ExtensionHostColorTheme.getColorThemeJson)
41
+ Command.register('ExtensionHost.getColorThemeNames', ExtensionHostColorTheme.getColorThemeNames)
42
+ Command.register('ExtensionHost.getMemoryUsage', ExtensionHost.wrapExtensionHostCommand(ExtensionHostStats.getMemoryUsage))
43
+ Command.register('ExtensionHost.getSourceControlBadgeCount', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSourceControl.getSourceControlBadgeCount))
44
+ Command.register('ExtensionHost.format', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFormatting.format))
45
+ Command.register('ExtensionHost.executeCommand', ExtensionHost.wrapExtensionHostCommand(ExtensionHostCommand.executeCommand))
46
+
47
+ Command.register('ExtensionHost.sourceControlGetChangedFiles', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSourceControl.getSourceControlChangedFiles))
48
+ Command.register('ExtensionHost.getLanguageConfiguration', ExtensionHostLanguages.getLanguageConfiguration)
49
+ Command.register('ExtensionHost.getColorThemes', ExtensionHostColorTheme.getColorThemes)
50
+ Command.register('ExtensionHostTextDocument.syncFull', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTextDocument.textDocumentSyncInitial))
51
+ Command.register('ExtensionHostHover.execute', ExtensionHost.wrapExtensionHostCommand(ExtensionHostHover.executeHoverProvider))
52
+ Command.register('ExtensionHostDiagnostic.execute', ExtensionHost.wrapExtensionHostCommand(ExtensionHostDiagnostic.executeDiagnosticProvider))
53
+ Command.register('ExtensionHostTextDocument.syncIncremental', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTextDocument.textDocumentSyncIncremental))
54
+ Command.register('ExtensionHostRename.executePrepareRename', ExtensionHost.wrapExtensionHostCommand(ExtensionHostRename.executePrepareRename))
55
+ Command.register('ExtensionHostRename.executeRename', ExtensionHost.wrapExtensionHostCommand(ExtensionHostRename.executeRename))
56
+ Command.register('ExtensionHostDefinition.executeDefinitionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostDefinition.executeDefinitionProvider))
57
+ Command.register('ExtensionHostFileSystem.readFile', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.readFile))
58
+ Command.register('ExtensionHostFileSystem.writeFile', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.writeFile))
59
+ Command.register('ExtensionHostFileSystem.readDirWithFileTypes', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.readDirWithFileTypes))
60
+ Command.register('ExtensionHostFileSystem.remove', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.remove))
61
+ Command.register('ExtensionHostFileSystem.rename', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.rename))
62
+ Command.register('ExtensionHostSourceControl.acceptInput', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSourceControl.sourceControlAcceptInput))
63
+ Command.register('ExtensionHost.start', ExtensionHost.start)
64
+ Command.register('ExtensionHost.activateAll', ExtensionHost.wrapExtensionHostCommand(ExtensionHostManagement.activateAll))
65
+ Command.register('ExtensionHost.enableExtension', ExtensionHost.wrapExtensionHostCommand(ExtensionHostManagement.enableExtension))
66
+ Command.register('ExtensionHostFileSystem.getPathSeparator', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.getPathSeparator))
67
+ Command.register('ExtensionHost.setWorkspacePath', ExtensionHost.wrapExtensionHostCommand(ExtensionHostWorkspace.setWorkspacePath))
68
+ Command.register('ExtensionHost.setWorkspaceRoot', ExtensionHost.wrapExtensionHostCommand(ExtensionHostWorkspace.setWorkspacePath))
69
+ Command.register('ExtensionHostOutput.getOutputChannels', ExtensionHost.wrapExtensionHostCommand(ExtensionHostOutput.getOutputChannels))
70
+ Command.register('ExtensionHost.getStatusBarItems', ExtensionHost.wrapExtensionHostCommand(ExtensionHostStatusBar.getStatusBarItems))
71
+ Command.register('ExtensionHostStatusBar.registerChangeListener', ExtensionHost.wrapExtensionHostCommand(ExtensionHostStatusBar.registerChangeListener))
72
+ Command.register('ExtensionHostTextDocument.setLanguageId', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTextDocument.setLanguageId))
73
+ Command.register('ExtensionHostQuickPick.handleQuickPickResult', ExtensionHost.wrapExtensionHostCommand(ExtensionHostQuickPick.handleQuickPickResult))
74
+ Command.register('ExtensionHostBraceCompletion.executeBraceCompletionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostBraceCompletion.executeBraceCompletionProvider))
75
+ Command.register('ExtensionHostReferences.executeReferenceProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostReferences.executeReferenceProvider))
76
+ Command.register('ExtensionHostImplementation.executeImplementationProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostImplementation.executeImplementationProvider))
77
+ Command.register('ExtensionHostClosingTag.executeTypeDefinitionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTypeDefinition.executeTypeDefinitionProvider))
78
+ Command.register('ExtensionHostClosingTag.executeClosingTagProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostClosingTag.executeClosingTagProvider))
79
+ Command.register('ExtensionHostSemanticTokens.executeSemanticTokenProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSemanticTokens.executeSemanticTokenProvider))
80
+ }
@@ -0,0 +1,163 @@
1
+ import VError from 'verror'
2
+ import * as Callback from '../Callback/Callback.js'
3
+ import * as ChildProcess from '../ChildProcess/ChildProcess.js'
4
+ import * as Error from '../Error/Error.js'
5
+ import * as JsonRpc from '../JsonRpc/JsonRpc.js'
6
+ import * as Platform from '../Platform/Platform.js'
7
+ import * as Socket from '../Socket/Socket.js'
8
+ import * as Assert from '../Assert/Assert.js'
9
+ // TODO maybe rename to extension host management for clarity
10
+
11
+ // TODO needed? probably not
12
+ const NULL_EXTENSION_HOST = {
13
+ dispose() {
14
+ throw new VError('not implemented')
15
+ },
16
+ send(message) {
17
+ throw new VError(
18
+ 'extension host must be started before commands can be invoked'
19
+ )
20
+ },
21
+ async invoke(commandId, ...args) {
22
+ throw new VError(
23
+ 'extension host must be started before commands can be invoked'
24
+ )
25
+ },
26
+ }
27
+
28
+ /**
29
+ * @type{{
30
+ * extensionHost: {dispose:()=>void, invoke:(commandId, ...args)=>Promise<any>},
31
+ * }}
32
+ */
33
+ export const state = {
34
+ extensionHost: NULL_EXTENSION_HOST,
35
+ }
36
+
37
+ const onMessage = (message) => {
38
+ if (message.id) {
39
+ if ('result' in message) {
40
+ Callback.resolve(message.id, message.result)
41
+ } else if ('error' in message) {
42
+ Callback.reject(
43
+ message.id,
44
+ new Error.OperationalError({
45
+ code: 'E_CALLBACK_REJECTED',
46
+ message: message.error.message,
47
+ stack: message.error.data.stack,
48
+ codeFrame: message.error.data.codeFrame,
49
+ // @ts-ignore
50
+ stderr: message.error.data.stderr,
51
+ })
52
+ )
53
+ } else {
54
+ Socket.send(message)
55
+ }
56
+ } else {
57
+ Socket.send(message)
58
+ }
59
+ }
60
+
61
+ // TODO this function is very ugly and has probably memory leaks
62
+ export const start = async (socket) => {
63
+ try {
64
+ Assert.object(socket)
65
+ const extensionHostPath = Platform.getExtensionHostPath()
66
+ const childProcess = ChildProcess.fork(extensionHostPath, {
67
+ execArgv: [
68
+ '--experimental-json-modules',
69
+ '--max-old-space-size=60',
70
+ '--enable-source-maps',
71
+ ],
72
+ env: {
73
+ ...process.env,
74
+ LOGS_DIR: Platform.getLogsDir(),
75
+ CONFIG_DIR: Platform.getConfigDir(),
76
+ },
77
+ })
78
+
79
+ const handleChildProcessError = (error) => {
80
+ console.error(`[Extension Host] ${error}`)
81
+ }
82
+
83
+ const handleChildProcessExit = (exitCode) => {
84
+ console.info(
85
+ `[SharedProcess] Extension Host exited with code ${exitCode}`
86
+ )
87
+ state.extensionHost = NULL_EXTENSION_HOST
88
+ }
89
+
90
+ const handleSocketClose = () => {
91
+ console.info('[shared process] disposing extension host')
92
+ childProcess.kill()
93
+ }
94
+
95
+ socket.on('close', handleSocketClose)
96
+
97
+ childProcess.on('error', handleChildProcessError)
98
+
99
+ childProcess.on('exit', handleChildProcessExit)
100
+
101
+ state.extensionHost = {
102
+ invoke(...args) {
103
+ return JsonRpc.invoke(childProcess, ...args)
104
+ },
105
+ dispose() {
106
+ childProcess.kill()
107
+ },
108
+ }
109
+
110
+ await new Promise((resolve, reject) => {
111
+ const handleFirstError = (error) => {
112
+ cleanup()
113
+ reject(error)
114
+ }
115
+ const handleFirstExit = (exitCode) => {
116
+ cleanup()
117
+ reject(
118
+ new globalThis.Error(`Extension Host exited with code ${exitCode}`)
119
+ )
120
+ }
121
+ const handleFirstMessage = () => {
122
+ cleanup()
123
+ childProcess.on('message', onMessage)
124
+ resolve(undefined)
125
+ }
126
+ const handleSocketClose = () => {
127
+ cleanup()
128
+ childProcess.off('error', handleChildProcessError)
129
+ childProcess.off('exit', handleChildProcessExit)
130
+ resolve(undefined)
131
+ }
132
+ const cleanup = () => {
133
+ childProcess.off('error', handleFirstError)
134
+ childProcess.off('exit', handleFirstExit)
135
+ childProcess.off('message', handleFirstMessage)
136
+ }
137
+ childProcess.on('error', handleFirstError)
138
+ childProcess.on('exit', handleFirstExit)
139
+ childProcess.on('message', handleFirstMessage)
140
+ socket.on('close', handleSocketClose)
141
+ })
142
+ } catch (error) {
143
+ // @ts-ignore
144
+ throw new VError(error, 'Failed to start extension host')
145
+ }
146
+ }
147
+
148
+ export const stop = () => {
149
+ state.extensionHost.dispose()
150
+ state.extensionHost = NULL_EXTENSION_HOST
151
+ }
152
+
153
+ export const restart = () => {
154
+ stop()
155
+ start()
156
+ }
157
+
158
+ export const wrapExtensionHostCommand = (fn) => {
159
+ const wrappedExtensionHostCommand = (...args) => {
160
+ return fn(state.extensionHost, ...args)
161
+ }
162
+ return wrappedExtensionHostCommand
163
+ }
@@ -0,0 +1,14 @@
1
+ export const executeBraceCompletionProvider = async (
2
+ extensionHost,
3
+ documentId,
4
+ offset,
5
+ openingBrace
6
+ ) => {
7
+ const completions = await extensionHost.invoke(
8
+ 'BraceCompletion.execute',
9
+ documentId,
10
+ offset,
11
+ openingBrace
12
+ )
13
+ return completions
14
+ }
@@ -0,0 +1,14 @@
1
+ export const executeClosingTagProvider = async (
2
+ extensionHost,
3
+ documentId,
4
+ offset,
5
+ openingBrace
6
+ ) => {
7
+ const completions = await extensionHost.invoke(
8
+ 'ClosingTag.execute',
9
+ documentId,
10
+ offset,
11
+ openingBrace
12
+ )
13
+ return completions
14
+ }
@@ -0,0 +1,60 @@
1
+ import * as Error from '../Error/Error.js'
2
+ import * as ExtensionManagement from '../ExtensionManagement/ExtensionManagement.js'
3
+ import * as ReadJson from '../JsonFile/JsonFile.js'
4
+
5
+ // TODO test this function
6
+ // TODO very similar with getIconTheme
7
+ export const getColorThemeJson = async (colorThemeId) => {
8
+ const extensions = await ExtensionManagement.getThemeExtensions()
9
+ for (const extension of extensions) {
10
+ if (!extension.colorThemes) {
11
+ continue
12
+ }
13
+ for (const colorTheme of extension.colorThemes) {
14
+ if (colorTheme.id !== colorThemeId) {
15
+ continue
16
+ }
17
+ const absolutePath = `${extension.path}/${colorTheme.path}`
18
+ try {
19
+ const json = await ReadJson.readJson(absolutePath)
20
+ return json
21
+ } catch (error) {
22
+ throw new Error.OperationalError({
23
+ cause: error,
24
+ code: 'E_COLOR_THEME_COULD_NOT_BE_LOADED',
25
+ message: `Failed to load color theme "${colorThemeId}"`,
26
+ })
27
+ }
28
+ }
29
+ }
30
+ throw new Error.OperationalError({
31
+ code: 'E_COLOR_THEME_NOT_FOUND',
32
+ message: `Color theme "${colorThemeId}" not found in extensions folder`,
33
+ })
34
+ }
35
+
36
+ const getColorThemeInfo = (extension) => {
37
+ return extension.colorThemes || []
38
+ }
39
+
40
+ const getExtensionColorThemeNames = (extension) => {
41
+ return extension.colorThemes || []
42
+ }
43
+
44
+ const getColorThemeId = (colorTheme) => {
45
+ return colorTheme.id
46
+ }
47
+
48
+ // TODO should send names to renderer worker or names with ids?
49
+ export const getColorThemeNames = async () => {
50
+ const extensions = await ExtensionManagement.getExtensions()
51
+ const colorThemes = extensions.flatMap(getExtensionColorThemeNames)
52
+ const colorThemeNames = colorThemes.map(getColorThemeId)
53
+ return colorThemeNames
54
+ }
55
+
56
+ export const getColorThemes = async () => {
57
+ const extensions = await ExtensionManagement.getExtensions()
58
+ const colorThemes = extensions.flatMap(getColorThemeInfo)
59
+ return colorThemes
60
+ }
@@ -0,0 +1,19 @@
1
+ import * as ExtensionManagement from '../ExtensionManagement/ExtensionManagement.js'
2
+
3
+ export const executeCommand = async (extensionHost, commandId, ...args) => {
4
+ return extensionHost.invoke('executeCommand', commandId, ...args)
5
+ }
6
+
7
+ const getExtensionCommands = (extension) => {
8
+ return extension.commands || []
9
+ }
10
+
11
+ export const getCommands = async () => {
12
+ const extensions = await ExtensionManagement.getExtensions()
13
+ return extensions.flatMap(getExtensionCommands)
14
+ }
15
+
16
+ export const getCommandsIpc = async () => {
17
+ const commands = await getCommands()
18
+ return commands
19
+ }
@@ -0,0 +1,12 @@
1
+ export const executeCompletionProvider = async (
2
+ extensionHost,
3
+ documentId,
4
+ offset
5
+ ) => {
6
+ const completions = await extensionHost.invoke(
7
+ 'executeCompletionProvider',
8
+ documentId,
9
+ offset
10
+ )
11
+ return completions
12
+ }
@@ -0,0 +1,12 @@
1
+ export const executeDefinitionProvider = async (
2
+ extensionHost,
3
+ textDocumentId,
4
+ offset
5
+ ) => {
6
+ const result = await extensionHost.invoke(
7
+ 'Definition.executeDefinitionProvider',
8
+ textDocumentId,
9
+ offset
10
+ )
11
+ return result
12
+ }
@@ -0,0 +1,7 @@
1
+ export const executeDiagnosticProvider = async (extensionHost, documentId) => {
2
+ const diagnostics = await extensionHost.invoke(
3
+ 'Diagnostic.execute',
4
+ documentId
5
+ )
6
+ return diagnostics
7
+ }
@@ -0,0 +1,23 @@
1
+ export const readFile = (extensionHost, protocol, uri) => {
2
+ return extensionHost.invoke('FileSystem.readFile', protocol, uri)
3
+ }
4
+
5
+ export const writeFile = (extensionHost, protocol, uri, content) => {
6
+ return extensionHost.invoke('FileSystem.writeFile', protocol, uri, content)
7
+ }
8
+
9
+ export const readDirWithFileTypes = (extensionHost, protocol, uri) => {
10
+ return extensionHost.invoke('FileSystem.readDirWithFileTypes', protocol, uri)
11
+ }
12
+
13
+ export const remove = (extensionHost, protocol, uri) => {
14
+ return extensionHost.invoke('FileSystem.remove', protocol, uri)
15
+ }
16
+
17
+ export const rename = (extensionHost, protocol, oldUri, newUri) => {
18
+ return extensionHost.invoke('FileSystem.rename', protocol, oldUri, newUri)
19
+ }
20
+
21
+ export const getPathSeparator = (extensionHost, protocol) => {
22
+ return extensionHost.invoke('FileSystem.getPathSeparator', protocol)
23
+ }
@@ -0,0 +1,4 @@
1
+ export const format = async (extensionHost, path, content) => {
2
+ const formattedContent = await extensionHost.invoke('format', path, content)
3
+ return formattedContent
4
+ }
@@ -0,0 +1,12 @@
1
+ export const executeHoverProvider = async (
2
+ extensionHost,
3
+ documentId,
4
+ offset
5
+ ) => {
6
+ const hover = await extensionHost.invoke(
7
+ 'executeHoverProvider',
8
+ documentId,
9
+ offset
10
+ )
11
+ return hover
12
+ }
@@ -0,0 +1,35 @@
1
+ import * as Error from '../Error/Error.js'
2
+ import * as ExtensionManagement from '../ExtensionManagement/ExtensionManagement.js'
3
+ import * as ReadJson from '../JsonFile/JsonFile.js'
4
+
5
+ export const getIconTheme = async (iconThemeId) => {
6
+ const extensions = await ExtensionManagement.getExtensions()
7
+ for (const extension of extensions) {
8
+ if (!extension.iconThemes) {
9
+ continue
10
+ }
11
+ for (const iconTheme of extension.iconThemes) {
12
+ if (iconTheme.id !== iconThemeId) {
13
+ continue
14
+ }
15
+ const absolutePath = `${extension.path}/${iconTheme.path}`
16
+ try {
17
+ const json = await ReadJson.readJson(absolutePath)
18
+ return {
19
+ extensionPath: extension.path,
20
+ json,
21
+ }
22
+ } catch (error) {
23
+ throw new Error.OperationalError({
24
+ cause: error,
25
+ code: 'E_ICON_THEME_COULD_NOT_BE_LOADED',
26
+ message: `Failed to load icon theme "${iconThemeId}"`,
27
+ })
28
+ }
29
+ }
30
+ }
31
+ throw new Error.OperationalError({
32
+ code: 'E_ICON_THEME_NOT_FOUND',
33
+ message: `Icon theme "${iconThemeId}" not found in extensions folder`,
34
+ })
35
+ }