Emacs as C++ IDE
Table of Contents
This guide is meant as supplement to Tudho's C/C++ Development Enivornment for Emacs Guide. It assumes you:
- Use CMake to build your projects
- Have Clang/LLVM installed
- Want to setup RTags and Irony
- Want to integrate RTags and Irony with Company.
Source code navigation using RTags
Prerequisites
- Build and install RTags using the RTags Quickstart Guide. Alternatively install RTags using your distribution's package manager.
- Install
rtags
from MELPA and add the following to your emacs init file:
(require 'rtags) (require 'company-rtags) (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)
To enable Helm integration add:
(require 'rtags-helm) (setq rtags-use-helm t)
Before using RTags
you need to start rdm and index your project. In
order to index your project, RTags requires you to export your
project's compile commands with cmake.
$ rdm & $ cd /path/to/project/root $ cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=1 $ rc -J .
We'll see how to automate this process with cmake-ide below.
Basic movements
- C-M-f runs
forward-sexp
, move forward over a balanced expression that can be a pair or a symbol. - C-M-b runs
backward-sexp
, move backward over a balanced expression that can be a pair or a symbol. - C-M-k runs
kill-sexp
, kill balanced expression forward that can be a pair or a symbol. - C-M-<SPC> or C-M-@ runs
mark-sexp
, put mark after following expression that can be a pair or a symbol. - C-M-a runs
beginning-of-defun
, which moves point to beginning of a function. - C-M-e runs
end-of-defun
, which moves point to end of a function. - C-M-h runs
mark-defun
, which put a region around whole current or following function.
Find definitions in project
- C-c-r . runs
rtags-find-symbol-at-point
, which jumps to the definition of the symbol under the cursor.
Find references in project
- C-c-r . runs
rtags-find-references-at-point
, which lists all references to the symbol under the cursor. - C-c-r < runs
rtags-find-references
, which prompts for the symbol name and finds all references. - C-c-r > runs
rtags-find-symbol
, which prompts for symbol name and finds all references.
Find files in project
- C-c r ; runs
rtags-find-file
, which prompts for file name to search for out of currently indexed files.
Alternatively, this can be better accomplished with Projectile.
Source code completion using Irony
Prerequisites
- Install
irony-mode
from MELPA and add the following to your emacs init file:
(add-hook 'c++-mode-hook 'irony-mode) (add-hook 'c-mode-hook 'irony-mode) (add-hook 'objc-mode-hook 'irony-mode) (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)
NOTE: Like RTags, Irony requires a compilation database. To create one run the following:
$ cd /path/to/project/root $ cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=1
The first time you run irony you must install the irony-server by runing
the command: M-x irony-install-server
Using Company with Irony
To use company-mode
with Irony:
- Install
company-irony
from melpa and add the following to your emacs init file:
(add-hook 'irony-mode-hook 'company-irony-setup-begin-commands) (setq company-backends (delete 'company-semantic company-backends)) (eval-after-load 'company '(add-to-list 'company-backends 'company-irony))
If you want to enable tab-completion with no delay use the following:
(setq company-idle-delay 0) (define-key c-mode-map [(tab)] 'company-complete) (define-key c++-mode-map [(tab)] 'company-complete)
Header file completion with company-irony-c-headers
To add support for completing C++ headers:
- Install
company-irony-c-headers
from MELPA - Remove the following to your emacs init file:
(eval-after-load 'company '(add-to-list 'company-backends 'company-irony))
- Add the following to your emacs init file:
(require 'company-irony-c-headers) (eval-after-load 'company '(add-to-list 'company-backends '(company-irony-c-headers company-irony)))
Syntax checking with Flycheck
Prerequisites
- Install
flycheck
from MELPA and add the following to your emacs init file:
(add-hook 'c++-mode-hook 'flycheck-mode) (add-hook 'c-mode-hook 'flycheck-mode)
Integrating RTags with Flycheck
To enable RTags and flycheck integration add the following to your emacs init file:
(require 'flycheck-rtags) (defun my-flycheck-rtags-setup () (flycheck-select-checker 'rtags) (setq-local flycheck-highlighting-mode nil) ;; RTags creates more accurate overlays. (setq-local flycheck-check-syntax-automatically nil)) ;; c-mode-common-hook is also called by c++-mode (add-hook 'c-mode-common-hook #'my-flycheck-rtags-setup)
Integrating Irony with Flycheck
- Install
flycheck-irony
from MELPA and add the following to your emacs init file:
(eval-after-load 'flycheck '(add-hook 'flycheck-mode-hook #'flycheck-irony-setup))
CMake automation with cmake-ide
Prerequisites
- Install
cmake-ide
from MELPA and add the following to your emacs init file:
(cmake-ide-setup)
Using cmake-ide
To have cmake-ide automatically create a compilation commands file in your project root create a .dir-locals.el containing the following:
((nil . ((cmake-ide-build-dir . "<PATH_TO_PROJECT_BUILD_DIRECTORY>"))))
You can now build your project using M-x
cmake-ide-compile
. Additionally, cmake-ide will automatically update
your RTags index as well.