2018-07-07
This is now very out of date! Updated method here: click.
I've seen a lot of posts on the Emacs and C++ subreddits over the last few months related to Emacs as a C/C++ IDE. If one gives the topic a quick googling a lot of tutorials pop up that will walk through using cquery, lsp-mode, rtags, ggtags, irony, company, ycmd, etc. (obviously there are a number of options out there and multiple blog posts and tutorials for each). I've personally tried using cquery and rtags (both libclang based) in combination with company-mode. Playing with those packages produced a hacked up Emacs init file and I didn't really know what I was doing at the time. I was never comfortable with the black box I created for myself -- so I decided to clean it up and start over after some research.
I've recently landed on a new setup using a combination of lsp-mode, company, and lsp-clangd. As is clear from the package name and post title, this method takes advantage of the LLVM/Clang tool clangd (which is very much in development).
Here's a quick rundown of the new configuration:
Ensure that company-lsp
is installed and enable company-mode (I
choose a global configuration):
Ensure that lsp-mode
and lsp-ui
are installed and required:
Unfortunately lsp-clangd
isn't in melpa yet, so I cloned it to my
.emacs.d
directory and make sure to point to it (while writing this
post there is an open GitHub
PR to add lsp-clangd to
melpa). Be sure to set the proper clangd executable path and add a
hook to C++ mode to enable it:
Like I said, Clangd is under heavy development, so expect some
imperfections. For example, using the version shipped with the LLVM
6.0.0 release wasn't working with header files. I went ahead and built
a bleeding edge installation (using brew install --HEAD llvm
on
macOS and building from the trunk of their svn repositories on a
Fedora machine; read how to do that
here and that fixed the
problem.
I use this setup in combination with compile_commands.json
files
that are produced by
CMake.
This file must be kept at the project root (using
projectile with a
.projectile
file at the project root helps when using git
repositories with submodules; lsp-mode appears to handle that nicely).
I'm still by no means an expert, but it was a good learning experience and I no longer have a black box from copying and pasting from other's Emacs init files. I have code completion and inter/intra-project file and definition jumping -- the two big features I like to add to my C++ development setup in Emacs.