通過Org模式管理Chromium和Firefox會話
我是會話管理器的鐵粉,它是 Chrome 和 Chromium 的小插件,可以保存所有打開的選項(xiàng)卡,為會話命名,并在需要時(shí)恢復(fù)會話。
它非常有用,特別是如果你像我一樣,白天的時(shí)候需要在多個(gè)“思維活動”之間切換——研究、開發(fā)或者閱讀新聞。或者你只是單純地希望記住幾天前的工作流(和選項(xiàng)卡)。
在我決定放棄 chromium 上除了 uBlock Origin 之外的所有擴(kuò)展后,就必須尋找一些替代品了。我的主要目標(biāo)是使之與瀏覽器無關(guān),同時(shí)會話鏈接必須保存在文本文件中,這樣我就可以享受所有純文本的好處了。還有什么比 org 模式更好呢 ;)
很久以前我就發(fā)現(xiàn)了這個(gè)小訣竅:通過命令行獲取當(dāng)前在谷歌 Chrome 中打開的標(biāo)簽 再加上些 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)))))
那么,它的工作原理是什么呢?
運(yùn)行上述代碼,打開一個(gè)新 org 模式文件并調(diào)用 M-x save-chromium-session
。它會創(chuàng)建類似這樣的東西:
* [2019-12-04 12:14:02]
- https://www.reddit.com/r/emacs/comments/...
- https://www.reddit.com/r/Clojure
- https://news.ycombinator.com
也就是任何在 chromium 實(shí)例中運(yùn)行著的 URL。要還原的話,則將光標(biāo)置于所需日期上然后運(yùn)行 M-x restore-chromium-session
。所有標(biāo)簽都應(yīng)該恢復(fù)了。
以下是我的使用案例,其中的數(shù)據(jù)是隨機(jī)生成的:
#+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
將從二進(jìn)制數(shù)據(jù)庫中讀取任何類似 URL 字符串的內(nèi)容,有時(shí)這將產(chǎn)生不完整的 URL。不過,你可以很方便地地編輯它們,從而保持會話文件簡潔。
為了真正打開標(biāo)簽,elisp 代碼中使用到了 browse-url,它可以通過 browse-url-browser-function
變量進(jìn)一步定制成運(yùn)行 Chromium、Firefox 或任何其他瀏覽器。請務(wù)必閱讀該變量的相關(guān)文檔。
別忘了把會話文件放在 git、mercurial 或 svn 中,這樣你就再也不會丟失會話歷史記錄了 :)
那么 Firefox 呢?
如果你正在使用 Firefox(最近的版本),并且想要獲取會話 URL,下面是操作方法。
首先,下載并編譯 lz4json,這是一個(gè)可以解壓縮 Mozilla lz4json 格式的小工具,F(xiàn)irefox 以這種格式來存儲會話數(shù)據(jù)。會話數(shù)據(jù)(在撰寫本文時(shí))存儲在 $HOME/.mozilla/firefox/<unique-name>/sessionstore-backup /recovery.jsonlz4
中。
如果 Firefox 沒有運(yùn)行,則沒有 recovery.jsonlz4
,這種情況下用 previous.jsonlz4
代替。
要提取網(wǎng)址,嘗試在終端運(yùn)行:
$ 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
更新本函數(shù)的文檔字符串、函數(shù)名以及進(jìn)一步的重構(gòu)都留作練習(xí)。