Emacs 是個非常吃重設定檔的編輯器,這一篇會為您解答最常遇到的一些問題。
很多系統不會為使用者事先建立設定檔,要自己手動建立。 方法是在 ~/
(家目錄)下建立一個叫 .emacs.d
的目錄,並在裡面開一個叫 init.el
的檔案。
建議把一切 Emacs 相關設定分門別類整理好存放在
.emacs.d
中,盡量不要全部擠到.emacs.d/init.el
,因為整理起來會很麻煩。可以參考 kanru 與 kuanyui (不才在下) 的
.emacs.d
目錄結構來整理。– ono hiroko
這也是個曾經讓我很困惑的問題。總之,最簡單的得知方法是 M-x customize
後,按”Apply and Save”,你會看到畫面下方的 minibuffer 寫著一串路徑,就是那個了。
另一個方法是,按 C-x C-f
後,輸入 ~
,就可以切到實際的 ~
目錄內。
Emacs 會優先讀取前者。然而在某些系統中會預設建立這個檔案,同時存在的話可能會發生設定衝突問題。 我是建議把前者刪掉,只使用後者,也方便使用版本控制系統管理你的設定檔。
網路上找到不錯的設定時,加入設定檔前可以先測試一下:
- 把設定貼到任何一個 buffer 中,最好是
emacs-lisp-mode
或者lisp-interaction-mode
的 buffer(例如一啟動 Emacs 後看到的*scratch*
)因為進一步修改比較容易,也有 syntax highlight - 把游標移動到括弧最尾端後,按
C-x C-e
,設定就立即生效了。
前面有詳細講過,因為 Emacs 本身就是一個完整的 Lisp 環境/直譯器,除了 Lisp 直譯器自己本身與一些低階命令外,其餘部份全是使用 Emacs Lisp 所建構而成。
C-x C-e
的動作代表「執行(eval)該 Lisp 表達式」,執行的結果(或更精確地說,執行該表達式後的 副作用 )也就會直接立刻影響整個 Emacs。
- 如果發生錯誤(會顯示一個叫做
*Backtrace*
的 buffer,內容大致是Debugger entered--Lisp error: (wrong-number-of-arguments (2 . 2) 0)
之類的),這時按q
關閉*Backtrace*
buffer,看哪裡出錯了再修改。
需要在啟用某個 mode 後,自動執行任意 function/啟用 minor-mode /做一些設定時,請使用 add-hook
。方法是:
(add-hook 'xxxxx-mode-hook 'function-name)
意思就是在 xxxxx-mode
啟動時,執行 function-name
這個 function
再提醒一次,查 mode 的正式名稱最快的方式:
C-h v
major-mode
可以查詢目前 buffer 下 major mode 的正式名稱C-h v
minor-mode-list
查詢目前 buffer 下所有啟動的 minor mode 的正式名稱
各個 mode 儲存 hook 的變數名稱一律是 「該 mode 的正式名稱 + -hook
」 ,例如想要在 python-mode
啟動時順便打開 highlight-symbol-mode
:
(add-hook 'python-mode-hook 'highlight-symbol-mode)
但上面這樣寫不太好。一般來說另外定義一個 function 是比較好、也非常常見的作法,像是這樣:
(defun my-c++-config ()
;; buffer-local variables 這類東西你就應該(基本上也只能)寫在 hook 裡
(add-to-list 'company-backends 'company-c-headers)
(setq flycheck-gcc-language-standard "c++11")
(setq flycheck-clang-language-standard "c++11")
;; ocal key-binding 的相關設定一起放在 hook 中是很常見的作法
(define-key c++-mode-map (kbd "C-c h") 'ff-find-other-file)
;; 這裡放一些希望隨著 C++ mode 自動啟動的 minor-mode
(flycheck-mode 1)
(rainbow-delimiters-mode-enable))
(add-hook 'c++-mode-hook 'my-c++-config)
雖然不太推薦(因為這樣會很難 remove-hook
),不過如果你很懶也可以寫成這樣啦:
(add-hook 'c++-mode-hook
(lambda () ; 爛打就是 Lisp 的 anonymous function 啦
(flycheck-mode 1)
(rainbow-delimiters-mode-enable)
;; 以下略
))
順帶一提,
prog-mode
是 programming 相關的絕大部分 major-mode 的 parent mode(例如python-mode
,perl-mode
,ruby-mode
…等等都是屬於prog-mode
,他們都會繼承prog-mode
的設定),所以你可以使用(add-hook 'prog-mode-hook ...)
之類的方式來自訂你想要的東西,而不用分別自訂各種程式語言的 mode,各種 mode 會自己繼承設定。
除了各個 minor-mode / major-mode 可以加 hook 外,Emacs 還有一些標準 hooks (Standard Hooks) 也是很常用到的(
add-hook
用法完全同上),例如:
- 檔案儲存前/後的
before-save-hook
與after-save-hook
- 關閉 buffer 前的
kill-buffer-hook
- 離開 Emacs 前的
kill-emacs-hook