Skip to content

Commit 43e27c6

Browse files
committed
feat: support router yaml block
1 parent a8c5a84 commit 43e27c6

10 files changed

+231
-29
lines changed

.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"vue.server.configFilePath": "./packages/playground/volar.config.js"
2+
"vue.server.configFilePath": "./packages/playground/volar.config.js",
3+
"prettier.enable": false
34
}

README.md

-3
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ export default defineUniPages({
6363
- **解析器支持:** JSON, JSON5, YAML
6464
- **默认:** JSON5
6565

66-
> [!NOTE]
67-
> 尽管支持多种解析器,但是建议你始终使用 `json``json5` 来作为默认解析器,因为这些解析器可以配合 [volar-service-uni-pages](./packages/volar/) 来获得**智能感知****字段提示**能力。
68-
6966
```html
7067
<!-- index.vue -->
7168
<!-- 使用 type="home" 属性设置首页 -->

packages/volar/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
"dependencies": {
4343
"@uni-helper/pages-json-schema": "workspace:^",
4444
"ts-json-schema-generator": "^1.3.0",
45-
"vscode-json-languageservice": "^5.3.6"
45+
"vscode-json-languageservice": "^5.3.6",
46+
"vscode-languageserver-textdocument": "^1.0.8",
47+
"yaml-language-server": "^1.14.0"
4648
},
4749
"devDependencies": {
4850
"@types/json-schema": "^7.0.13",

packages/volar/src/index.ts

+56-19
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import type { Service } from '@volar/language-service'
2-
import * as json from 'vscode-json-languageservice'
3-
import pagesJsonSchema from '@uni-helper/pages-json-schema/schema.json'
2+
import { type LanguageService } from 'yaml-language-server'
3+
import type * as json from 'vscode-json-languageservice'
4+
import { type TextDocument } from 'vscode-languageserver-textdocument'
5+
import { createJsonLs } from './jsonLs'
6+
import { createYamlLs } from './yamlLs'
7+
import { isYaml } from './utils'
48

5-
type TextDocument = any
6-
7-
pagesJsonSchema.$ref = '#/definitions/PageMetaDatum'
8-
pagesJsonSchema.definitions.PageMetaDatum.required = []
99
export interface Provide {
1010
'json/jsonDocument': (document: TextDocument) => json.JSONDocument | undefined
1111
'json/languageService': () => json.LanguageService
12+
'yaml/languageService': () => LanguageService
1213
}
1314

1415
export default (): Service<Provide> => (context): ReturnType<Service<Provide>> => {
@@ -19,30 +20,39 @@ export default (): Service<Provide> => (context): ReturnType<Service<Provide>> =
1920
return { triggerCharacters } as any
2021

2122
const jsonDocuments = new WeakMap<TextDocument, [number, json.JSONDocument]>()
22-
const jsonLs = json.getLanguageService({})
23-
jsonLs.configure({
24-
allowComments: true,
25-
schemas: [
26-
{
27-
fileMatch: ['*.customBlock_route_*.json*'],
28-
uri: 'foo://route-custom-block.schema.json',
29-
schema: {
30-
...pagesJsonSchema,
31-
},
32-
},
33-
],
34-
})
23+
const jsonLs = createJsonLs(context)
24+
const yamlLs = createYamlLs(context)
3525

3626
return {
3727

3828
provide: {
3929
'json/jsonDocument': getJsonDocument,
4030
'json/languageService': () => jsonLs,
31+
'yaml/languageService': () => yamlLs,
4132
},
4233

4334
triggerCharacters,
4435

36+
provideCodeActions(document, range, context) {
37+
if (isYaml(document)) {
38+
return yamlLs.getCodeAction(document, {
39+
context,
40+
range,
41+
textDocument: document,
42+
})
43+
}
44+
},
45+
46+
provideCodeLenses(document) {
47+
if (isYaml(document))
48+
return yamlLs.getCodeLens(document)
49+
50+
},
51+
4552
provideCompletionItems(document, position) {
53+
if (isYaml(document))
54+
return yamlLs.doComplete(document, position, false)
55+
4656
return worker(document, async (jsonDocument) => {
4757
return await jsonLs.doComplete(document, position, jsonDocument)
4858
})
@@ -53,12 +63,18 @@ export default (): Service<Provide> => (context): ReturnType<Service<Provide>> =
5363
},
5464

5565
provideDefinition(document, position) {
66+
if (isYaml(document))
67+
return yamlLs.doDefinition(document, { position, textDocument: document })
68+
5669
return worker(document, async (jsonDocument) => {
5770
return await jsonLs.findDefinition(document, position, jsonDocument)
5871
})
5972
},
6073

6174
provideDiagnostics(document) {
75+
if (isYaml(document))
76+
return yamlLs.doValidation(document, false)
77+
6278
return worker(document, async (jsonDocument) => {
6379
const documentLanguageSettings = undefined // await getSettings(); // TODO
6480

@@ -71,19 +87,29 @@ export default (): Service<Provide> => (context): ReturnType<Service<Provide>> =
7187
})
7288
},
7389

90+
7491
provideHover(document, position) {
92+
if (isYaml(document))
93+
return yamlLs.doHover(document, position)
94+
7595
return worker(document, async (jsonDocument) => {
7696
return await jsonLs.doHover(document, position, jsonDocument)
7797
})
7898
},
7999

80100
provideDocumentLinks(document) {
101+
if (isYaml(document))
102+
return yamlLs.findLinks(document)
103+
81104
return worker(document, async (jsonDocument) => {
82105
return await jsonLs.findLinks(document, jsonDocument)
83106
})
84107
},
85108

86109
provideDocumentSymbols(document) {
110+
if (isYaml(document))
111+
return yamlLs.findDocumentSymbols2(document, {})
112+
87113
return worker(document, async (jsonDocument) => {
88114
return await jsonLs.findDocumentSymbols2(document, jsonDocument)
89115
})
@@ -102,17 +128,28 @@ export default (): Service<Provide> => (context): ReturnType<Service<Provide>> =
102128
},
103129

104130
provideFoldingRanges(document) {
131+
if (isYaml(document))
132+
return yamlLs.getFoldingRanges(document, {})
133+
134+
105135
return worker(document, async () => {
106136
return await jsonLs.getFoldingRanges(document)
107137
})
108138
},
109139

110140
provideSelectionRanges(document, positions) {
141+
if (isYaml(document))
142+
return yamlLs.getSelectionRanges(document, positions)
143+
111144
return worker(document, async (jsonDocument) => {
112145
return await jsonLs.getSelectionRanges(document, positions, jsonDocument)
113146
})
114147
},
115148

149+
resolveCodeLens(codeLens) {
150+
return yamlLs.resolveCodeLens(codeLens)
151+
},
152+
116153
provideDocumentFormattingEdits(document, range, options) {
117154
return worker(document, async () => {
118155
const options_2 = await context.env.getConfiguration?.<json.FormattingOptions & { enable: boolean }>('json.format')

packages/volar/src/jsonLs.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as json from 'vscode-json-languageservice'
2+
import type { ServiceContext } from '@volar/language-service'
3+
import { schema } from './schema'
4+
5+
export function createJsonLs(_context: ServiceContext) {
6+
const jsonLs = json.getLanguageService({})
7+
jsonLs.configure({
8+
allowComments: true,
9+
schemas: [
10+
{
11+
fileMatch: ['*.customBlock_route_*.json*'],
12+
uri: 'foo://route-custom-block.schema.json',
13+
schema,
14+
},
15+
],
16+
})
17+
return jsonLs
18+
}

packages/volar/src/schema.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import pagesJsonSchema from '@uni-helper/pages-json-schema/schema.json'
2+
3+
pagesJsonSchema.$ref = '#/definitions/PageMetaDatum'
4+
pagesJsonSchema.definitions.PageMetaDatum.required = []
5+
6+
export const schema = pagesJsonSchema

packages/volar/src/utils.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { type TextDocument } from 'vscode-languageserver-textdocument'
2+
3+
export function isYaml(document: TextDocument): boolean {
4+
return document.languageId === 'yaml'
5+
}

packages/volar/src/yamlLs.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { getLanguageService } from 'yaml-language-server'
2+
import type { ServiceContext } from '@volar/language-service'
3+
import { schema } from './schema'
4+
5+
function noop(): undefined { }
6+
7+
export function createYamlLs(context: ServiceContext) {
8+
const ls = getLanguageService({
9+
schemaRequestService: async uri => await context.env.fs?.readFile(uri) ?? '',
10+
telemetry: {
11+
send: noop,
12+
sendError: noop,
13+
sendTrack: noop,
14+
},
15+
// @ts-expect-error https://github.com/redhat-developer/yaml-language-server/pull/910
16+
clientCapabilities: context?.env?.clientCapabilities,
17+
workspaceContext: {
18+
resolveRelativePath(relativePath, resource) {
19+
return String(new URL(relativePath, resource))
20+
},
21+
},
22+
})
23+
24+
ls.configure({
25+
completion: true,
26+
customTags: [],
27+
format: true,
28+
hover: true,
29+
isKubernetes: false,
30+
validate: true,
31+
yamlVersion: '1.2',
32+
schemas: [
33+
{
34+
fileMatch: ['*.customBlock_route_*.yaml*'],
35+
uri: 'foo://route-custom-block.schema.yaml',
36+
schema,
37+
},
38+
],
39+
})
40+
41+
return ls
42+
}

packages/volar/tsconfig.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"compilerOptions": {
33
"target": "esnext",
4+
"jsx": "preserve",
45
"useDefineForClassFields": true,
56
"module": "esnext",
67
"moduleResolution": "node",
7-
"jsx": "preserve",
8-
"sourceMap": true,
98
"resolveJsonModule": true,
9+
"sourceMap": true,
1010
"esModuleInterop": true,
1111
"skipLibCheck": true
1212
}

0 commit comments

Comments
 (0)