Skip to content

API 参考

核心模块

App

主应用实例,通过 this.app 访问。

typescript
// 获取当前活动文件
const file = app.workspace.getActiveFile();

// 获取仓库信息
const vault = app.vault;

// 获取工作区
const workspace = app.workspace;

// 获取元数据缓存
const metadataCache = app.metadataCache;

Plugin

插件基类。

typescript
class MyPlugin extends Plugin {
  async onload() {
    // 插件入口
  }

  onunload() {
    // 清理资源
  }

  // 数据持久化
  async loadData(): Promise<T>
  async saveData(data: T): Promise<void>

  // 注册方法
  addCommand(command: Command): Command
  addRibbonIcon(icon: string, title: string, callback: (evt: MouseEvent) => any): HTMLElement
  addStatusBarItem(): HTMLElement
  addSettingTab(settingTab: PluginSettingTab): void
  registerView(type: string, viewCreator: ViewCreator): void
  registerEvent(eventRef: EventRef): void
  registerDomEvent(el: HTMLElement, type: string, callback: (evt: Event) => any): void
  registerInterval(id: number): void
}

Workspace

工作区管理。

typescript
const workspace = app.workspace;

// 获取活动视图
const view = workspace.getActiveViewOfType(MarkdownView);

// 获取活动编辑器
const editor = workspace.activeEditor?.editor;

// 打开文件
await workspace.openLinkText('note-name', '', true);

// 获取叶子
const leaf = workspace.getLeaf(false);
const leaf = workspace.getLeaf(true); // 新建标签页

// 更新视图
await leaf.setViewState({
  type: 'markdown',
  state: { file: 'path/to/file.md' }
});

// 事件
workspace.on('file-open', (file) => { });
workspace.on('active-leaf-change', (leaf) => { });
workspace.on('layout-change', () => { });

Vault

文件系统操作。

typescript
const vault = app.vault;

// 获取文件
const file = vault.getAbstractFileByPath('path/to/file.md');
const folder = vault.getAbstractFileByPath('path/to/folder');

// 列出文件
const files = vault.getFiles();
const mdFiles = vault.getMarkdownFiles();

// 读取文件
const content = await vault.read(file);
const data = await vault.readBinary(file);

// 写入文件
await vault.modify(file, 'new content');
await vault.append(file, '\nmore content');

// 创建文件
await vault.create('path/new.md', 'content');
await vault.createFolder('new-folder');

// 删除文件
await vault.trash(file, true);  // 移到回收站
await vault.delete(file);        // 永久删除

// 重命名/移动
await vault.rename(file, 'new/path.md');

// 事件
vault.on('create', (file) => { });
vault.on('modify', (file) => { });
vault.on('delete', (file) => { });
vault.on('rename', (file, oldPath) => { });

MetadataCache

元数据缓存。

typescript
const cache = app.metadataCache;

// 获取文件元数据
const metadata = cache.getFileCache(file);

// 访问 frontmatter
const frontmatter = metadata?.frontmatter;

// 访问链接
const links = metadata?.links;
const embeds = metadata?.embeds;

// 访问标题
const headings = metadata?.headings;

// 获取反向链接
const backlinks = cache.getBacklinksForFile(file);

// 解析链接
const linkInfo = cache.getFirstLinkpathDest('[[note-name]]', '');

// 事件
cache.on('changed', (file) => { });
cache.on('resolved', () => { });

Editor

编辑器操作。

typescript
const editor = workspace.activeEditor?.editor;

// 获取内容
const content = editor.getValue();
const line = editor.getLine(lineNumber);

// 设置内容
editor.setValue('new content');
editor.replaceRange('text', { line: 0, ch: 0 }, { line: 0, ch: 5 });

// 光标操作
const cursor = editor.getCursor();
const selections = editor.listSelections();
editor.setCursor({ line: 0, ch: 0 });
editor.setSelection({ line: 0, ch: 0 }, { line: 1, ch: 0 });

// 选中文本
const selected = editor.getSelection();
editor.replaceSelection('new text');

// 滚动
editor.scrollIntoView({ line: 10, ch: 0 });
editor.scrollTo(0, 100);

// 行操作
const count = editor.lineCount();
const pos = editor.posToOffset({ line: 0, ch: 0 });
const coords = editor.offsetToPos(0);

// 折叠
editor.fold(lineNumber);
editor.unfold(lineNumber);
editor.toggleFold(lineNumber);

TFile / TFolder

文件和文件夹类型。

typescript
// TFile 属性
file.path     // 完整路径
file.name     // 文件名(含扩展名)
file.basename // 文件名(不含扩展名)
file.extension // 扩展名
file.parent   // 父文件夹
file.stat     // 文件状态 { mtime, ctime, size }

// TFolder 属性
folder.path   // 完整路径
folder.name   // 文件夹名
folder.parent // 父文件夹
folder.children // 子文件/文件夹

// 类型检查
if (file instanceof TFile) { }
if (folder instanceof TFolder) { }

Commands

命令定义。

typescript
interface Command {
  id: string;
  name: string;
  icon?: string;
  editorCallback?: (editor: Editor, view: MarkdownView) => void;
  editorCheckCallback?: (checking: boolean, editor: Editor, view: MarkdownView) => boolean | void;
  callback?: () => void;
  checkCallback?: (checking: boolean) => boolean | void;
}

// 注册命令
this.addCommand({
  id: 'my-command',
  name: 'My Command',
  editorCallback: (editor, view) => {
    editor.replaceSelection('Hello!');
  }
});

Settings

设置面板。

typescript
class MySettingTab extends PluginSettingTab {
  display(): void {
    const { containerEl } = this;
    containerEl.empty();

    // 文本设置
    new Setting(containerEl)
      .setName('Name')
      .setDesc('Description')
      .addText(text => text
        .setPlaceholder('Placeholder')
        .setValue(value)
        .onChange(async (value) => { }));

    // 开关设置
    new Setting(containerEl)
      .addToggle(toggle => toggle
        .setValue(bool)
        .onChange(async (value) => { }));

    // 下拉选择
    new Setting(containerEl)
      .addDropdown(dropdown => dropdown
        .addOption('key', 'Label')
        .setValue(value)
        .onChange(async (value) => { }));

    // 滑块
    new Setting(containerEl)
      .addSlider(slider => slider
        .setLimits(0, 100, 1)
        .setValue(value)
        .setDynamicTooltip()
        .onChange(async (value) => { }));

    // 按钮
    new Setting(containerEl)
      .addButton(button => button
        .setButtonText('Click me')
        .setCta()
        .onClick(() => { }));
  }
}

Notice

通知消息。

typescript
import { Notice } from 'obsidian';

// 基本用法
new Notice('Message');

// 设置持续时间(毫秒)
new Notice('Message', 5000);

// 无限持续时间
new Notice('Message', 0);

模态框。

typescript
import { App, Modal } from 'obsidian';

class MyModal extends Modal {
  constructor(app: App) {
    super(app);
  }

  onOpen() {
    const { contentEl } = this;
    contentEl.createEl('h1', { text: 'Title' });
  }

  onClose() {
    const { contentEl } = this;
    contentEl.empty();
  }
}

// 打开模态框
new MyModal(this.app).open();

FuzzySuggestModal

模糊搜索模态框。

typescript
import { App, FuzzySuggestModal } from 'obsidian';

class MySuggestModal extends FuzzySuggestModal<string> {
  items: string[];

  constructor(app: App, items: string[]) {
    super(app);
    this.items = items;
  }

  getItems(): string[] {
    return this.items;
  }

  getItemText(item: string): string {
    return item;
  }

  onChooseItem(item: string, evt: MouseEvent | KeyboardEvent): void {
    console.log('Selected:', item);
  }
}

常用类型

typescript
// 文件类型
type TAbstractFile = TFile | TFolder;

// 编辑器位置
interface EditorPosition {
  line: number;
  ch: number;
}

// 编辑器范围
interface EditorRange {
  from: EditorPosition;
  to: EditorPosition;
}

// 视图状态
interface ViewState {
  type: string;
  state: Record<string, any>;
}

// 工作区叶子
class WorkspaceLeaf {
  view: View;
  tabHeaderEl: HTMLElement;

  getViewState(): ViewState;
  setViewState(viewState: ViewState): Promise<void>;
  openFile(file: TFile): Promise<void>;
}

更多资源

Events

事件系统是插件与 Obsidian 交互的核心机制。

事件监听

typescript
// 在插件中监听事件
this.registerEvent(
  this.app.vault.on('create', (file) => {
    console.log('文件创建:', file.path);
  })
);

// 监听工作区事件
this.registerEvent(
  this.app.workspace.on('file-open', (file) => {
    if (file) {
      console.log('打开文件:', file.path);
    }
  })
);

registerEvent

使用 this.registerEvent() 而非 app.vault.on(),这样插件卸载时会自动取消监听,避免内存泄漏。

常用 Vault 事件

事件参数说明
create(file: TAbstractFile)文件或文件夹创建
modify(file: TAbstractFile)文件内容修改
delete(file: TAbstractFile)文件或文件夹删除
rename(file: TAbstractFile, oldPath: string)文件或文件夹重命名

常用 Workspace 事件

事件参数说明
file-open(file: TFile &#124; null)活动文件变更
active-leaf-change(leaf: WorkspaceLeaf &#124; null)活动叶子变更
layout-change工作区布局变化
resize窗口大小变化
quick-open快速切换打开

自定义事件

typescript
// 触发自定义事件
this.app.workspace.trigger('my-plugin:action', { data: 'value' });

// 监听自定义事件
this.registerEvent(
  this.app.workspace.on('my-plugin:action' as any, (data) => {
    console.log('收到自定义事件:', data);
  })
);

FileManager

文件管理器,提供高级文件操作。

typescript
const fileManager = app.fileManager;

// 获取笔记的新链接文本(处理别名等)
const linkText = fileManager.generateMarkdownLink(
  file,      // 目标文件
  sourcePath, // 来源文件路径
  '#heading', // 可选子路径
  '别名'      // 可选别名
);

// 保存前端元数据
await fileManager.processFrontMatter(file, (frontmatter) => {
  frontmatter.tags = ['updated'];
  frontmatter.lastModified = Date.now();
});

// 重命名并更新链接
await fileManager.renameFile(file, 'new/path.md');

processFrontMatter

processFrontMatter 是安全修改 frontmatter 的推荐方式,它会自动处理 YAML 序列化:

typescript
// 添加标签
await app.fileManager.processFrontMatter(file, (fm) => {
  if (!fm.tags) fm.tags = [];
  fm.tags.push('new-tag');
});

// 修改属性
await app.fileManager.processFrontMatter(file, (fm) => {
  fm.status = 'done';
  fm.completedAt = new Date().toISOString();
});

// 删除属性
await app.fileManager.processFrontMatter(file, (fm) => {
  delete fm.temporaryField;
});

注意

processFrontMather 会在文件内容中重新生成 frontmatter 块,可能改变格式(如引号风格、缩进)。如果需要精确控制格式,请使用 vault.modify() 直接修改文件内容。

RequestUrl

HTTP 请求 API,用于与外部服务交互。

typescript
import { requestUrl, RequestUrlParam } from 'obsidian';

// GET 请求
const response = await requestUrl('https://api.example.com/data');
console.log(response.json);

// POST 请求
const result = await requestUrl({
  url: 'https://api.example.com/submit',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token'
  },
  body: JSON.stringify({ key: 'value' })
});

// 带超时的请求
try {
  const data = await requestUrl({
    url: 'https://api.example.com/data',
    method: 'GET',
    throw: false  // 不自动抛出 HTTP 错误
  });
  if (data.status === 200) {
    console.log(data.json);
  }
} catch (error) {
  console.error('请求失败:', error);
}

CORS 限制

Obsidian 的 requestUrl 不受浏览器 CORS 限制,可以直接请求任何外部 API。这是插件开发相对于普通 Web 应用的优势之一。

Editor Extensions

编辑器扩展 API,用于自定义编辑器行为。

状态栏

typescript
// 添加状态栏项
const statusBarItem = this.addStatusBarItem();
statusBarItem.setText('就绪');
statusBarItem.addClass('my-plugin-status');

// 更新状态
function updateStatus(text: string) {
  statusBarItem.setText(text);
}

功能区图标

typescript
// 添加功能区图标
const ribbonIcon = this.addRibbonIcon(
  'star',           // 图标名称
  'My Plugin',      // 提示文本
  (evt: MouseEvent) => {
    // 点击回调
    new Notice('功能已触发');
  }
);

// 自定义图标样式
ribbonIcon.addClass('my-plugin-ribbon');

命令面板

typescript
// 注册命令
this.addCommand({
  id: 'format-note',
  name: '格式化当前笔记',
  editorCallback: (editor, view) => {
    const content = editor.getValue();
    const formatted = formatContent(content);
    editor.setValue(formatted);
  }
});

// 带条件的命令
this.addCommand({
  id: 'insert-date',
  name: '插入日期',
  checkCallback: (checking) => {
    const file = app.workspace.getActiveFile();
    if (!file) return false;
    if (checking) return true;
    // 执行操作
    app.workspace.activeEditor?.editor.replaceSelection(
      new Date().toLocaleDateString()
    );
  }
});

View

自定义视图 API。

typescript
import { ItemView, WorkspaceLeaf } from 'obsidian';

// 定义视图类型常量
const VIEW_TYPE_EXAMPLE = 'example-view';

class ExampleView extends ItemView {
  constructor(leaf: WorkspaceLeaf) {
    super(leaf);
  }

  getViewType(): string {
    return VIEW_TYPE_EXAMPLE;
  }

  getDisplayText(): string {
    return '示例视图';
  }

  getIcon(): string {
    return 'star';
  }

  async onOpen() {
    const container = this.containerEl.children[1];
    container.empty();
    container.createEl('h1', { text: '示例视图' });
    container.createEl('p', { text: '这是一个自定义视图。' });
  }

  async onClose() {
    // 清理资源
  }
}

// 注册视图
this.registerView(VIEW_TYPE_EXAMPLE, (leaf) => new ExampleView(leaf));

// 打开视图
async function openExampleView() {
  const leaf = app.workspace.getLeaf(false);
  await leaf.setViewState({
    type: VIEW_TYPE_EXAMPLE,
    active: true,
  });
}

Plugin Settings

插件设置的完整模式。

typescript
// 定义设置接口
interface MyPluginSettings {
  apiKey: string;
  autoSync: boolean;
  syncInterval: number;
  folders: string[];
}

// 默认设置
const DEFAULT_SETTINGS: MyPluginSettings = {
  apiKey: '',
  autoSync: true,
  syncInterval: 60,
  folders: [],
};

// 在插件中加载/保存设置
class MyPlugin extends Plugin {
  settings: MyPluginSettings;

  async onload() {
    await this.loadSettings();
  }

  async loadSettings() {
    this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
  }

  async saveSettings() {
    await this.saveData(this.settings);
  }
}

// 设置面板
class MySettingTab extends PluginSettingTab {
  plugin: MyPlugin;

  display(): void {
    const { containerEl } = this;
    containerEl.empty();

    containerEl.createEl('h2', { text: '插件设置' });

    // API Key
    new Setting(containerEl)
      .setName('API Key')
      .setDesc('输入你的 API 密钥')
      .addText((text) =>
        text
          .setPlaceholder('sk-xxx')
          .setValue(this.plugin.settings.apiKey)
          .onChange(async (value) => {
            this.plugin.settings.apiKey = value;
            await this.plugin.saveSettings();
          })
      );

    // 自动同步开关
    new Setting(containerEl)
      .setName('自动同步')
      .setDesc('启用后定时自动同步')
      .addToggle((toggle) =>
        toggle
          .setValue(this.plugin.settings.autoSync)
          .onChange(async (value) => {
            this.plugin.settings.autoSync = value;
            await this.plugin.saveSettings();
          })
      );

    // 同步间隔
    new Setting(containerEl)
      .setName('同步间隔')
      .setDesc('自动同步的间隔时间(分钟)')
      .addSlider((slider) =>
        slider
          .setLimits(5, 120, 5)
          .setValue(this.plugin.settings.syncInterval)
          .setDynamicTooltip()
          .onChange(async (value) => {
            this.plugin.settings.syncInterval = value;
            await this.plugin.saveSettings();
          })
      );

    // 文件夹选择
    new Setting(containerEl)
      .setName('同步文件夹')
      .setDesc('选择要同步的文件夹')
      .addDropdown((dropdown) => {
        const folders = app.vault.getAllFolders();
        folders.forEach((folder) => {
          dropdown.addOption(folder.path, folder.name || '/');
        });
        dropdown.onChange(async (value) => {
          if (!this.plugin.settings.folders.includes(value)) {
            this.plugin.settings.folders.push(value);
            await this.plugin.saveSettings();
          }
        });
      });
  }
}

// 注册设置面板
this.addSettingTab(new MySettingTab(this.app, this));

常用图标

Obsidian 内置的 Lucide 图标可在 addRibbonIconaddCommand 等处使用:

图标名用途
document文档/笔记
folder文件夹
search搜索
star收藏/标记
gear设置
plus新建/添加
trash删除
pencil编辑
link链接
image图片
code代码
checkmark完成/确认
cross关闭/取消
refresh刷新
download下载
upload上传
clipboard剪贴板
calendar日历
clock时间
tag标签

完整图标列表参见 Lucide Icons