Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/easy-stars-go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"expressive-code-twoslash": patch
---

Improves codeblock processing to ensure extra lines that don't exist in the twoslash output do not make it to the final output.
5 changes: 3 additions & 2 deletions packages/expressive-code-twoslash/src/helpers/processors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ export function processTwoslashCodeBlock(

// Remove any extra lines from the EC code block
if (twoslashCodeBlock.length < ecCodeBlock.length) {
for (let i = twoslashCodeBlock.length; i < ecCodeBlock.length; i++) {
codeBlock.deleteLine(twoslashCodeBlock.length);
for (let i = ecCodeBlock.length - 1; i >= twoslashCodeBlock.length; i--) {
const exists = codeBlock.getLine(i);
if (exists) codeBlock.deleteLine(i);
}
}
}
Expand Down
16 changes: 12 additions & 4 deletions packages/expressive-code-twoslash/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,13 @@ export default function ecTwoSlash(options: PluginTwoslashOptions = {}): Express
...twoslashEslintOptions,
});

const snippetTsconfigPath = resolveTsconfigPath(cwd, tsConfigPath);
const { options: baseCompilerOptions } = parseSnippetTsconfig(snippetTsconfigPath);
// Get the TSConfig path for getting the default library files for Twoslash
const _TsConfigPath = resolveTsconfigPath(cwd, tsConfigPath);

// Get the default compiler options from the parsed TSConfig, which includes the default library files for Twoslash
const { options: baseCompilerOptions } = parseSnippetTsconfig(_TsConfigPath);

// Get the directory of the default library files for Twoslash, which is needed for proper module resolution in Twoslash
const tsLibDirectory = path.dirname(ts.getDefaultLibFilePath(baseCompilerOptions));

return definePlugin({
Expand Down Expand Up @@ -138,8 +142,10 @@ export default function ecTwoSlash(options: PluginTwoslashOptions = {}): Express
// Add the include to the includes map if it exists
if (include) includes.add(include, codeWithIncludes);

// If the trigger is "eslint", we want to set a full filename with extension instead of just the language identifier,
// because ESLint's Twoslasher needs the full filename to properly parse the code block and provide accurate completions.
const extension =
trigger === "twoslash" ? codeBlock.language : `index.${codeBlock.language}`;
trigger === "eslint" ? `index.${codeBlock.language}` : codeBlock.language;

// Twoslash the code block
const twoslash = twoslasher(codeWithIncludes, extension, {
Expand All @@ -153,7 +159,9 @@ export default function ecTwoSlash(options: PluginTwoslashOptions = {}): Express
},
});

// Update EC code block with the twoslash information
// Update EC code block with the twoslash information this is important to ensure that if the end user
// is using the @showEmit functionality, the emitted code is properly displayed in the code block.
// Twoslash output code, could be TypeScript, but could also be a JS/JSON/d.ts representation of the code.
if (twoslash.extension) {
codeBlock.language = twoslash.extension;
}
Expand Down
Loading