2017-06-08 11:47:56 +02:00
|
|
|
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
|
2015-06-15 09:06:10 +02:00
|
|
|
|
2017-12-27 17:10:21 -05:00
|
|
|
(defvar +cc-default-include-paths (list "include/")
|
|
|
|
"A list of default paths, relative to a project root, to search for headers in
|
|
|
|
C/C++. Paths can be absolute. This is ignored if your project has a JSON
|
|
|
|
compilation database.")
|
2017-09-19 05:06:50 +02:00
|
|
|
|
2017-12-27 17:10:21 -05:00
|
|
|
(defvar +cc-default-compiler-options
|
2017-09-19 05:06:50 +02:00
|
|
|
`((c-mode . nil)
|
|
|
|
(c++-mode
|
|
|
|
. ,(list "-std=c++11" ; use C++11 by default
|
|
|
|
(when IS-MAC
|
|
|
|
;; NOTE beware: you'll get abi-inconsistencies when passing
|
2017-09-20 14:25:35 +02:00
|
|
|
;; std-objects to libraries linked with libstdc++ (e.g. if you
|
|
|
|
;; use boost which wasn't compiled with libc++)
|
2017-09-19 05:06:50 +02:00
|
|
|
(list "-stdlib=libc++"))))
|
|
|
|
(objc-mode . nil))
|
|
|
|
"A list of default compiler options for the C family. These are ignored if a
|
|
|
|
compilation database is present in the project.")
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;; Plugins
|
|
|
|
;;
|
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! cc-mode
|
2015-06-15 09:06:10 +02:00
|
|
|
:commands (c-mode c++-mode objc-mode java-mode)
|
2016-05-12 22:11:43 -04:00
|
|
|
:mode ("\\.mm" . objc-mode)
|
2017-09-20 01:34:47 +02:00
|
|
|
:preface
|
|
|
|
(defun +cc-c++-header-file-p ()
|
2017-06-23 18:13:33 +02:00
|
|
|
(and buffer-file-name
|
|
|
|
(equal (file-name-extension buffer-file-name) "h")
|
|
|
|
(or (file-exists-p (expand-file-name
|
|
|
|
(concat (file-name-sans-extension buffer-file-name)
|
|
|
|
".cpp")))
|
2017-12-10 14:49:52 -05:00
|
|
|
(when-let* ((file (car-safe (projectile-get-other-files
|
|
|
|
buffer-file-name
|
|
|
|
(projectile-current-project-files)))))
|
2017-06-23 18:13:33 +02:00
|
|
|
(equal (file-name-extension file) "cpp")))))
|
|
|
|
|
2017-09-20 01:34:47 +02:00
|
|
|
(defun +cc-objc-header-file-p ()
|
2017-06-23 18:13:33 +02:00
|
|
|
(and buffer-file-name
|
|
|
|
(equal (file-name-extension buffer-file-name) "h")
|
|
|
|
(re-search-forward "@\\<interface\\>" magic-mode-regexp-match-limit t)))
|
|
|
|
|
2017-09-20 14:25:35 +02:00
|
|
|
(push (cons #'+cc-c++-header-file-p 'c++-mode) magic-mode-alist)
|
2017-09-20 01:34:47 +02:00
|
|
|
(push (cons #'+cc-objc-header-file-p 'objc-mode) magic-mode-alist)
|
|
|
|
|
|
|
|
:init
|
|
|
|
(setq-default c-basic-offset tab-width)
|
2016-04-08 14:02:55 -04:00
|
|
|
|
2016-04-23 22:08:46 -04:00
|
|
|
:config
|
2017-02-23 00:06:12 -05:00
|
|
|
(set! :electric '(c-mode c++-mode objc-mode java-mode)
|
2017-02-20 20:55:21 -05:00
|
|
|
:chars '(?\n ?\}))
|
2017-02-23 00:06:12 -05:00
|
|
|
(set! :company-backend
|
2017-02-19 18:57:16 -05:00
|
|
|
'(c-mode c++-mode objc-mode)
|
2017-04-17 02:19:20 -04:00
|
|
|
'(company-irony-c-headers company-irony))
|
2016-03-23 11:58:08 -04:00
|
|
|
|
2017-09-17 22:01:04 +02:00
|
|
|
;;; Style/formatting
|
2017-02-19 18:57:16 -05:00
|
|
|
;; C/C++ style settings
|
|
|
|
(c-toggle-electric-state -1)
|
|
|
|
(c-toggle-auto-newline -1)
|
2017-09-20 14:25:35 +02:00
|
|
|
(c-set-offset 'substatement-open '0) ; don't indent brackets
|
|
|
|
(c-set-offset 'inline-open '+)
|
|
|
|
(c-set-offset 'block-open '+)
|
|
|
|
(c-set-offset 'brace-list-open '+)
|
|
|
|
(c-set-offset 'case-label '+)
|
|
|
|
(c-set-offset 'access-label '-)
|
|
|
|
(c-set-offset 'arglist-intro '+)
|
|
|
|
(c-set-offset 'arglist-close '0)
|
2017-09-17 22:01:04 +02:00
|
|
|
;; Indent privacy keywords at same level as class properties
|
|
|
|
;; (c-set-offset 'inclass #'+cc-c-lineup-inclass)
|
|
|
|
|
|
|
|
;;; Better fontification (also see `modern-cpp-font-lock')
|
|
|
|
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
|
|
|
|
(add-hook! (c-mode c++-mode) #'highlight-numbers-mode)
|
|
|
|
(add-hook! (c-mode c++-mode) #'+cc|fontify-constants)
|
|
|
|
|
|
|
|
;; Improve indentation of inline lambdas in C++11
|
|
|
|
(advice-add #'c-lineup-arglist :around #'+cc*align-lambda-arglist)
|
2017-02-19 18:57:16 -05:00
|
|
|
|
2017-09-17 22:01:04 +02:00
|
|
|
;;; Keybindings
|
|
|
|
;; Completely disable electric keys because it interferes with smartparens and
|
|
|
|
;; custom bindings. We'll do this ourselves.
|
|
|
|
(setq c-tab-always-indent nil
|
|
|
|
c-electric-flag nil)
|
|
|
|
(dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")"))
|
|
|
|
(define-key c-mode-base-map key nil))
|
|
|
|
;; Smartparens and cc-mode both try to autoclose angle-brackets intelligently.
|
|
|
|
;; The result isn't very intelligent (causes redundant characters), so just do
|
|
|
|
;; it ourselves.
|
|
|
|
(map! :map c++-mode-map
|
2017-02-19 18:57:16 -05:00
|
|
|
"<" nil
|
2017-09-17 22:01:04 +02:00
|
|
|
:i ">" #'+cc/autoclose->-maybe)
|
|
|
|
|
|
|
|
;; ...and leave it to smartparens
|
|
|
|
(sp-with-modes '(c-mode c++-mode objc-mode java-mode)
|
|
|
|
(sp-local-pair "<" ">" :when '(+cc-sp-point-is-template-p +cc-sp-point-after-include-p))
|
|
|
|
(sp-local-pair "/*" "*/" :post-handlers '(("||\n[i]" "RET") ("| " "SPC")))
|
|
|
|
;; Doxygen blocks
|
|
|
|
(sp-local-pair "/**" "*/" :post-handlers '(("||\n[i]" "RET") ("||\n[i]" "SPC")))
|
|
|
|
(sp-local-pair "/*!" "*/" :post-handlers '(("||\n[i]" "RET") ("[d-1]< | " "SPC")))))
|
2017-02-19 18:57:16 -05:00
|
|
|
|
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! modern-cpp-font-lock
|
2017-12-08 22:33:12 -05:00
|
|
|
:hook (c++-mode . modern-c++-font-lock-mode))
|
2016-06-23 01:32:56 -04:00
|
|
|
|
2017-02-19 18:57:16 -05:00
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! irony
|
2016-04-23 22:08:46 -04:00
|
|
|
:after cc-mode
|
2017-05-25 20:11:24 +02:00
|
|
|
:commands irony-install-server
|
2017-12-08 22:33:12 -05:00
|
|
|
:preface (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
|
|
|
:hook ((c-mode c++-mode objc-mode) . irony-mode)
|
2016-04-23 22:08:46 -04:00
|
|
|
:config
|
2017-09-19 05:06:50 +02:00
|
|
|
(unless (file-directory-p irony-server-install-prefix)
|
|
|
|
(warn "irony-mode: server isn't installed; run M-x irony-install-server"))
|
|
|
|
;; Initialize compilation database, if present. Otherwise, fall back on
|
2017-12-27 17:10:21 -05:00
|
|
|
;; `+cc-default-compiler-options'.
|
2017-09-19 05:06:50 +02:00
|
|
|
(add-hook 'irony-mode-hook #'+cc|irony-init-compile-options))
|
2017-04-08 23:37:40 -04:00
|
|
|
|
2017-09-17 22:01:04 +02:00
|
|
|
(def-package! irony-eldoc
|
|
|
|
:after irony
|
2017-12-08 22:33:12 -05:00
|
|
|
:hook (irony-mode . irony-eldoc))
|
2016-04-23 22:08:46 -04:00
|
|
|
|
2017-03-19 22:47:50 -04:00
|
|
|
(def-package! flycheck-irony
|
|
|
|
:when (featurep! :feature syntax-checker)
|
|
|
|
:after irony
|
2017-09-17 22:01:04 +02:00
|
|
|
:config
|
|
|
|
(add-hook 'irony-mode-hook #'flycheck-mode)
|
|
|
|
(flycheck-irony-setup))
|
2016-04-23 22:08:46 -04:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
2017-02-19 18:57:16 -05:00
|
|
|
;; Tools
|
|
|
|
;;
|
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! disaster :commands disaster)
|
2017-02-19 18:57:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;; Major modes
|
|
|
|
;;
|
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! cmake-mode
|
2017-12-26 18:12:15 -05:00
|
|
|
:mode "/CMakeLists\\.txt$"
|
|
|
|
:mode "\\.cmake\\$"
|
2017-02-19 18:57:16 -05:00
|
|
|
:config
|
2017-02-23 00:06:12 -05:00
|
|
|
(set! :company-backend 'cmake-mode '(company-cmake company-yasnippet)))
|
2015-06-15 09:06:10 +02:00
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! cuda-mode :mode "\\.cuh?$")
|
2015-06-15 09:06:10 +02:00
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! opencl-mode :mode "\\.cl$")
|
2016-05-01 17:23:14 -04:00
|
|
|
|
2017-02-23 00:06:12 -05:00
|
|
|
(def-package! demangle-mode
|
2017-12-08 22:33:12 -05:00
|
|
|
:hook llvm-mode)
|
2017-07-06 12:44:03 +02:00
|
|
|
|
|
|
|
(def-package! glsl-mode
|
|
|
|
:mode "\\.glsl$"
|
|
|
|
:mode "\\.vert$"
|
|
|
|
:mode "\\.frag$"
|
|
|
|
:mode "\\.geom$")
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
2017-12-26 14:14:36 -05:00
|
|
|
;; Company plugins
|
2017-07-06 12:44:03 +02:00
|
|
|
;;
|
|
|
|
|
2017-12-26 14:14:36 -05:00
|
|
|
(def-package! company-cmake
|
|
|
|
:when (featurep! :completion company)
|
|
|
|
:after cmake-mode)
|
|
|
|
|
|
|
|
(def-package! company-irony
|
|
|
|
:when (featurep! :completion company)
|
|
|
|
:after irony)
|
2017-07-06 12:44:03 +02:00
|
|
|
|
2017-12-26 14:14:36 -05:00
|
|
|
(def-package! company-irony-c-headers
|
|
|
|
:when (featurep! :completion company)
|
|
|
|
:after company-irony)
|
|
|
|
|
|
|
|
(def-package! company-glsl
|
|
|
|
:when (featurep! :completion company)
|
|
|
|
:after glsl-mode
|
|
|
|
:config
|
|
|
|
(if (executable-find "glslangValidator")
|
|
|
|
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
|
|
|
|
(set! :company-backend 'glsl-mode '(company-glsl))))
|
2017-07-06 12:44:03 +02:00
|
|
|
|
|
|
|
|
2017-12-26 18:12:36 -05:00
|
|
|
;;
|
|
|
|
;; Rtags Support
|
|
|
|
;;
|
|
|
|
|
|
|
|
(def-package! rtags
|
|
|
|
:after cc-mode
|
|
|
|
:config
|
|
|
|
(setq rtags-autostart-diagnostics t
|
|
|
|
rtags-use-bookmarks nil
|
2017-12-26 23:34:17 -05:00
|
|
|
rtags-completions-enabled nil
|
2017-12-26 19:24:12 -05:00
|
|
|
;; If not using ivy or helm to view results, use a pop-up window rather
|
|
|
|
;; than displaying it in the current window...
|
|
|
|
rtags-results-buffer-other-window t
|
|
|
|
;; ...and don't auto-jump to first match before making a selection.
|
|
|
|
rtags-jump-to-first-match nil)
|
|
|
|
|
|
|
|
(let ((bins (cl-remove-if-not #'executable-find '("rdm" "rc"))))
|
|
|
|
(if (/= (length bins) 2)
|
|
|
|
(warn "cc-mode: couldn't find %s, disabling rtags support" bins)
|
2017-12-27 00:49:08 -05:00
|
|
|
(add-hook! (c-mode c++-mode) #'rtags-start-process-unless-running)
|
2017-12-26 19:24:12 -05:00
|
|
|
(set! :jump '(c-mode c++-mode)
|
|
|
|
:definition #'rtags-find-symbol-at-point
|
|
|
|
:references #'rtags-find-references-at-point)))
|
|
|
|
|
|
|
|
(add-hook 'doom-cleanup-hook #'rtags-cancel-process)
|
2017-12-27 00:49:08 -05:00
|
|
|
(add-hook! kill-emacs (ignore-errors (rtags-cancel-process)))
|
2017-12-26 19:24:12 -05:00
|
|
|
|
|
|
|
;; Use rtags-imenu instead of imenu/counsel-imenu
|
2017-12-26 19:39:20 -05:00
|
|
|
(map! :map (c-mode-map c++-mode-map) [remap imenu] #'rtags-imenu)
|
2017-12-26 19:24:12 -05:00
|
|
|
|
2017-12-26 18:12:36 -05:00
|
|
|
(add-hook 'rtags-jump-hook #'evil-set-jump)
|
|
|
|
(add-hook 'rtags-after-find-file-hook #'recenter))
|
|
|
|
|
|
|
|
(def-package! ivy-rtags
|
|
|
|
:when (featurep! :completion ivy)
|
|
|
|
:after rtags
|
|
|
|
:init
|
|
|
|
;; NOTE Ivy integration breaks when rtags is byte-compiled with Emacs 26 or
|
|
|
|
;; later, so we un-byte-compile it before we load it.
|
|
|
|
(eval-when-compile
|
|
|
|
(when (>= emacs-major-version 26)
|
|
|
|
(when-let* ((elc-file (locate-library "rtags.elc" t doom--package-load-path)))
|
|
|
|
(delete-file elc-file))))
|
|
|
|
:config (setq rtags-display-result-backend 'ivy))
|
|
|
|
|
|
|
|
(def-package! helm-rtags
|
|
|
|
:when (featurep! :completion helm)
|
|
|
|
:after rtags
|
|
|
|
:config (setq rtags-display-result-backend 'helm))
|