本来自己的Emacs配置文件,是直接克隆的purcell的,然后又加入了一些自己的设定,结果导致现在的配置文件越来越臃肿,而且很多配置项发生了冲突,很多自己不需要的功能的配置,开始占用自己的精力。
所以,决定重新配置自己的Emacs。
从零开始,一项一项梳理,只保留自己需要的,自己用不到的一个也不加。
本文先整理出来编译代码相关的部分。大量来自purcell或者其它网友的配置,少量自己的定义。
编译之前
- 自定义编译命令,把编译窗口减小一点。同时,编译完成还回到原来窗口。
lisp
(defun my-compile ()
"Run compile and resize the compile window."
(interactive)
(save-buffer)
(call-interactively 'compile)
(let* ((cur (selected-window))
(win (get-buffer-window "*compilation*")))
(select-window win)
(shrink-window-horizontally 10)
(select-window cur)))
- 复用编译窗口
lisp
;; 编译buffer变量
(defvar sanityinc/last-compilation-buffer nil
"The last buffer in which compilation took place.")
;; 编译时自动保存编译buffer变量
(with-eval-after-load 'compile
(defun sanityinc/save-compilation-buffer (&rest _)
"Save the compilation buffer to find it later."
(setq sanityinc/last-compilation-buffer next-error-last-buffer))
(advice-add 'compilation-start :after 'sanityinc/save-compilation-buffer)
;; 编译前先查找是否编译buffer变量存在,而且可用
(defun sanityinc/find-prev-compilation (orig &optional edit-command)
"Find the previous compilation buffer, if present, and recompile there."
(if (and (null edit-command)
(not (derived-mode-p 'compilation-mode))
sanityinc/last-compilation-buffer
(buffer-live-p (get-buffer sanityinc/last-compilation-buffer)))
(with-current-buffer sanityinc/last-compilation-buffer
(funcall orig edit-command))
(funcall orig edit-command)))
;; 添加编译前查找为recompile命令的advice
(advice-add 'recompile :around 'sanityinc/find-prev-compilation))
编译中
- 使用ansi-color显示编译过程中的颜色标识
lisp
(with-eval-after-load 'compile
(require 'ansi-color)
;; 动态颜色显示区域回调函数
(defun sanityinc/colourise-compilation-buffer ()
(when (eq major-mode 'compilation-mode)
(ansi-color-apply-on-region compilation-filter-start (point-max))))
;; 添加为回调
(add-hook 'compilation-filter-hook 'sanityinc/colourise-compilation-buffer))
- 设定自动滚动编译输出
lisp
(setq-default compilation-scroll-output t)
编译之后
- 使用alert通知编译结果
lisp
(require-package 'alert)
(defun sanityinc/alert-after-compilation-finish (buf result)
"Use `alert' to report compilation RESULT if BUF is hidden."
(when (buffer-live-p buf)
(unless (catch 'is-visible
(walk-windows (lambda (w)
(when (eq (window-buffer w) buf)
(throw 'is-visible t))))
nil)
(alert (concat "Compilation " result)
:buffer buf
:category 'compilation))))
(with-eval-after-load 'compile
(add-hook 'compilation-finish-functions
'sanityinc/alert-after-compilation-finish))
- 如果编译的buffer没有位于多窗口中,切换到其它buffer;否则,关闭窗口。
lisp
(defun my-compile-exit (&optional buffer)
"Exit compile BUFFER."
(interactive)
(if (one-window-p t)
(progn
(projectile-project-buffers-other-buffer))
(progn
(delete-window (get-buffer-window buffer)))))
- 跳转到第一个错误。如果没有错误,调用前面定义的退出buffer。
lisp
(defun goto-first-error-or-exit (buffer string)
"Call exit BUFFER when no errors."
(interactive)
(with-current-buffer buffer
(goto-char (point-min))
(condition-case err
(compilation-next-error 1)
(error
(run-with-timer 1 nil
(lambda (buf)
(my-compile-exit buf))
buffer)))))
- 编译完成自动执行前面定义的跳转或者关闭。
lisp
(add-hook 'compilation-finish-functions 'goto-first-error-or-exit)
其中,关闭编译buffer之前等待1秒钟,方便简单留意一下编译信息。
- 给编译窗口加几个快捷键
lisp
(add-hook 'compilation-mode-hook
(lambda ()
(local-set-key (kbd "n") 'compilation-next-error)
(local-set-key (kbd "p") 'compilation-previous-error)
(local-set-key (kbd "q") (lambda ()
(interactive)
(my-compile-exit (current-buffer))))))
其中,p跳转到前面一个错误,n跳转到后面一个错误,q退出。
CMake相关
因为很多项目使用Cmake做的构建系统,所以CMake相关的配置,也一并整理到编译相关的配置里。
- 关联CMake配置文件为cmake-mode
lisp
(setq auto-mode-alist
(append '(("CMakeLists\\.txt\\'" . cmake-mode)
("\\.cmake\\'" . cmake-mode))
auto-mode-alist))
- 添加cmake的自动补全
lisp
(add-hook 'cmake-mode-hook
(lambda()
(add-to-list 'company-backends 'company-cmake)))
快捷键绑定
在cc-mode的模式下,使用Ctrl-x c编译;使用F7重编译。
lisp
(with-eval-after-load 'cc-mode
(define-key c-mode-base-map (kbd "C-x c") 'my-compile)
(define-key c-mode-base-map (kbd "<F7>") 'recompile))