从IDE到Emacs,到底做到什么程度值得?

先介绍一下我自己的情况,我是本科刚刚毕业半年,现供职于一家游戏开发公司。

在入职之前我已经长期使用Emacs作为我编写代码时的文本编辑器,也稍微涉猎了一些代码补全、代码跳转的功能扩展,在自己开发的小工程里,这些功能表现得基本让我满意。

入职以后,我主要负责客户端的工作,使用vs2010进行C/C++开发。公司的代码库很庞大而且复杂,至今我还没能弄清每一个模块的具体作用。因此使用Emacs进行代码补全或者跳转对我来说成为一件几乎不可能的事情。之前我使用semantic作为company的后端,但是用semantic需要手动配置工程信息到一个文件里,但对于一个我不熟悉的代码库,我真的不知道该如何去编写这个文件。

所以我试图寻求一个简单傻瓜的方法,我尝试了用clang作为company的后端,但是clang在有些最简单的地方表现得很糟糕。所以现在我更多的使用grep,这种原始的工具去定位我想要看的代码,速度很慢,但是至少一直可行。有的时候我甚至不得不打开VS,利用VS的跳转功能,找到代码所在位置,然后再用Emacs浏览。

这就是我现在面临的问题:当你的工作环境不适用于你现有的Emacs设置的时候,你该做多少努力去试图让一切在Emacs内部工作得井井有条?我昨天尝试了解了gtags, ctags但是这些基于tag的方法总是不能保证完美的实时性。而semantic不仅缓慢还容易出错,一旦解析失败,所有的一切都将不能工作。

仅就C/C++来说,现在是否有一个成熟的方法,能够将任何一个代码工程,迅速地在Emacs内打开,并在代码编写的时候提供一些IDE级别的辅助功能,包括但不限于:

  1. 代码补全
  2. 代码跳转 (1和2都依赖于对整个工程的结构信息的了解)
  3. 实时错误检查 (这个貌似可以用Flycheck)
1 个赞

论坛的头10贴里面有讲写 C/C++ 的插件,cquery 和lsp,可以看一下

谢谢你的回复。

我尝试了lsp,不过看起来lsp的补全和代码跳转还是依赖于tags。我安装了ctags,在代码工程的根目录下运行ctags -R -e要好久,生成了一个大小32M的TAGS文件,而每次修改该代码之后都要重新生成这一文件,这种方法效率未免太低。基于tags的方式是很精准易用,但是一旦代码有改动,事情就麻烦起来了。

用IDE

别折磨自己……虽然我也用Global(GNU的TAG系统)……

2 个赞

请阅读

可能我需要更新下我的文章了,稍旧 使用cquery:C++ language server | MaskRay

ripgrep 的 spacemacs SPC s D, SPC s P 等我也在用

1 个赞

但是IDE的文本编辑实在太痛苦了,vs2010还有emacs扩展,而2015就没有。

朋友,按照你的文章做了,不过在emacs启动后第一次调用lsp-cquery-enable的时候,返回错误:

Code/Trunk/: lsp-cquery has exited (exited abnormally with code 256)

我是在cygwin下使用emacs,language server是下载的预编译版本,因为我在编译时执行

$ git submodule update --init && ./waf configure build

时提示错误,大概意思是找不到cygwin平台的llvm预编译版本。

工程根目录下创建了.cquery文件,内容只有一行

clang++

然后用Emacs的包管理系统安装了lsp-mode, cquery, 在init.el中加入了

(setq cquery-executable "~/Downloads/cquery/bin/cquery")
(require 'cquery)

情况就是这样了,请帮忙看看哪里出问题了?

你的 bin/cquery 根本没有构建出来……怎么能期望 emacs-cquery 能用

./waf configure使用wscript,下载 releases.llvm.org prebuilt binary,但没有 cygwin 的。 你可以试试用 MSVC 或 msys2 编译 cquery/.appveyor.yml at master · jacobdufault/cquery · GitHub 有人提供 msys2 构建命令。Create new page · jacobdufault/cquery Wiki · GitHub 你如果折腾出来的话,请根据需要更新Wiki,publicly editable

我不用Windows,所以我不知道具体情况

echo clang++ > .cquery 这个做法是对的,你用 cl.exe 的话可能 echo clang-cl > .cquery 更合适(clang的cl.exe兼容模式--driver-mode=cl),会定义_MSC_VER等macro

(setq cquery-executable “~/Downloads/cquery/bin/cquery”) (require 'cquery)

这些都是对的

搭车问一下,cquery支持交叉编译的项目吗?

我没说清楚,因为编译没通过,所以我就下载里网页里 提供的预编译版本的cquery,然后init.el里面设置的也是预编译版本的程序的位置。这样也还是需要下载llvm的预编译版本吗?

因为预编译版本是linux的,所以实际上windows上跑不起来是吧……?

% ln -s /usr/bin/clang aarch64-unknown-linux-gnu-clang
% ./aarch64-unknown-linux-gnu-clang -E -v -dM -xc - < /dev/null

可以观察发现clang根据自己的argv0把target设置为aarch64-unknown-linux-gnu,并定义了 __AARCH64EL__等macro。所以我猜如果你能弄出

"arguments":["aarch64-unknown-linux-gnu-gcc",...]compile_commands.json,libclang能索引,进而cquery支持

如果难以弄出compile_commands.json的话echo aarch64-unknown-linux-gnu-g++ > .cquery,但C文件可能会被当作C++

你折腾出来后欢迎写到 https://github.com/cquery-project/cquery/wiki/compile_commands.json

谢谢回复,最近特别忙,没时间折腾,等闲一点的时候,如果还没有答案会折腾这个事情.

交叉编译的问题在于不同的项目会要求特定的编译器和特定的库.不知道cquery/lsp框架是否有足够的灵活性,可以针对不同的项目使用不同的编译环境,甚至可能同一个项目可能需要随时切换编译环境.

Windows Subsystem for Linux 不知道是否可以。

其他跨OS能运行Linux的有 FreeBSD

不知道特定编译器指什么。如果clang模拟不了的话就没救了。各大发行版发布的clang默认都是支持全targets的,你可以clang -target powerpc64le看效果。只是缺少 system C/C++ headers。

cross compile通常用gcc,你可以用那个target的gcc -v把隐含的 -isystem include path都加到 compile_commands.json/.cquery 里去

你如果想试简单例子的话 printf 'clang++\n-target\nmips64\n' > .cquery 观察

#ifdef __mips64
int good;
#else
int bad;
#endif

我可以不用waf直接用python运行wscript这个脚本吗?

python.exe waf configure

在windows的命令行下运行这个脚本会报检测不到stdio.h的错误,我装了VS2010,VS2017 Build Tools也确实有这个文件……但是脚本总是检测不到。

或许我们需要一个windows预编译版本……

还有个问题……如果我已经安装了clang和llvm,能不能把路径设定进去,这样就不需要下载了……

用VS 2017或者VSCode

说真的搞到现在我是有点服气了,用IDE确实是一种幸福……

我花了两天的时间,在论坛里找各种方法,很多emacs插件并没有特别好的使用说明,有些因为时间、平台的差异,已经难以复用……

现在看来,Emacs最大的优点在于它可以进行编程,进而方便地实现一些个人需求,而如果想要达到IDE那种人人都容易上手的易用程度,可能还是有点困难。另外,我觉得Emacs的威力大概正比于使用者的实力……我这种菜鸟还得多多学习。

我觉得emacs,以及类似的开源软件,"达到人人都能使用的程度"从来就不是他们的目标,他们的主要目标就是自己用着爽.

3 个赞