Skip to content

Commit

Permalink
fix(twoslash)!: rename renderer hook nodeCompletions to `nodeComple…
Browse files Browse the repository at this point in the history
…tion`
  • Loading branch information
antfu committed Jan 14, 2024
1 parent e9d1f33 commit b7637bc
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 72 deletions.
128 changes: 67 additions & 61 deletions packages/shikiji-twoslash/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,73 +120,79 @@ export function createTransformerFactory(
throw new Error(`[shikiji-twoslash] Cannot find token at L${line}:${character}`)
}

const skipTokens = new Set<Element | Text>()
const tokensSkipHover = new Set<Element | Text>()
const postActions: (() => void)[] = []

for (const error of twoslash.errors) {
const token = locateTextToken(error.line, error.character)
if (!token)
for (const node of twoslash.nodes) {
if (node.type === 'tag') {
if (renderer.lineCustomTag)
insertAfterLine(node.line, renderer.lineCustomTag.call(this, node))
continue

skipTokens.add(token)

if (renderer.nodeError) {
const clone = { ...token }
Object.assign(token, renderer.nodeError.call(this, error, clone))
}

if (renderer.lineError)
insertAfterLine(error.line, renderer.lineError.call(this, error))
}

for (const query of twoslash.queries) {
const token = locateTextToken(query.line, query.character)
if (!token)
continue

skipTokens.add(token)

if (renderer.nodeQuery) {
const clone = { ...token }
Object.assign(token, renderer.nodeQuery.call(this, query, clone))
}

if (renderer.lineQuery)
insertAfterLine(query.line, renderer.lineQuery.call(this, query, token))
}

for (const completion of twoslash.completions) {
const token = locateTextToken(completion.line, completion.character)
if (!token)
continue

skipTokens.add(token)

if (renderer.nodeCompletions) {
const clone = { ...token }
Object.assign(token, renderer.nodeCompletions.call(this, completion, clone))
const token = locateTextToken(node.line, node.character)

switch (node.type) {
case 'error': {
if (token && renderer.nodeError) {
tokensSkipHover.add(token)
const clone = { ...token }
Object.assign(token, renderer.nodeError.call(this, node, clone))
}
if (renderer.lineError)
insertAfterLine(node.line, renderer.lineError.call(this, node))
break
}
case 'query': {
if (token && renderer.nodeQuery) {
tokensSkipHover.add(token)
const clone = { ...token }
Object.assign(token, renderer.nodeQuery.call(this, node, clone))
}
if (renderer.lineQuery)
insertAfterLine(node.line, renderer.lineQuery.call(this, node, token))
break
}
case 'completion': {
if (token && renderer.nodeCompletion) {
tokensSkipHover.add(token)
const clone = { ...token }
Object.assign(token, renderer.nodeCompletion.call(this, node, clone))
}
if (renderer.lineCompletion)
insertAfterLine(node.line, renderer.lineCompletion.call(this, node))
break
}
case 'highlight': {
if (token && renderer.nodeHightlight) {
tokensSkipHover.add(token)
const clone = { ...token }
Object.assign(token, renderer.nodeHightlight.call(this, node, clone))
}
if (renderer.lineHighlight)
insertAfterLine(node.line, renderer.lineHighlight.call(this, node))
break
}
case 'hover': {
// Hover will be handled after all other nodes are processed
if (token && renderer.nodeStaticInfo) {
postActions.push(() => {
if (tokensSkipHover.has(token))
return
const clone = { ...token }
Object.assign(token, renderer.nodeStaticInfo.call(this, node, clone))
})
}
break
}
default: {
if (throws)
// @ts-expect-error Unknown node type
throw new Error(`[shikiji-twoslash] Unknown node type: ${node.type}`)
}
}

if (renderer.lineCompletions)
insertAfterLine(completion.line, renderer.lineCompletions.call(this, completion))
}

for (const info of twoslash.hovers) {
const token = locateTextToken(info.line, info.character)
if (!token || token.type !== 'text')
continue

// If it's already rendered as popup or error, skip it
if (skipTokens.has(token))
continue

const clone = { ...token }
Object.assign(token, renderer.nodeStaticInfo.call(this, info, clone))
}

if (renderer.lineCustomTag) {
for (const tag of twoslash.tags)
insertAfterLine(tag.line, renderer.lineCustomTag.call(this, tag))
}
postActions.forEach(i => i())
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/shikiji-twoslash/src/renderer-classic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function rendererClassic(): TwoSlashRenderer {
]
},

lineCompletions(query) {
lineCompletion(query) {
return [
{
type: 'element',
Expand Down
4 changes: 2 additions & 2 deletions packages/shikiji-twoslash/src/renderer-rich.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ export function rendererRich(options: RendererRichOptions = {}): TwoSlashRendere
}
},

nodeCompletions(query, node) {
nodeCompletion(query, node) {
if (node.type !== 'text')
throw new Error(`[shikiji-twoslash] nodeCompletions only works on text nodes, got ${node.type}`)
throw new Error(`[shikiji-twoslash] nodeCompletion only works on text nodes, got ${node.type}`)

const leftPart = query.completionsPrefix || ''
const rightPart = node.value.slice(leftPart.length || 0)
Expand Down
10 changes: 6 additions & 4 deletions packages/shikiji-twoslash/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NodeCompletion, NodeError, NodeHover, NodeQuery, NodeTag, TwoSlashOptions, TwoSlashReturn, twoslasher } from 'twoslash'
import type { NodeCompletion, NodeError, NodeHighlight, NodeHover, NodeQuery, NodeTag, TwoSlashOptions, TwoSlashReturn, twoslasher } from 'twoslash'
import type { CodeToHastOptions, ShikijiTransformerContext } from 'shikiji-core'
import type { Element, ElementContent, Text } from 'hast'

Expand Down Expand Up @@ -51,10 +51,12 @@ export interface TwoSlashRenderer {
lineError?(this: ShikijiTransformerContext, error: NodeError): ElementContent[]
lineCustomTag?(this: ShikijiTransformerContext, tag: NodeTag): ElementContent[]
lineQuery?(this: ShikijiTransformerContext, query: NodeQuery, targetNode?: Element | Text): ElementContent[]
lineCompletions?(this: ShikijiTransformerContext, query: NodeCompletion): ElementContent[]
lineCompletion?(this: ShikijiTransformerContext, query: NodeCompletion): ElementContent[]
lineHighlight?(this: ShikijiTransformerContext, query: NodeHighlight): ElementContent[]

nodeError?(this: ShikijiTransformerContext, error: NodeError, node: Element | Text): Partial<ElementContent>
nodeStaticInfo(this: ShikijiTransformerContext, info: NodeHover, node: Element | Text): Partial<ElementContent>
nodeError?(this: ShikijiTransformerContext, error: NodeError, node: Element | Text): Partial<ElementContent>
nodeQuery?(this: ShikijiTransformerContext, query: NodeQuery, node: Element | Text): Partial<ElementContent>
nodeCompletions?(this: ShikijiTransformerContext, query: NodeCompletion, node: Element | Text): Partial<ElementContent>
nodeCompletion?(this: ShikijiTransformerContext, query: NodeCompletion, node: Element | Text): Partial<ElementContent>
nodeHightlight?(this: ShikijiTransformerContext, query: NodeHighlight, node: Element | Text): Partial<ElementContent>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
html, body { margin: 0; }
.shiki { padding: 2em; }
</style>
<pre class="shiki vitesse-light twoslash lsp" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#AB5959">const</span><span> </span><span style="color:#B07D48"><data-lsp lsp="const a: boolean">a</data-lsp></span><span style="color:#AB5959"> </span><span style="color:#999999">=</span><span style="color:#AB5959"> </span><span style="color:#B07D48"><data-lsp lsp="var Number: NumberConstructor">Number</data-lsp></span><span style="color:#999999">.</span><span style="color:#59873A">isNaN</span><span style="color:#999999">(</span><span style="color:#2F798A">123</span><span style="color:#999999">)</span></span><div class="meta-line"> <span class="inline-completions"><ul class="dropdown"><li><span><span class="result-found">i</span>sFinite</span></li><li><span><span class="result-found">i</span>sInteger</span></li><li><span><span class="result-found">i</span>sNaN</span></li><li><span><span class="result-found">i</span>sSafeInteger</span></li></ul></span></div><span class="line"></span></code></pre>
<pre class="shiki vitesse-light twoslash lsp" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#AB5959">const</span><span> </span><span style="color:#B07D48"><data-lsp lsp="const a: boolean">a</data-lsp></span><span style="color:#AB5959"> </span><span style="color:#999999">=</span><span style="color:#AB5959"> </span><span style="color:#B07D48"><data-lsp lsp="var Number: NumberConstructor">Number</data-lsp></span><span style="color:#999999">.</span><span style="color:#59873A"><data-lsp lsp="(method) NumberConstructor.isNaN(number: unknown): boolean">isNaN</data-lsp></span><span style="color:#999999">(</span><span style="color:#2F798A">123</span><span style="color:#999999">)</span></span><div class="meta-line"> <span class="inline-completions"><ul class="dropdown"><li><span><span class="result-found">i</span>sFinite</span></li><li><span><span class="result-found">i</span>sInteger</span></li><li><span><span class="result-found">i</span>sNaN</span></li><li><span><span class="result-found">i</span>sSafeInteger</span></li></ul></span></div><span class="line"></span></code></pre>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<span class="line"><span style="color:#DBD7CAEE"> </span><span style="color:#4D9375">throw</span><span style="color:#DBD7CAEE"> </span><span style="color:#C98A7D99">"</span><span style="color:#C98A7D">unimplemented</span><span style="color:#C98A7D99">"</span></span>
<span class="line"><span style="color:#666666">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#CB7676">let</span><span> </span><span style="color:#BD976A">a</span><span style="color:#CB7676"> </span><span style="color:#666666">=</span><span style="color:#CB7676"> </span><span style="color:#80A665"><data-lsp lsp="function createLabel<&#x22;typescript&#x22;>(idOrName: &#x22;typescript&#x22;): NameLabel">createLabel</data-lsp></span><span style="color:#666666">(</span><span style="color:#C98A7D99">"</span><span style="color:#C98A7D">typescript</span><span style="color:#C98A7D99">"</span><span style="color:#666666">)</span></span><div class="meta-line"> <span class="popover"><div class="arrow"></div>let a: NameLabel</span></div><span class="line"></span>
<span class="line"><span style="color:#CB7676">let</span><span> </span><span style="color:#BD976A"><data-lsp lsp="let b: IdLabel">b</data-lsp></span><span style="color:#CB7676"> </span><span style="color:#666666">=</span><span style="color:#CB7676"> </span><span style="color:#80A665">createLabel</span><span style="color:#666666">(</span><span style="color:#4C9A91">2.8</span><span style="color:#666666">)</span></span><div class="meta-line"> <span class="popover"><div class="arrow"></div>function createLabel&#x3C;2.8>(idOrName: 2.8): IdLabel</span></div><span class="line"></span>
<span class="line"><span style="color:#CB7676">let</span><span> </span><span style="color:#BD976A"><data-lsp lsp="let c: IdLabel | NameLabel">c</data-lsp></span><span style="color:#CB7676"> </span><span style="color:#666666">=</span><span style="color:#CB7676"> </span><span style="color:#80A665"><data-lsp lsp="function createLabel<&#x22;hello&#x22; | 42>(idOrName: &#x22;hello&#x22; | 42): IdLabel | NameLabel">createLabel</data-lsp></span><span style="color:#666666">(</span><span style="color:#BD976A"><data-lsp lsp="var Math: Math">Math</data-lsp></span><span style="color:#666666">.</span><span style="color:#80A665">random</span><span style="color:#666666">()</span><span> </span><span style="color:#CB7676">?</span><span> </span><span style="color:#C98A7D99">"</span><span style="color:#C98A7D">hello</span><span style="color:#C98A7D99">"</span><span> </span><span style="color:#CB7676">:</span><span> </span><span style="color:#4C9A91">42</span><span style="color:#666666">)</span></span><div class="meta-line"> <span class="inline-completions"><ul class="dropdown"><li><span><span class="result-found">r</span>andom</span></li><li><span><span class="result-found">r</span>ound</span></li></ul></span></div><span class="line"></span></code></pre>
<span class="line"><span style="color:#CB7676">let</span><span> </span><span style="color:#BD976A"><data-lsp lsp="let a: NameLabel">a</data-lsp></span><span style="color:#CB7676"> </span><span style="color:#666666">=</span><span style="color:#CB7676"> </span><span style="color:#80A665"><data-lsp lsp="function createLabel<&#x22;typescript&#x22;>(idOrName: &#x22;typescript&#x22;): NameLabel">createLabel</data-lsp></span><span style="color:#666666">(</span><span style="color:#C98A7D99">"</span><span style="color:#C98A7D">typescript</span><span style="color:#C98A7D99">"</span><span style="color:#666666">)</span></span><div class="meta-line"> <span class="popover"><div class="arrow"></div>let a: NameLabel</span></div><span class="line"></span>
<span class="line"><span style="color:#CB7676">let</span><span> </span><span style="color:#BD976A"><data-lsp lsp="let b: IdLabel">b</data-lsp></span><span style="color:#CB7676"> </span><span style="color:#666666">=</span><span style="color:#CB7676"> </span><span style="color:#80A665"><data-lsp lsp="function createLabel<2.8>(idOrName: 2.8): IdLabel">createLabel</data-lsp></span><span style="color:#666666">(</span><span style="color:#4C9A91">2.8</span><span style="color:#666666">)</span></span><div class="meta-line"> <span class="popover"><div class="arrow"></div>function createLabel&#x3C;2.8>(idOrName: 2.8): IdLabel</span></div><span class="line"></span>
<span class="line"><span style="color:#CB7676">let</span><span> </span><span style="color:#BD976A"><data-lsp lsp="let c: IdLabel | NameLabel">c</data-lsp></span><span style="color:#CB7676"> </span><span style="color:#666666">=</span><span style="color:#CB7676"> </span><span style="color:#80A665"><data-lsp lsp="function createLabel<&#x22;hello&#x22; | 42>(idOrName: &#x22;hello&#x22; | 42): IdLabel | NameLabel">createLabel</data-lsp></span><span style="color:#666666">(</span><span style="color:#BD976A"><data-lsp lsp="var Math: Math">Math</data-lsp></span><span style="color:#666666">.</span><span style="color:#80A665"><data-lsp lsp="(method) Math.random(): number">random</data-lsp></span><span style="color:#666666">()</span><span> </span><span style="color:#CB7676">?</span><span> </span><span style="color:#C98A7D99">"</span><span style="color:#C98A7D">hello</span><span style="color:#C98A7D99">"</span><span> </span><span style="color:#CB7676">:</span><span> </span><span style="color:#4C9A91">42</span><span style="color:#666666">)</span></span><div class="meta-line"> <span class="inline-completions"><ul class="dropdown"><li><span><span class="result-found">r</span>andom</span></li><li><span><span class="result-found">r</span>ound</span></li></ul></span></div><span class="line"></span></code></pre>

0 comments on commit b7637bc

Please sign in to comment.