Skip to content

Commit

Permalink
feat(plugin-shiki): add built-in twoslash support
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Jan 24, 2025
1 parent dc4abbb commit bb50152
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 71 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"trackpad",
"tsbuildinfo",
"twikoo",
"twoslash",
"umami",
"unmount",
"vuejs",
Expand Down
49 changes: 16 additions & 33 deletions docs/.vuepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import process from 'node:process'
import { transformerTwoslash } from '@shikijs/twoslash'

Check failure on line 2 in docs/.vuepress/config.ts

View workflow job for this annotation

GitHub Actions / build-check

'transformerTwoslash' is defined but never used

Check failure on line 2 in docs/.vuepress/config.ts

View workflow job for this annotation

GitHub Actions / bundle-check

'transformerTwoslash' is defined but never used

Check failure on line 2 in docs/.vuepress/config.ts

View workflow job for this annotation

GitHub Actions / build-check

'transformerTwoslash' is defined but never used

Check failure on line 2 in docs/.vuepress/config.ts

View workflow job for this annotation

GitHub Actions / bundle-check

'transformerTwoslash' is defined but never used
import { viteBundler } from '@vuepress/bundler-vite'
import { webpackBundler } from '@vuepress/bundler-webpack'
import { getModulePath } from '@vuepress/helper'
Expand Down Expand Up @@ -155,39 +156,21 @@ export default defineUserConfig({
NpmBadge: path.resolve(__dirname, './components/NpmBadge.vue'),
},
}),
// only enable shiki plugin in production mode
IS_PROD
? shikiPlugin({
langs: [
'bash',
'diff',
'json',
'md',
'scss',
'ts',
'vue',
'less',
'java',
'py',
'vb',
'bat',
'cs',
'cpp',
],
themes: {
light: 'one-light',
dark: 'one-dark-pro',
},
lineNumbers: 10,
notationDiff: true,
notationErrorLevel: true,
notationFocus: true,
notationHighlight: true,
notationWordHighlight: true,
whitespace: true,
collapsedLines: false,
})
: [],
shikiPlugin({
themes: {
light: 'one-light',
dark: 'one-dark-pro',
},
lineNumbers: 10,
notationDiff: true,
notationErrorLevel: true,
notationFocus: true,
notationHighlight: true,
notationWordHighlight: true,
whitespace: true,
collapsedLines: false,
twoslash: true,
}),
cachePlugin(),
],

Expand Down
17 changes: 1 addition & 16 deletions docs/.vuepress/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,6 @@ export default defaultTheme({
alert: true,
},
// use shiki plugin in production mode instead
prismjs: IS_PROD
? false
: {
themes: {
light: 'one-light',
dark: 'one-dark',
},
lineNumbers: 10,
notationDiff: true,
notationErrorLevel: true,
notationFocus: true,
notationHighlight: true,
notationWordHighlight: true,
whitespace: true,
collapsedLines: false,
},
prismjs: false,
},
})
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"docs:serve": "http-server -a localhost .vuepress/dist"
},
"dependencies": {
"@shikijs/twoslash": "^2.1.0",
"@vuepress/bundler-vite": "2.0.0-rc.19",
"@vuepress/bundler-webpack": "2.0.0-rc.19",
"@vuepress/helper": "workspace:*",
Expand Down
38 changes: 38 additions & 0 deletions docs/plugins/markdown/shiki.md
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,44 @@ body > div {
- Also see:
- [Shiki > Render Whitespace](https://shiki.style/packages/transformers#transformerrenderwhitespace)

### twoslash

- Type: `boolean`

- Default: `false`

- Details: Whether enable [twoslash](https://github.com/twoslashes/twoslash).

::: tip

For size reasons, the plugin does not include the `@shiki/twoslash` package by default. If you want to use it, you need to install it manually.

:::

- Also see:

- [Shiki > Twosplash](https://shiki.style/packages/twoslash)

- Example:

**Input:**

````md
```ts twoslash
const a = 1
const b = 2
console.log(a + b)
```
````

**Output:**

```ts twoslash
const a = 1
const b = 2
console.log(a + b)
```

## Advanced Options

### defaultLang
Expand Down
6 changes: 6 additions & 0 deletions plugins/markdown/plugin-shiki/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,14 @@
"synckit": "^0.9.2"
},
"peerDependencies": {
"@shikijs/twoslash": "^2.1.0",
"vuepress": "2.0.0-rc.19"
},
"peerDependenciesMeta": {
"@shikijs/twoslash": {
"optional": true
}
},
"publishConfig": {
"access": "public"
},
Expand Down
9 changes: 9 additions & 0 deletions plugins/markdown/plugin-shiki/src/client/styles/twoslash.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
div[data-highlighter='shiki'] {
pre.twoslash {
--twoslash-popup-bg: var(--code-c-bg, var(--shiki-light-bg));

[data-theme='dark'] & {
--twoslash-popup-bg: var(--code-c-bg, var(--shiki-dark-bg));
}
}
}
11 changes: 10 additions & 1 deletion plugins/markdown/plugin-shiki/src/node/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,13 @@ import type { ShikiHighlightOptions } from './types.js'
export type ShikiPluginOptions = MarkdownItLineNumbersOptions &
MarkdownItPreWrapperOptions &
Pick<MarkdownItCollapsedLinesOptions, 'collapsedLines'> &
ShikiHighlightOptions
ShikiHighlightOptions & {
/**
* Enable twoslash
*
* @description You should install `@shikijs/twoslash` manually.
*
* @default false
*/
twoslash?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const prepareClientConfigFile = (
notationHighlight,
notationWordHighlight,
whitespace,
twoslash,
}: ShikiPluginOptions,
): Promise<string> => {
const imports: string[] = [
Expand Down Expand Up @@ -80,6 +81,13 @@ export const prepareClientConfigFile = (
setups.push('setupCollapsedLines()')
}

if (twoslash) {
imports.push(
`import "${getModulePath('@shikijs/twoslash/style-rich.css', import.meta)}"`,
`import "${getModulePath(`${PLUGIN_NAME}/styles/twoslash.css`, import.meta)}"`,
)
}

let code = imports.join('\n')

if (setups.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,34 @@ import {
transformerNotationWordHighlight,
transformerRenderWhitespace,
} from '@shikijs/transformers'
import type { TransformerTwoslashIndexOptions } from '@shikijs/twoslash'
import type { WhitespacePosition } from '@vuepress/highlighter-helper'
import { resolveWhitespacePosition } from '@vuepress/highlighter-helper'
import type { ShikiTransformer } from 'shiki'
import { colors } from 'vuepress/utils'
import type { ShikiHighlightOptions } from '../types.js'
import { logger } from '../utils.js'
import {
addClassTransformer,
cleanupTransformer,
emptyLineTransformer,
removeEscapeTransformer,
} from './vuepressTransformers.js'

let transformerTwoslash:
| ((options?: TransformerTwoslashIndexOptions) => ShikiTransformer)
| null

try {
;({ transformerTwoslash } = await import('@shikijs/twoslash'))
} catch {
transformerTwoslash = null
}

export const getTransformers = (
options: ShikiHighlightOptions,
options: ShikiHighlightOptions & {
twoslash?: boolean
},
): ShikiTransformer[] => {
const transformers: ShikiTransformer[] = []

Expand Down Expand Up @@ -66,6 +81,20 @@ export const getTransformers = (
transformers.push(transformerMetaWordHighlight())
}

if (options.twoslash) {
if (transformerTwoslash)
transformers.push(
transformerTwoslash({
explicitTrigger: true,
}),
)
else {
logger.error(
`${colors.cyan('twoslash')} is enabled, but ${colors.magenta('@shikijs/twoslash')} is not installed, please install it manually`,
)
}
}

transformers.push(
addClassTransformer,
cleanupTransformer,
Expand Down
Loading

0 comments on commit bb50152

Please sign in to comment.