diff --git a/package.json b/package.json index f78f2b2f..0271b39d 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,10 @@ "license": "MIT", "devDependencies": { "@aidenlx/folder-note-core": "^1.3.1", + "@codemirror/language": "^0.19.0", + "@codemirror/rangeset": "^0.19.0", + "@codemirror/state": "^0.19.0", + "@codemirror/view": "^0.19.0", "@rollup/plugin-commonjs": "^18.1.0", "@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-typescript": "^8.2.1", @@ -31,7 +35,7 @@ "auto-plugin-obsidian": "^0.1.4", "eslint": "^7.29.0", "mocha": "^9.1.3", - "obsidian": "^0.12.0", + "obsidian": "^0.13.11", "obsidian-dataview": "^0.4.20", "rollup": "^2.32.1", "rollup-plugin-svelte": "7.1.0", diff --git a/rollup.config.js b/rollup.config.js index 2e958f13..d0a4c792 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -12,7 +12,21 @@ export default { file: "main.js", exports: "default", }, - external: ["obsidian", "fs", "os", "path"], + external: ["obsidian", "fs", "os", "path", + "@codemirror/autocomplete", + "@codemirror/closebrackets", + "@codemirror/commands", + "@codemirror/fold", + "@codemirror/gutter", + "@codemirror/history", + "@codemirror/language", + "@codemirror/rangeset", + "@codemirror/rectangular-selection", + "@codemirror/search", + "@codemirror/state", + "@codemirror/stream-parser", + "@codemirror/text", + "@codemirror/view",], plugins: [ svelte({ emitCss: false, diff --git a/src/BreadcrumbsSettingTab.ts b/src/BreadcrumbsSettingTab.ts index fc9bbcb2..c02fb9f3 100644 --- a/src/BreadcrumbsSettingTab.ts +++ b/src/BreadcrumbsSettingTab.ts @@ -26,7 +26,7 @@ import type { DebugLevel, Relations, visTypes } from "./interfaces"; import type BCPlugin from "./main"; import MatrixView from "./Views/MatrixView"; import { getFields, splitAndTrim, strToRegex } from "./sharedFunctions"; -import { drawTrail } from "./Views/TrailView"; +import {drawTrail, updateLPView} from "./Views/TrailView"; const fragWithHTML = (html: string) => createFragment((frag) => (frag.createDiv().innerHTML = html)); @@ -485,6 +485,7 @@ export class BCSettingTab extends PluginSettingTab { settings.showBCs = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -500,6 +501,7 @@ export class BCSettingTab extends PluginSettingTab { settings.showBCsInEditLPMode = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -533,6 +535,7 @@ export class BCSettingTab extends PluginSettingTab { settings.showTrail = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }); }) .addToggle((toggle) => { @@ -543,6 +546,7 @@ export class BCSettingTab extends PluginSettingTab { settings.showGrid = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }); }) .addToggle((toggle) => { @@ -553,6 +557,7 @@ export class BCSettingTab extends PluginSettingTab { settings.showJuggl = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }); }) .addToggle((toggle) => { @@ -563,6 +568,7 @@ export class BCSettingTab extends PluginSettingTab { settings.showPrevNext = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }); }); @@ -576,6 +582,7 @@ export class BCSettingTab extends PluginSettingTab { settings.gridDots = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -603,6 +610,7 @@ export class BCSettingTab extends PluginSettingTab { settings.gridHeatmap = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -659,6 +667,7 @@ export class BCSettingTab extends PluginSettingTab { await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -673,6 +682,7 @@ export class BCSettingTab extends PluginSettingTab { await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -689,6 +699,7 @@ export class BCSettingTab extends PluginSettingTab { settings.trailSeperator = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -705,6 +716,7 @@ export class BCSettingTab extends PluginSettingTab { settings.noPathMessage = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); @@ -720,6 +732,7 @@ export class BCSettingTab extends PluginSettingTab { settings.respectReadableLineLength = value; await plugin.saveSettings(); await drawTrail(plugin); + updateLPView(); }) ); diff --git a/src/Views/TrailView.ts b/src/Views/TrailView.ts index 81357322..6f4db20e 100644 --- a/src/Views/TrailView.ts +++ b/src/Views/TrailView.ts @@ -1,6 +1,6 @@ import type { MultiGraph } from "graphology"; import { error, info } from "loglevel"; -import { MarkdownView, Notice, TFile } from "obsidian"; +import { MarkdownView, Notice, TFile, editorViewField } from "obsidian"; import type { BCSettings } from "../interfaces"; import NextPrev from "../Components/NextPrev.svelte"; import TrailGrid from "../Components/TrailGrid.svelte"; @@ -16,6 +16,70 @@ import { import type BCPlugin from "../main"; import { getFields, getRealnImplied } from "../sharedFunctions"; import {createJugglTrail} from "../Visualisations/Juggl"; +import {Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate, WidgetType} from "@codemirror/view"; +import {RangeSet, RangeSetBuilder} from "@codemirror/rangeset"; + +let UPDATE_LP_VIEW = false; + +export function updateLPView() { + UPDATE_LP_VIEW = true; +} + +export function buildCMPlugin(plugin: BCPlugin) { + class TrailWidget extends WidgetType { + element: HTMLElement; + constructor(element: HTMLElement) { + super(); + this.element = element; + } + + toDOM(view: EditorView): HTMLElement { + console.log("TO the doM!"); + this.element.detach(); + return this.element; + } + + ignoreEvent(_event: Event): boolean { + return true; + } + } + + return ViewPlugin.fromClass( + class { + decorations: DecorationSet; + + constructor(view: EditorView) { + this.decorations = new RangeSetBuilder().finish(); + this.buildDecorations(view).then(value => {this.decorations = value;}); + } + + update(update: ViewUpdate) { + if (UPDATE_LP_VIEW) { + this.buildDecorations(update.view).then(value => {this.decorations = value;}); + UPDATE_LP_VIEW = false; + } + } + + destroy() {} + + async buildDecorations(view: EditorView) { + let builder = new RangeSetBuilder(); + if (plugin.settings.showBCsInEditLPMode) { + let mdView: MarkdownView = view.state.field(editorViewField); + let element = await _drawTrail(plugin, mdView); + let widget = Decoration.widget({ + widget: new TrailWidget(element) + }); + builder.add(0, 0, widget); + } + return builder.finish(); + } + }, + { + decorations: v => v.decorations + } + ) +} function getLimitedTrailSub(plugin: BCPlugin) { const { settings, mainG } = plugin; @@ -70,6 +134,15 @@ function getBreadcrumbs( } export async function drawTrail(plugin: BCPlugin): Promise { + const activeMDView = plugin.app.workspace.getActiveViewOfType(MarkdownView); + console.log(activeMDView.getMode()); + if (activeMDView.getMode() !== "preview") { + return; + } + await _drawTrail(plugin, activeMDView); +} + +async function _drawTrail(plugin: BCPlugin, activeMDView: MarkdownView): Promise { try { const { settings, db, app } = plugin; const { @@ -83,7 +156,7 @@ export async function drawTrail(plugin: BCPlugin): Promise { showBCsInEditLPMode, } = settings; db.start2G("drawTrail"); - const activeMDView = app.workspace.getActiveViewOfType(MarkdownView); + const mode = activeMDView?.getMode(); if ( !showBCs || @@ -116,14 +189,16 @@ export async function drawTrail(plugin: BCPlugin): Promise { view = activeMDView.previewMode.containerEl.querySelector( "div.markdown-preview-view" ); - } else { + activeMDView.containerEl + .querySelectorAll(".BC-trail") + ?.forEach((trail) => trail.remove()); + } + else { view = activeMDView.contentEl.querySelector("div.markdown-source-view"); if (view.hasClass("is-live-preview")) livePreview = true; } - activeMDView.containerEl - .querySelectorAll(".BC-trail") - ?.forEach((trail) => trail.remove()); + const closedUp = getLimitedTrailSub(plugin); const sortedTrails = getBreadcrumbs(settings, closedUp, file); @@ -194,6 +269,7 @@ export async function drawTrail(plugin: BCPlugin): Promise { if (cmSizer) cmSizer.before(trailDiv); } + trailDiv.empty(); if (settings.indexNotes.includes(basename)) { trailDiv.innerText = "Index Note"; @@ -237,6 +313,7 @@ export async function drawTrail(plugin: BCPlugin): Promise { ); } db.end2G(); + return trailDiv; } catch (err) { error(err); plugin.db.end2G(); diff --git a/src/Visualisations/Juggl.ts b/src/Visualisations/Juggl.ts index 8cb3d207..de8591ee 100644 --- a/src/Visualisations/Juggl.ts +++ b/src/Visualisations/Juggl.ts @@ -225,14 +225,12 @@ export function createJugglTrail( .split("\n") .map((line) => { const pair = line.split("- "); - console.log({pair}) - return pair[1]; + return pair.slice(1).join("- "); }) .filter((pair) => pair && pair !== ""); let nodesS = new Set(lines); nodesS.add(source); const nodes = Array.from(nodesS).map(s => s + ".md"); - console.log({nodes}); jugglDown = createJuggl(plugin, target, nodes, args); diff --git a/src/main.ts b/src/main.ts index 0b018849..c6feca6d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,7 +33,7 @@ import { getFields } from "./sharedFunctions"; import DucksView from "./Views/DucksView"; import MatrixView from "./Views/MatrixView"; import StatsView from "./Views/StatsView"; -import { drawTrail } from "./Views/TrailView"; +import {buildCMPlugin, drawTrail, UPDATE_LP_VIEW, updateLPView} from "./Views/TrailView"; import TreeView from "./Views/TreeView"; import { VisModal } from "./VisModal"; @@ -240,7 +240,7 @@ export default class BCPlugin extends Plugin { callback: async () => { settings.showBCsInEditLPMode = !settings.showBCsInEditLPMode; await this.saveSettings(); - await drawTrail(this); + updateLPView(); }, }); @@ -293,6 +293,9 @@ export default class BCPlugin extends Plugin { () => new VisModal(this.app, this).open() ); + this.registerEditorExtension(buildCMPlugin(this)); + console.log("Registered editor extension"); + this.registerMarkdownCodeBlockProcessor( "breadcrumbs", getCodeblockCB(this) diff --git a/yarn.lock b/yarn.lock index 45233cdf..d471f38d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -99,6 +99,47 @@ "chalk" "^2.0.0" "js-tokens" "^4.0.0" +"@codemirror/language@^0.19.0": + "integrity" "sha512-pNNUtYWMIMG0lUSKyUXJr8U0rFiCKsKFXbA2Oj17PC+S1FY99hV0z1vcntW67ekAIZw9DMEUQnLsKBuIbAUX7Q==" + "resolved" "https://registry.npmjs.org/@codemirror/language/-/language-0.19.7.tgz" + "version" "0.19.7" + dependencies: + "@codemirror/state" "^0.19.0" + "@codemirror/text" "^0.19.0" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.5" + "@lezer/lr" "^0.15.0" + +"@codemirror/rangeset@^0.19.0", "@codemirror/rangeset@^0.19.5": + "integrity" "sha512-wYtgGnW2Jtrh2nj7vpcBoEZib+jfyilrLN6w7YMTzzSRN8xXhYRorOUg4VQIa1JwFcMQrjSCkIdqXsDqOX1cYg==" + "resolved" "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.19.6.tgz" + "version" "0.19.6" + dependencies: + "@codemirror/state" "^0.19.0" + +"@codemirror/state@^0.19.0", "@codemirror/state@^0.19.3", "@codemirror/state@^0.19.6": + "integrity" "sha512-sqIQZE9VqwQj7D4c2oz9mfLhlT1ElAzGB5lO1lE33BPyrdNy1cJyCIOecT4cn4VeJOFrnjOeu+IftZ3zqdFETw==" + "resolved" "https://registry.npmjs.org/@codemirror/state/-/state-0.19.6.tgz" + "version" "0.19.6" + dependencies: + "@codemirror/text" "^0.19.0" + +"@codemirror/text@^0.19.0": + "integrity" "sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==" + "resolved" "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz" + "version" "0.19.6" + +"@codemirror/view@^0.19.0", "@codemirror/view@^0.19.31": + "integrity" "sha512-ol4smHAwhWkW8p1diPZiZkLZVmKybKhQigwyrgdF7k1UFNY+/KDH4w2xic8JQXxX+v0ppMsoNf11C+afKJze5g==" + "resolved" "https://registry.npmjs.org/@codemirror/view/-/view-0.19.39.tgz" + "version" "0.19.39" + dependencies: + "@codemirror/rangeset" "^0.19.5" + "@codemirror/state" "^0.19.3" + "@codemirror/text" "^0.19.0" + "style-mod" "^4.0.0" + "w3c-keyname" "^2.2.4" + "@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": "integrity" "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==" "resolved" "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz" @@ -154,6 +195,18 @@ "@types/yargs" "^16.0.0" "chalk" "^4.0.0" +"@lezer/common@^0.15.0", "@lezer/common@^0.15.5": + "integrity" "sha512-vv0nSdIaVCRcJ8rPuDdsrNVfBOYe/4Szr/LhF929XyDmBndLDuWiCCHooGlGlJfzELyO608AyDhVsuX/ZG36NA==" + "resolved" "https://registry.npmjs.org/@lezer/common/-/common-0.15.11.tgz" + "version" "0.15.11" + +"@lezer/lr@^0.15.0": + "integrity" "sha512-LBqPzUjeW5GRdxHyUlAn6VdpyutV74fIaAtooYdU8dWz5wUjdO5eA1FyHpl1KAhFycoMmjI8D96NJZ0MRNyLJg==" + "resolved" "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.6.tgz" + "version" "0.15.6" + dependencies: + "@lezer/common" "^0.15.0" + "@nodelib/fs.scandir@2.1.5": "integrity" "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==" "resolved" "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -3330,11 +3383,13 @@ "papaparse" "^5.3.1" "parsimmon" "^1.18.0" -"obsidian@^0.12.0", "obsidian@^0.12.17": - "integrity" "sha512-YvCAlRym9D8zNPXt6Ez8QubSTVGoChx6lb58zqI13Dcrz3l1lgUO+pcOGDiD5Qa67nzDZLXo3aV2rqkCCpTvGQ==" - "resolved" "https://registry.npmjs.org/obsidian/-/obsidian-0.12.17.tgz" - "version" "0.12.17" +"obsidian@^0.12.17", "obsidian@^0.13.11": + "integrity" "sha512-KxOvAh4CG5vzcukmHvyuK9hUIr6ZFlM9FQfGZEwrrEV8VG2/W2Tk5cWrg0VM7EkGE3QBmjX6owjIDIO8QDXVUQ==" + "resolved" "https://registry.npmjs.org/obsidian/-/obsidian-0.13.11.tgz" + "version" "0.13.11" dependencies: + "@codemirror/state" "^0.19.6" + "@codemirror/view" "^0.19.31" "@types/codemirror" "0.0.108" "moment" "2.29.1" @@ -4243,6 +4298,11 @@ "@tokenizer/token" "^0.3.0" "peek-readable" "^4.0.1" +"style-mod@^4.0.0": + "integrity" "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==" + "resolved" "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz" + "version" "4.0.0" + "supports-color@^2.0.0": "integrity" "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" @@ -4615,6 +4675,11 @@ dependencies: "source-map" "^0.5.1" +"w3c-keyname@^2.2.4": + "integrity" "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==" + "resolved" "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz" + "version" "2.2.4" + "wcsize@^1.0.0": "integrity" "sha1-qKLhXmqKdHkdulgPaaV9J+hQ6h4=" "resolved" "https://registry.npmjs.org/wcsize/-/wcsize-1.0.0.tgz"