Emacs 中 C/C++ 編程基本環境配置

這篇文章本來是『走近 Emacs』的內容,當時由於考慮到 Emacs 的用戶未必寫 C/C++ 代碼,因此就將它隔離了出來。前端

當你用 Emacs 打開或新建一份擴展名爲 .c 的文件時,Emacs 會自動開啓內置的 C 模式。這個模式提供了語法高亮、自動縮進等基本功能。同時 Emacs 也容許用戶深度定製符合本身使用習慣的代碼編輯功能,前提是你須要對 Emacs Lisp 擴展語言有必定了解。linux

C/C++ 代碼編輯基本配置

若是你不熟悉也不打算學習 Emacs Lisp 語言,那就只能將他人寫好的配置代碼扔到 $HOME/.emacs$HOME/.emacs.d/init.el 文件中。如今推薦使用後者做爲 Emacs 的配置文件。c++

不少年前我從一個我忘記了他的網絡 ID 的傢伙那裏抄來一段 C 代碼的配置:程序員

;;;; c mode ;;;;
(defvar xgp-cfsi-left-PAREN-old nil
  "Command used to input \"(\"")
(make-variable-buffer-local 'xgp-cfsi-left-PAREN-old)

(defun xgp-cfsi-modify-alist (alist term new)
  (let ((tl (assq term (symbol-value alist))))
    (if tl
        (setcdr tl new)
      (add-to-list alist (cons term new)))))

(defun xgp-cfsi (style)
  "Deciding whether using CFSI."
  (interactive "Style: ")
  (c-set-style style)
  (setq indent-tabs-mode
        nil
        c-hanging-semi&comma-criteria
        (quote (c-semi&comma-inside-parenlist)))

  (xgp-cfsi-modify-alist 'c-hanging-braces-alist 'class-open nil)
  (xgp-cfsi-modify-alist 'c-hanging-braces-alist 'class-close nil)
  (local-set-key " " 'self-insert-command))

(defun xgp-cfsi-erase-blanks ()
  "Erase all trivial blanks for CFSI."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "[ \t]+$" nil t)
      (replace-match "" nil nil))))

(defun linux-c-mode()
  (define-key c-mode-map [return] 'newline-and-indent)
  (setq imenu-sort-function 'imenu--sort-by-name)
  (interactive)
  (imenu-add-menubar-index)
  (which-function-mode)
  (c-toggle-auto-state)
  (c-toggle-hungry-state)
  (setq indent-tabs-mode nil)
  (xgp-cfsi "linux"))
(add-hook 'c-mode-common-hook 'linux-c-mode)

這樣配置以後,C/C++ 代碼編輯功能會強大一些。例如,敲擊 Backspace 鍵能夠連續刪除多行空行;在代碼行尾鍵入 ; 會自動換行;代碼縮進長度變爲 8 個空白字符……這些配置,我用了不少年,到如今也不知道它具體都作了些什麼。正則表達式

C++ 的代碼,由於我平時寫的不太多,因此沒做配置。不過上述的 C 模式配置的這些功能,也適合 C++ 代碼的編輯。segmentfault

C/C++ 代碼自動提示

你如今所用的 Emacs 版本應該是 >= 24,若是不是,想辦法升級吧。不然本節內容不太適合你閱讀,除非你懂得如何手動安裝 Emacs 擴展包。bash

若是用過 Visual C++.net 或者 Eclipse,想必會對它們的代碼編輯器提供的代碼自動提示功能念念不忘,於是抱怨 Emacs 的 C 模式未提供此功能。事實上是有的,可是要實現 C/C++ 代碼的自動提示,這須要 Emacs 懂得如何去解析 C/C++ 代碼,似這類繁重又專業的任務讓一個文本編輯器來作,不合常理,更況且 Emacs 並不是 C/C++ 程序員的專用編輯器。網絡

Emacs 可以作到的事情必需要與文本編輯直接相關,可是它有能力藉助其餘工具彌補自身不足。像 C/C++ 代碼分析這樣的任務,交給一個專業的 C/C++ 編譯器最好不過了。雖然藉助咱們所熟悉的 gcc 是可行的,但它不如另外一款編譯前端 clang 好用,由於後者在設計時就考慮到了與代碼編輯器的整合。編輯器

安裝 clang

咱們所要作的首先是想辦法安裝 clang。Gentoo Linux 用戶只需:ide

$ sudo emerge -avt clang

而後先去幹別的事吧,clang 畢竟是 C++ 寫的 C/C++ 編譯器,是個挺大的項目,編譯耗時會挺長,長的我都忘記了到底須要多久,彷佛比編譯 libreoffice 或者 firefox 快一些。

安裝 company

Emacs 自己是沒法與 clang 溝通的,可是 Emacs Lisp 能夠強大到容許 Emacs 用戶自行編寫擴展包以實現 Emacs 與 clang 的溝通。因而就有人寫出了 company 這個擴展包。

在 Emacs 24 以前的時代,要爲 Emacs 安裝擴展包,須要從網絡上下載擴展包,而後複製到 Emacs 所能搜索到的目錄,最後在 Emacs 配置文件中對擴展包進行配置。

從 Emacs 24 開始,Emacs 對擴展包進行統一管理,極大程度上簡化了擴展包的搜索與安裝過程。打開 Emacs,而後執行 M-x list-packages ,若是網速足夠快,應該很快就能看到 Emacs 官方提供的擴展包列表。

待軟件包列表出現後,執行 C-s M-r ^ +company ,回車便可讓光標跳到 company 擴展包信息所在的文本行,繼而敲擊 i 鍵(表示要安裝該擴展包),再敲擊 x 鍵(表示執行安裝過程),稍等片刻,Emacs 會自動從下載 company 擴展包並安裝至 $HOME/.emacs.d 目錄。

提示:C-s 是開啓 Emacs 查找模式, M-r 是將查找模式切換爲正則表達式查找模式,而 ^ +companyy 是用於匹配『位於行首且由多個空格與 company 字符串構成的字符串』的正則表達式。

若是之後要刪除 company 擴展,步驟與安裝步驟相似,只是將 i 鍵替換爲 d 鍵(表示刪除)。

配置 company

company 安裝完畢後,在 Emacs 配置文件中作如下配置:

;; 代碼補全
(add-hook 'c-mode-hook 'company-mode)
(add-hook 'c++-mode-hook 'company-mode)

這樣即可將 company 掛接到 Emacs C 模式上。這樣,每當 Emacs 打開 C/C++ 文件時company 模式便會被自動開啓。

下圖是 company 與clang 成功『溝通』後的結果:

company 的代碼自動提示

因爲 clang 默認會去 Linux 標準目錄 /usr/include 中去搜索庫的頭文件,可是有些庫的頭文件是安裝在非標準位置的。例如 PCL 庫的頭文件,默認安裝在 usr/include/pcl-1.7,若要對 PCL 庫函數進行自動補全,那麼就須要將這個路徑告訴 clang。eigen 庫也存在這個問題。解決方法是在項目源碼的頂層目錄下建立 .dir-locals.el 文件,內容相似於:

((nil . ((company-clang-arguments . ("-I/usr/include/pcl-1.7/"
                                     "-I/usr/include/eigen3/")))))

若是誰有更好的讓 clang 自動搜索庫的頭文件路徑的方法,還請不吝賜教。

相關文章
相關標籤/搜索