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:
And the following Emacs packages:
company-mode(text completion framework for Emacs)
company-ycmd(company-mode client for emacs-ycmd)
flycheck(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)
So let’s install
- Install the dependencies
- On debian-based systems:
sudo apt-get install build-essential cmake python-dev
- On macOS:
xcode-select --installand install
- On debian-based systems:
Clone the ycmd-repo and run
git submodule update --init --recursivein the repo-folder.
- Now you can build
ycmdfor C-family languages:
To make completion work in Emacs (including snippet-completion), we need the following configuration in our
;; 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
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
;; 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
Using YCM-Generator, you can generate such a configuration for you project.
Clone the repository and add
config_gen.py in you
Now you can change into your project and run
config_gen.py . to generate a
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!