はじめに
Templater で新たな自動化スクリプトを作りたくて検索していたら、とあるページが目にとまった
Obsidianにコマンドメニューを作る方法 - Jazzと読書の日々
このブログ、Dataview や Templater の検索すると頻繁にヒットするのだが、筆者様はかなり JavaScript に精通されていて難しめのスクリプトが多いので、いつもはスルーしていた (すみません)
ただ今回のページ簡単なスクリプトだけどなんか有用そうだぞ?という謎センサーが働いた
Dataview で command ID を取得して Templater で実行する…なるほど
ブログの方はリンク切れしていたが検索すると以下のページを見つけた
DataviewJS Snippet Showcase - Share & showcase - Obsidian Forum
Dataviewjs で下記のコードブロックを書くと Obsidian の全てのコマンドパレットの command ID を取得できるとのこと
これは…凄いんじゃないか?
Dataview で command ID を取得する
↓まずはデフォルトでホットキーが割り当てられたコマンド&新規でホットキーを割り当てたコマンド一覧を Dataview で表示させる
const getNestedObject = (nestedObj, pathArr) => {
return pathArr.reduce((obj, key) =>
(obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}
function hilite(keys, how) {
// need to check if existing key combo is overridden by undefining it
if (keys && keys[1][0] !== undefined) {
return how + keys.flat(2).join('+').replace('Mod', 'Ctrl') + how;
} else {
return how + '–' + how;
}
}
function getHotkey(arr, highlight=true) {
let hi = highlight ? '**' : '';
let defkeys = arr.hotkeys ? [[getNestedObject(arr.hotkeys, [0, 'modifiers'])],
[getNestedObject(arr.hotkeys, [0, 'key'])]] : undefined;
let ck = app.hotkeyManager.customKeys[arr.id];
var hotkeys = ck ? [[getNestedObject(ck, [0, 'modifiers'])], [getNestedObject(ck, [0, 'key'])]] : undefined;
return hotkeys ? hilite(hotkeys, hi) : hilite(defkeys, '');
}
let cmds = dv.array(Object.entries(app.commands.commands))
.where(v => getHotkey(v[1]) != '–')
.sort(v => v[1].id, 'asc')
.sort(v => getHotkey(v[1], false), 'asc');
dv.paragraph(cmds.length + " commands with assigned hotkeys; " +
"non-default hotkeys <strong>bolded</strong>.<br><br>");
dv.table(["Command ID", "Name in current locale", "Hotkeys"],
cmds.map(v => [
v[1].id,
v[1].name,
getHotkey(v[1]),
])
);
↓全てのコマンド一覧
const getNestedObject = (nestedObj, pathArr) => {
return pathArr.reduce((obj, key) =>
(obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}
function hilite(keys, how) {
// need to check if existing key combo is overridden by undefining it
if (keys && keys[1][0] !== undefined) {
return how + keys.flat(2).join('+').replace('Mod', 'Ctrl') + how;
} else {
return how + '–' + how;
}
}
function getHotkey(arr, highlight=true) {
let hi = highlight ? '**' : '';
let defkeys = arr.hotkeys ? [[getNestedObject(arr.hotkeys, [0, 'modifiers'])],
[getNestedObject(arr.hotkeys, [0, 'key'])]] : undefined;
let ck = app.hotkeyManager.customKeys[arr.id];
var hotkeys = ck ? [[getNestedObject(ck, [0, 'modifiers'])], [getNestedObject(ck, [0, 'key'])]] : undefined;
return hotkeys ? hilite(hotkeys, hi) : hilite(defkeys, '');
}
let cmds = dv.array(Object.entries(app.commands.commands))
.sort(v => v[1].id, 'asc');
dv.paragraph(cmds.length + " commands currently enabled; " +
"non-default hotkeys <strong>bolded</strong>.<br><br>");
dv.table(["Command ID", "Name in current locale", "Hotkeys"],
cmds.map(v => [
v[1].id,
v[1].name,
getHotkey(v[1]),
])
);
Templater で実行する
app.commands.executeCommandById("command ID")
Templater のスクリプト内で、このスクリプトの command ID
に Dataview で抽出した ID を入力するだけで、そのコマンドが実行できる
元記事は要するに、このコードを Templater の標準機能である tp.system.suggester
に突っ込んで選択式にしたという内容のようだ
自分でも書けるレベルだが、折角載っているので丸パクリする
list = {
"表記名1" : "command ID1",
"表記名2" : "command ID2",
"表記名3" : "command ID3"
};
k = Object.keys(list);
x = await tp.system.suggester(k, k);
if(x) app.commands.executeCommandById(list[x]);
ブックマークとして活用
色々活用はできそうだが、簡単な例を試してみる
URL を開くスクリプトを一覧にしてブックマークリストとしてみる
Web ブラウザで特定のページを開くスクリプトは凄くシンプル
open ("URL")
このスクリプトを下記の手順で使えるようにしていく
- Templater でコマンドパレットに登録
- Dataview で command ID を確認
- 先程のスクリプトに投入
- Commander プラグインでボタン化
とりあえず Obsidian からよく行く Bluesky と pCloud のスクリプトを登録してみた
ボタンをクリックしてみると suggester が表示される
Bluesky をクリックすると…
完成!
おわりに
Templater を利用してブックマークリストを作成したが、ブックマークリストくらいだったらあえて別々に登録して呼び出す必要はないかもしれない
本来ここにはコマンドパレットの全てが登録できるので、元記事の用に Command menu として使うこともできる
また、コマンドパレットを連続して起動するマクロのような使用もできるだろう (Commander にも同じ機能があるけど)
Templater が更に便利になりました