vscode-zoterolens/src/decorations.ts

86 lines
2.8 KiB
TypeScript

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);
}