From fdbee2f24034e7f255d34c52da062592de656b73 Mon Sep 17 00:00:00 2001 From: William So Date: Tue, 12 Sep 2023 20:10:31 +0800 Subject: [PATCH] Add cwd detection for canvases Signed-off-by: William So --- .changeset/rare-gorillas-tease.md | 5 ++++ README.md | 2 +- sources/@types/obsidian.ts | 33 +++++++++++++++++++++++++-- sources/require/context.ts | 38 +++++++++++++++++++++++-------- 4 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 .changeset/rare-gorillas-tease.md diff --git a/.changeset/rare-gorillas-tease.md b/.changeset/rare-gorillas-tease.md new file mode 100644 index 0000000..f9c8943 --- /dev/null +++ b/.changeset/rare-gorillas-tease.md @@ -0,0 +1,5 @@ +--- +"obsidian-modules": minor +--- + +Add cwd detection for canvases. diff --git a/README.md b/README.md index 774394a..8d75686 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Contributions are welcome! The todos here, ordered alphabetically, are things planned for the plugin. There are no guarantees that they will be completed. However, we are likely to accept contributions for them. - Add startup modules. -- Add context detection for `dv.view` and canvases. +- Add context detection for `dv.view`. - User-defined module aliases. - Add bare module transformation support for more CDNs such as . - Faster import analysis and transformation. diff --git a/sources/@types/obsidian.ts b/sources/@types/obsidian.ts index 9f25646..117f445 100644 --- a/sources/@types/obsidian.ts +++ b/sources/@types/obsidian.ts @@ -1,5 +1,11 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ declare module "obsidian" { + interface Canvas extends Private<$Canvas, PrivateKey> { } + interface CanvasNode extends Private<$CanvasNode, PrivateKey> { } + interface CanvasNodeInfo extends Private<$CanvasNodeInfo, PrivateKey> { } + interface MarkdownEmbedInfo + extends Private<$MarkdownEmbedInfo, PrivateKey> { } + interface MarkdownFileInfo extends Private { } interface MarkdownPreviewRenderer extends Private<$MarkdownPreviewRenderer, PrivateKey> { } namespace Plugins { @@ -9,7 +15,14 @@ declare module "obsidian" { } } } -import type { MarkdownFileInfo } from "obsidian" +import type { + Canvas, + CanvasNode, + CanvasNodeInfo, + FileView, + MarkdownEmbedInfo, + MarkdownFileInfo, +} from "obsidian" import type { Private } from "@polyipseity/obsidian-plugin-library" import type { TemplaterPlugin } from "templater-obsidian" @@ -21,7 +34,23 @@ declare module "@polyipseity/obsidian-plugin-library" { } } +interface $Canvas { + readonly view: FileView +} + +interface $CanvasNode { + readonly canvas: Canvas +} + +interface $CanvasNodeInfo extends MarkdownFileInfo { + readonly node: CanvasNode +} + +interface $MarkdownEmbedInfo extends MarkdownFileInfo { + readonly owner: CanvasNodeInfo | MarkdownFileInfo +} + interface $MarkdownPreviewRenderer { - readonly owner: MarkdownFileInfo + readonly owner: MarkdownEmbedInfo | MarkdownFileInfo readonly onRender: () => void } diff --git a/sources/require/context.ts b/sources/require/context.ts index 112f517..cc8a15c 100644 --- a/sources/require/context.ts +++ b/sources/require/context.ts @@ -1,8 +1,10 @@ import { + type CanvasNodeInfo, type MarkdownFileInfo, MarkdownPreviewRenderer, editorInfoField, } from "obsidian" +import { constant, noop } from "lodash-es" import { patchPlugin, revealPrivate, @@ -11,7 +13,6 @@ import { EditorView } from "@codemirror/view" import type { ModulesPlugin } from "../main.js" import type { StateField } from "@codemirror/state" import { around } from "monkey-around" -import { noop } from "lodash-es" export function patchContextForEditor(context: ModulesPlugin): void { context.register(around(EditorView.prototype, { @@ -21,12 +22,23 @@ export function patchContextForEditor(context: ModulesPlugin): void { ...args: Parameters ): ReturnType { const { api: { requires } } = context, - req = requires.get(self) - req?.context.cwds.push(this.state.field( - // Typing bug - editorInfoField as StateField, - false, - )?.file?.parent?.path ?? null) + req = requires.get(self), + info = this.state.field( + // Typing bug + editorInfoField as StateField, + false, + ) + let path = info?.file?.parent?.path + if (path === void 0 && info) { + const info2 = info as CanvasNodeInfo | typeof info + path = revealPrivate(context, [info2], info3 => { + if ("node" in info3) { + return info3.node.canvas.view.file.parent?.path + } + return path + }, constant(path)) + } + req?.context.cwds.push(path ?? null) try { next.apply(this, args) } finally { @@ -47,8 +59,16 @@ export function patchContextForPreview(context: ModulesPlugin): void { ...args: Parameters ): ReturnType { const { api: { requires } } = context, - req = requires.get(self) - req?.context.cwds.push(this.owner.file?.parent?.path ?? null) + req = requires.get(self), + { owner } = this + let path = owner.file?.parent?.path + if (path === void 0 && "owner" in owner) { + const { owner: owner2 } = owner + if ("node" in owner2) { + path = owner2.node.canvas.view.file.parent?.path + } + } + req?.context.cwds.push(path ?? null) try { next.apply(this, args) } finally {