Obsidianプラグイン作成方法の調査ログ-内容

主にObsidianのプラグインは TypeScript で作成されている。
#lang/NodeJS が必要。

まずリポジトリをクローンする。
以下のコマンドはサンプルをクローンするものである。

cd plugins/.obsidian/plugins
git clone https://github.com/pjeby/hot-reload
git clone https://github.com/obsidianmd/obsidian-sample-plugin

hot-realoadプラグインは開発状況を即座に反映してくれるプラグインである。

sample-pluginはプラグインのテンプレートである。

ここで、sample-pluginmain.tsの内容を見てみる。全体的なセクションとしては以下の6つとなる。

// (1):obsidian.d.tsからモジュールのインポート
import { App, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
 
// (2) 設定用のインターフェースを作成
interface MyPluginSettings {
	mySetting: string;
}
 
// (3) 設定用のデフォルト値を作成
const DEFAULT_SETTINGS: MyPluginSettings = {
	mySetting: 'default'
}
 
// (4):プラグインの基本機能を作成する
export default class MyPlugin extends Plugin {...}
 
// (5):モーダルを作成する
class SampleModal extends Modal {...}
 
// (6):設定画面を構築する
class SampleSettingTab extends PluginSettingTab {...}
  • (1)ではobsidian.d.tsというファイルからモジュールをインポートしている。
  • (2)は設定用のインターフェースを作成している。
  • (3)では設定のデフォルト値を記述
  • (4)では作成するプラグインの基本機能を記述する。
  • (5)では子ウィンドウ(モーダル)を作成。
  • (6)では設定画面を構築している。

Note

(4)が特に重要。
ここがプラグインの本体となる。

ここで(4)のMyPluginクラスのメンバを見ていく。

export default class MyPlugin extends Plugin {
	settings: MyPluginSettings;
	
	//(1)
	async onload() { ... }
	
	//(2)
	onunload() { ... }
	
	//(3)
	async loadSettings() { ... }
	
	//(4)
	async saveSettings() { ... }
}

このクラスの中には4つしかメソッドが存在していない。

  • (1)ではロードした際の動作
  • (2)ではアンロードした際の動作
  • (3)では設定をロードするコード
  • (4)では設定値を保存するコード

さらにonLoadのコードの中身を見ていく。

await this.loadSettings();
 
		// This creates an icon in the left ribbon.
		const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
			// Called when the user clicks the icon.
			new Notice('This is a notice!');
		});
		// Perform additional things with the ribbon
		ribbonIconEl.addClass('my-plugin-ribbon-class');
 
		// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
		const statusBarItemEl = this.addStatusBarItem();
		statusBarItemEl.setText('Status Bar Text');
 
		// This adds a simple command that can be triggered anywhere
		this.addCommand({
			id: 'open-sample-modal-simple',
			name: 'Open sample modal (simple)',
			callback: () => {
				new SampleModal(this.app).open();
			}
		});
		// This adds an editor command that can perform some operation on the current editor instance
		this.addCommand({
			id: 'sample-editor-command',
			name: 'Sample editor command',
			editorCallback: (editor: Editor, view: MarkdownView) => {
				console.log(editor.getSelection());
				editor.replaceSelection('Sample Editor Command');
			}
		});
		// This adds a complex command that can check whether the current state of the app allows execution of the command
		this.addCommand({
			id: 'open-sample-modal-complex',
			name: 'Open sample modal (complex)',
			checkCallback: (checking: boolean) => {
				// Conditions to check
				const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
				if (markdownView) {
					// If checking is true, we're simply "checking" if the command can be run.
					// If checking is false, then we want to actually perform the operation.
					if (!checking) {
						new SampleModal(this.app).open();
					}
 
					// This command will only show up in Command Palette when the check function returns true
					return true;
				}
			}
		});
 
		// This adds a settings tab so the user can configure various aspects of the plugin
		this.addSettingTab(new SampleSettingTab(this.app, this));
 
		// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
		// Using this function will automatically remove the event listener when this plugin is disabled.
		this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
			console.log('click', evt);
		});
 
		// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
		this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));

一番上のこのコードは左のリボンバーにdiceアイコンをもつ、Notice関数をコールバックするボタンを変数に追加する。

// This creates an icon in the left ribbon.
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
	// Called when the user clicks the icon.
	new Notice('This is a notice!');
});

そして、そのDOMをにクラスを追加している。

// Perform additional things with the ribbon
ribbonIconEl.addClass('my-plugin-ribbon-class');