Skip to content

Commit

Permalink
Improved performance by switching to cachedRead
Browse files Browse the repository at this point in the history
Using cached read should improve performance when reading files to
check for tasks.

I also cleaned up some code which now uses proper type checking based
on the types provided by the obsidian API.

Relates to #15.
  • Loading branch information
schemar committed Apr 18, 2021
1 parent d06c73c commit e53cdd2
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 31 deletions.
31 changes: 25 additions & 6 deletions src/Obsidian.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
App,
Editor,
EventRef,
MarkdownPostProcessor,
MarkdownPostProcessorContext,
Expand All @@ -8,6 +9,7 @@ import {
TAbstractFile,
TFile,
Vault,
View,
Workspace,
} from 'obsidian';

Expand Down Expand Up @@ -54,18 +56,30 @@ export class Obsidian {
return activeLeaf.view;
}

public get editor(): CodeMirror.Editor {
return (this.workspace.activeLeaf.view as any).sourceMode
.cmEditor as CodeMirror.Editor;
public get editor(): Editor | undefined {
const view: View = this.workspace.activeLeaf.view;
if (view instanceof MarkdownView) {
return view.editor;
} else {
return undefined;
}
}

public getMarkdownFilePaths(): string[] {
return this.vault.getMarkdownFiles().map((file) => file.path);
}

public async readLines({ path }: { path: string }): Promise<string[]> {
public async readLines({
path,
}: {
path: string;
}): Promise<string[] | undefined> {
const file = this.vault.getAbstractFileByPath(path);
const fileContent = await this.vault.read(file as TFile);
if (!(file instanceof TFile)) {
return undefined;
}

const fileContent = await this.vault.cachedRead(file);
const fileLines = fileContent.split('\n');

return fileLines;
Expand All @@ -79,8 +93,13 @@ export class Obsidian {
lines: string[];
}): Promise<void> {
const file = this.vault.getAbstractFileByPath(path);
if (!(file instanceof TFile)) {
console.error('Tasks: trying to write non-file:', path);
return Promise.resolve();
}

const fileContent = lines.join('\n');
return this.vault.modify(file as TFile, fileContent);
return this.vault.modify(file, fileContent);
}

public addCommand(command: {
Expand Down
26 changes: 6 additions & 20 deletions src/Tasks/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { REGEX_TASK, Task } from './Task';
export class Cache {
private readonly obsidian: Obsidian;
private readonly mutex: Mutex;
private readonly markdownRegexp = /.*\.md$/;

private readonly subscribedHandlers: { [number: number]: () => void };
private registeredMaxId: number = 0;
Expand Down Expand Up @@ -49,20 +48,12 @@ export class Cache {

private subscribeToFileEvents(): void {
this.obsidian.subscribeToCreation(async (path: string) => {
if (!this.markdownRegexp.test(path)) {
return;
}

await this.mutex.runExclusive(async () => {
await this.updateFiles({ paths: [path] });
});
});

this.obsidian.subscribeToModification(async (path: string) => {
if (!this.markdownRegexp.test(path)) {
return;
}

await this.mutex.runExclusive(async () => {
this.tasks = this.tasks.filter(
(task: Task) => task.path !== path,
Expand All @@ -72,10 +63,6 @@ export class Cache {
});

this.obsidian.subscribeToDeletion(async (path: string) => {
if (!this.markdownRegexp.test(path)) {
return;
}

await this.mutex.runExclusive(async () => {
this.tasks = this.tasks.filter(
(task: Task) => task.path !== path,
Expand All @@ -86,13 +73,6 @@ export class Cache {

this.obsidian.subscribeToRenaming(
async (oldPath: string, newPath: string) => {
if (
!this.markdownRegexp.test(oldPath) ||
!this.markdownRegexp.test(newPath)
) {
return;
}

await this.mutex.runExclusive(async () => {
this.tasks = this.tasks.map(
(task: Task): Task => {
Expand Down Expand Up @@ -124,6 +104,12 @@ export class Cache {
for (const path of paths) {
let precedingHeader: string | undefined = undefined;
const lines = await this.obsidian.readLines({ path });
// If there are no lines, we don't need to parse.
// Could be a directory, for example.
if (lines === undefined) {
continue;
}

let pageIndex = 0;
for (
let lineNumber = 0;
Expand Down
10 changes: 10 additions & 0 deletions src/Tasks/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export class Commands {
}

const editor = this.obsidian.editor;
if (editor === undefined) {
// If we are not in an editor, the command shouldn't be shown.
return false;
}

const currentLine = editor.getLine(editor.getCursor().line);

const isTasksLine = REGEX_TASK.test(currentLine);
Expand All @@ -33,7 +38,12 @@ export class Commands {
if (path === undefined) {
return;
}
// We are certain we are in the editor on a tasks line due to the check above.
const editor = obsidian.editor;
if (editor === undefined) {
return;
}

const cursorPosition = editor.getCursor();
const lineNumber = cursorPosition.line;
this.file.toggleDone({ path, lineNumber });
Expand Down
14 changes: 9 additions & 5 deletions src/Tasks/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@ export class File {
}: {
path: string;
lineNumber: number;
}) {
const fileLines = await this.obsidian.readLines({ path });
const line = fileLines[lineNumber];
fileLines[lineNumber] = this.toggleLine({
}): Promise<void> {
const lines = await this.obsidian.readLines({ path });
if (lines === undefined) {
return;
}

const line = lines[lineNumber];
lines[lineNumber] = this.toggleLine({
line,
path,
lineNumber,
});

await this.obsidian.writeLines({ path, lines: fileLines });
await this.obsidian.writeLines({ path, lines });
}

private toggleLine({
Expand Down

0 comments on commit e53cdd2

Please sign in to comment.