2022年4月

原因

obsidian的日记插件可以设置在打开obsidian的时候自动创建/打开当天的日记,但是并不会每天0点的时候自动创建,并且如果我的obsidian处于一直打开的状态下该设置并不起作用,因为其逻辑是在第一次运行obsidian的时候才会执行。

有这个需求的原因是因为我使用dateview插件通过日记文件创建的时间查询出从创建时间开始+24小时的文件,并关联到日记文件中,大概效果如图

2022-04-27_03-26.png
因为他每天不会自动创建,会导致我手动创建的时候并不是固定的,所以可能因为+24小时导致查询到第二天的文章,基于这个需求我需要修改一下日历插件让他自动创建日记文件。

实现

首先阅读了一下日历插件的源码,发现的他的view层绑定了如下事件

        super(leaf);
        this.openOrCreateDailyNote = this.openOrCreateDailyNote.bind(this);
        this.openOrCreateWeeklyNote = this.openOrCreateWeeklyNote.bind(this);
        this.onNoteSettingsUpdate = this.onNoteSettingsUpdate.bind(this);
        this.onFileCreated = this.onFileCreated.bind(this);
        this.onFileDeleted = this.onFileDeleted.bind(this);
        this.onFileModified = this.onFileModified.bind(this);
        this.onFileOpen = this.onFileOpen.bind(this);
        this.onHoverDay = this.onHoverDay.bind(this);
        this.onHoverWeek = this.onHoverWeek.bind(this);
        this.onContextMenuDay = this.onContextMenuDay.bind(this);
        this.onContextMenuWeek = this.onContextMenuWeek.bind(this);
        this.registerEvent(
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.app.workspace.on("periodic-notes:settings-updated", this.onNoteSettingsUpdate));
        this.registerEvent(this.app.vault.on("create", this.onFileCreated));
        this.registerEvent(this.app.vault.on("delete", this.onFileDeleted));
        this.registerEvent(this.app.vault.on("modify", this.onFileModified));
        this.registerEvent(this.app.workspace.on("file-open", this.onFileOpen));

猜测一下就知道openOrCreateDailyNote就是创建日历的函数了,函数的定义如下

    async openOrCreateDailyNote(date, inNewSplit) {
        console.log(date,inNewSplit)
        const { workspace } = this.app;
        const existingFile = getDailyNote_1(date, get_store_value(dailyNotes));
        if (!existingFile) {
            // File doesn't exist
            tryToCreateDailyNote(date, inNewSplit, this.settings, (dailyNote) => {
                activeFile.setFile(dailyNote);
            });
            return;
        }
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const mode = this.app.vault.getConfig("defaultViewMode");
        const leaf = inNewSplit
            ? workspace.splitActiveLeaf()
            : workspace.getUnpinnedLeaf();
        await leaf.openFile(existingFile, { mode });
        activeFile.setFile(existingFile);
    }
}

可以发现传进去一个date参数就可以自动创建了,我一开始一些date参数的类型是new Date(),后来发现并不是,obsidian内置的日期库是使用的moment并绑定在了window.moment上,所以对插件的onload参数做一些修改,就可以实现了


 async onload() {
        setInterval(()=>{
            // 定时创建日历,每半小时执行一次
            const {moment} = window;
            console.log('[*] calendar onload setTimeout')
            const date= moment();
            // 为了防止重复执行,这里判断必须是0点
            if(date.hour()==0){ 
                tryToCreateDailyNote(date, false, {shouldConfirmBeforeCreate:false}, (dailyNote) => {
                    console.log("success");
                });
            }
        },1000*60*30)
       
        console.log('[*] calendar onload')

        this.register(settings.subscribe((value) => {
            this.options = value;
        }));
        ....
    }

这样就可以保证在0点到1点之间去创建日记文件了。

备注

这里要注意下我修改的插件是calendar,而不是内置的daily-note