@lvce-editor/shared-process 0.89.1 → 0.89.3
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/package.json +8 -8
- package/src/parts/BuiltinExtensionsPath/BuiltinExtensionsPath.js +1 -1
- package/src/parts/ElectronProcess/ElectronProcess.ipc.js +3 -0
- package/src/parts/ElectronProcess/ElectronProcess.js +12 -0
- package/src/parts/Exit/Exit.js +5 -2
- package/src/parts/IsPromptMode/IsPromptMode.js +6 -0
- package/src/parts/LanguageServer/LanguageServer.ipc.js +7 -0
- package/src/parts/LanguageServer/LanguageServer.js +78 -0
- package/src/parts/LanguageServerConnection/LanguageServerConnection.js +303 -0
- package/src/parts/LanguageServerMessageParser/LanguageServerMessageParser.js +32 -0
- package/src/parts/Module/Module.js +2 -0
- package/src/parts/ModuleId/ModuleId.js +1 -0
- package/src/parts/ModuleMap/ModuleMap.js +5 -0
- package/src/parts/Platform/Platform.js +3 -3
- package/src/parts/PreloadUrl/PreloadUrl.js +1 -1
- package/src/parts/ResolveRoot/ResolveRoot.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.89.
|
|
3
|
+
"version": "0.89.3",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -18,28 +18,28 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@lvce-editor/assert": "1.7.0",
|
|
21
|
-
"@lvce-editor/auth-process": "1.
|
|
22
|
-
"@lvce-editor/extension-host-helper-process": "0.89.
|
|
21
|
+
"@lvce-editor/auth-process": "1.9.0",
|
|
22
|
+
"@lvce-editor/extension-host-helper-process": "0.89.3",
|
|
23
23
|
"@lvce-editor/ipc": "16.3.0",
|
|
24
24
|
"@lvce-editor/json-rpc": "8.2.0",
|
|
25
25
|
"@lvce-editor/jsonc-parser": "1.5.0",
|
|
26
26
|
"@lvce-editor/pretty-error": "2.0.0",
|
|
27
27
|
"@lvce-editor/process-explorer": "3.10.0",
|
|
28
|
-
"@lvce-editor/rpc-registry": "9.
|
|
28
|
+
"@lvce-editor/rpc-registry": "9.35.0",
|
|
29
29
|
"@lvce-editor/verror": "1.7.0",
|
|
30
30
|
"is-object": "^1.0.2",
|
|
31
31
|
"xdg-basedir": "^5.1.0"
|
|
32
32
|
},
|
|
33
33
|
"optionalDependencies": {
|
|
34
34
|
"@lvce-editor/embeds-process": "4.9.1",
|
|
35
|
-
"@lvce-editor/file-system-process": "5.
|
|
36
|
-
"@lvce-editor/file-watcher-process": "4.
|
|
35
|
+
"@lvce-editor/file-system-process": "5.4.0",
|
|
36
|
+
"@lvce-editor/file-watcher-process": "4.4.0",
|
|
37
37
|
"@lvce-editor/network-process": "5.2.0",
|
|
38
38
|
"@lvce-editor/preload": "1.5.0",
|
|
39
39
|
"@lvce-editor/preview-process": "11.0.0",
|
|
40
|
-
"@lvce-editor/pty-host": "8.
|
|
40
|
+
"@lvce-editor/pty-host": "8.3.0",
|
|
41
41
|
"@lvce-editor/search-process": "15.1.0",
|
|
42
|
-
"@lvce-editor/typescript-compile-process": "5.
|
|
42
|
+
"@lvce-editor/typescript-compile-process": "5.3.0",
|
|
43
43
|
"open": "^11.0.0",
|
|
44
44
|
"tail": "^2.2.6",
|
|
45
45
|
"tmp-promise": "^3.0.3",
|
|
@@ -3,6 +3,6 @@ import { fileURLToPath } from 'url'
|
|
|
3
3
|
|
|
4
4
|
export const getBuiltinExtensionsPath = () => {
|
|
5
5
|
const staticServerPath = fileURLToPath(import.meta.resolve('@lvce-editor/static-server'))
|
|
6
|
-
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '
|
|
6
|
+
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', 'f1db6cb', 'extensions')
|
|
7
7
|
return builtinExtensionsPath
|
|
8
8
|
}
|
|
@@ -3,6 +3,9 @@ import * as ElectronProcess from './ElectronProcess.js'
|
|
|
3
3
|
export const name = 'ElectronProcess'
|
|
4
4
|
|
|
5
5
|
export const Commands = {
|
|
6
|
+
getArgv: ElectronProcess.getArgv,
|
|
6
7
|
getChromeVersion: ElectronProcess.getChromeVersion,
|
|
7
8
|
getElectronVersion: ElectronProcess.getElectronVersion,
|
|
9
|
+
writeStderr: ElectronProcess.writeStderr,
|
|
10
|
+
writeStdout: ElectronProcess.writeStdout,
|
|
8
11
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as ParentIpc from '../MainProcess/MainProcess.js'
|
|
2
2
|
|
|
3
|
+
export const getArgv = () => {
|
|
4
|
+
return ParentIpc.invoke('Process.getArgv')
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
export const getElectronVersion = () => {
|
|
4
8
|
return ParentIpc.invoke('Process.getElectronVersion')
|
|
5
9
|
}
|
|
@@ -7,3 +11,11 @@ export const getElectronVersion = () => {
|
|
|
7
11
|
export const getChromeVersion = () => {
|
|
8
12
|
return ParentIpc.invoke('Process.getChromeVersion')
|
|
9
13
|
}
|
|
14
|
+
|
|
15
|
+
export const writeStderr = (value) => {
|
|
16
|
+
return ParentIpc.invoke('Process.writeStderr', value)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const writeStdout = (value) => {
|
|
20
|
+
return ParentIpc.invoke('Process.writeStdout', value)
|
|
21
|
+
}
|
package/src/parts/Exit/Exit.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import * as ParentIpc from '../MainProcess/MainProcess.js'
|
|
2
2
|
|
|
3
|
-
export const exit = () => {
|
|
4
|
-
|
|
3
|
+
export const exit = (code) => {
|
|
4
|
+
if (code === undefined) {
|
|
5
|
+
return ParentIpc.invoke('Exit.exit')
|
|
6
|
+
}
|
|
7
|
+
return ParentIpc.invoke('Exit.exit', code)
|
|
5
8
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { dirname } from 'node:path'
|
|
2
|
+
import { pathToFileURL } from 'node:url'
|
|
3
|
+
import { LanguageServerConnection } from '../LanguageServerConnection/LanguageServerConnection.js'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
const connections = new Map ()
|
|
26
|
+
|
|
27
|
+
const normalizeDocumentUri = (uri) => {
|
|
28
|
+
if (uri.startsWith('/')) {
|
|
29
|
+
return pathToFileURL(uri).href
|
|
30
|
+
}
|
|
31
|
+
return uri
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const getRootUri = (documentUri) => {
|
|
35
|
+
if (documentUri.startsWith('file:')) {
|
|
36
|
+
return new URL('.', documentUri).href
|
|
37
|
+
}
|
|
38
|
+
if (documentUri.startsWith('/')) {
|
|
39
|
+
return pathToFileURL(dirname(documentUri)).href
|
|
40
|
+
}
|
|
41
|
+
return new URL('.', documentUri).href
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const hasSameOptions = (state, uri, argv) => {
|
|
45
|
+
return state.uri === uri && state.argv.length === argv.length && state.argv.every((argument, index) => argument === argv[index])
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const getConnection = (id, uri, argv, rootUri) => {
|
|
49
|
+
const existing = connections.get(id)
|
|
50
|
+
if (existing && existing.connection.isRunning() && hasSameOptions(existing, uri, argv)) {
|
|
51
|
+
return existing.connection
|
|
52
|
+
}
|
|
53
|
+
existing?.connection.dispose()
|
|
54
|
+
const connection = new LanguageServerConnection({ argv, rootUri, uri })
|
|
55
|
+
connections.set(id, {
|
|
56
|
+
argv: [...argv],
|
|
57
|
+
connection,
|
|
58
|
+
uri,
|
|
59
|
+
})
|
|
60
|
+
return connection
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const complete = async ({ argv, id, offset, textDocument, uri } ) => {
|
|
64
|
+
const normalizedDocument = {
|
|
65
|
+
...textDocument,
|
|
66
|
+
uri: normalizeDocumentUri(textDocument.uri),
|
|
67
|
+
}
|
|
68
|
+
const rootUri = getRootUri(normalizedDocument.uri)
|
|
69
|
+
const connection = getConnection(`${id}:${rootUri}`, uri, argv, rootUri)
|
|
70
|
+
return connection.complete(normalizedDocument, offset)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const disposeAll = () => {
|
|
74
|
+
for (const state of connections.values()) {
|
|
75
|
+
state.connection.dispose()
|
|
76
|
+
}
|
|
77
|
+
connections.clear()
|
|
78
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { spawn, } from 'node:child_process'
|
|
2
|
+
import { basename } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { LanguageServerMessageParser } from '../LanguageServerMessageParser/LanguageServerMessageParser.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
const getPosition = (text, offset) => {
|
|
41
|
+
const safeOffset = Math.max(0, Math.min(offset, text.length))
|
|
42
|
+
const before = text.slice(0, safeOffset)
|
|
43
|
+
const lastLineBreak = before.lastIndexOf('\n')
|
|
44
|
+
return {
|
|
45
|
+
character: lastLineBreak === -1 ? safeOffset : safeOffset - lastLineBreak - 1,
|
|
46
|
+
line: before.split('\n').length - 1,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const getWorkspaceName = (rootUri) => {
|
|
51
|
+
try {
|
|
52
|
+
return basename(fileURLToPath(rootUri)) || 'workspace'
|
|
53
|
+
} catch {
|
|
54
|
+
return 'workspace'
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class LanguageServerConnection {
|
|
59
|
+
child
|
|
60
|
+
documents = new Map ()
|
|
61
|
+
parser = new LanguageServerMessageParser()
|
|
62
|
+
pendingRequests = new Map ()
|
|
63
|
+
ready
|
|
64
|
+
rootUri
|
|
65
|
+
nextRequestId = 1
|
|
66
|
+
running = true
|
|
67
|
+
stderr = ''
|
|
68
|
+
|
|
69
|
+
constructor({ argv, rootUri, uri } ) {
|
|
70
|
+
this.rootUri = rootUri
|
|
71
|
+
this.child = spawn(fileURLToPath(uri), [...argv], {
|
|
72
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
73
|
+
})
|
|
74
|
+
this.child.stdout.on('data', (chunk) => {
|
|
75
|
+
this.handleData(chunk)
|
|
76
|
+
})
|
|
77
|
+
this.child.stderr.on('data', (chunk) => {
|
|
78
|
+
this.stderr += chunk.toString()
|
|
79
|
+
})
|
|
80
|
+
this.child.on('error', (error) => {
|
|
81
|
+
this.handleExit(error)
|
|
82
|
+
})
|
|
83
|
+
this.child.on('exit', (code, signal) => {
|
|
84
|
+
const detail = this.stderr.trim()
|
|
85
|
+
const suffix = detail ? `: ${detail}` : ''
|
|
86
|
+
this.handleExit(new Error(`Language server exited with code ${code} and signal ${signal}${suffix}`))
|
|
87
|
+
})
|
|
88
|
+
this.ready = this.initialize()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
isRunning() {
|
|
92
|
+
return this.running
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
dispose() {
|
|
96
|
+
if (!this.running) {
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
this.running = false
|
|
100
|
+
this.child.kill()
|
|
101
|
+
this.rejectPendingRequests(new Error('Language server was disposed'))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async complete(textDocument, offset) {
|
|
105
|
+
await this.ready
|
|
106
|
+
this.syncDocument(textDocument)
|
|
107
|
+
const result = await this.sendRequest('textDocument/completion', {
|
|
108
|
+
context: {
|
|
109
|
+
triggerKind: 1,
|
|
110
|
+
},
|
|
111
|
+
position: getPosition(textDocument.text, offset),
|
|
112
|
+
textDocument: {
|
|
113
|
+
uri: textDocument.uri,
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
if (Array.isArray(result)) {
|
|
117
|
+
return result
|
|
118
|
+
}
|
|
119
|
+
if (result && typeof result === 'object' && Array.isArray((result).items)) {
|
|
120
|
+
return (result).items
|
|
121
|
+
}
|
|
122
|
+
return []
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async initialize() {
|
|
126
|
+
await this.sendRequest('initialize', {
|
|
127
|
+
capabilities: {
|
|
128
|
+
textDocument: {
|
|
129
|
+
completion: {
|
|
130
|
+
completionItem: {
|
|
131
|
+
snippetSupport: true,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
synchronization: {
|
|
135
|
+
didSave: true,
|
|
136
|
+
dynamicRegistration: false,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
workspace: {
|
|
140
|
+
configuration: true,
|
|
141
|
+
workspaceFolders: true,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
clientInfo: {
|
|
145
|
+
name: 'Lvce Editor',
|
|
146
|
+
},
|
|
147
|
+
processId: process.pid,
|
|
148
|
+
rootUri: this.rootUri,
|
|
149
|
+
workspaceFolders: [
|
|
150
|
+
{
|
|
151
|
+
name: getWorkspaceName(this.rootUri),
|
|
152
|
+
uri: this.rootUri,
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
})
|
|
156
|
+
this.sendNotification('initialized', {})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
syncDocument(textDocument) {
|
|
160
|
+
const previous = this.documents.get(textDocument.uri)
|
|
161
|
+
if (!previous || previous.languageId !== textDocument.languageId) {
|
|
162
|
+
if (previous) {
|
|
163
|
+
this.sendNotification('textDocument/didClose', {
|
|
164
|
+
textDocument: {
|
|
165
|
+
uri: textDocument.uri,
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
const next = {
|
|
170
|
+
languageId: textDocument.languageId,
|
|
171
|
+
text: textDocument.text,
|
|
172
|
+
version: 1,
|
|
173
|
+
}
|
|
174
|
+
this.documents.set(textDocument.uri, next)
|
|
175
|
+
this.sendNotification('textDocument/didOpen', {
|
|
176
|
+
textDocument: {
|
|
177
|
+
languageId: next.languageId,
|
|
178
|
+
text: next.text,
|
|
179
|
+
uri: textDocument.uri,
|
|
180
|
+
version: next.version,
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
if (previous.text === textDocument.text) {
|
|
186
|
+
return
|
|
187
|
+
}
|
|
188
|
+
const next = {
|
|
189
|
+
...previous,
|
|
190
|
+
text: textDocument.text,
|
|
191
|
+
version: previous.version + 1,
|
|
192
|
+
}
|
|
193
|
+
this.documents.set(textDocument.uri, next)
|
|
194
|
+
this.sendNotification('textDocument/didChange', {
|
|
195
|
+
contentChanges: [
|
|
196
|
+
{
|
|
197
|
+
text: next.text,
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
textDocument: {
|
|
201
|
+
uri: textDocument.uri,
|
|
202
|
+
version: next.version,
|
|
203
|
+
},
|
|
204
|
+
})
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
handleData(chunk) {
|
|
208
|
+
try {
|
|
209
|
+
const messages = this.parser.push(chunk)
|
|
210
|
+
for (const message of messages) {
|
|
211
|
+
this.handleMessage(message)
|
|
212
|
+
}
|
|
213
|
+
} catch (error) {
|
|
214
|
+
this.handleExit(error instanceof Error ? error : new Error(String(error)))
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
handleMessage(message) {
|
|
219
|
+
if (message.method && message.id !== undefined && message.id !== null) {
|
|
220
|
+
this.handleServerRequest(message)
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
if (message.id === undefined || message.id === null) {
|
|
224
|
+
return
|
|
225
|
+
}
|
|
226
|
+
const pending = this.pendingRequests.get(message.id)
|
|
227
|
+
if (!pending) {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
this.pendingRequests.delete(message.id)
|
|
231
|
+
if (message.error) {
|
|
232
|
+
pending.reject(new Error(message.error.message || `Language server request failed with code ${message.error.code}`))
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
pending.resolve(message.result)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
handleServerRequest(message) {
|
|
239
|
+
let result = null
|
|
240
|
+
if (message.method === 'workspace/configuration') {
|
|
241
|
+
const itemCount = Array.isArray(message.params?.items) ? message.params.items.length : 0
|
|
242
|
+
result = Array.from({ length: itemCount }).fill(null)
|
|
243
|
+
} else if (message.method === 'workspace/workspaceFolders') {
|
|
244
|
+
result = [
|
|
245
|
+
{
|
|
246
|
+
name: getWorkspaceName(this.rootUri),
|
|
247
|
+
uri: this.rootUri,
|
|
248
|
+
},
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
this.sendMessage({
|
|
252
|
+
id: message.id,
|
|
253
|
+
jsonrpc: '2.0',
|
|
254
|
+
result,
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
handleExit(error) {
|
|
259
|
+
if (!this.running) {
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
this.running = false
|
|
263
|
+
this.rejectPendingRequests(error)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
rejectPendingRequests(error) {
|
|
267
|
+
for (const pending of this.pendingRequests.values()) {
|
|
268
|
+
pending.reject(error)
|
|
269
|
+
}
|
|
270
|
+
this.pendingRequests.clear()
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
sendNotification(method, params) {
|
|
274
|
+
this.sendMessage({
|
|
275
|
+
jsonrpc: '2.0',
|
|
276
|
+
method,
|
|
277
|
+
params,
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
sendRequest(method, params) {
|
|
282
|
+
if (!this.running) {
|
|
283
|
+
return Promise.reject(new Error('Language server is not running'))
|
|
284
|
+
}
|
|
285
|
+
const id = this.nextRequestId++
|
|
286
|
+
const promise = new Promise ((resolve, reject) => {
|
|
287
|
+
this.pendingRequests.set(id, { reject, resolve })
|
|
288
|
+
})
|
|
289
|
+
this.sendMessage({
|
|
290
|
+
id,
|
|
291
|
+
jsonrpc: '2.0',
|
|
292
|
+
method,
|
|
293
|
+
params,
|
|
294
|
+
})
|
|
295
|
+
return promise
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
sendMessage(message) {
|
|
299
|
+
const content = JSON.stringify(message)
|
|
300
|
+
const header = `Content-Length: ${Buffer.byteLength(content)}\r\n\r\n`
|
|
301
|
+
this.child.stdin.write(header + content)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const headerSeparator = Buffer.from('\r\n\r\n')
|
|
2
|
+
const contentLengthRegex = /(?:^|\r\n)Content-Length:\s*(\d+)/i
|
|
3
|
+
|
|
4
|
+
export class LanguageServerMessageParser {
|
|
5
|
+
buffer = Buffer.alloc(0)
|
|
6
|
+
|
|
7
|
+
push(chunk) {
|
|
8
|
+
this.buffer = Buffer.concat([this.buffer, chunk])
|
|
9
|
+
const messages = []
|
|
10
|
+
while (true) {
|
|
11
|
+
const headerEnd = this.buffer.indexOf(headerSeparator)
|
|
12
|
+
if (headerEnd === -1) {
|
|
13
|
+
break
|
|
14
|
+
}
|
|
15
|
+
const header = this.buffer.subarray(0, headerEnd).toString('ascii')
|
|
16
|
+
const match = contentLengthRegex.exec(header)
|
|
17
|
+
if (!match) {
|
|
18
|
+
throw new Error('Language server message is missing Content-Length')
|
|
19
|
+
}
|
|
20
|
+
const contentLength = Number(match[1])
|
|
21
|
+
const contentStart = headerEnd + headerSeparator.length
|
|
22
|
+
const contentEnd = contentStart + contentLength
|
|
23
|
+
if (this.buffer.length < contentEnd) {
|
|
24
|
+
break
|
|
25
|
+
}
|
|
26
|
+
const content = this.buffer.subarray(contentStart, contentEnd).toString('utf8')
|
|
27
|
+
this.buffer = this.buffer.subarray(contentEnd)
|
|
28
|
+
messages.push(JSON.parse(content))
|
|
29
|
+
}
|
|
30
|
+
return messages
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -110,6 +110,8 @@ export const load = (moduleId) => {
|
|
|
110
110
|
return import('../InstallExtension/InstallExtension.ipc.js')
|
|
111
111
|
case ModuleId.IsAutoUpdateSupported:
|
|
112
112
|
return import('../IsAutoUpdateSupported/IsAutoUpdateSupported.ipc.js')
|
|
113
|
+
case ModuleId.LanguageServer:
|
|
114
|
+
return import('../LanguageServer/LanguageServer.ipc.js')
|
|
113
115
|
case ModuleId.OpenExternal:
|
|
114
116
|
return import('../OpenExternal/OpenExternal.ipc.js')
|
|
115
117
|
case ModuleId.OpenNativeFolder:
|
|
@@ -67,8 +67,11 @@ export const getModuleId = (commandId) => {
|
|
|
67
67
|
case 'ElectronPowerSaveBlocker.start':
|
|
68
68
|
case 'ElectronPowerSaveBlocker.stop':
|
|
69
69
|
return ModuleId.ElectronPowerSaveBlocker
|
|
70
|
+
case 'ElectronProcess.getArgv':
|
|
70
71
|
case 'ElectronProcess.getChromeVersion':
|
|
71
72
|
case 'ElectronProcess.getElectronVersion':
|
|
73
|
+
case 'ElectronProcess.writeStderr':
|
|
74
|
+
case 'ElectronProcess.writeStdout':
|
|
72
75
|
return ModuleId.ElectronProcess
|
|
73
76
|
case 'ElectronSafeStorage.decryptString':
|
|
74
77
|
case 'ElectronSafeStorage.encryptString':
|
|
@@ -244,6 +247,8 @@ export const getModuleId = (commandId) => {
|
|
|
244
247
|
return ModuleId.InstallExtension
|
|
245
248
|
case 'IsAutoUpdateSupported.isAutoUpdateSupported':
|
|
246
249
|
return ModuleId.IsAutoUpdateSupported
|
|
250
|
+
case 'LanguageServer.complete':
|
|
251
|
+
return ModuleId.LanguageServer
|
|
247
252
|
case 'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage':
|
|
248
253
|
return ModuleId.ListProcessesWithMemoryUsage
|
|
249
254
|
case 'Native.openFolder':
|
|
@@ -61,11 +61,11 @@ export const getSetupName = () => {
|
|
|
61
61
|
return 'Lvce-Setup'
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export const version = '0.89.
|
|
64
|
+
export const version = '0.89.3'
|
|
65
65
|
|
|
66
|
-
export const commit = '
|
|
66
|
+
export const commit = 'f1db6cb'
|
|
67
67
|
|
|
68
|
-
export const date = '2026-07-
|
|
68
|
+
export const date = '2026-07-14T11:58:48.000Z'
|
|
69
69
|
|
|
70
70
|
export const getVersion = () => {
|
|
71
71
|
return version
|
|
@@ -2,5 +2,5 @@ import { join } from 'node:path'
|
|
|
2
2
|
import * as Root from '../Root/Root.js'
|
|
3
3
|
|
|
4
4
|
export const getPreloadUrl = () => {
|
|
5
|
-
return join(Root.root, 'static', '
|
|
5
|
+
return join(Root.root, 'static', 'f1db6cb', 'packages', 'preload', 'dist', 'index.js')
|
|
6
6
|
}
|
|
@@ -5,6 +5,7 @@ import * as Env from '../Env/Env.js'
|
|
|
5
5
|
import * as GetWorkspaceId from '../GetWorkspaceId/GetWorkspaceId.js'
|
|
6
6
|
import * as IsAbsolutePath from '../IsAbsolutePath/IsAbsolutePath.js'
|
|
7
7
|
import * as IsElectron from '../IsElectron/IsElectron.js'
|
|
8
|
+
import * as IsPromptMode from '../IsPromptMode/IsPromptMode.js'
|
|
8
9
|
import * as ParentIpc from '../MainProcess/MainProcess.js'
|
|
9
10
|
import * as Platform from '../Platform/Platform.js'
|
|
10
11
|
import * as PlatformPaths from '../PlatformPaths/PlatformPaths.js'
|
|
@@ -33,7 +34,7 @@ export const resolveRoot = async () => {
|
|
|
33
34
|
const argv = await ParentIpc.invoke('Process.getArgv')
|
|
34
35
|
const relevantArgv = argv.slice(1)
|
|
35
36
|
const last = relevantArgv.at(-1)
|
|
36
|
-
if (last && last === '.') {
|
|
37
|
+
if (IsPromptMode.isPromptMode(relevantArgv) || (last && last === '.')) {
|
|
37
38
|
const actual = process.cwd()
|
|
38
39
|
return {
|
|
39
40
|
homeDir: PlatformPaths.getHomeDir(),
|