From WikEmacs
Jump to navigation Jump to search

C/C++ Development Environment for Emacs

In this guide, I will help you to setup an efficient working C/C++ environment. Despite looking long, the setup is short and easy (mostly copy/paste Emacs Lisp code into your init.el); most of the guide are explanations and demonstrations of many useful features. Following this guide, you should be able to browse the Linux kernel source tree inside Emacs effortlessly, such as jump to definition/references at cursor, go back and forth between jumping points, finding any file instantly, switching between .h and .c/.cpp. We include demos in the end.

Source code navigation

Install GNU Global

Install GNU Global:

   apt-get install global 

Or get the sources here and for windows users, get the win32 port.

Install ggtags from MELPA and add this snippet to your init file:

(require 'ggtags)
(add-hook 'c-mode-common-hook
          (lambda ()
            (when (derived-mode-p 'c-mode 'c++-mode 'java-mode 'asm-mode)
              (ggtags-mode 1))))

And define some keybinding if you wish:

(define-key ggtags-mode-map (kbd "C-c g s") 'ggtags-find-other-symbol)
(define-key ggtags-mode-map (kbd "C-c g h") 'ggtags-view-tag-history)
(define-key ggtags-mode-map (kbd "C-c g r") 'ggtags-find-reference)
(define-key ggtags-mode-map (kbd "C-c g f") 'ggtags-find-file)
(define-key ggtags-mode-map (kbd "C-c g c") 'ggtags-create-tags)
(define-key ggtags-mode-map (kbd "C-c g u") 'ggtags-update-tags)

(define-key ggtags-mode-map (kbd "M-,") 'pop-tag-mark)

Use helm-gtags

helm is a nice interactive interface to many tools, so helm-gtags is very handy. Remember to setup Helm before using helm-gtags. When includes the above file in your ~/.emacs.d, remember to add (require 'setup-helm) to your init.el.

Basic config:

 helm-gtags-ignore-case t
 helm-gtags-auto-update t
 helm-gtags-use-input-at-cursor t
 helm-gtags-pulse-at-cursor t
 helm-gtags-prefix-key "\C-cg"
 helm-gtags-suggested-key-mapping t

(require 'helm-gtags)
;; Enable helm-gtags-mode
(add-hook 'dired-mode-hook 'helm-gtags-mode)
(add-hook 'eshell-mode-hook 'helm-gtags-mode)
(add-hook 'c-mode-hook 'helm-gtags-mode)
(add-hook 'c++-mode-hook 'helm-gtags-mode)
(add-hook 'asm-mode-hook 'helm-gtags-mode)

And some keybindings:

(define-key helm-gtags-mode-map (kbd "C-c g a") 'helm-gtags-tags-in-this-function)
(define-key helm-gtags-mode-map (kbd "M-s") 'helm-gtags-select)
(define-key helm-gtags-mode-map (kbd "M-.") 'helm-gtags-dwim)
(define-key helm-gtags-mode-map (kbd "M-,") 'helm-gtags-pop-stack)
(define-key helm-gtags-mode-map (kbd "C-c <") 'helm-gtags-previous-history)
(define-key helm-gtags-mode-map (kbd "C-c >") 'helm-gtags-next-history)

Create the tags

Before using the ggtags or helm-gtags, remember to create a GTAGS database by running the command ggtags-create-tags .

Or run gtags at your project root in terminal:

   $ cd /path/to/project/root
   $ gtags

After this, 3 files are created:

  • GTAGS: definition database
  • GRTAGS: reference database
  • GPATH: path name database


  • 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 is end-of-defun.
  • C-M-h runs mark-defun, which put a region around whole current or following function.

Find definitions in current buffer

The Imenu facility offers a way to find the major definitions, such as function definitions, variable definitions in a file by name. ggtags can integrate Imenu:

   (setq-local imenu-create-index-function #'ggtags-build-imenu-index)

If you use Helm, use helm-semantic-or-imenu. You can use it as an outline tree like in other IDEs.

Find definitions in project

Using gtags: by default, M-. runs ggtags-find-tag-dwim when ggtags-mode is enabled. The command ggtags-find-tag-dwim jump to tag base on context:

  • If the tag at point is a definition, ggtags jumps to a reference. If there is more than one reference, it displays a list of references.
  • If the tag at point is a reference, ggtags jumps to tag definition.
  • If the tag at point is an include header, it jumps to that header.

You can jump back to original location where you invoked ggtags-find-tag-dwim by M-,, which runs pop-tag-mark (if you follow my key bindings).

You can also find arbitrary tag definition when invoking M-. on blank space. A prompt asks you for tag pattern, which is a regexp.

If ggtags gives you a list of candidates, you can use M-n to move to next candidate and M-p to move back previous candidate. Use M-g s to invoke Isearch on candidate buffer list

Using helm-gtags: If key bindings are properly setup as above, M-. runs helm-gtags-dwim, which behaves the same as ggtags-find-tag-dwim. Similarly, you jump back to original location by using M-,, which runs tags-loop-continue (Emacs default).

helm-gtags provides a really nice feature that uses Helm to display all available tags in a project and incrementally filtering, and is really fast using helm-gtags-select, which is bound to M-s in my setup above. This is useful when you want to explore tags in unfamiliar project.

Find references in project

Using helm-gtags: Either run helm-gtags-dwim or helm-gtags-find-rtags, bound to C-c g r, which only finds references.

Find functions that current functions call

If you want to list all the functions that the current function - the function that point is inside - calls, you can do that with helm-gtags-tags-in-this-function, which is bound to C-c g a in my setup.

Find files in project

Using projectile

projectile is a very nice and complete solution.

Using ggtags

Run ggtags-find-file

Browse source tree with Speedbar file browser

You can use many packages for that, such as speedbar or sr-speedbar (in MELPA) to have the tree in the same frame.

General completion with company-mode

See company-mode.

Besides, company-c-headers provides auto-completion for C/C++ headers using Company. After installing from MELPA, set it up:

   (add-to-list 'company-backends 'company-c-headers)



Project management with EDE


See also

The source of this page with many demos: http://tuhdo.github.io/c-ide.html