import { window, OverviewRulerLane, DecorationOptions, Uri, MarkdownString, Range, workspace, ExtensionContext } from "vscode"; import { findReferences } from "./reference"; let timeout: NodeJS.Timer | undefined = undefined; // create a decorator type that we use to decorate small numbers const referenceDecorationType = window.createTextEditorDecorationType({ borderWidth: '2px', borderStyle: 'none none solid none', overviewRulerColor: 'blue', overviewRulerLane: OverviewRulerLane.Right, light: { // this color will be used in light color themes borderColor: 'darkblue' }, dark: { // this color will be used in dark color themes borderColor: 'lightblue' } }); let activeEditor = window.activeTextEditor; function updateDecorations() { if (!activeEditor) { return; } const regEx = /\d+/g; const text = activeEditor.document.getText(); const decorations: DecorationOptions[] = []; const references = findReferences(activeEditor.document); for(let reference of references) { const uriArguments = `?${encodeURIComponent(JSON.stringify([reference]))}`; const pdfCommandUri = Uri.parse(`command:zoterolens.openZoteroPDF`+uriArguments); const viewCommandUri = Uri.parse(`command:zoterolens.showInZotero`+uriArguments); const pageNr = reference.pagenr === null ? "" : `(${reference.pagenr})`; const contents = new MarkdownString(`${reference.citekey} ${pageNr}\n\n[View in Zotero](${viewCommandUri}) | [Open PDF](${pdfCommandUri})`); // To enable command URIs in Markdown content, you must set the `isTrusted` flag. // When creating trusted Markdown string, make sure to properly sanitize all the // input content so that only expected command URIs can be executed contents.isTrusted = true; const decoration = { range: reference.range, hoverMessage: contents }; decorations.push(decoration); } activeEditor.setDecorations(referenceDecorationType, decorations); } function triggerUpdateDecorations(throttle = false) { if (timeout) { clearTimeout(timeout); timeout = undefined; } if (throttle) { timeout = setTimeout(updateDecorations, 500); } else { updateDecorations(); } } export function activateDecorations(context: ExtensionContext) { if (activeEditor) { triggerUpdateDecorations(); } window.onDidChangeActiveTextEditor(editor => { activeEditor = editor; if (editor) { triggerUpdateDecorations(); } }, null, context.subscriptions); workspace.onDidChangeTextDocument(event => { console.log(event.contentChanges); if (activeEditor && event.document === activeEditor.document) { triggerUpdateDecorations(true); } }, null, context.subscriptions); }