Skip to content

Commit cc12827

Browse files
committed
feat: introduce vitepress-plugin-twoslash
1 parent 5ce7e1f commit cc12827

File tree

14 files changed

+393
-360
lines changed

14 files changed

+393
-360
lines changed

docs/.vitepress/config.ts

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import type { DefaultTheme } from 'vitepress'
22
import { defineConfig } from 'vitepress'
3-
import { transformerTwoSlash } from 'shikiji-twoslash'
43
import { bundledThemes } from 'shikiji'
4+
import { defaultInfoProcessor, transformerTwoslash } from 'vitepress-plugin-twoslash'
55
import { version } from '../../package.json'
66
import vite from './vite.config'
7-
import { rendererFloatingVue } from './renderer-floating-vue'
87

98
const GUIDES: DefaultTheme.NavItemWithLink[] = [
109
{ text: 'Getting Started', link: '/guide/' },
@@ -55,9 +54,14 @@ export default defineConfig({
5554
}))
5655
},
5756
codeTransformers: [
58-
transformerTwoSlash({
59-
explicitTrigger: true,
60-
renderer: rendererFloatingVue(),
57+
transformerTwoslash({
58+
processHoverInfo(info) {
59+
return defaultInfoProcessor(info)
60+
// Remove shikiji_core namespace
61+
.replace(/\bshikiji_core\./g, '')
62+
// Remove member access
63+
.replace(/^[a-zA-Z0-9_]*(\<[^\>]*\>)?\./, '')
64+
},
6165
}),
6266
{
6367
// Render custom themes with codeblocks
@@ -92,21 +96,7 @@ export default defineConfig({
9296
return code
9397
},
9498
},
95-
{
96-
name: 'shikiji:vitepress-patch',
97-
preprocess(_, options) {
98-
const cleanup = options.transformers?.find(i => i.name === 'vitepress:clean-up')
99-
if (cleanup)
100-
options.transformers?.splice(options.transformers.indexOf(cleanup), 1)
10199

102-
// Disable v-pre for twoslash, because we need render it with FloatingVue
103-
if (options.meta?.__raw?.includes('twoslash')) {
104-
const vPre = options.transformers?.find(i => i.name === 'vitepress:v-pre')
105-
if (vPre)
106-
options.transformers?.splice(options.transformers.indexOf(vPre), 1)
107-
}
108-
},
109-
},
110100
{
111101
name: 'shikiji:remove-escape',
112102
postprocess(code) {

docs/.vitepress/theme/index.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
// https://vitepress.dev/guide/custom-theme
2-
import { h } from 'vue'
32
import Theme from 'vitepress/theme'
3+
import TwoSlashFloatingVue from 'vitepress-plugin-twoslash/client'
44
import 'uno.css'
5-
import 'shikiji-twoslash/style-rich.css'
6-
import 'floating-vue/dist/style.css'
75
import './style.css'
8-
import './custom.css'
96
import { createPinia } from 'pinia'
10-
import FloatingVue from 'floating-vue'
7+
import type { EnhanceAppContext } from 'vitepress'
118

129
export default {
1310
extends: Theme,
14-
Layout: () => {
15-
return h(Theme.Layout, null, {})
16-
},
17-
enhanceApp({ app }: any) {
11+
enhanceApp({ app }: EnhanceAppContext) {
1812
app.use(createPinia())
19-
20-
FloatingVue.options.themes.menu.delay = { show: 0, hide: 0 }
21-
app.use(FloatingVue)
13+
app.use(TwoSlashFloatingVue)
2214
},
2315
}

docs/packages/twoslash.md

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -187,40 +187,4 @@ app.innerHTML = await codeToHtml(source, {
187187

188188
## Integrations
189189

190-
### VitePress
191-
192-
VitePress uses Shikiji for syntax highlighting since [`1.0.0-rc.30`](https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md#100-rc30-2023-11-23). To use this transformer, you can add it to the `markdown.codeTransformers` option in your VitePress config file.
193-
194-
```ts twoslash
195-
// .vitepress/config.ts
196-
import { defineConfig } from 'vitepress'
197-
import { rendererRich, transformerTwoSlash } from 'shikiji-twoslash'
198-
199-
export default defineConfig({
200-
markdown: {
201-
codeTransformers: [
202-
transformerTwoSlash({
203-
// This makes TwoSlash only run on code blocks with `twoslash` presented in the codeframe
204-
explicitTrigger: true,
205-
// Use the rich renderer
206-
renderer: rendererRich({
207-
// This makes VitePress ignore the additional meta DOM on copy
208-
// Available since VitePress 1.0.0-rc.33
209-
classExtra: 'vp-copy-ignore',
210-
}),
211-
})
212-
]
213-
},
214-
})
215-
```
216-
217-
And import the CSS in your `.vitepress/theme/index.ts`
218-
219-
```ts
220-
// .vitepress/theme/index.ts
221-
import 'shikiji-twoslash/style-rich.css'
222-
223-
export default {
224-
// ...
225-
}
226-
```
190+
- [VitePress](/packages/vitepress#twoslash) - Enable TwoSlash support in VitePress.

docs/packages/vitepress.md

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
11
# VitePress Integration
22

3-
You don't need explicit integration in [VitePress](https://vitepress.dev/) as VitePress already uses Shikiji under the hood.
3+
[VitePress](https://vitepress.dev/) uses Shikiji under the hood, so you don't need explicit integration.
44

55
VitePress provides [a few options for customizing Shikiji](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts#L66-L112). Learn more about them in the [VitePress documentation](https://vitepress.dev/reference/site-config#markdown).
6+
7+
## TwoSlash
8+
9+
To enable [TypeScript TwoSlash](/packages/twoslash) (type hover on code snippets) in VitePress, we provide a VitePress plugin for easy setup. Pre-styled, with [Floating Vue](https://floating-vue.starpad.dev/) to display the type information out side of the code container.
10+
11+
<Badges name="vitepress-plugin-twoslash" />
12+
13+
```bash
14+
npm i -D vitepress-plugin-twoslash
15+
```
16+
17+
In your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):
18+
19+
```ts twoslash
20+
// .vitepress/config.ts
21+
import { defineConfig } from 'vitepress'
22+
import { transformerTwoslash } from 'vitepress-plugin-twoslash' // [!code hl]
23+
24+
export default defineConfig({
25+
markdown: {
26+
codeTransformers: [
27+
transformerTwoslash() // [!code hl]
28+
]
29+
}
30+
})
31+
```
32+
33+
And then in your [`.vitepress/theme/index.ts`](https://vitepress.dev/guide/custom-theme):
34+
35+
```ts twoslash
36+
// @noErrors: true
37+
// .vitepress/theme/index.ts
38+
import Theme from 'vitepress/theme'
39+
import TwoSlashFloatingVue from 'vitepress-plugin-twoslash/client' // [!code hl]
40+
import './custom-style.css'
41+
import type { EnhanceAppContext } from 'vitepress'
42+
43+
export default {
44+
extends: Theme,
45+
enhanceApp({ app }: EnhanceAppContext) {
46+
app.use(TwoSlashFloatingVue) // [!code hl]
47+
},
48+
}
49+
```
50+
51+
That's it, you can now use `ts twoslash` in your markdown files to enable the beautiful type hover.
52+
53+
````md
54+
```ts twoslash
55+
console.log('hello')
56+
// ^?
57+
```
58+
````
59+
60+
It will be rendered as:
61+
62+
```ts twoslash
63+
console.log('hello')
64+
// ^?
65+
```

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"typescript": "^5.3.3",
5858
"unbuild": "^2.0.0",
5959
"vite": "^5.0.11",
60+
"vitepress-plugin-twoslash": "workspace:*",
6061
"vitest": "^1.1.3",
6162
"vue-tsc": "^1.8.27",
6263
"wrangler": "^3.22.3"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# vitepress-plugin-twoslash
2+
3+
Enable TwoSlash support in VitePress.
4+
5+
[Documentation](https://shikiji.netlify.app/packages/vitepress#twoslash)
6+
7+
## License
8+
9+
MIT
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { defineBuildConfig } from 'unbuild'
2+
3+
export default defineBuildConfig({
4+
entries: [
5+
'src/index.ts',
6+
'src/client.ts',
7+
],
8+
declaration: true,
9+
rollup: {
10+
emitCJS: false,
11+
},
12+
externals: [
13+
'hast',
14+
'vitepress-plugin-twoslash',
15+
'vitepress-plugin-twoslash/style.css',
16+
],
17+
})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"name": "vitepress-plugin-twoslash",
3+
"type": "module",
4+
"version": "0.9.0-0",
5+
"description": "Enable TwoSlash support in VitePress",
6+
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
7+
"license": "MIT",
8+
"homepage": "https://github.com/antfu/shikiji#readme",
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/antfu/shikiji.git",
12+
"directory": "packages/vitepress-plugin-twoslash"
13+
},
14+
"bugs": "https://github.com/antfu/shikiji/issues",
15+
"keywords": [
16+
"shiki",
17+
"twoslash",
18+
"vitepress-plugin"
19+
],
20+
"sideEffects": false,
21+
"exports": {
22+
".": {
23+
"types": "./dist/index.d.mts",
24+
"default": "./dist/index.mjs"
25+
},
26+
"./client": {
27+
"types": "./dist/client.d.mts",
28+
"default": "./dist/client.mjs"
29+
},
30+
"./style.css": "./style.css"
31+
},
32+
"main": "./dist/index.mjs",
33+
"module": "./dist/index.mjs",
34+
"types": "./dist/index.d.mts",
35+
"typesVersions": {
36+
"*": {
37+
"./client": [
38+
"./dist/client.d.mts"
39+
],
40+
"*": [
41+
"./dist/index.d.mts"
42+
]
43+
}
44+
},
45+
"files": [
46+
"*.css",
47+
"dist"
48+
],
49+
"scripts": {
50+
"build": "unbuild",
51+
"dev": "unbuild --stub",
52+
"prepublishOnly": "nr build"
53+
},
54+
"dependencies": {
55+
"floating-vue": "^5.0.2",
56+
"mdast-util-from-markdown": "^2.0.0",
57+
"mdast-util-gfm": "^3.0.0",
58+
"mdast-util-to-hast": "^13.0.2",
59+
"shikiji": "workspace:*",
60+
"shikiji-twoslash": "workspace:*",
61+
"vue": "^3.4.7"
62+
}
63+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import 'shikiji-twoslash/style-rich.css'
2+
import 'floating-vue/dist/style.css'
3+
import 'vitepress-plugin-twoslash/style.css'
4+
5+
import type { Plugin } from 'vue'
6+
import FloatingVue from 'floating-vue'
7+
8+
export type FloatingVueConfig = Parameters<(typeof FloatingVue)['install']>[1]
9+
10+
/**
11+
* Vue plugin to install FloatingVue with styles.
12+
*
13+
* Import this function in `.vitepress/theme/index.ts` and use `app.use(TwoSlashFloatingVue)` inside the `enhanceApp` hook.
14+
*/
15+
const TwoSlashFloatingVue: Plugin<[FloatingVueConfig?]> = {
16+
install: (app, options: FloatingVueConfig = {}) => {
17+
app.use(FloatingVue, {
18+
...options,
19+
themes: {
20+
twoslash: {
21+
$extend: 'menu',
22+
delay: { show: 0, hide: 0 },
23+
},
24+
...options.theme,
25+
},
26+
})
27+
},
28+
}
29+
30+
export default TwoSlashFloatingVue

0 commit comments

Comments
 (0)