用 GPT 写了一个定时保存文件路径的插件

由于官方提供的保存新建笔记路径的方法不够灵活,自己用 GPT写了一个插件,可以定时选择一个文件夹,将这段时间内所有新建的笔记都添加在这个文件夹内,定时过了之后将自动恢复保存到根目录中,这样可以很方便解决一个下午或一个晚上只添加某个领域的笔记,不用再重新移动文件夹了,代码可以自己修改设定的时间,以及返回默认的文件夹
main.js

const { Plugin, Notice, TFolder, SuggestModal } = require("obsidian");

class FolderSuggestModal extends SuggestModal {
  constructor(app, getItems, onChoose) {
    super(app);
    this.getItems = getItems;
    this.onChooseCb = onChoose;
    this.setPlaceholder("输入以搜索文件夹…");
  }
  getSuggestions(query) {
    const q = query.toLowerCase();
    return this.getItems().filter(f => f.path.toLowerCase().includes(q));
  }
  renderSuggestion(folder, el) {
    el.createEl("div", { text: folder.path });
  }
  onChooseSuggestion(folder) {
    this.onChooseCb(folder);
  }
}

module.exports = class TargetNewNoteFolder extends Plugin {
  async onload() {
    this.settings = Object.assign({ targetFolderPath: "", timerId: null }, await this.loadData());

    this.statusEl = this.addStatusBarItem();
    this.statusEl.classList.add("clickable-icon");
    this.statusEl.setAttr(
      "title",
      "点击设置新笔记目标文件夹(含 [[未解析链接]] 创建)\nAlt+点击:清除设置"
    );
    this.updateStatusBarText();

    this.statusEl.addEventListener("click", async (evt) => {
      if (evt.altKey) {
        await this.setTargetFolder("");
        new Notice("已清除新笔记目标文件夹。");
        return;
      }
      const folders = this.getAllFolders();
      if (folders.length === 0) {
        new Notice("此库中没有文件夹。");
        return;
      }
      const modal = new FolderSuggestModal(this.app, () => folders, async (folder) => {
        await this.setTargetFolder(folder.path);
        new Notice(`新笔记目标文件夹:${folder.path}`);
      });
      modal.open();
    });

    this._origGetNewFileParent = this.app.fileManager.getNewFileParent.bind(this.app.fileManager);

    const self = this;
    this.app.fileManager.getNewFileParent = function (source) {
      const target = self.getTargetFolder();
      if (target) return target;
      return self._origGetNewFileParent(source);
    };

    this.registerEvent(
      this.app.vault.on("delete", async (file) => {
        if (file instanceof TFolder && file.path === this.settings.targetFolderPath) {
          await this.setTargetFolder("");
          new Notice("目标文件夹已被删除,设置已清除。");
        }
      })
    );

    this.register(() => {
      if (this._origGetNewFileParent) {
        this.app.fileManager.getNewFileParent = this._origGetNewFileParent;
      }
      if (this.settings.timerId) {
        clearTimeout(this.settings.timerId);
      }
    });
  }

  getAllFolders() {
    return this.app.vault.getAllLoadedFiles().filter(f => f instanceof TFolder);
  }

  getTargetFolder() {
    const p = this.settings.targetFolderPath;
    if (!p) return null;
    const af = this.app.vault.getAbstractFileByPath(p);
    return af instanceof TFolder ? af : null;
  }

  async setTargetFolder(path) {
    this.settings.targetFolderPath = path || "";
    await this.saveData(this.settings);
    this.updateStatusBarText();

    // 如果选的不是根目录,就启动定时器
    if (path && path !== "/") {
      this.startFolderTimer();
    } else {
      if (this.settings.timerId) {
        clearTimeout(this.settings.timerId);
        this.settings.timerId = null;
      }
    }
  }

  startFolderTimer() {
    if (this.settings.timerId) {
      clearTimeout(this.settings.timerId);
    }
    this.settings.timerId = setTimeout(async () => {
      await this.setTargetFolder("/");
      new Notice("已超过 1 分钟,目标文件夹已自动恢复为根目录。");
    }, 5 * 1000);
  }

  updateStatusBarText() {
    const label = this.settings.targetFolderPath ? this.settings.targetFolderPath : "(未设置)";
    this.statusEl.setText(`📂 ${label}`);
  }
};

manifest.json

{
  "id": "target-new-note-folder",
  "name": "Target New Note Folder",
  "version": "1.0.0",
  "minAppVersion": "0.15.0",
  "description": "点击状态栏选择目标文件夹;所有新建笔记(含 [[未解析链接]] 创建)都保存到该文件夹。",
  "author": "Alpha Custom",
  "isDesktopOnly": false
}

2 个赞