Skip to content

Latest commit

 

History

History
102 lines (71 loc) · 5.34 KB

05-設定檔相關的基本概念.org

File metadata and controls

102 lines (71 loc) · 5.34 KB

設定檔

Emacs 是個非常吃重設定檔的編輯器,這一篇會為您解答最常遇到的一些問題。

基本問題

我裝好 Emacs 了,但我沒看到使用者設定檔啊?

很多系統不會為使用者事先建立設定檔,要自己手動建立。 方法是在 ~/ (家目錄)下建立一個叫 .emacs.d 的目錄,並在裡面開一個叫 init.el 的檔案。

建議把一切 Emacs 相關設定分門別類整理好存放在 .emacs.d 中,盡量不要全部擠到 .emacs.d/init.el ,因為整理起來會很麻煩。

可以參考 kanrukuanyui (不才在下) 的 .emacs.d 目錄結構來整理。

– ono hiroko

但 Windows 下, ~/ 的實際目錄到底在哪裡?」

這也是個曾經讓我很困惑的問題。總之,最簡單的得知方法是 M-x customize 後,按”Apply and Save”,你會看到畫面下方的 minibuffer 寫著一串路徑,就是那個了。

另一個方法是,按 C-x C-f 後,輸入 ~ ,就可以切到實際的 ~ 目錄內。

我該使用 ~/.emacs 當作我的設定檔,還是 ~/.emacs.d/init.el ?」

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 啟動時執行一些東西

需要在啟用某個 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-hookafter-save-hook
  • 關閉 buffer 前的 kill-buffer-hook
  • 離開 Emacs 前的 kill-emacs-hook

Standard hooks 的完整列表請參閱官方文件