## Issue <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" /> <span class="link-card-v2-site-name">GitHub</span> </div> <div class="link-card-v2-title"> [Feature Request] return value for pickers · Issue #319 · tadashi-aikawa/obsidian-another-quick-switcher </div> <div class="link-card-v2-content"> As far as I know, any picker (say File Name Search) does not return a value ( I tested this and it returns a boo ... </div> <img class="link-card-v2-image" src="https://opengraph.githubassets.com/6fedf55cf55cf6b85c59b782a6b287c4bf02d380f9d5725d4f12f83cb9ba356c/tadashi-aikawa/obsidian-another-quick-switcher/issues/319" /> <a href="https://github.com/tadashi-aikawa/obsidian-another-quick-switcher/issues/319"></a> </div> ## Plan: ピッカーAPIの実装(外部スクリプト連携用) TemplaterなどのスクリプトからAQSのピッカーを呼び出し、選択結果を取得できるPromise-base APIを実装します。各モーダルに `openAndGetValue()` メソッドを追加し、プラグインの `api` プロパティ経由で公開します。 ### Steps 1. src/api.ts を新規作成し、`AnotherQuickSwitcherAPI` クラスと各ピッカーの返り値型(`FilePickResult`, `HeaderPickResult` など)を定義する 2. [AbstractSuggestionModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) に `resolvePromise`/`rejectPromise` プロパティと `apiMode` フラグを追加し、`onClose` でキャンセル時の reject 処理を実装する 3. 各モーダル([AnotherQuickSwitcherModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html), [HeaderModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html), [BacklinkModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html), [LinkModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html), [InFileModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html), [GrepModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html))に `openAndGetValue(): Promise<T | null>` メソッドを追加し、選択時に `resolve` を呼び出すよう `chooseCurrentSuggestion` を修正する 4. [main.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の `AnotherQuickSwitcher` クラスに `api` プロパティを追加し、`onload()` で `AnotherQuickSwitcherAPI` インスタンスを生成・公開する 5. README または docs にAPI使用例(Templater連携サンプル)を追記する ### Further Considerations 1. **APIモード時のファイルオープン動作**: APIから呼び出された場合、ファイルを自動で開くべきか? → オプション引数 `{ openFile: boolean }` で制御する / 開かない(純粋に値を返す)/ 常に開く 2. **キャンセル時の挙動**: キャンセル時に `null` を返す vs エラーを throw する → `throw_on_cancel` オプションで選択可能にするか 3. **FolderModal/MoveModal のAPI化**: これらもAPI化するか、まずは検索系モーダルのみに絞るか ## 回答 対象は AnotherQuickSwitcherModal だけでいいです。 その上で回答です。 1. 『純粋に値を返す』で良い。他のスクリプトと連携できるのが今回の趣旨であり、ファイルを開いてしまったら本末転倒 2. nullを返す 3. しない。AnotherQuickSwitcherModalだけ。 ## Plan: AnotherQuickSwitcherModal ピッカーAPI実装 Templater等のスクリプトから `app.plugins.plugins['obsidian-another-quick-switcher'].api.pickFile()` で呼び出し、選択されたTFileを返すPromise-base APIを実装します。APIモード時はファイルを開かず純粋に値のみ返し、キャンセル時は `null` を返します。 ### Steps 1. src/api.ts を新規作成し、`AnotherQuickSwitcherAPI` クラスと `pickFile(options?)` メソッドを定義。オプションで `inputQuery` や `searchTarget` を渡せるようにする 2. [AnotherQuickSwitcherModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) に `apiMode` フラグと `resolveApiPromise` / `rejectApiPromise` を追加。`openAndGetValue(): Promise<TFile | null>` メソッドを新設する 3. `chooseCurrentSuggestion` を修正し、`apiMode` が `true` の場合は `appHelper.openFile()` をスキップして `resolveApiPromise(fileToOpened)` を呼ぶ 4. `onClose` を修正し、`apiMode` が `true` かつ未解決の場合に `resolveApiPromise(null)` を呼ぶ(キャンセル時) 5. [main.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の `AnotherQuickSwitcher` クラスに `public api: AnotherQuickSwitcherAPI` を追加し、`onload()` でインスタンス化・公開する ### Further Considerations 1. **pickFile のオプション引数**: デフォルトの `SearchCommand` をどう決めるか → `file` をデフォルトに / ユーザーが `searchTarget` を指定可能にする / 設定から読み込む ## 回答 > 1. src/api.ts を新規作成し、`AnotherQuickSwitcherAPI` クラスと `pickFile(options?)` メソッドを定義。オプションで `inputQuery` や `searchTarget` を渡せるようにする クエリやsearthTargetなどを渡すのではなく、**Another Quick SwitcherのSearch Commandsで登録されたコマンドタイトル(ex: Recent search)** を指定したら、そのモードでモーダルを表示するようにしてください。 ## Plan: AnotherQuickSwitcherModal ピッカーAPI実装 Templater等のスクリプトから `app.plugins.plugins['obsidian-another-quick-switcher'].api.pickFile("Recent search")` のようにSearch Command名を指定して呼び出し、選択されたTFileを返すPromise-base APIを実装します。APIモード時はファイルを開かず純粋に値のみ返し、キャンセル時は `null` を返します。 ### Steps 1. src/api.ts を新規作成し、`AnotherQuickSwitcherAPI` クラスを定義。`pickFile(commandName: string): Promise<TFile | null>` メソッドを実装し、`settings.searchCommands` から `name` が一致する `SearchCommand` を検索してモーダルを表示する 2. [AnotherQuickSwitcherModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) に `apiMode` フラグと `resolveApiPromise: ((file: TFile | null) => void) | null` を追加。`openAndGetValue(): Promise<TFile | null>` メソッドを新設する 3. `chooseCurrentSuggestion` を修正し、`apiMode` が `true` の場合は `appHelper.openFile()` をスキップして `resolveApiPromise(fileToOpened)` を呼び、`close()` する 4. `onClose` を修正し、`apiMode` が `true` かつ `resolveApiPromise` が未呼び出しの場合に `resolveApiPromise(null)` を呼ぶ(キャンセル時) 5. [main.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の `AnotherQuickSwitcher` クラスに `public api: AnotherQuickSwitcherAPI` を追加し、`onload()` でインスタンス化・公開する ### Further Considerations 1. **存在しないコマンド名の指定時**: `null` を即座に返す / エラーをthrowする / 利用可能なコマンド名リストを返すヘルパーメソッド `listCommands()` を追加する ## 回答 >1. **存在しないコマンド名の指定時**: `null` を即座に返す / エラーをthrowする / 利用可能なコマンド名リストを返すヘルパーメソッド `listCommands()` を追加する エラーをthrowする。 SearchCommandはCheck/Uncheck機能(multi select)で複数の `TFile` を選択することができるため、戻り値は `Promise<TFile|null>` ではなく `Promise<TFile[]|null>` になるのでは? ## Plan: AnotherQuickSwitcherModal ピッカーAPI実装 Templater等のスクリプトから `app.plugins.plugins['obsidian-another-quick-switcher'].api.pickFile("Recent search")` のようにSearch Command名を指定して呼び出し、選択されたTFile配列を返すPromise-base APIを実装します。APIモード時はファイルを開かず純粋に値のみ返し、キャンセル時は `null` を返します。存在しないコマンド名の場合はエラーをthrowします。 ### Steps 1. src/api.ts を新規作成し、`AnotherQuickSwitcherAPI` クラスを定義。`pickFile(commandName: string): Promise<TFile[] | null>` メソッドを実装し、`settings.searchCommands` から `name` が一致する `SearchCommand` を検索してモーダルを表示する。コマンド名が見つからない場合は `Error` をthrowする 2. [AnotherQuickSwitcherModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) に `apiMode` フラグと `resolveApiPromise: ((files: TFile[] | null) => void) | null` を追加。`openAndGetValue(): Promise<TFile[] | null>` メソッドを新設する 3. `chooseCurrentSuggestion` を修正し、`apiMode` が `true` の場合は `appHelper.openFile()` をスキップ。`checkedItems` があれば複数ファイル、なければ単一ファイルを配列として `resolveApiPromise([...files])` を呼び、`close()` する 4. `onClose` を修正し、`apiMode` が `true` かつ `resolveApiPromise` が未呼び出しの場合に `resolveApiPromise(null)` を呼ぶ(キャンセル時) 5. [main.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の `AnotherQuickSwitcher` クラスに `public api: AnotherQuickSwitcherAPI` を追加し、`onload()` でインスタンス化・公開する ### Further Considerations 1. **APIの型定義の公開**: Templater等から型補完を受けられるよう、型定義を別ファイル(`src/types.ts` など)にエクスポートするか、READMEに型情報を記載するか ## 回答 > 1. **APIの型定義の公開**: Templater等から型補完を受けられるよう、型定義を別ファイル(`src/types.ts` など)にエクスポートするか、READMEに型情報を記載するか READMEでよい。 > 3. `chooseCurrentSuggestion` を修正し、`apiMode` が `true` の場合は `appHelper.openFile()` をスキップ。`checkedItems` があれば複数ファイル、なければ単一ファイルを配列として `resolveApiPromise([...files])` を呼び、`close()` する `resolveApiPromise` の処理は `appHelper.openFile()` の中に書くのか? それとも呼び出し元でif文により分岐するのか? ## Plan: AnotherQuickSwitcherModal ピッカーAPI実装 Templater等のスクリプトから `app.plugins.plugins['obsidian-another-quick-switcher'].api.pickFile("Recent search")` のようにSearch Command名を指定して呼び出し、選択されたTFile配列を返すPromise-base APIを実装します。APIモード時はファイルを開かず純粋に値のみ返し、キャンセル時は `null` を返します。存在しないコマンド名の場合はエラーをthrowします。 ### Steps 1. src/api.ts を新規作成し、`AnotherQuickSwitcherAPI` クラスを定義。`pickFile(commandName: string): Promise<TFile[] | null>` メソッドを実装し、`settings.searchCommands` から `name` が一致する `SearchCommand` を検索してモーダルを表示する。コマンド名が見つからない場合は `Error` をthrowする 2. [AnotherQuickSwitcherModal.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) に `apiMode` フラグと `resolveApiPromise: ((files: TFile[] | null) => void) | null` を追加。`openAndGetValue(): Promise<TFile[] | null>` メソッドを新設する 3. `chooseCurrentSuggestion` を修正し、呼び出し元で `if (this.apiMode)` 分岐を追加。`true` の場合は `appHelper.openFile()` を呼ばず、`checkedItems` があれば複数ファイル、なければ単一ファイルを配列として `resolveApiPromise([...files])` を呼び `close()` して早期リターン。`false` の場合は既存の `appHelper.openFile()` 処理を実行 4. `onClose` を修正し、`apiMode` が `true` かつ `resolveApiPromise` が未呼び出しの場合に `resolveApiPromise(null)` を呼ぶ(キャンセル時) 5. [main.ts](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の `AnotherQuickSwitcher` クラスに `public api: AnotherQuickSwitcherAPI` を追加し、`onload()` でインスタンス化・公開する 6. [README.md](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) にAPI使用例(Templater連携サンプル)と型情報を追記する ``` いくつか修正・整理を加える。 ``` ## デグレリスク(影響範囲と理由) 1. **[silentClose()](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) 経由のモーダル遷移の挙動** - [onClose](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の [willSilentClose](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) 判定位置を変更したため、モーダル遷移時に「履歴・プレビュー復元」系の後処理がスキップされる条件が変わっています。 - 該当箇所: [AnotherQuickSwitcherModal.ts:290-323](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) - リスク: ナビゲーション(show links/backlinks、navigate back/forward)で履歴・状態復元のタイミングが微妙に変わる可能性。 2. **APIモードの引き回し** - 新しいモーダル生成時に [apiMode](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) と [resolveApiPromise](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) を引き継ぐように変更しました。 - 該当箇所: [AnotherQuickSwitcherModal.ts:1333-1381](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html), [AnotherQuickSwitcherModal.ts:1406-1444](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) - リスク: 既存のモーダル遷移で「本来はAPIモードでないのに、引き継ぎが発生する」可能性は低いですが、引数が間違って渡ると全体に影響します。 3. **[open](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) キー操作時の分岐** - APIモード時、[open](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) キー押下でファイルを開かずに [resolveApiWithFiles](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) を呼ぶ分岐を追加。 - 該当箇所: [AnotherQuickSwitcherModal.ts:1099-1135](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) - リスク: 通常モードで [apiMode](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) が誤って true になると、既存の「openでファイルを開く」動作が失われます。 4. **[initialLeaf](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の取り扱い** - API側で [activeFileLeaf](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) を渡すように変更。 - 該当箇所: [api.ts:38-73](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) - リスク: 低。むしろ従来と同等の挙動に揃えた改善。 5. **[onClose](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) のAPIキャンセル処理** - [resolveApiPromise(null)](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) が [silentClose](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) で走らないように移動。 - 該当箇所: [AnotherQuickSwitcherModal.ts:290-323](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) - リスク: 低。ただし [silentClose](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) 以外のケースで [resolveApiPromise](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) が残存すると、複数回解決の可能性が理論上あるため、他の閉じ方との組み合わせは確認が必要。 ## 重点確認ポイント(手動) - [show links](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) / `show backlinks` / [navigate back](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) / [navigate forward](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) の後に: - 返り値が `null` にならない - 既存の履歴復元やプレビュー復帰の動作が保たれる - 通常利用で [open](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) / [open in new tab](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) などが従来通り動く ## 結論 デグレリスクは **低〜中**。特にモーダル遷移と [onClose](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) まわりが中心的な影響範囲です。上記ポイントの手動確認で十分に検知可能な範囲です。