There are a lot of blog-posts how to add C++ support to Emacs. But i would like to share my personal configuration, because it took my some time to get it working properly. I tested this tutorial on macOS, but added some notes on how to do it on linux based systems.

First of all you need the following packages/tools:

ycmd (the server-part)

And the following Emacs packages:

emacs-ycmd (the client)

company-mode (text completion framework for Emacs)

(text completion framework for Emacs) company-ycmd (company-mode client for emacs-ycmd)

yasnippet (for snippets)

flycheck (on-the-fly syntax checking extension for Emacs)

(on-the-fly syntax checking extension for Emacs) flycheck-ycmd (flycheck client for emacs-ycmd)

eldoc (to show the argument list in the echo area)

Install requirements

So let’s install ycmd first:

Install the dependencies On debian-based systems: sudo apt-get install build-essential cmake python-dev On macOS: xcode-select --install and install cmake with homebrew

Clone the ycmd-repo and run git submodule update --init --recursive in the repo-folder.

Now you can build ycmd for C-family languages: ./build.py --clang-completer

Configure Emacs

To make completion work in Emacs (including snippet-completion), we need the following configuration in our init.el .

;; Snippets ( use-package yasnippet :ensure t :diminish yas-minor-mode :init ( yas-global-mode t )) ;; Autocomplete ( use-package company :defer 10 :diminish company-mode :bind ( :map company-active-map ( "M-j" . company-select-next ) ( "M-k" . company-select-previous )) :preface ;; enable yasnippet everywhere ( defvar company-mode/enable-yas t "Enable yasnippet for all backends." ) ( defun company-mode/backend-with-yas ( backend ) ( if ( or ( not company-mode/enable-yas ) ( and ( listp backend ) ( member 'company-yasnippet backend ))) backend ( append ( if ( consp backend ) backend ( list backend )) ' ( :with company-yasnippet )))) :init ( global-company-mode t ) :config ;; no delay no autocomplete ( validate-setq company-idle-delay 0 company-minimum-prefix-length 2 company-tooltip-limit 20 ) ( validate-setq company-backends ( mapcar #' company-mode/backend-with-yas company-backends )))

Now you should have some basic auto-completion in all buffers.

To get C++-completion you now need to install the ycmd-client for emacs.

;; Code-comprehension server ( use-package ycmd :ensure t :init ( add-hook 'c++-mode-hook #' ycmd-mode ) :config ( set-variable 'ycmd-server-command ' ( "python2" "/path/to/ycmd/ycmd" )) ( set-variable 'ycmd-global-config ( expand-file-name "~/path/to/ycmd/ycm_conf.py" )) ( set-variable 'ycmd-extra-conf-whitelist ' ( "~/Repos/*" )) ( use-package company-ycmd :ensure t :init ( company-ycmd-setup ) :config ( add-to-list 'company-backends ( company-mode/backend-with-yas 'company-ycmd ))))

This configuration adds a hook to c++-mode and enables ycmd-mode . You need to adjust your paths to ycmd (the server-part which you installed earlier) and the ycm_conf.py inside the server-repo.

You may want to configure a whitelist of paths, where ycmd is allowed to load project-specific configurations, but we will get to this later.

For on-the-fly syntax checking, you need to install flycheck and flycheck-ycmd .

;; On-the-fly syntax checking ( use-package flycheck :ensure t :diminish flycheck-mode :init ( global-flycheck-mode t )) ( use-package flycheck-ycmd :commands ( flycheck-ycmd-setup ) :init ( add-hook 'ycmd-mode-hook 'flycheck-ycmd-setup ))

ElDoc shows the argument list of a function in the echo area.

;; Show argument list in echo area ( use-package eldoc :diminish eldoc-mode :init ( add-hook 'ycmd-mode-hook 'ycmd-eldoc-setup ))

Configure ycmd for a complex project

ycmd now works just fine for simple project. But as soon as you start using external libraries or something like this, you need a specific configuration-file for ycmd . Using YCM-Generator, you can generate such a configuration for you project.

Clone the repository and add config_gen.py in you $PATH .

Now you can change into your project and run config_gen.py . to generate a .ycm_extra_conf.py Take a look into this configuration file and make sure the generator did a good job. There is an array with flags at the top of the file. For C++ projects you may want to have something like this:

flags = [ '-std=c++14' , '-x' , 'c++' , /// '-I /path/to/include' ... ]

You can run M-x ycmd-show-debug-info to check, if your setup works.

For other configurations, take a look at my init.el. If have trouble configuring you emacs using this blog-post, please let me know!