diff --git a/src/components/mathpreview.ts b/src/components/mathpreview.ts index dc1bb28c..e44ea96b 100644 --- a/src/components/mathpreview.ts +++ b/src/components/mathpreview.ts @@ -58,8 +58,8 @@ export class MathPreview { const typesetOpts = { scale, color: this.color } try { const xml = await this.mj.typeset(typesetArg, typesetOpts) - const md = utils.svgToDataUrl(xml) - return new vscode.Hover(new vscode.MarkdownString(this.mputils.addDummyCodeBlock(`![equation](${md})`)), tex.range ) + const dataUrl = utils.svgToDataUrl(xml) + return new vscode.Hover(new vscode.MarkdownString(this.mputils.addDummyCodeBlock(`![equation](${dataUrl})`)), tex.range ) } catch(e) { this.extension.logger.error(`Error while MathJax is rendering: ${typesetArg}`) this.extension.logger.logError(e) diff --git a/src/providers/completion.ts b/src/providers/completion.ts index 6d7805dd..b687893b 100644 --- a/src/providers/completion.ts +++ b/src/providers/completion.ts @@ -75,7 +75,7 @@ export class Completer implements vscode.CompletionItemProvider { this.import = new Import(extension) this.subImport = new SubImport(extension) this.glossary = new Glossary(extension) - this.bracketReplacer = new BracketReplacer() + this.bracketReplacer = new BracketReplacer(extension) this.commandAdder = new CommandAdder(this.command) this.commandRemover = new CommandRemover() this.commandReplacer = new CommandReplacer() @@ -160,7 +160,8 @@ export class Completer implements vscode.CompletionItemProvider { ast = await this.extension.latexAstManager.getDocAst(document) } for (const provider of providers) { - items = [...items, ...provider.provide(document, position, context, ast)] + const providedItems = await provider.provide(document, position, context, ast) + items = [...items, ...providedItems] } return items } diff --git a/src/providers/completionlib/bracketreplacer.ts b/src/providers/completionlib/bracketreplacer.ts index ca2072b1..83ac1224 100644 --- a/src/providers/completionlib/bracketreplacer.ts +++ b/src/providers/completionlib/bracketreplacer.ts @@ -5,6 +5,9 @@ import { IContexAwareProvider } from './interface.js' import { reverseCaseOfFirstCharacterAndConvertToHex } from './utils/sortkey.js' import { getPrevChar } from './utils/position.js' import { ContextAwareKind } from './completionkind.js' +import type { MathPreview } from '../../components/mathpreview.js' +import { ExternalPromise } from '../../utils/externalpromise.js' +import { Logger } from '../../components/logger.js' export class BracketReplacer implements IContexAwareProvider { @@ -80,6 +83,37 @@ export class BracketReplacer implements IContexAwareProvider { ] ) + private readonly bracketDocumentMapPromise = new ExternalPromise>() + + constructor(private readonly extension: { + readonly logger: Logger, + readonly mathPreview: MathPreview + }) { + setTimeout(() => this.initializeBracketDocumentMap(), 0) + } + + async initializeBracketDocumentMap() { + const bracketDocumentMap = new Map() + for (const [key, pairs] of this.bracketPairs) { + // Skip the last group of brackets because they are not supported by MathJax. + if (key === '04') { + continue + } + for (const [left, right] of pairs) { + try { + const {svgDataUrl} = await this.extension.mathPreview.generateSVG({ + texString: `\\begin{align*}${left}x${right} + ${left} \\sum a_i ${right}\\end{align*}`, + envname: 'align*' + }, '') + bracketDocumentMap.set(left, new vscode.MarkdownString(`![${left}${right}](${svgDataUrl})`)) + } catch { + this.extension.logger.debug(`Failed to generate preview for ${left}${right}`) + } + } + } + this.bracketDocumentMapPromise.resolve(bracketDocumentMap) + } + test(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext): boolean { if (context.triggerKind === vscode.CompletionTriggerKind.TriggerCharacter) { return false @@ -95,7 +129,7 @@ export class BracketReplacer implements IContexAwareProvider { return false } - provide(document: vscode.TextDocument, position: vscode.Position, _context: vscode.CompletionContext, ast: latexParser.LatexAst | undefined) { + async provide(document: vscode.TextDocument, position: vscode.Position, _context: vscode.CompletionContext, ast: latexParser.LatexAst | undefined) { if (!ast) { return [] } @@ -142,6 +176,11 @@ export class BracketReplacer implements IContexAwareProvider { item.sortText = sortText item.filterText = document.getText(leftBracketRange) item.additionalTextEdits = [ledit, redit] + const bracketDocumentMap = await this.bracketDocumentMapPromise.promise + const md = bracketDocumentMap.get(left) + if (md) { + item.documentation = md + } suggestions.push(item) } } diff --git a/src/providers/completionlib/interface.ts b/src/providers/completionlib/interface.ts index 2a29b814..98203ec0 100644 --- a/src/providers/completionlib/interface.ts +++ b/src/providers/completionlib/interface.ts @@ -25,5 +25,5 @@ export interface ICommand { export interface IContexAwareProvider { readonly needsAst: boolean, test(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext): boolean, - provide(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext, ast: latexParser.LatexAst | undefined): vscode.CompletionItem[] + provide(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext, ast: latexParser.LatexAst | undefined): vscode.CompletionItem[] | Thenable }