From d424df98760270164b857049754f2e098b14e1ff Mon Sep 17 00:00:00 2001 From: Jeremy Valentine <38669521+valentine195@users.noreply.github.com> Date: Mon, 22 Apr 2024 10:29:03 -0400 Subject: [PATCH] feat!: Dataview field lookups are now based on the **current active file**, not a cached set of fields. --- src/api/api.dataview.ts | 57 +++++++---------------------------------- src/lexer/lexer.ts | 19 +++++++++++--- src/main.ts | 5 +++- 3 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/api/api.dataview.ts b/src/api/api.dataview.ts index 5a41359..93713ce 100644 --- a/src/api/api.dataview.ts +++ b/src/api/api.dataview.ts @@ -1,4 +1,4 @@ -import { Component, type App } from "obsidian"; +import { Component, TFile, type App } from "obsidian"; import { getAPI } from "obsidian-dataview"; import type { DvAPIInterface } from "obsidian-dataview/lib/typings/api"; import { Lexer } from "src/lexer/lexer"; @@ -16,61 +16,22 @@ class DVManager extends Component { api: DvAPIInterface; inline: Map = new Map(); - async registerDataviewInlineFields() { - if (!this.canUseDataview) return; - await this.dataviewReady(); + ready: boolean = false; - const pages = this.api.index.pages; - - pages.forEach(({ fields }) => { - for (const [key, value] of fields) { - if ( - typeof value !== "number" || - Number.isNaN(value) || - value == undefined - ) - continue; - this.inline.set(key, value); - } - }); - - Lexer.setInlineFields(this.inline); - this.registerEvent( - this.app.metadataCache.on( - "dataview:metadata-change", - (type, file) => { - if (type === "update") { - const page = this.api.page(file.path); - - if (!page) return; - - for (let key in page) { - let value = page[key]; - if ( - typeof value !== "number" || - Number.isNaN(value) || - value == undefined - ) - continue; - this.inline.set(key, value); - } - Lexer.setInlineFields(this.inline); - } - } - ) - ); - } initialize(app: App) { this.app = app; this.api = getAPI(); - - this.app.workspace.onLayoutReady(async () => { - await this.registerDataviewInlineFields(); - }); + this.dataviewReady().then(() => (this.ready = true)); return this; } + getFieldValueFromFile(field: string, file: TFile): string | null { + if (!this.canUseDataview || !this.ready) return null; + + return this.api.index.pages.get(file.path)?.fields.get(field) ?? null; + } + get canUseDataview() { return this.app.plugins.getPlugin("dataview") != null; } diff --git a/src/lexer/lexer.ts b/src/lexer/lexer.ts index 323f1bb..095c635 100644 --- a/src/lexer/lexer.ts +++ b/src/lexer/lexer.ts @@ -1,6 +1,9 @@ /* import lexer from "lex"; */ import * as moo from "moo"; +import type { App } from "obsidian"; +import { API } from "src/api/api"; +import { DataviewManager } from "src/api/api.dataview"; import type { Conditional } from "src/roller"; export const TAG_REGEX = @@ -108,6 +111,7 @@ export interface LexicalToken extends Partial { } class LexerClass { + app: App; constructor() { this.parser = new Parser({ "+": { @@ -132,6 +136,10 @@ class LexerClass { } }); } + initialize(app: App): LexerClass { + this.app = app; + return this; + } lexer = moo.compile({ WS: [{ match: /[ \t]+/u }, { match: /[{}]+/u }], table: TABLE_REGEX, @@ -181,10 +189,13 @@ class LexerClass { { match: /\b[A-Za-z][A-Za-z0-9_]+\b/u, value: (match) => { - if (this.inline.has(match)) { - return `${this.inline.get(match)}`; - } - return match; + const file = this.app.workspace.getActiveFile(); + if (!file) return match; + + return ( + DataviewManager.getFieldValueFromFile(match, file) ?? + match + ); } } ], diff --git a/src/main.ts b/src/main.ts index 5b0bcf4..fcd6a65 100644 --- a/src/main.ts +++ b/src/main.ts @@ -46,7 +46,10 @@ export default class DiceRollerPlugin extends Plugin { this.register(() => delete window["DiceRoller"]); this.addChild(DataviewManager.initialize(this.app)); - Lexer.setDefaults(this.data.defaultFace, this.data.defaultRoll); + Lexer.initialize(this.app).setDefaults( + this.data.defaultFace, + this.data.defaultRoll + ); this.addSettingTab(new SettingTab(this.app, this));