Skip to content

cmdr 插件教程

Commander 插件使用指南

Commander 是 Obsidian 中用于自定义命令入口的插件,可以将任意 Obsidian 命令、代码片段和脚本添加到 Ribbon 栏、侧边栏、右键菜单和文件标题栏。

插件特点

特性说明
🎛️ 多位置绑定Ribbon、侧边栏、右键菜单、标题栏均可添加
⌨️ 快捷方式为任意命令创建快捷键
📝 代码片段运行自定义 JavaScript 代码
🔧 自定义命令创建组合命令序列
🖼️ 图标系统支持 Lucide 和自定义图标

安装插件

  1. 打开「设置」→「第三方插件」→ 关闭「安全模式」
  2. 点击「浏览」→ 搜索「Commander」→ 安装并启用

基础配置

打开配置面板

  • 命令Commander: Open settings
  • 在「Settings」选项卡中管理所有命令

添加命令到 Ribbon 栏

Ribbon 栏是 Obsidian 左侧的图标区域:

  1. 在 Commander 设置中点击「Add」→ 选择「Ribbon」
  2. 选择要添加的命令
  3. 选择图标(如 📝🔍📅
  4. 设置提示文字

常用 Ribbon 命令:

命令图标说明
打开日记📅打开今日日记
搜索🔍全局搜索
新建笔记✏️创建新笔记
命令面板⌨️打开命令面板

添加命令到右键菜单

  1. 点击「Add」→ 选择「Context Menu」
  2. 选择命令
  3. 设置菜单位置(文件菜单 / 编辑菜单 / 文件夹菜单)

代码片段

Commander 支持运行自定义 JavaScript 代码片段。

创建代码片段

  1. 在设置中选择「Snippets」选项卡
  2. 点击「Add snippet」
  3. 编写 JavaScript 代码

常用片段

一键创建带日期的笔记

javascript
// 创建以当前日期命名的笔记
const today = new Date().toISOString().slice(0, 10);
const fileName = `Journal/Daily/${today}.md`;

const template = `---
date: ${today}
tags: [日记]
---

# ${today}

## 今日记录

`;

await app.vault.create(fileName, template);
new Notice(`已创建 ${today} 日记`);

快速添加任务

javascript
// 在当前笔记末尾添加新任务
const file = app.workspace.getActiveFile();
if (file) {
  const task = `\n- [ ] 新任务 📅 ${new Date().toISOString().slice(0, 10)}`;
  await app.vault.append(file, task);
  new Notice('已添加任务');
}

切换主题

javascript
// 在亮色/暗色主题间切换
const theme = document.body.classList.contains('theme-dark') 
  ? 'light' : 'dark';
app.changeTheme(theme);
new Notice(`已切换到${theme === 'dark' ? '暗色' : '亮色'}主题`);

自定义命令序列

将多个命令组合成一个序列,一次执行。

创建命令序列

  1. 在设置中选择「Commands」选项卡
  2. 点击「Add command」
  3. 选择多个命令并设置执行顺序

示例:晨间工作流

序列:晨间规划
├─ 1. 打开今日日记
├─ 2. 打开本周周记
└─ 3. 聚焦日记编辑器

示例:日终回顾

序列:日终回顾
├─ 1. 显示今日日记
├─ 2. 标记已完成任务
└─ 3. 创建明日待办

图标系统

Commander 使用 Lucide 图标库。

选择图标

  1. 在添加命令时点击图标选择器
  2. 输入图标名称搜索(如 calendarsearch
  3. 点击选择

常用图标对照

操作图标名称
日历calendar
搜索search
新建plus
标签tag
文件夹folder
链接link
设置settings
保存save

高级配置

条件显示

设置命令在特定条件下才显示:

javascript
// 仅当笔记为日记时显示
module.exports = {
  condition: (app) => {
    const file = app.workspace.getActiveFile();
    return file && file.path.includes('Journal/Daily');
  }
};

文件类型过滤

javascript
// 仅在 Markdown 文件中显示
module.exports = {
  filter: (file) => file.extension === 'md'
};

快捷键管理

在「Shortcuts」选项卡中管理所有命令的快捷键:

操作说明
查看快捷键列出所有已设置的快捷键
搜索按命令名搜索快捷键
导出导出快捷键配置
导入导入快捷键配置

常用命令配置

Ribbon 栏配置

图标命令说明
📅Daily notes: Open today's daily note打开日记
📁New file新建笔记
🔍Search: Open search pane打开搜索
📋Commander: Open settings打开设置
🏷️Editor: Toggle tags view标签视图

右键菜单配置

菜单位置命令说明
文件菜单Daily notes: Open today's daily note用日记打开
编辑菜单Editor: Toggle strikethrough添加删除线
文件夹菜单New note here在此处新建

常见问题

Q: Ribbon 图标不显示?

  1. 确认插件已启用
  2. 检查图标名称是否正确
  3. 重启 Obsidian

Q: 代码片段运行报错?

检查 JavaScript 语法是否正确,Commander 的代码片段在 sandbox 环境中运行,部分 API 可能受限。

Q: 如何备份配置?

在 Commander 设置中有「Export」选项,可以导出所有命令和片段配置为 JSON 文件。

Q: 如何隐藏默认 Ribbon 图标?

在 Commander 设置中启用「Hide default ribbon icons」,然后选择性显示需要的图标。

Commander 高级使用案例

本文介绍 Commander 插件的进阶配置,包括复杂脚本、命令序列、API 集成和自动化工作流。

复杂代码片段

批量文件操作

javascript
const folder = app.workspace.getActiveFolder();
if (folder) {
  const children = folder.children;
  for (const child of children) {
    if (child instanceof TFile && child.extension === 'md') {
      const oldName = child.basename;
      const newName = oldName.replace(/\s+/g, '-');
      if (oldName !== newName) {
        await app.fileManager.renameFile(child, `${folder.path}/${newName}.md`);
      }
    }
  }
  new Notice(`已处理 ${children.length} 个文件`);
}

智能模板插入

javascript
const file = app.workspace.getActiveFile();
const fileName = file?.basename || 'untitled';

const templates = {
  '日记': `---
date: {{date:YYYY-MM-DD}}
tags: [日记]
---

# {{date:YYYY-MM-DD}}`,

  '会议': `---
date: {{date:YYYY-MM-DD}}
participants: []
---

# 会议记录 | {{date:YYYY-MM-DD}}

## 参会人员
## 议程
1. 
## 决策
## 待办
- [ ] `,

  '项目': `---
project:
status: 🟡 进行中
tags: [项目]
---

# 项目名称

## 目标
## 里程碑
- [ ] 
`
};

const template = templates[fileName] || templates['日记'];
const editor = app.workspace.getActiveEditor();
if (editor) {
  editor.replaceSelection(template);
  new Notice(`已插入 ${fileName} 模板`);
}

命令序列

每周回顾序列

序列:每周回顾
├─ 1. 打开本周周记
├─ 2. 收集过去 7 天日记中的任务完成情况
├─ 3. 统计完成率
└─ 4. 在周记中生成周报

项目启动序列

序列:启动新项目
├─ 1. 提示输入项目名称
├─ 2. 创建项目文件夹
├─ 3. 生成项目笔记(使用模板)
└─ 4. 创建项目日记分区

API 集成

调用外部 API

javascript
const response = await fetch('https://api.example.com/data');
const data = await response.json();

const file = app.workspace.getActiveFile();
if (file) {
  const content = await app.vault.read(file);
  const updatedContent = content + `\n\n## API 数据\n\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\``;
  await app.vault.modify(file, updatedContent);
  new Notice('已同步数据');
}

Obsidian API 高级用法

javascript
app.metadataCache.on('changed', (file, data) => {
  if (file.path.includes('Journal/Daily')) {
    const hasTodos = data.includes('- [ ]');
    if (hasTodos) {
      console.log(`日记 ${file.basename} 有待办`);
    }
  }
});

自动化脚本

每日自动归档

javascript
const moment = window.moment || require('moment');
const threshold = moment().subtract(30, 'days');
const journalFolder = 'Journal/Daily';

const files = app.vault.getFiles()
  .filter(f => f.path.startsWith(journalFolder))
  .filter(f => {
    const date = moment(f.basename, 'YYYY-MM-DD');
    return date.isBefore(threshold);
  });

if (files.length > 0) {
  for (const file of files) {
    const newPath = `Archives/Journal/${file.name}`;
    await app.fileManager.renameFile(file, newPath);
  }
  new Notice(`已归档 ${files.length} 个旧日记`);
} else {
  new Notice('没有需要归档的日记');
}

任务统计生成

javascript
const file = app.workspace.getActiveFile();
if (file) {
  const content = await app.vault.read(file);
  const total = (content.match(/- \[ \]/g) || []).length;
  const completed = (content.match(/- \[x\]/g) || []).length;
  const percentage = total > 0 ? Math.round(completed / total * 100) : 0;
  
  const stats = `\n\n---\n\n**任务统计**: ${completed}/${total} (${percentage}%)\n\n${'█'.repeat(percentage / 5)}${'░'.repeat(20 - percentage / 5)}`;
  
  await app.vault.append(file, stats);
  new Notice(`已生成任务统计: ${percentage}%`);
}

调试技巧

javascript
// 使用 console 输出到控制台
console.log('=== Commander Debug ===');
console.log('Active file:', app.workspace.getActiveFile()?.path);

// 错误处理
try {
  await app.vault.create('test.md', 'content');
} catch (error) {
  console.error('Error:', error);
  new Notice(`执行失败: ${error.message}`);
}

常见问题

Q: 片段执行后无响应?

  1. 检查 JavaScript 代码是否有语法错误
  2. 在开发者工具中查看控制台错误
  3. 尝试简化代码逐步排查

Q: 如何调试复杂脚本?

使用 console.log 输出中间变量值,在 Obsidian 的「开发者工具」→「控制台」中查看。