代码补全

company + irony on llvm

最近看emacs-devel里面关于IDE的讨论,有人提到semantic和irony-mode,分别尝试了一下,配置起来都很复杂,其中semantic无法补全LLVM里面的SmallVector,发信到邮件列表求帮助,暂时没有反馈。于是又试了irony-mode,折腾了好几天,才从log里面发现libclang couldn’t parse这样的错误信息,试了一下,原来是我们的项目用gcc编译没问题,用clang编译报错。改正之后就能正常工作了,补全信息非常准确,唯一的不足就是慢,尤其是第一次补全,要等十几秒,可能是LLVM的文件都比较大吧。

上图的效果是配合company-mode使用(单独使用irony-mode的话,使用C-M-i补全),需要分别下载company-mode, irony-mode, 和company-irony。我的配置如下:

(require 'company)
(add-hook 'c++-mode-hook 'company-mode)
(add-hook 'c-mode-hook 'company-mode)

;;; irony-mode

(add-to-list 'load-path "~/elisp/3rd-party-lib/irony-mode/")
(require 'irony)
(require 'irony-cdb)
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'c-mode-hook 'irony-mode)

(add-to-list 'load-path "~/elisp/3rd-party-lib/company-irony/")
(require 'company-irony)
(eval-after-load 'company
  '(progn
     (setq company-idle-delay 3)
     (add-to-list 'company-backends 'company-irony)))

;; replace the `completion-at-point' and `complete-symbol' bindings in
;; irony-mode's buffers by irony-mode's function
(defun my-irony-mode-hook ()
  (define-key irony-mode-map [remap completion-at-point]
    'irony-completion-at-point-async)
  (define-key irony-mode-map [remap complete-symbol]
    'irony-completion-at-point-async))
(add-hook 'irony-mode-hook 'my-irony-mode-hook)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)

(require 'irony-cdb-json)
(irony-cdb-json-add-compile-commands-path
 "~/src/llvm/trunk"
 "~/src/llvm/trunk/build/compile_commands.json")

需要最后一句手工配置LLVM项目是因为irony找不到compile_commands.json文件。产生这个文件的方法是添加一个cmake宏:-DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Stack overflow in regexp matcher

在Emacs里面使用gdb-many-windows调试,非常方便。但是有时候碰到复杂的局部变量,gdb-mi会无法显示,并报错:Stack overflow in regexp matcher。

不能显示局部变量问题不大,大不了手工使用p命令。问题是之后gdb-mi的状态就乱掉了,无法继续调试,非常烦人。

终于,使用下面的patch,一切都平静了……

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 27846ed..d147b82 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -4022,7 +4022,7 @@ member."
 ;; Don't display values of arrays or structures.
 ;; These can be expanded using gud-watch.
 (defun gdb-locals-handler-custom ()
-  (let ((locals-list (bindat-get-field (gdb-json-partial-output) 'locals))
+  (let ((locals-list (bindat-get-field (ignore-errors (gdb-json-partial-output)) 'locals))
         (table (make-gdb-table)))
     (dolist (local locals-list)
       (let ((name (bindat-get-field local 'name))