From 56a383ade01a119d294ccbe527b9d43d10fea058 Mon Sep 17 00:00:00 2001 From: Michael Brenan Date: Fri, 6 Oct 2023 00:58:33 -0700 Subject: [PATCH] fix formatting --- src/ui/views/inline-field-live-preview.ts | 174 ++++++++++++---------- 1 file changed, 97 insertions(+), 77 deletions(-) diff --git a/src/ui/views/inline-field-live-preview.ts b/src/ui/views/inline-field-live-preview.ts index bc24999d..113edb76 100644 --- a/src/ui/views/inline-field-live-preview.ts +++ b/src/ui/views/inline-field-live-preview.ts @@ -1,10 +1,17 @@ import { App, Component, MarkdownRenderer, editorInfoField } from "obsidian"; import { EditorState, RangeSet, RangeSetBuilder, RangeValue, StateField } from "@codemirror/state"; -import { Decoration, DecorationSet, EditorView, PluginValue, ViewPlugin, ViewUpdate, WidgetType } from "@codemirror/view"; +import { + Decoration, + DecorationSet, + EditorView, + PluginValue, + ViewPlugin, + ViewUpdate, + WidgetType, +} from "@codemirror/view"; import { InlineField, extractInlineFields } from "data-import/inline-field"; import { canonicalizeVarName } from "util/normalize"; - class InlineFieldValue extends RangeValue { constructor(public field: InlineField) { super(); @@ -18,7 +25,7 @@ function buildInlineFields(state: EditorState): RangeSet { const line = state.doc.line(lineNumber); const inlineFields = extractInlineFields(line.text); for (const field of inlineFields) { - builder.add(line.from + field.start, line.from + field.end, new InlineFieldValue(field)) + builder.add(line.from + field.start, line.from + field.end, new InlineFieldValue(field)); } } return builder.finish(); @@ -29,94 +36,103 @@ export const inlineFieldsField = StateField.define>({ create: buildInlineFields, update(oldFields, tr) { return tr.docChanged ? buildInlineFields(tr.state) : oldFields; - } + }, }); /** Create a view plugin that renders inline fields in live preview just as in the reading view. */ -export const replaceInlineFieldsInLivePreview = (app: App) => ViewPlugin.fromClass( - class implements PluginValue { - decorations: DecorationSet; - overlappingIndices: number[]; - - constructor(view: EditorView) { - this.decorations = this.buildDecoration(view); - this.overlappingIndices = this.getOverlappingIndices(view.state); - } +export const replaceInlineFieldsInLivePreview = (app: App) => + ViewPlugin.fromClass( + class implements PluginValue { + decorations: DecorationSet; + overlappingIndices: number[]; + + constructor(view: EditorView) { + this.decorations = this.buildDecoration(view); + this.overlappingIndices = this.getOverlappingIndices(view.state); + } - update(update: ViewUpdate): void { - // To reduce the total number of updating the decorations, we only update if - // the state of overlapping (i.e. which inline field is overlapping with the cursor) has changed - // except when the document has changed or the viewport has changed. + update(update: ViewUpdate): void { + // To reduce the total number of updating the decorations, we only update if + // the state of overlapping (i.e. which inline field is overlapping with the cursor) has changed + // except when the document has changed or the viewport has changed. - const oldIndices = this.overlappingIndices; - const newIndices = this.getOverlappingIndices(update.state); + const oldIndices = this.overlappingIndices; + const newIndices = this.getOverlappingIndices(update.state); - let overlapChanged = - update.startState.field(inlineFieldsField).size != update.state.field(inlineFieldsField).size - || JSON.stringify(oldIndices) != JSON.stringify(newIndices) - - this.overlappingIndices = newIndices; + let overlapChanged = + update.startState.field(inlineFieldsField).size != update.state.field(inlineFieldsField).size || + JSON.stringify(oldIndices) != JSON.stringify(newIndices); - if (update.docChanged || update.viewportChanged || overlapChanged) { - this.decorations = this.buildDecoration(update.view); - } - } + this.overlappingIndices = newIndices; - buildDecoration(view: EditorView): DecorationSet { - const markdownView = view.state.field(editorInfoField); - if (!(markdownView instanceof Component)) { - // For a canvas card not assosiated with a note in the vault, - // editorInfoField is not MarkdownView, which inherits from the Component class. - // A component object is required to pass to MarkdownRenderer.render. - return Decoration.none; + if (update.docChanged || update.viewportChanged || overlapChanged) { + this.decorations = this.buildDecoration(update.view); + } } - const file = markdownView.file; - if (!file) return Decoration.none; - - const info = view.state.field(inlineFieldsField); - const builder = new RangeSetBuilder(); - const selection = view.state.selection.main; - - let x = 0; - for (const { from, to } of view.visibleRanges) { - info.between(from, to, (start, end, { field }) => { - // If the inline field is not overlapping with the cursor, we replace it with a widget. - if (start > selection.to || end < selection.from) { - builder.add( - start, - end, - Decoration.replace({ - widget: new InlineFieldWidget(app, field, x++, file.path, markdownView), - }) - ); - } - }); + buildDecoration(view: EditorView): DecorationSet { + const markdownView = view.state.field(editorInfoField); + if (!(markdownView instanceof Component)) { + // For a canvas card not assosiated with a note in the vault, + // editorInfoField is not MarkdownView, which inherits from the Component class. + // A component object is required to pass to MarkdownRenderer.render. + return Decoration.none; + } + + const file = markdownView.file; + if (!file) return Decoration.none; + + const info = view.state.field(inlineFieldsField); + const builder = new RangeSetBuilder(); + const selection = view.state.selection.main; + + let x = 0; + for (const { from, to } of view.visibleRanges) { + info.between(from, to, (start, end, { field }) => { + // If the inline field is not overlapping with the cursor, we replace it with a widget. + if (start > selection.to || end < selection.from) { + builder.add( + start, + end, + Decoration.replace({ + widget: new InlineFieldWidget(app, field, x++, file.path, markdownView), + }) + ); + } + }); + } + return builder.finish(); } - return builder.finish(); - } - getOverlappingIndices(state: EditorState): number[] { - const selection = state.selection.main; - const cursor = state.field(inlineFieldsField).iter(); - const indices: number[] = []; - let i = 0; - while (cursor.value) { - if (cursor.from <= selection.to && cursor.to >= selection.from) { - indices.push(i); + getOverlappingIndices(state: EditorState): number[] { + const selection = state.selection.main; + const cursor = state.field(inlineFieldsField).iter(); + const indices: number[] = []; + let i = 0; + while (cursor.value) { + if (cursor.from <= selection.to && cursor.to >= selection.from) { + indices.push(i); + } + cursor.next(); + i++; } - cursor.next(); - i++; + return indices; } - return indices; + }, + { + decorations: instance => instance.decorations, } - }, { - decorations: instance => instance.decorations, -}); + ); /** A widget which inline fields are replaced with. */ class InlineFieldWidget extends WidgetType { - constructor(public app: App, public field: InlineField, public id: number, public sourcePath: string, public parentComponent: Component) { + constructor( + public app: App, + public field: InlineField, + public id: number, + public sourcePath: string, + public parentComponent: Component + ) { super(); } @@ -159,13 +175,17 @@ class InlineFieldWidget extends WidgetType { async renderMarkdown(el: HTMLElement, source: string) { const children = await renderMarkdown(this.app, source, this.sourcePath, this.parentComponent); - if (children) - el.replaceChildren(...children); + if (children) el.replaceChildren(...children); } } /** Easy-to-use version of MarkdownRenderer.render. Returns only the child nodes intead of a container block. */ -export async function renderMarkdown(app: App, markdown: string, sourcePath: string, component: Component): Promise { +export async function renderMarkdown( + app: App, + markdown: string, + sourcePath: string, + component: Component +): Promise { const el = createSpan(); await MarkdownRenderer.render(app, markdown, el, sourcePath, component); for (const child of el.children) { @@ -173,5 +193,5 @@ export async function renderMarkdown(app: App, markdown: string, sourcePath: str return child.childNodes; } } - return null + return null; }