@lvce-editor/shared-process 0.89.3 → 0.90.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.
- package/config/defaultSettings.json +1 -3
- package/package.json +3 -2
- package/src/parts/BuiltinExtensionsPath/BuiltinExtensionsPath.js +1 -1
- package/src/parts/LanguageServerConnection/LanguageServerConnection.js +86 -19
- package/src/parts/MarkdownLanguageServerRequest/MarkdownLanguageServerRequest.js +116 -0
- package/src/parts/Platform/Platform.js +3 -3
- package/src/parts/PreloadUrl/PreloadUrl.js +1 -1
|
@@ -35,12 +35,10 @@
|
|
|
35
35
|
|
|
36
36
|
"sessionReplay.enabled": false,
|
|
37
37
|
|
|
38
|
-
"serviceWorker.enabled": false,
|
|
39
|
-
|
|
40
38
|
"simpleBrowser.suggestions": false,
|
|
41
39
|
|
|
42
40
|
"terminal.backend": "real",
|
|
43
|
-
"terminal.renderer": "
|
|
41
|
+
"terminal.renderer": "xterm",
|
|
44
42
|
"terminal.separateConnection": false,
|
|
45
43
|
|
|
46
44
|
"window.titleBarStyle": "custom",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.90.2",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@lvce-editor/assert": "1.7.0",
|
|
21
21
|
"@lvce-editor/auth-process": "1.9.0",
|
|
22
|
-
"@lvce-editor/extension-host-helper-process": "0.
|
|
22
|
+
"@lvce-editor/extension-host-helper-process": "0.90.2",
|
|
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",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"@lvce-editor/rpc-registry": "9.35.0",
|
|
29
29
|
"@lvce-editor/verror": "1.7.0",
|
|
30
30
|
"is-object": "^1.0.2",
|
|
31
|
+
"markdown-it": "^14.3.0",
|
|
31
32
|
"xdg-basedir": "^5.1.0"
|
|
32
33
|
},
|
|
33
34
|
"optionalDependencies": {
|
|
@@ -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', '6faf35c', 'extensions')
|
|
7
7
|
return builtinExtensionsPath
|
|
8
8
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { spawn, } from 'node:child_process'
|
|
2
|
-
import { basename } from 'node:path'
|
|
2
|
+
import { basename, extname } from 'node:path'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
import { LanguageServerMessageParser } from '../LanguageServerMessageParser/LanguageServerMessageParser.js'
|
|
5
|
+
import {
|
|
6
|
+
executeMarkdownLanguageServerRequest,
|
|
7
|
+
isMarkdownLanguageServerRequest,
|
|
8
|
+
} from '../MarkdownLanguageServerRequest/MarkdownLanguageServerRequest.js'
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
|
|
@@ -36,6 +40,21 @@ import { LanguageServerMessageParser } from '../LanguageServerMessageParser/Lang
|
|
|
36
40
|
|
|
37
41
|
|
|
38
42
|
|
|
43
|
+
|
|
44
|
+
const getSpawnOptions = (uri, argv) => {
|
|
45
|
+
const executablePath = fileURLToPath(uri)
|
|
46
|
+
const extension = extname(executablePath).toLowerCase()
|
|
47
|
+
if (extension === '.js' || extension === '.mjs' || extension === '.cjs') {
|
|
48
|
+
return {
|
|
49
|
+
args: [executablePath, ...argv],
|
|
50
|
+
command: process.execPath,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
args: argv,
|
|
55
|
+
command: executablePath,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
39
58
|
|
|
40
59
|
const getPosition = (text, offset) => {
|
|
41
60
|
const safeOffset = Math.max(0, Math.min(offset, text.length))
|
|
@@ -62,13 +81,15 @@ export class LanguageServerConnection {
|
|
|
62
81
|
pendingRequests = new Map ()
|
|
63
82
|
ready
|
|
64
83
|
rootUri
|
|
84
|
+
markdownConfigured = false
|
|
65
85
|
nextRequestId = 1
|
|
66
86
|
running = true
|
|
67
87
|
stderr = ''
|
|
68
88
|
|
|
69
89
|
constructor({ argv, rootUri, uri } ) {
|
|
70
90
|
this.rootUri = rootUri
|
|
71
|
-
|
|
91
|
+
const { args, command } = getSpawnOptions(uri, argv)
|
|
92
|
+
this.child = spawn(command, [...args], {
|
|
72
93
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
73
94
|
})
|
|
74
95
|
this.child.stdout.on('data', (chunk) => {
|
|
@@ -103,6 +124,7 @@ export class LanguageServerConnection {
|
|
|
103
124
|
|
|
104
125
|
async complete(textDocument, offset) {
|
|
105
126
|
await this.ready
|
|
127
|
+
this.configureMarkdown(textDocument.languageId)
|
|
106
128
|
this.syncDocument(textDocument)
|
|
107
129
|
const result = await this.sendRequest('textDocument/completion', {
|
|
108
130
|
context: {
|
|
@@ -122,6 +144,35 @@ export class LanguageServerConnection {
|
|
|
122
144
|
return []
|
|
123
145
|
}
|
|
124
146
|
|
|
147
|
+
configureMarkdown(languageId) {
|
|
148
|
+
if (languageId !== 'markdown' || this.markdownConfigured) {
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
this.markdownConfigured = true
|
|
152
|
+
this.sendNotification('workspace/didChangeConfiguration', {
|
|
153
|
+
settings: {
|
|
154
|
+
markdown: {
|
|
155
|
+
occurrencesHighlight: {
|
|
156
|
+
enabled: true,
|
|
157
|
+
},
|
|
158
|
+
preferredMdPathExtensionStyle: 'auto',
|
|
159
|
+
server: {
|
|
160
|
+
log: 'off',
|
|
161
|
+
},
|
|
162
|
+
suggest: {
|
|
163
|
+
paths: {
|
|
164
|
+
enabled: true,
|
|
165
|
+
includeWorkspaceHeaderCompletions: 'never',
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
validate: {
|
|
169
|
+
enabled: false,
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
125
176
|
async initialize() {
|
|
126
177
|
await this.sendRequest('initialize', {
|
|
127
178
|
capabilities: {
|
|
@@ -217,7 +268,7 @@ export class LanguageServerConnection {
|
|
|
217
268
|
|
|
218
269
|
handleMessage(message) {
|
|
219
270
|
if (message.method && message.id !== undefined && message.id !== null) {
|
|
220
|
-
this.handleServerRequest(message)
|
|
271
|
+
void this.handleServerRequest(message)
|
|
221
272
|
return
|
|
222
273
|
}
|
|
223
274
|
if (message.id === undefined || message.id === null) {
|
|
@@ -235,24 +286,40 @@ export class LanguageServerConnection {
|
|
|
235
286
|
pending.resolve(message.result)
|
|
236
287
|
}
|
|
237
288
|
|
|
238
|
-
handleServerRequest(message)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
289
|
+
async handleServerRequest(message) {
|
|
290
|
+
try {
|
|
291
|
+
let result = null
|
|
292
|
+
if (message.method === 'workspace/configuration') {
|
|
293
|
+
const itemCount = Array.isArray(message.params?.items) ? message.params.items.length : 0
|
|
294
|
+
result = Array.from({ length: itemCount }).fill(null)
|
|
295
|
+
} else if (message.method === 'workspace/workspaceFolders') {
|
|
296
|
+
result = [
|
|
297
|
+
{
|
|
298
|
+
name: getWorkspaceName(this.rootUri),
|
|
299
|
+
uri: this.rootUri,
|
|
300
|
+
},
|
|
301
|
+
]
|
|
302
|
+
} else if (isMarkdownLanguageServerRequest(message.method || '')) {
|
|
303
|
+
result = await executeMarkdownLanguageServerRequest(message.method || '', message.params || {}, {
|
|
304
|
+
documents: this.documents,
|
|
305
|
+
rootUri: this.rootUri,
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
this.sendMessage({
|
|
309
|
+
id: message.id,
|
|
310
|
+
jsonrpc: '2.0',
|
|
311
|
+
result,
|
|
312
|
+
})
|
|
313
|
+
} catch (error) {
|
|
314
|
+
this.sendMessage({
|
|
315
|
+
error: {
|
|
316
|
+
code: -32_603,
|
|
317
|
+
message: error instanceof Error ? error.message : String(error),
|
|
248
318
|
},
|
|
249
|
-
|
|
319
|
+
id: message.id,
|
|
320
|
+
jsonrpc: '2.0',
|
|
321
|
+
})
|
|
250
322
|
}
|
|
251
|
-
this.sendMessage({
|
|
252
|
-
id: message.id,
|
|
253
|
-
jsonrpc: '2.0',
|
|
254
|
-
result,
|
|
255
|
-
})
|
|
256
323
|
}
|
|
257
324
|
|
|
258
325
|
handleExit(error) {
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import MarkdownIt from 'markdown-it'
|
|
2
|
+
import { readFile, readdir, stat } from 'node:fs/promises'
|
|
3
|
+
import { isAbsolute, relative, resolve, sep } from 'node:path'
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const markdownFileExtensions = new Set(['.markdown', '.md', '.mdown', '.mdtext', '.mdtxt', '.mdwn', '.mkd', '.mkdn'])
|
|
21
|
+
const ignoredDirectories = new Set(['.git', 'node_modules'])
|
|
22
|
+
const markdownIt = new MarkdownIt({ html: true })
|
|
23
|
+
|
|
24
|
+
export const isMarkdownLanguageServerRequest = (method) => {
|
|
25
|
+
return (
|
|
26
|
+
method === 'markdown/parse' ||
|
|
27
|
+
method === 'markdown/fs/readFile' ||
|
|
28
|
+
method === 'markdown/fs/readDirectory' ||
|
|
29
|
+
method === 'markdown/fs/stat' ||
|
|
30
|
+
method === 'markdown/findMarkdownFilesInWorkspace'
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const getWorkspacePath = (uri, rootUri) => {
|
|
35
|
+
const rootPath = resolve(fileURLToPath(rootUri))
|
|
36
|
+
const targetPath = resolve(fileURLToPath(uri))
|
|
37
|
+
const relativePath = relative(rootPath, targetPath)
|
|
38
|
+
if (relativePath === '..' || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)) {
|
|
39
|
+
throw new Error(`Language server file request is outside the workspace`)
|
|
40
|
+
}
|
|
41
|
+
return targetPath
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const getMarkdownText = async (params, context) => {
|
|
45
|
+
if (typeof params.text === 'string') {
|
|
46
|
+
return params.text
|
|
47
|
+
}
|
|
48
|
+
if (!params.uri) {
|
|
49
|
+
throw new Error(`Markdown parse request is missing a uri`)
|
|
50
|
+
}
|
|
51
|
+
const document = context.documents.get(params.uri)
|
|
52
|
+
if (document) {
|
|
53
|
+
return document.text
|
|
54
|
+
}
|
|
55
|
+
const path = getWorkspacePath(params.uri, context.rootUri)
|
|
56
|
+
return readFile(path, 'utf8')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const findMarkdownFiles = async (rootPath) => {
|
|
60
|
+
const result = []
|
|
61
|
+
const visit = async (directory) => {
|
|
62
|
+
const entries = await readdir(directory, { withFileTypes: true })
|
|
63
|
+
await Promise.all(
|
|
64
|
+
entries.map(async (entry) => {
|
|
65
|
+
const path = resolve(directory, entry.name)
|
|
66
|
+
if (entry.isDirectory()) {
|
|
67
|
+
if (ignoredDirectories.has(entry.name)) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
await visit(path)
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
const extensionIndex = entry.name.lastIndexOf('.')
|
|
74
|
+
const extension = extensionIndex === -1 ? '' : entry.name.slice(extensionIndex).toLowerCase()
|
|
75
|
+
if (markdownFileExtensions.has(extension)) {
|
|
76
|
+
result.push(pathToFileURL(path).href)
|
|
77
|
+
}
|
|
78
|
+
}),
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
await visit(rootPath)
|
|
82
|
+
return result.sort()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const executeMarkdownLanguageServerRequest = async (
|
|
86
|
+
method,
|
|
87
|
+
params,
|
|
88
|
+
context,
|
|
89
|
+
) => {
|
|
90
|
+
if (method === 'markdown/parse') {
|
|
91
|
+
return markdownIt.parse(await getMarkdownText(params, context), {})
|
|
92
|
+
}
|
|
93
|
+
if (method === 'markdown/findMarkdownFilesInWorkspace') {
|
|
94
|
+
return findMarkdownFiles(getWorkspacePath(context.rootUri, context.rootUri))
|
|
95
|
+
}
|
|
96
|
+
if (!params.uri) {
|
|
97
|
+
throw new Error(`Markdown file request is missing a uri`)
|
|
98
|
+
}
|
|
99
|
+
const path = getWorkspacePath(params.uri, context.rootUri)
|
|
100
|
+
if (method === 'markdown/fs/readFile') {
|
|
101
|
+
return [...(await readFile(path))]
|
|
102
|
+
}
|
|
103
|
+
if (method === 'markdown/fs/readDirectory') {
|
|
104
|
+
const entries = await readdir(path, { withFileTypes: true })
|
|
105
|
+
return entries.map((entry) => [entry.name, { isDirectory: entry.isDirectory() }])
|
|
106
|
+
}
|
|
107
|
+
if (method === 'markdown/fs/stat') {
|
|
108
|
+
try {
|
|
109
|
+
const fileStat = await stat(path)
|
|
110
|
+
return { isDirectory: fileStat.isDirectory() }
|
|
111
|
+
} catch {
|
|
112
|
+
return undefined
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Unsupported Markdown language server request: ${method}`)
|
|
116
|
+
}
|
|
@@ -61,11 +61,11 @@ export const getSetupName = () => {
|
|
|
61
61
|
return 'Lvce-Setup'
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export const version = '0.
|
|
64
|
+
export const version = '0.90.2'
|
|
65
65
|
|
|
66
|
-
export const commit = '
|
|
66
|
+
export const commit = '6faf35c'
|
|
67
67
|
|
|
68
|
-
export const date = '2026-07-
|
|
68
|
+
export const date = '2026-07-15T08:29:42.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', '6faf35c', 'packages', 'preload', 'dist', 'index.js')
|
|
6
6
|
}
|