我是怎樣使用 Emacs 的

發表於2016-08-05

一直以來都想寫一篇關於我當前 Emacs 配置的文章,來描述我是如何在 Mac 和 Linux 上使用 Emacs 的,即我的 Emacs 工作流。我使用這套配置一年多了,一直以來這套配置都工作的很好,幾乎不需要怎麼調整。我現在用的是 Emacs24,但是這套配置對更早些版本的Emacs也適用。

首先,我需要解釋一下我是怎麼工作的,以及我希望我的Emacs工作流能達到什麼效果. 我大多數時候用的都是命令列,隨機在終端或者Emacs的eshell中執行. 當然長時間的tail日誌或者ssh操作可能導致Emacs崩潰因此這類操作我一般不在eshell中進行. 我之前用過很長一段時間點額vim,我習慣於快速開啟一個檔案,做一些修改,然後再關閉這個檔案. 但是我也確實發現在Emacs中同時開啟多個檔案也很有用. Emacs daemon似乎能夠滿足這兩種模式,但是我不喜歡在我登入系統或啟動Emacs時自動啟動該功能.

Avdi Grimm 曾經寫過 一篇文章關於他是如何執行Emacs的,這篇文章給我以啟示。在這之前我不太常用emacsclient. 但隨後我發現它的 -a 引數能自動啟動daemon,正是我所需要的. Avdi就是使用該指令碼來啟動emacsclient並建立新frame的. 預設情況下,終端會掛起並等待你關閉Emacs,但是你可以給 ec 指令碼(指令碼內容在後面)傳遞 -n 引數,這會使得控制權立刻回到終端.

My ‘Emacs Workflow’

我的工作流有點與眾不同. 當在圖形化的Emacs中開啟一個檔案的時候,我會編輯這個檔案但不會去關閉它. 然後我經常會再回到終端去執行命令處理那個新編輯過的檔案(rake test或mvn packge). 這意味著終端執行emacsclient後不能一直在那等待emacsclient執行完畢. 若已經有一個圖形化的emacs在執行,我希望能在這個emacs中編輯檔案而不是重新開啟一個新frame. 若有一個圖形化的Emacs在執行但是處於最小化狀態,則我希望最大化這個emacs然後用它開啟檔案.

對於一下快速編輯的情況,我希望在當前終端用Emacs快速開啟檔案,做出修改,然後關閉該檔案. 這時終端應該等待直到我完成修改.

Sidebar

我在學會magit前都是使用這種快速編輯的方法來提交git commit的. 若你沒有用過magit,我強烈推薦你花點時間學習它. 參加 http://magit.github.io/magit/magit.html. 這也是為什麼我在 ~/.bashrc 中新增了 export editor=et 的緣故了.

Tools

最終,我寫了兩個指令碼: ecet. 前一個指令碼會在圖形化Emacs中開啟emacsclient然後將控制權立即交回shell. 後一個會在當前終端開啟emacs並等待我完成編輯. 由於兩個指令碼都是連線的同一個daemon,因此所有開啟的檔案對兩者都是可見的. 兩個指令碼都會在daemon未啟動的情況下自動啟動daemon. ec 指令碼還有一些額外的程式碼用來實現我工作流中所描述的那樣將焦點切換到emacs上. 下面是指令碼的內容,我已經加上了註釋了.

ec

et

Github repo

可以在https://github.com/mjwall/dotfiles 中找到這兩個指令碼以及在Mac和Linux下安裝Emacs的方法. 該倉庫存放的其實是我的 ~/.emac.d 配置. 我把所有的東西都放在一起,這樣便於在新機器上重建配置,也便於在多型機器之間同步配置.

Warning

若你用的是Mac,請務必保證新版本的emacs和emacsclient被放在了正確的路徑中. 可以去gist 上看看我是怎麼做的. 當然肯定還有其他更好的實現方式吧.

Bonus, executing elisp

我使用這兩個指令碼的另一種方式是使用 -e 選項來執行elisp程式碼. 例如,我就在我的bashrc中為magit設定了一個alias. 由於用到了這兩個指令碼因此它也能自動啟動daemon並自動捕獲焦點. 下面是定義alias的方法

這樣在終端中執行magit就會呼叫Emacs並在當前目錄下執行magit-status了. This was inspired by a similiar tweet somewhere, but takes advantage of the rest of the ec script.

Stopping the Daemon

最後還有一個指令碼用於關閉daemon,這個指令碼常用於重新載入emacs配置. 有時我的Mac在關機時會掛起等待Emacs退出,因此我一般都是先手工執行該指令碼關閉Emacs. 指令碼內容如下:

es

似乎有很好的方法能解決Mac關機掛起的問題,但這個問題對我來說不是什麼大問題,因此我沒有深入這個問題.

Wrap up

若你讀到了這裡,你可能會想”在shell執行elisp程式碼真不錯啊”。如果你有這個想法,可以看看 https://github.com/mjwall/dotfiles/blob/master/bin/ed.el, 你會看到下面這樣的實現方式

想象一下吧. 藉助這種能力,你可以遍歷一個git倉庫,將其原始碼中的所有tab都替換成空格. 這樣做可能沒什麼意義,但是想一想也覺得蠻有意思的。

如果你沒有讀到這裡,可能是因為你覺得這樣搞太小題大做了。嗯,沒準你是對的。

相關文章