Obsidian 自己自足:折騰 Obsidian-Query-Control插件

1. 背景

Obsidian-Query-Control(后面簡稱為 OQC 插件) 是Obsidian 中一個非常有用的插件。一說到它我就贊不絕口。原因是:這個插件做了一件 Obsidian 本來就可以做,但是卻沒有做的事情:對搜索結果的 markdown 語法進行二次渲染。而且,完成度非常高:不僅針對搜索面板,內嵌搜索,后向連接內的顯示結果markdown 全部進行了渲染,更加感人的是,還把原本只在搜索面板中的搜索控制和排序功能,完整地移植到了內嵌搜索和后向連接面板。我實在想不出,為啥 Obsidian 的作者不把這個功能直接寫進 Obsidian,而且還是在這個插件存在了好幾年的今天。

Obsidian-Query-Control 對我來說,做大的作用在于隨時按需動態檢索待辦事項,并且可以直接將任務“原封不動”地呈現在任意的筆記里,然后可以打印成 PDF共享給別人。估計你已經看出來了,這個在做任務分解和工作分配的時候,簡直是 must-have。即便是安排自己的工作,有了動態檢索和結果 markdown 渲染,幾乎可以按需地組織呈現 Obsidian 內存儲的一切筆記的內容了。

然而,遺憾的是,由于插件所實現的功能,基于對整個 Obsidian 的非常精巧的“攔截”+“替換” + “移植”操作,因此,在Obsidian 更新到 1.2.x之后,插件突然不能工作了。在 0.16版本升級的時候,也出現過類似的情況。不過作者在 1 個多月后,還是給出了 bug 修復。但是這次,插件作者托人放話了:太忙了,估計一段時間內都沒法更新。

于是,自從 Obsidian 內側版本更新到 1.2.x之后,我就通過版本回滾,一直使用1.1.15的老版本,原因只有一個:用 Obsidian-Query-Control。但是,這顯然不是辦法:Obsidian 早晚都是要再升級的。這種“伸手”和“等別人解決”的懶散方式,遲早有一天要破產的。所以,我決定從零開始,在不會 typescript 的前提下,也完全不會前端開發調試的前提下,直接上術臺,調試和修復這個 bug。

2. 先說“手術”結果

手術之后,功能恢復了 70%,現在你可以:

  • 讓搜索面板,嵌入搜索,后向連接窗體,顯示渲染后的結果
    • backlink 界面的搜索能力恢復情況是 100%
  • 可以用插件原作者提供的 query 語句中的參數配置命令(這里要再膜拜一下,原作者太 NB,太貼心了)控制嵌入搜索結果的呈現方式:
    • 搜索的題目
    • 折疊/展開
    • 是否擴展
    • 是否markdown渲染
    • 搜索結果的三種結果排序依據的正序,倒序排序

沒有恢復的功能

  • 搜索面板的控制按鈕,全都去掉了。 這也是這次出現問題的原因:Obsidian 的搜索視圖變了,而且是外表和內心一起變了。
    • 好消息是:搜索面板的控制,可以通過調整Obsidian-Query-Control 設置界面中配置參數來調整,無法隨時更改。
    • 壞消息是:改完設置,如果要生效,需要重啟 Obsidian
  • 內嵌搜索
    • 壞消息是:控制按鈕全都被砍掉了。原因同上。
    • 好消息是:內嵌搜索的控制,可以通過搜索命令來實現。 其實,我個人更喜歡這個方式。我發現,針對特定用途的檢索,向排序啊,渲染啊這些配置都是相對比較固定的。因此可以把常用的幾種搜索配置,全部固化在筆記模板中,需要的時候按需插入模板就好了,靈活方便。

我目前的配置是:我會把Obsidian-Query-Control 配置中的“默認渲染”的選項關閉,來確保搜索面板能夠呈現比較原始的文本信息結果。如果需要渲染后的結果,可以直接新建一個臨時筆記,然后用 query 命令構建一個完成了 markdown 解析的結果。如果你沒有用過 query命令,告訴你一個好消息:query 的檢索命令是與搜索面板完全一樣的,一樣靈活,快捷,一樣地對筆記本身沒有影響,而且還能渲染成原來筆記中的樣子。這也是我為什么沒有用 DataView 插件的原因。

改好的插件的下載地址:
https://github.com/zhao414/obsidian-query-control/releases/tag/0.5_fix_fix_for_Obsidian_1.2.5

在 Obsidian 的插件目錄中,用上述 main.js 替換 OCQ 插件原始的main.js即可。

3. 調試過程

3.1. 搭建調試環境

我是路人直接上到手術臺主刀的位置。站定低頭一看,我靠,不僅是個外星生物(Type Script, OMG,沒用過),手術所需條件也是“全都沒有”(好吧,VSCode 好歹還是裝了的),所以,這個過程也就從最基本的搭建調試環境開始(基于 MacOS,姑且算是開局選了個 Easy 模式吧)。

  1. 搭建JS 和 TS 的調試環境。在 MacOS 下面,參照 https://github.com/obsidianmd/obsidian-sample-plugin 中的說您,利用 NPM,這個配置過程幾乎是全自動化的。
  2. 安裝一個 VS Code和 Github Desktop。后者比較傻瓜,適合沒有什么特殊需求的初學者。
  3. 用 Github Desktop 從 Github 上把插件的代碼庫拖下來。
  4. 按照 https://github.com/obsidianmd/obsidian-sample-pluginFirst time developing plugins? 中說明的步驟,在本地完成對插件的編譯。
    1. 按照說明,運行npm run dev 后,就會開始第一次編譯,在代碼庫目錄里生成 dist 目錄:./dist,以及編譯好的 js 文件:./dist/main.js。這個終端窗口不要關閉,npm 會自動檢查后繼的代碼變動并自動完成編譯。
    2. 如果沒有生成編譯好的js 文件,也不用著急,用 VS Code 打開插件代碼庫中src目錄下的 main.ts
    3. 隨便改動點什么,例如加個空格,npm 變回自動完成編譯
    4. 如果還是沒有編譯,檢查聯網(編譯過程需要解決 depency,下載必要的包),停止當前的npm run dev,返回步驟 1 重新開始。
  5. 重要: 將編譯好的 main.js 放入 Obsidian 的對應的插件目錄,替換掉原有的。這個操作還是很有必要的,雖然不清楚原理,但是這樣操作之后,在 Obsidian Developer Tool里調試的時候,就能直接看到和跟蹤編譯前的TS代碼了。這會必直接跟蹤編譯后的 js 代碼方便太多了。

3.2. 出現問題的原因

Obsidian 1.2.x之后,SearchView 中似乎去掉了原本包含在其中的 searchHeaderDOM。

OQC 插件的一個操作就是攔截這個searchHeaderDOM,然后生成一個新的 DOM,并在其中插入搜索控制的 UI以及對應的調用,然后再將這個改好的 DOM“縫合”回去,從而實現“無縫插入全新控制界面”的結果。

這是一個我看來非常巧妙的外科手術操作,原作者一看就知道是大牛。并且,這樣一番操作之后,相當于直接給 Obsidian 本體做了增強,所以我一直認為,OB 的作者應該考慮把這個功能收編進基本功能里。當然,也可以能 OB 的作者,比較反感這種產品發布之后再“開刀”的情況,所以,遲遲不給出積極的回應。

言歸正傳,這個searchHeaderDOM被 Obsidian 拿掉之后,這個手術就做不成了,自然就運行不下去了。

但是,經過單步調試和分析原始的 TS 可以發現,受影響的僅僅是植入UI這個環節。 OQC 針對 Search/Qurey 的其他幾個核心功能,雖然也是通過精確的外科手術,在巧妙的時機抓住攔截對象并完成“改造”,但是這些操作本身和 UI 的改造過程是并行的,并且涉及的 SearchResultDOM 對象仍然有效(沒有被 OB 作者干掉),因此,可以判斷這些實際功能應該是仍然可以工作的。

通過分析代碼發現,OQC對于 Backlink的其改造方法與 OQC 對 Search/Query 過程的改造類似,而這種改造并沒有因為這次 OB 升級發生影響,因此可以進一步判斷,如果把對搜索 UI 的部分的“手術”停掉,大概率核心功能的代碼應該還可以重用。

3.3. 解題

問題定位清楚了,解決問題的思路就成型了

  • 清理掉所有 searchHeaderDOM 對象以及其成員對象的實例
  • 清理掉所有與上述實例相關的引用。

Bingo!

3.4. “手術”結果

請參見 先說“手術”結果 部分。

4. 下一步計劃(留給高人)

目前的“手術”,屏蔽掉了有問題的部分而已,相當于給一個病人做了成功的止血手術,把命保住了。

如果需要重建對 Search/Query 的控制界面,目前看到有幾個可能的思路:

  • 從 Backlink 實例中復制一個 HeaderDOM,然后移植到 searchView 中,看看能不能 work
  • 參照新的 Native Search Pane 中的模式,重構一個類似的基于菜單的全新控制面板。
  • 完全 out-of-scratch,自己寫一套 UI(其實,這個和第一個有點類似,因為原本 Backlink中的 DOM 的內容,就是插件原作者“自造”的)

本人水平有限,要實現上述任意一個思路,都得從 0 開始學起,估計都得猴年馬月了。因此,如果有高人有興趣,歡迎 fork,歡迎改造,歡迎一起把這個 NB 的插件做好。

最后,向原作者致敬,經過我這么一番野路子折騰,代碼依然健壯,太厲害了。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容