Skip to content

Commit

Permalink
feat: support twoslash v0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Feb 8, 2024
1 parent 18c2239 commit b419794
Show file tree
Hide file tree
Showing 13 changed files with 370 additions and 432 deletions.
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
"unocss": "^0.58.5",
"unplugin-vue-components": "^0.26.0",
"vitepress": "^1.0.0-rc.42",
"vue": "^3.4.15"
"vue": "^3.4.16"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"taze": "^0.13.3",
"typescript": "^5.3.3",
"unbuild": "^2.0.0",
"vite": "^5.0.12",
"vite": "^5.1.0",
"vite-tsconfig-paths": "^4.3.1",
"vitepress-plugin-mermaid": "^2.0.16",
"vitest": "^1.2.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/monaco/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@
"@shikijs/core": "workspace:*"
},
"devDependencies": {
"monaco-editor-core": "^0.45.0"
"monaco-editor-core": "^0.46.0"
}
}
2 changes: 1 addition & 1 deletion packages/shiki/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"@shikijs/core": "workspace:*"
},
"devDependencies": {
"tm-grammars": "^1.1.3",
"tm-grammars": "^1.1.4",
"tm-themes": "^1.1.1",
"vscode-oniguruma": "^1.7.0"
}
Expand Down
4 changes: 2 additions & 2 deletions packages/twoslash/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@
},
"dependencies": {
"@shikijs/core": "workspace:*",
"twoslash": "^0.1.2"
"twoslash": "^0.2.0"
},
"devDependencies": {
"@iconify-json/carbon": "^1.1.28",
"@iconify-json/carbon": "^1.1.29",
"@iconify-json/codicon": "^1.1.41",
"@shikijs/twoslash": "^3.1.2",
"hast-util-from-html": "^2.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/twoslash/scripts/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'
import { icons as codicon } from '@iconify-json/codicon'
import { icons as carbon } from '@iconify-json/carbon'
import { fromHtml } from 'hast-util-from-html'
import type { CompletionItem } from '../src/icons'
import type { CompletionEntry } from 'typescript'

async function buildIcons(filepath: string, map: Record<string, string>) {
const result = Object.fromEntries(
Expand Down Expand Up @@ -39,7 +39,7 @@ await buildIcons(
interface: 'carbon:connect',
function: 'carbon:function',
string: 'carbon:string-text',
} satisfies Partial<Record<CompletionItem['kind'], string>>,
} satisfies Partial<Record<CompletionEntry['kind'], string>>,
)

await buildIcons(
Expand Down
10 changes: 5 additions & 5 deletions packages/twoslash/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
* This file is the core of the @shikijs/twoslash package,
* Decoupled from twoslash's implementation and allowing to introduce custom implementation or cache system.
*/
import type { TwoslashExecuteOptions } from 'twoslash'
import type { ShikiTransformer } from '@shikijs/core'
import type { TwoslashExecuteOptions, TwoslashGenericFunction } from 'twoslash'
import type { ShikiTransformer, ShikiTransformerContextMeta } from '@shikijs/core'
import type { Element, ElementContent, Text } from 'hast'

import { splitTokens } from '@shikijs/core'
import type { ShikiTransformerContextMeta } from 'shiki'
import type { TransformerTwoslashOptions, TwoslashRenderer, TwoslashShikiFunction, TwoslashShikiReturn } from './types'
import { ShikiTwoslashError } from './error'

Expand All @@ -24,7 +23,7 @@ export function defaultTwoslashOptions(): TwoslashExecuteOptions {
}

export function createTransformerFactory(
defaultTwoslasher: TwoslashShikiFunction,
defaultTwoslasher: TwoslashShikiFunction | TwoslashGenericFunction,
defaultRenderer?: TwoslashRenderer,
) {
return function transformerTwoslash(options: TransformerTwoslashOptions = {}): ShikiTransformer {
Expand Down Expand Up @@ -59,8 +58,9 @@ export function createTransformerFactory(
lang = langAlias[this.options.lang]

if (filter(lang, code, this.options)) {
const twoslash = twoslasher(code, lang, twoslashOptions)
const twoslash = (twoslasher as TwoslashShikiFunction)(code, lang, twoslashOptions)
map.set(this.meta, twoslash)
this.meta.twoslash = twoslash
this.options.lang = twoslash.meta?.extension || lang
return twoslash.code
}
Expand Down
2 changes: 1 addition & 1 deletion packages/twoslash/src/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import tagIcons from './icons-tags.json'

export type CompletionItem = NonNullable<NodeCompletion['completions']>[number]

export const defaultCompletionIcons: Record<CompletionItem['kind'], Element | undefined> = completionIcons as any
export const defaultCompletionIcons: Record<string, Element | undefined> = completionIcons as any
export const defaultCustomTagIcons: Record<string, Element | undefined> = tagIcons as any
2 changes: 1 addition & 1 deletion packages/twoslash/src/renderer-classic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function rendererClassic(): TwoslashRenderer {
type: 'element',
tagName: 'li',
properties: {
class: i.kindModifiers?.split(',').includes('deprecated')
class: 'kindModifiers' in i && typeof i.kindModifiers === 'string' && i.kindModifiers?.split(',').includes('deprecated')
? 'deprecated'
: undefined,
},
Expand Down
117 changes: 60 additions & 57 deletions packages/twoslash/src/renderer-rich.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Element, ElementContent, Text } from 'hast'
import type { ShikiTransformerContextCommon } from '@shikijs/core'
import type { NodeError, NodeHover, NodeQuery } from 'twoslash'
import type { TwoslashRenderer } from './types'
import type { CompletionItem } from './icons'
import { defaultCompletionIcons, defaultCustomTagIcons } from './icons'
import { ShikiTwoslashError } from './error'

Expand All @@ -21,7 +20,7 @@ export interface RendererRichOptions {
* If `false`, no icons will be rendered.
* @default defaultCompletionIcons
*/
completionIcons?: Partial<Record<CompletionItem['kind'], ElementContent>> | false
completionIcons?: Partial<Record<string, ElementContent>> | false

/**
* Custom icons for custom tags lines.
Expand Down Expand Up @@ -389,60 +388,64 @@ export function rendererRich(options: RendererRichOptions = {}): TwoslashRendere
throw new ShikiTwoslashError(`Renderer hook nodeCompletion only works on text nodes, got ${node.type}`)

const items: Element[] = query.completions
.map(i => ({
type: 'element',
tagName: 'li',
properties: {},
children: [
...completionIcons
? [<Element>{
type: 'element',
tagName: 'span',
properties: { class: `twoslash-completions-icon completions-${i.kind.replace(/\s/g, '-')}` },
children: [
completionIcons[i.kind] || completionIcons.property,
].filter(Boolean),
}]
: [],
{
type: 'element',
tagName: 'span',
properties: {
class: i.kindModifiers?.split(',').includes('deprecated')
? 'deprecated'
: undefined,
},
children: [
{
type: 'element',
tagName: 'span',
properties: { class: 'twoslash-completions-matched' },
children: [
{
type: 'text',
value: i.name.startsWith(query.completionsPrefix)
? query.completionsPrefix
: '',
},
],
},
{
.map((i) => {
const kind = i.kind || 'default'
const isDeprecated = 'kindModifiers' in i && typeof i.kindModifiers === 'string' && i.kindModifiers?.split(',').includes('deprecated')
return {
type: 'element',
tagName: 'li',
properties: {},
children: [
...completionIcons
? [<Element>{
type: 'element',
tagName: 'span',
properties: { class: 'twoslash-completions-unmatched' },
properties: { class: `twoslash-completions-icon completions-${kind.replace(/\s/g, '-')}` },
children: [
{
type: 'text',
value: i.name.startsWith(query.completionsPrefix)
? i.name.slice(query.completionsPrefix.length || 0)
: i.name,
},
],
completionIcons[kind] || completionIcons.property,
].filter(Boolean),
}]
: [],
{
type: 'element',
tagName: 'span',
properties: {
class: isDeprecated
? 'deprecated'
: undefined,
},
],
},
],
}))
children: [
{
type: 'element',
tagName: 'span',
properties: { class: 'twoslash-completions-matched' },
children: [
{
type: 'text',
value: i.name.startsWith(query.completionsPrefix)
? query.completionsPrefix
: '',
},
],
},
{
type: 'element',
tagName: 'span',
properties: { class: 'twoslash-completions-unmatched' },
children: [
{
type: 'text',
value: i.name.startsWith(query.completionsPrefix)
? i.name.slice(query.completionsPrefix.length || 0)
: i.name,
},
],
},
],
},
],
}
})

const cursor = extend(
hast?.completionCursor,
Expand Down Expand Up @@ -651,13 +654,13 @@ export function defaultHoverInfoProcessor(type: string) {

function getErrorLevelClass(error: NodeError) {
switch (error.level) {
case 0:
case 'warning':
return 'twoslash-error-level-warning'
case 1:
return '' // 'twoslash-error-level-error'
case 2:
case 'suggestion':
return 'twoslash-error-level-suggestion'
case 'message':
return 'twoslash-error-level-message'
default:
return 'twoslash-error-level-info'
return ''
}
}
10 changes: 8 additions & 2 deletions packages/twoslash/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NodeCompletion, NodeError, NodeHighlight, NodeHover, NodeQuery, NodeTag, TwoslashExecuteOptions, TwoslashOptions, TwoslashReturn } from 'twoslash'
import type { NodeCompletion, NodeError, NodeHighlight, NodeHover, NodeQuery, NodeTag, TwoslashExecuteOptions, TwoslashGenericFunction, TwoslashOptions, TwoslashReturn } from 'twoslash'
import type { CodeToHastOptions, ShikiTransformerContext } from '@shikijs/core'
import type { Element, ElementContent, Text } from 'hast'

Expand All @@ -10,6 +10,12 @@ export type TwoslashShikiReturn =

export type TwoslashShikiFunction = (code: string, lang?: string, options?: TwoslashExecuteOptions) => TwoslashShikiReturn

declare module '@shikijs/core' {
interface ShikiTransformerContextMeta {
twoslash?: TwoslashShikiReturn
}
}

export interface TransformerTwoslashOptions {
/**
* Languages to apply this transformer to
Expand All @@ -33,7 +39,7 @@ export interface TransformerTwoslashOptions {
/**
* Custom instance of twoslasher function
*/
twoslasher?: TwoslashShikiFunction
twoslasher?: TwoslashShikiFunction | TwoslashGenericFunction
/**
* Options to pass to twoslash
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/vitepress-twoslash/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"mdast-util-gfm": "^3.0.0",
"mdast-util-to-hast": "^13.1.0",
"shiki": "workspace:*",
"twoslash-vue": "^0.1.2",
"vue": "^3.4.15"
"twoslash-vue": "^0.2.0",
"vue": "^3.4.16"
}
}
Loading

0 comments on commit b419794

Please sign in to comment.