deep
1
首先先请教几个问题:
个人的日常工作主要以写c代码为主(90%以上时间),目前使用的是spacemacs,但是感觉对emacs功能的利用率可能不到10%,甚至不到1%,请问在spacemacs或emacs中:
- c模式是否可以做到修改.c文件中的函数定义时,.h文件对应的声明也跟着变化?
- c模式是否可以做到当调用了某一个函数时,可以自动或通过快捷键的方式包含对应的头文件?(能支持工程中的头文件最好,否则只支持标准库的也可以)。
- c模式是否可以像eclipse那样选择一个变量将其提取成局部变量,或将一段代码提取成一个函数?
题外话:目前编辑C代码的话,都有哪些公认的强大工具或功能插件?希望大家能够帮我推荐一下。
PS:个人是键盘党,目前我只知道emacs和vim(没用过 )可以在不碰鼠标且双手不离开打字区的情况下完成工作。
1 个赞
我的配置,我平时也用写一点 c,规模不大. init-c-c++.el
:
rtags
代替 ctag
gtag
实现 reference
, definition
等的跳转,irony-mode
改善 c/c++
的编码体验,cmake-ide
,cmake-mode
集成rtags
以及cmake
实现IDE 的build 和index.
;;; package --- Summary:
;;; Commentary:
;;; Code:
(use-package irony
:ensure t
:init (progn
(defun samray/irony-mode-hook ()
(define-key irony-mode-map [remap completion-at-point] 'counsel-irony)
(define-key irony-mode-map [remap complete-symbol] 'counsel-irony))
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'c-mode-hook 'irony-mode)
(add-hook 'irony-mode-hook 'samray/irony-mode-hook)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options))
)
(use-package clang-format
:ensure t
:commands (clang-format-region clang-format-buffer)
)
(use-package cmake-ide
:ensure t
:init (progn
(add-hook 'c++-mode-hook (lambda () (cmake-ide-setup)))
(add-hook 'c-mode-hook (lambda () (cmake-ide-setup)))
)
)
(use-package cmake-mode
:ensure t
:mode (
("CMakeLists\\.txt\\'" . cmake-mode)
("\\.cmake\\'" . cmake-mode)
))
(use-package rtags
:ensure t
:init (progn
(setq rtags-completions-enabled t)
(eval-after-load 'company
'(add-to-list
'company-backends 'company-rtags))
;; (setq rtags-autostart-diagnostics t)
(rtags-enable-standard-keybindings)
)
)
;;; Tell emacs to open .h file in C++ mode
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
(provide 'init-c-c++)
;;; init-c-c++.el ends here
使用flycheck
和flycheck-irony
做syntax check
init-syntax-check.el
;;; package --- Summary:
;;; Commentary:
;;; Code:
(use-package flycheck
:ensure t
:demand t
:config(progn
(setq flycheck-mode-line-prefix "FC")
(global-flycheck-mode t)))
(use-package flycheck-irony
:ensure t
:defer t
:init (progn
(add-hook 'flycheck-mode-hook #'flycheck-irony-setup)
))
(add-hook 'c++-mode-hook (lambda ()
(setq flycheck-clang-language-standard "c++11")
(setq irony-additional-clang-options '("-std=c++11"))
))
(provide 'init-syntax-checking)
;;; init-syntax-checking.el ends here
代码补全部分:company
驱动,其他的注释也挺清楚了
;;; C/C++ headers completion
(use-package company-c-headers
:ensure t
:defer t
:init (progn (add-hook 'c-mode-hook
(lambda () (add-to-list 'company-backends 'company-c-headers))
)
(add-hook 'c++-mode-hook
(lambda () (add-to-list 'company-backends 'company-c-headers)))
)
)
;;; backends for irony
(use-package company-irony
:ensure t
:defer t
:init (progn (add-hook 'c-mode-hook
(lambda () (add-to-list 'company-backends 'company-irony)))
(add-hook 'c++-mode-hook
(lambda () (add-to-list 'company-backends 'company-irony)))
))
;;; backends for irony-c-header
(use-package company-irony-c-headers
:ensure t
:defer t
:init (progn (add-hook 'c-mode-hook
(lambda () (add-to-list 'company-backends 'company-irony-c-headers)))
(add-hook 'c++-mode-hook
(lambda () (add-to-list 'company-backends 'company-irony-c-headers)))
))
我的 全部Emacs 配置
一位大佬的教程:
https://tuhdo.github.io/c-ide.html
好的,看了一些,配置都是依赖clang,但有些时候真不想用clang,因为很多服务器各种原因限制上安装特别麻烦,还有种思路是基于tags,感觉基于buffer的很不灵活,很多根本就没有补全啊
什么叫基于 buffer 的补全很不灵活? 不太理解你的意思,不基于 clang的补全也有,那是基于 tags
的补全,我见得比较多的就是像我上面提到的那位大佬那样,使用 ggtags
生成源文件和头文件的 symbol,进行补全和跳转的。而上面提到的 rtags
是根据编译器生成的 compile_command.json 来进行补全的(这个表述可能不准确,我没有详细了解过,大意是这样),不过对于大项目来说,有同学提到 rtags
性能会出现问题
对的,company补全看后端:
1,现在最好用的是clang,最智能,能识别变量,函数以及之间的关系;
2,比较死板的的就是基于tag,像ctags,gtags等都是基于分析代码,根据符号生成tag文件,但我觉得这个有个问题,一是他会查找tag中所有的符号,有时候我不需要那么多,另一个是tag文件是手动生成的,我定义一个新变量,后面马上用就没法补全了;
3,基于buffer就是分析当前buffer中的符号,相关信息应该是保存在内存中,提供补全机制。我了解的是company-dabbrev实现了这个功能。但是我在写c++代码时,写一个之前有过的变量时,完全没有补全提示,自己试了试,有些情况可以,有些不可以,所以我觉得比较难用。我用vscode和vim就没有这种问题。
- ctags blog.binchen.org 有隔段时间自动更新tags的代码,gtags我用spacemacs会自动生成tags,具体怎么做的没研究。
- dabbrev应该还是比较可靠的,不会动不动不行,看看
company-backends
是不是出了问题?
最近不大想用tags了,因为更好的lsp已经在敲门了。而且我现在不写服务端了,用不到XD
好的,多谢,我在研究研究。
lsp看起来很吊,但我觉得真正用起来也有挑战,C++补全本身就比较蛋疼,使用lsp我觉得还是要用clang来支持,但服务器和别人一起用,真的不想装软件或者更新,太麻烦了。
shaka
13
lsp很不错, 不过需要装cquery. 你可以搜索一下大牛MaskRay的贴子.
Samray
14
如果你服务器和别人一起用,我觉得你可以试试Emacs 的tramp,你在本地安装clang 等依赖,然后用本地的编辑器编辑服务器上的源码,我有时候就是这么做的。只不过我编辑的不是服务器的代码,是docker 里面的代码,因为docker 的镜像一般只有一个vi 编辑器
LLVM Download Page 下載預編譯 clang+llvm
spacemacs 默認 spacemacs-jump-handlers-c+±mode 的 dumb-mode 以前總是搗蛋,大項目很容易卡死
Samray
16
dumb-jump 是工作原理就是使用 rg/ag
进行搜索,然后匹配,没有半点语法或者语意上的分析,感觉性能还不如 ctags/ggtags
, 但是优点是简单易用,没有那么多的配置要求,不想 tags
系统那么折腾.
dumb-jump-go 是默認 jump handlers 裏的,其他選項 如果不移動point (比如 find-references 列出選項後你取消了) 那麼 dumb-jump 就會生效
我想看下你cquery的配置,上面的链接失效了,新链接可以给下么