通過 Org 模式管理 Chromium 和 Firefox 對談

2020-02-24 11:30:00

我是對談管理器的鐵粉,它是 Chrome 和 Chromium 的小外掛,可以儲存所有開啟的索引標籤,為對談命名,並在需要時恢復對談。

它非常有用,特別是如果你像我一樣,白天的時候需要在多個“思維活動”之間切換——研究、開發或者閱讀新聞。或者你只是單純地希望記住幾天前的工作流(和索引標籤)。

在我決定放棄 chromium 上除了 uBlock Origin 之外的所有擴充套件後,就必須尋找一些替代品了。我的主要目標是使之與瀏覽器無關,同時對談連結必須儲存在文字檔案中,這樣我就可以享受所有純文字的好處了。還有什麼比 org 模式更好呢 ;)

很久以前我就發現了這個小訣竅:通過命令列獲取當前在谷歌 Chrome 中開啟的標籤 再加上些 elisp 程式碼:

(require 'cl-lib)(defun save-chromium-session ()  "Reads chromium current session and generate org-mode heading with items."  (interactive)  (save-excursion    (let* ((cmd "strings ~/'.config/chromium/Default/Current Session' | 'grep' -E '^https?://' | sort | uniq")           (ret (shell-command-to-string cmd)))      (insert       (concat        "* "        (format-time-string "[%Y-%m-%d %H:%M:%S]")        "\n"        (mapconcat 'identity                   (cl-reduce (lambda (lst x)                                (if (and x (not (string= "" x)))                                    (cons (concat "  - " x) lst)                                  lst))                              (split-string ret "\n")                              :initial-value (list))                   "\n"))))))(defun restore-chromium-session ()  "Restore session, by openning each link in list with (browse-url).Make sure to put cursor on date heading that contains list of urls."  (interactive)  (save-excursion    (beginning-of-line)    (when (looking-at "^\\*")      (forward-line 1)      (while (looking-at "^[ ]+-[ ]+\\(http.?+\\)$")        (let* ((ln (thing-at-point 'line t))               (ln (replace-regexp-in-string "^[ ]+-[ ]+" "" ln))               (ln (replace-regexp-in-string "\n" "" ln)))          (browse-url ln))        (forward-line 1)))))

那麼,它的工作原理是什麼呢?

執行上述程式碼,開啟一個新 org 模式檔案並呼叫 M-x save-chromium-session。它會建立類似這樣的東西:

* [2019-12-04 12:14:02]  - https://www.reddit.com/r/emacs/comments/...  - https://www.reddit.com/r/Clojure  - https://news.ycombinator.com

也就是任何在 chromium 範例中執行著的 URL。要還原的話,則將游標置於所需日期上然後執行 M-x restore-chromium-session。所有標籤都應該恢復了。

以下是我的使用案例,其中的資料是隨機生成的:

#+TITLE: Browser sessions* [2019-12-01 23:15:00]...* [2019-12-02 18:10:20]...* [2019-12-03 19:00:12]  - https://www.reddit.com/r/emacs/comments/...  - https://www.reddit.com/r/Clojure  - https://news.ycombinator.com* [2019-12-04 12:14:02]  - https://www.reddit.com/r/emacs/comments/...  - https://www.reddit.com/r/Clojure  - https://news.ycombinator.com

請注意,用於讀取 Chromium 對談的方法並不完美:strings 將從二進位制資料庫中讀取任何類似 URL 字串的內容,有時這將產生不完整的 URL。不過,你可以很方便地地編輯它們,從而保持對談檔案簡潔。

為了真正開啟標籤,elisp 程式碼中使用到了 browse-url,它可以通過 browse-url-browser-function 變數進一步客製化成執行 Chromium、Firefox 或任何其他瀏覽器。請務必閱讀該變數的相關文件。

別忘了把對談檔案放在 git、mercurial 或 svn 中,這樣你就再也不會丟失對談歷史記錄了 :)

那麼 Firefox 呢?

如果你正在使用 Firefox(最近的版本),並且想要獲取對談 URL,下面是操作方法。

首先,下載並編譯 lz4json,這是一個可以解壓縮 Mozilla lz4json 格式的小工具,Firefox 以這種格式來儲存對談資料。對談資料(在撰寫本文時)儲存在 $HOME/.mozilla/firefox/<unique-name>/sessionstore-backup /recovery.jsonlz4 中。

如果 Firefox 沒有執行,則沒有 recovery.jsonlz4,這種情況下用 previous.jsonlz4 代替。

要提取網址,嘗試在終端執行:

$ lz4jsoncat recovery.jsonlz4 | grep -oP '"(http.+?)"' | sed 's/"//g' | sort | uniq

然後更新 save-chromium-session 為:

(defun save-chromium-session ()  "Reads chromium current session and converts it to org-mode chunk."  (interactive)  (save-excursion    (let* ((path "~/.mozilla/firefox/<unique-name>/sessionstore-backups/recovery.jsonlz4")           (cmd (concat "lz4jsoncat " path " | grep -oP '\"(http.+?)\"' | sed 's/\"//g' | sort | uniq"))           (ret (shell-command-to-string cmd)))...;; rest of the code is unchanged

更新本函數的文件字串、函數名以及進一步的重構都留作練習。