Skip to content

Commit

Permalink
fix: no longer causes a split view to appear when opening a file.
Browse files Browse the repository at this point in the history
This release should also fix any startup errors.

BREAKING CHANGE: removed the options to sync folds between the editor
and the Outline view. Because of the internal Obsidian changes, this
logic has been broken for a while and has been removed.
  • Loading branch information
liamcain committed Jul 17, 2023
1 parent a657e88 commit 8d556cb
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 651 deletions.
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
"lodash": "4.17.21"
},
"devDependencies": {
"@codemirror/basic-setup": "^0.19.0",
"@codemirror/buildhelper": "^0.1.0",
"@codemirror/lang-css": "^0.19.3",
"@codemirror/language": "^0.19.3",
"@codemirror/rangeset": "^0.19.1",
"@codemirror/view": "^0.19.7",
"@codemirror/basic-setup": "^0.20.0",
"@codemirror/buildhelper": "^1.0.0",
"@codemirror/lang-css": "^6.2.0",
"@codemirror/language": "^6.8.0",
"@codemirror/rangeset": "^0.19.9",
"@codemirror/view": "^6.15.0",
"@types/lodash": "4.14.179",
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "5.13.0",
Expand Down
11 changes: 6 additions & 5 deletions src/creaseWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import {
DecorationSet,
EditorView,
MatchDecorator,
PluginField,
ViewPlugin,
ViewUpdate,
WidgetType,
} from "@codemirror/view";
import { App, editorLivePreviewField, Menu, setIcon } from "obsidian";
import { App, Menu, editorLivePreviewField, setIcon } from "obsidian";

class CreaseWidget extends WidgetType {
constructor(
Expand All @@ -26,9 +25,9 @@ class CreaseWidget extends WidgetType {

toDOM() {
const creaseEl = createSpan("cm-creases-icon");
setIcon(creaseEl, "shirt", 12);
setIcon(creaseEl, "shirt");
creaseEl.addEventListener("click", (evt) => {
const menu = new Menu(this.app);
const menu = new Menu();
menu
.addItem((item) =>
item
Expand Down Expand Up @@ -87,7 +86,9 @@ export function creasePlugin(app: App) {
},
{
decorations: (v) => v.decorations,
provide: PluginField.atomicRanges.from((val) => val.decorations),
provide: plugin => EditorView.atomicRanges.of(view => {
return view.plugin(plugin)?.decorations || Decoration.none
})
}
);
}
270 changes: 1 addition & 269 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import sortBy from "lodash/sortBy";
import remove from "lodash/remove";
import {
Editor,
EditorChange,
EditorSelection,
EventRef,
FoldPosition,
HeadingCache,
MarkdownRenderer,
MarkdownView,
Menu,
OutlineView,
Plugin,
stripHeading,
TAbstractFile,
TemplaterAppendedEvent,
TemplaterNewNoteEvent,
TFile,
WorkspaceLeaf,
} from "obsidian";
import { foldable } from "@codemirror/language";
import { around } from "monkey-around";
Expand All @@ -28,20 +22,6 @@ import { CreasesSettings, CreasesSettingTab, DEFAULT_SETTINGS } from "./settings

const headingLevels = [1, 2, 3, 4, 5, 6];

function selectionInclude(selection: EditorSelection, fromLine: number, toLine: number) {
const { anchor, head } = selection;

// selection anchor is between
if (anchor.line >= fromLine && anchor.line <= toLine) return true;
// selection head is between
if (head.line >= fromLine && head.line <= toLine) return true;
// selection envelopes (head < anchor)
if (head.line < fromLine && anchor.line > toLine) return true;
// selection envelopes (head > anchor)
if (anchor.line < fromLine && head.line > toLine) return true;
return false;
}

const BLOCK_ID_REGEX = /\^([a-zA-Z0-9-]+)$/;

export default class CreasesPlugin extends Plugin {
Expand Down Expand Up @@ -85,18 +65,6 @@ export default class CreasesPlugin extends Plugin {
editorCallback: this.clearCreases.bind(this),
});

this.addCommand({
id: "increase-fold-level-at-cursor",
name: "Fold more",
editorCallback: this.increaseFoldLevelAtCursor.bind(this),
});

this.addCommand({
id: "decrease-fold-level-at-cursor",
name: "Fold less",
editorCallback: this.decreaseFoldLevelAtCursor.bind(this),
});

this.addCommand({
id: "increase-fold-level",
name: "Increase heading fold level",
Expand All @@ -110,10 +78,9 @@ export default class CreasesPlugin extends Plugin {
});

this.app.workspace.onLayoutReady(() => {
this.patchCoreOutlinePlugin();
// this.patchCoreOutlinePlugin();
this.registerEvent(this.app.vault.on("create", this.onNewFile.bind(this)));
this.patchCoreTemplatePlugin();
this.patchFileSuggest();
});

headingLevels.forEach((level) => {
Expand Down Expand Up @@ -159,29 +126,6 @@ export default class CreasesPlugin extends Plugin {
);
}

private async increaseFoldLevelAtCursor(editor: Editor, view: MarkdownView) {
const foldInfo = await this.app.foldManager.load(view.file);
const folds = foldInfo?.folds ?? [];

const selections = editor.listSelections();
selections.forEach((selection) => {
const parentFolds = this.getAllParentFolds(editor, selection);
for (let i = parentFolds.length - 1; i >= 0; i--) {
const parentFold = parentFolds[i];
if (!folds.find((fold) => fold.from === parentFold.from)) {
folds.push(parentFold);
break;
}
}
});

view.currentMode.applyFoldInfo({
folds,
lines: view.editor.lineCount(),
});
view.onMarkdownFold();
}

private onFileOpen(_file: TFile): void {
if (this.app.workspace.activeLeaf) {
this.patchMarkdownView();
Expand Down Expand Up @@ -266,29 +210,6 @@ export default class CreasesPlugin extends Plugin {
}
}

async decreaseFoldLevelAtCursor(editor: Editor, view: MarkdownView) {
const foldInfo = await this.app.foldManager.load(view.file);
const folds = foldInfo?.folds ?? [];

const selections = editor.listSelections();
selections.forEach((selection) => {
const parentFolds = this.getAllParentFolds(editor, selection);
for (let i = 0; i < parentFolds.length; i++) {
const parentFold = parentFolds[i];
if (folds.find((fold) => fold.from === parentFold.from)) {
remove(folds, (f) => f.from === parentFold.from);
break;
}
}
});

view.currentMode.applyFoldInfo({
folds,
lines: view.editor.lineCount(),
});
view.onMarkdownFold();
}

async decreaseHeadingFoldLevel(_editor: Editor, view: MarkdownView) {
const foldInfo = view.currentMode.getFoldInfo();
const existingFolds = foldInfo?.folds ?? [];
Expand Down Expand Up @@ -358,30 +279,6 @@ export default class CreasesPlugin extends Plugin {

this.register(
around(leaf.view.constructor.prototype, {
onMarkdownFold(old: () => void) {
return async function () {
await old.call(this);

if (plugin.settings.syncOutlineView === "none") {
return;
}
const existingFolds = (this as MarkdownView).currentMode.getFoldInfo();

const outlineViewLeaf = workspace.getLeavesOfType("outline")[0];
if (outlineViewLeaf) {
const outlineView = outlineViewLeaf.view as OutlineView;
if (outlineView.file === this.file) {
const treeView = outlineView.treeView;
for (const item of treeView.allItems) {
const isFolded = !!existingFolds?.folds.find(
(fold) => fold.from === item.heading.position.start.line
);
item.setCollapsed(isFolded);
}
}
}
};
},
onLoadFile(old: (file: TFile) => void) {
return async function (file: TFile) {
await old.call(this, file);
Expand Down Expand Up @@ -426,171 +323,6 @@ export default class CreasesPlugin extends Plugin {
);
}

private getAnyLeaf(): WorkspaceLeaf {
let leaf: WorkspaceLeaf | null = this.app.workspace.activeLeaf;
if (leaf) return leaf;

this.app.workspace.iterateAllLeaves(l => {
if (!leaf) {
leaf = l;
}
});
return leaf!;
}

private patchCoreOutlinePlugin() {
const leaf = this.getAnyLeaf();

const plugin = this as CreasesPlugin;
let outlineView: OutlineView | undefined = undefined;
try {
outlineView = this.app.viewRegistry.viewByType["outline"](leaf) as OutlineView;
} catch (e) {
// Outline plugin not enabled
return;
}


const treeView = outlineView.treeView;
const tempEl = createDiv();
const tempTreeView = treeView.constructor(tempEl);
tempTreeView.renderOutline([
{
heading: "test",
level: 1,
},
]);

this.register(
around(tempTreeView.allItems[0].constructor.prototype, {
onCollapseClick(old: () => void) {
return function (e: MouseEvent) {
old.call(this, e);

if (plugin.settings.syncOutlineView !== "bidirectional") {
return;
}

const view = plugin.app.workspace.getActiveViewOfType(MarkdownView);
if (view) {
const existingFolds = view.currentMode.getFoldInfo()?.folds ?? [];
if (this.collapsed) {
const foldPositions = [
...existingFolds,
{
from: this.heading.position.start.line,
to: this.heading.position.start.line + 1,
},
];
view.currentMode.applyFoldInfo({
folds: foldPositions,
lines: view.editor.lineCount(),
});
} else {
view.currentMode.applyFoldInfo({
folds: existingFolds.filter(
(fold) => this.heading.position.start.line !== fold.from
),
lines: view.editor.lineCount(),
});
}
view.onMarkdownFold();
}
};
},
render(old: () => void) {
return function () {
old.call(this);
const view = plugin.app.workspace.getActiveViewOfType(MarkdownView);
if (view) {
this.innerEl.empty();
MarkdownRenderer.renderMarkdown(
this.heading.heading,
this.innerEl,
view.file.path,
this
);

const existingFolds = view.currentMode.getFoldInfo()?.folds ?? [];
if (
existingFolds.find(
(fold) => fold.from === this.heading.position.start.line
)
) {
this.setCollapsed(true);
}
}
};
},
})
);
outlineView.close();
}

private patchFileSuggest() {
const suggests = this.app.workspace.editorSuggest.suggests;
const fileSuggest = suggests.find((s) => (s as any).mode !== undefined);
if (!fileSuggest) {
return;
}

this.register(
around(fileSuggest.constructor.prototype, {
getGlobalBlockSuggestions(old: () => any[]) {
return async function (...args: any[]) {
const blocks = await old.call(this, ...args);
if (!blocks) {
return null;
}
return blocks.map((b: any) => {
if (b.node.type !== "heading") {
return b;
}
return {
...b,
display: stripHeading(
b.node.data.hProperties.dataHeading.replace(CREASE_REGEX, "")
),
};
});
};
},
getGlobalHeadingSuggestions(old: () => HeadingCache[]) {
return async function (...args: any[]) {
const headings = await old.call(this, ...args);
if (!headings) {
return null;
}
return headings.map((h: HeadingCache) => ({
...h,
heading: stripHeading(h.heading.replace(CREASE_REGEX, "")),
}));
};
},

getHeadingSuggestions(old: () => HeadingCache[]) {
return async function (...args: any[]) {
const headings = await old.call(this, ...args);
if (!headings) {
return null;
}
return headings.map((h: HeadingCache) => ({
...h,
heading: stripHeading(h.heading.replace(CREASE_REGEX, "")),
}));
};
},
})
);
}

private getAllParentFolds(editor: Editor, selection: EditorSelection): FoldPosition[] {
const allFoldsInFile = this.getAllFoldableLines(editor);
return allFoldsInFile.filter((fold) =>
selectionInclude(selection, fold.from, fold.to)
);
}

private getAllFoldableLines(editor: Editor): FoldPosition[] {
if (this.app.vault.getConfig("legacyEditor")) {
const foldOpts = editor.cm.state.foldGutter.options;
Expand Down

0 comments on commit 8d556cb

Please sign in to comment.