返回 slidev
languagePlugin.ts
根目录 / packages / vscode / language-server / languagePlugin.ts
1 import type { SlidevMarkdown } from '@slidev/types'
2 import type { LanguagePlugin, VirtualCode } from '@volar/language-core'
3 import type { URI } from 'vscode-uri'
4 import { parseSync } from '@slidev/parser'
5
6 export const slidevLanguagePlugin: LanguagePlugin<URI> = {
7 getLanguageId() {
8 return undefined
9 },
10 createVirtualCode(uri, languageId, snapshot) {
11 if (languageId === 'markdown') {
12 const source = snapshot.getText(0, snapshot.getLength())
13 const parsed = parseSync(source, uri.fsPath, {
14 noParseYAML: true,
15 preserveCR: true,
16 })
17
18 return {
19 id: 'root',
20 languageId: 'markdown',
21 mappings: [],
22 embeddedCodes: [...getEmbeddedCodes(parsed)],
23 snapshot,
24 }
25 }
26 },
27 }
28
29 function* getEmbeddedCodes(parsed: SlidevMarkdown): Generator<VirtualCode> {
30 const lines = parsed.raw.split('\n')
31 function lineToPos(line: number) {
32 let pos = 0
33 for (let i = 0; i <= line && i < lines.length; i++) {
34 pos += lines[i].length + 1
35 }
36 return pos
37 }
38 for (const { frontmatterRaw, start, contentStart, content, index } of parsed.slides) {
39 if (frontmatterRaw != null) {
40 yield {
41 id: `frontmatter_${index}`,
42 languageId: 'yaml',
43 snapshot: {
44 getText: (start, end) => frontmatterRaw.substring(start, end),
45 getLength: () => frontmatterRaw.length,
46 getChangeRange: () => undefined,
47 },
48 mappings: [{
49 sourceOffsets: [lineToPos(start)],
50 generatedOffsets: [0],
51 lengths: [frontmatterRaw.length],
52 data: {
53 verification: true,
54 completion: true,
55 semantic: true,
56 navigation: true,
57 structure: true,
58 format: true,
59 },
60 }],
61 embeddedCodes: [],
62 }
63 }
64 if (content) {
65 yield {
66 id: `content_${index}`,
67 languageId: 'markdown',
68 snapshot: {
69 getText: (start, end) => content.substring(start, end),
70 getLength: () => content.length,
71 getChangeRange: () => undefined,
72 },
73 mappings: [{
74 sourceOffsets: [lineToPos(contentStart)],
75 generatedOffsets: [0],
76 lengths: [content.length],
77 data: {
78 verification: true,
79 completion: true,
80 semantic: true,
81 navigation: true,
82 structure: true,
83 format: false,
84 },
85 }],
86 embeddedCodes: [],
87 }
88 }
89 }
90 }
91
91 lines TYPESCRIPT