lang/cc: general config refactor
+ Auto-add the nearest include/ folder to compiler header search path. + Remove unneeded fontification hooks (now covered by modern-cpp-font-lock). + Enable C++11 support by default
This commit is contained in:
parent
91783e0695
commit
570b093ac4
2 changed files with 89 additions and 109 deletions
|
@ -1,7 +1,7 @@
|
||||||
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
|
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +cc*lineup-arglist (orig-fun &rest args)
|
(defun +cc*align-lambda-arglist (orig-fun &rest args)
|
||||||
"Improve indentation of continued C++11 lambda function opened as argument."
|
"Improve indentation of continued C++11 lambda function opened as argument."
|
||||||
(if (and (eq major-mode 'c++-mode)
|
(if (and (eq major-mode 'c++-mode)
|
||||||
(ignore-errors
|
(ignore-errors
|
||||||
|
@ -21,59 +21,61 @@
|
||||||
(backward-char)
|
(backward-char)
|
||||||
(looking-at-p "[^ \t]>"))
|
(looking-at-p "[^ \t]>"))
|
||||||
(forward-char)
|
(forward-char)
|
||||||
(call-interactively 'self-insert-command)))
|
(call-interactively #'self-insert-command)))
|
||||||
|
|
||||||
(defun +cc--copy-face (new-face face)
|
|
||||||
"Define NEW-FACE from existing FACE."
|
|
||||||
(copy-face face new-face)
|
|
||||||
(eval `(defvar ,new-face nil))
|
|
||||||
(set new-face new-face))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun +cc|extra-fontify-c++ ()
|
|
||||||
;; We could place some regexes into `c-mode-common-hook', but
|
|
||||||
;; note that their evaluation order matters.
|
|
||||||
;; NOTE modern-cpp-font-lock will eventually supercede some of these rules
|
|
||||||
(font-lock-add-keywords
|
|
||||||
nil '(;; c++11 string literals
|
|
||||||
;; L"wide string"
|
|
||||||
;; L"wide string with UNICODE codepoint: \u2018"
|
|
||||||
;; u8"UTF-8 string", u"UTF-16 string", U"UTF-32 string"
|
|
||||||
("\\<\\([LuU8]+\\)\".*?\"" 1 font-lock-keyword-face)
|
|
||||||
;; R"(user-defined literal)"
|
|
||||||
;; R"( a "quot'd" string )"
|
|
||||||
;; R"delimiter(The String Data" )delimiter"
|
|
||||||
;; R"delimiter((a-z))delimiter" is equivalent to "(a-z)"
|
|
||||||
("\\(\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\)" 1 font-lock-keyword-face t) ; start delimiter
|
|
||||||
( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\(.*?\\))[^\\s-\\\\()]\\{0,16\\}\"" 1 font-lock-string-face t) ; actual string
|
|
||||||
( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(.*?\\()[^\\s-\\\\()]\\{0,16\\}\"\\)" 1 font-lock-keyword-face t) ; end delimiter
|
|
||||||
) t))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun +cc|extra-fontify-c/c++ ()
|
|
||||||
(font-lock-add-keywords
|
|
||||||
nil '(;; PREPROCESSOR_CONSTANT, PREPROCESSORCONSTANT
|
|
||||||
("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face)
|
|
||||||
("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face)
|
|
||||||
;; integer/float/scientific numbers
|
|
||||||
("\\<\\([\\-+]*[0-9\\.]+\\)\\>" 1 font-lock-constant-face t)
|
|
||||||
("\\<\\([\\-+]*[0-9\\.]+\\)\\(f\\)\\>"
|
|
||||||
(1 font-lock-constant-face t)
|
|
||||||
(2 font-lock-keyword-face t))
|
|
||||||
("\\<\\([\\-+]*[0-9\\.]+\\)\\([eE]\\)\\([\\-+]?[0-9]+\\)\\>"
|
|
||||||
(1 font-lock-constant-face t)
|
|
||||||
(2 font-lock-keyword-face t)
|
|
||||||
(3 font-lock-constant-face t))
|
|
||||||
) t))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +cc-sp-point-is-template-p (id action context)
|
(defun +cc-sp-point-is-template-p (id action context)
|
||||||
|
"Return t if point is in the right place for C++ angle-brackets."
|
||||||
(and (sp-in-code-p id action context)
|
(and (sp-in-code-p id action context)
|
||||||
(sp-point-after-word-p id action context)))
|
(sp-point-after-word-p id action context)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +cc-sp-point-after-include-p (id action context)
|
(defun +cc-sp-point-after-include-p (id action context)
|
||||||
|
"Return t if point is in an #include."
|
||||||
(and (sp-in-code-p id action context)
|
(and (sp-in-code-p id action context)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char (line-beginning-position))
|
(goto-char (line-beginning-position))
|
||||||
(looking-at-p "[ ]*#include[^<]+"))))
|
(looking-at-p "[ ]*#include[^<]+"))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +cc-c-lineup-inclass (_langelem)
|
||||||
|
"Indent privacy keywords at same level as class properties."
|
||||||
|
(if (memq major-mode '(c-mode c++-mode))
|
||||||
|
(let ((inclass (assq 'inclass c-syntactic-context)))
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (c-langelem-pos inclass))
|
||||||
|
(if (or (looking-at "struct")
|
||||||
|
(looking-at "typedef struct"))
|
||||||
|
'+
|
||||||
|
'++)))
|
||||||
|
'+))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Hooks
|
||||||
|
;;
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +cc|fontify-constants ()
|
||||||
|
"Better fontification for preprocessor constants"
|
||||||
|
(font-lock-add-keywords
|
||||||
|
nil '(("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face)
|
||||||
|
("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face))
|
||||||
|
t))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +cc|irony-add-include-paths ()
|
||||||
|
"Seek out and add the nearest include/ folders to clang's options."
|
||||||
|
(when-let (dir (locate-dominating-file buffer-file-name "include/"))
|
||||||
|
(cl-pushnew (concat "-I" (expand-file-name "include/" dir))
|
||||||
|
irony-additional-clang-options :test #'equal)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +cc|use-c++11 ()
|
||||||
|
"Enable C++11 support with clang (via irony)."
|
||||||
|
(cl-pushnew "-std=c++11" irony-additional-clang-options :test #'equal)
|
||||||
|
(when IS-MAC
|
||||||
|
;; NOTE beware: you'll get abi-inconsistencies when passing std-objects to
|
||||||
|
;; libraries linked with libstdc++ (e.g. if you use boost which wasn't
|
||||||
|
;; compiled with libc++)
|
||||||
|
(cl-pushnew "-stdlib=libc++" irony-additional-clang-options :test #'equal)))
|
||||||
|
|
|
@ -27,30 +27,13 @@
|
||||||
(push (cons #'+cc--objc-header-file-p 'objc-mode) magic-mode-alist)
|
(push (cons #'+cc--objc-header-file-p 'objc-mode) magic-mode-alist)
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(setq c-tab-always-indent nil
|
|
||||||
c-electric-flag nil)
|
|
||||||
|
|
||||||
(set! :electric '(c-mode c++-mode objc-mode java-mode)
|
(set! :electric '(c-mode c++-mode objc-mode java-mode)
|
||||||
:chars '(?\n ?\}))
|
:chars '(?\n ?\}))
|
||||||
|
|
||||||
(set! :company-backend
|
(set! :company-backend
|
||||||
'(c-mode c++-mode objc-mode)
|
'(c-mode c++-mode objc-mode)
|
||||||
'(company-irony-c-headers company-irony))
|
'(company-irony-c-headers company-irony))
|
||||||
|
|
||||||
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
|
;;; Style/formatting
|
||||||
(add-hook 'c-mode-hook #'highlight-numbers-mode) ; fontify numbers in C
|
|
||||||
(add-hook 'c++-mode-hook #'+cc|extra-fontify-c++) ; fontify C++11 string literals
|
|
||||||
|
|
||||||
(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"))))
|
|
||||||
|
|
||||||
;; Improve indentation of inline lambdas in C++11
|
|
||||||
(advice-add #'c-lineup-arglist :around #'+cc*lineup-arglist)
|
|
||||||
|
|
||||||
;; C/C++ style settings
|
;; C/C++ style settings
|
||||||
(c-toggle-electric-state -1)
|
(c-toggle-electric-state -1)
|
||||||
(c-toggle-auto-newline -1)
|
(c-toggle-auto-newline -1)
|
||||||
|
@ -62,44 +45,38 @@
|
||||||
(c-set-offset 'access-label '-)
|
(c-set-offset 'access-label '-)
|
||||||
(c-set-offset 'arglist-intro '+)
|
(c-set-offset 'arglist-intro '+)
|
||||||
(c-set-offset 'arglist-close '0)
|
(c-set-offset 'arglist-close '0)
|
||||||
|
;; Indent privacy keywords at same level as class properties
|
||||||
|
;; (c-set-offset 'inclass #'+cc-c-lineup-inclass)
|
||||||
|
|
||||||
(defun +cc--c-lineup-inclass (_langelem)
|
;;; Better fontification (also see `modern-cpp-font-lock')
|
||||||
(if (memq major-mode '(c-mode c++-mode))
|
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
|
||||||
(let ((inclass (assq 'inclass c-syntactic-context)))
|
(add-hook! (c-mode c++-mode) #'highlight-numbers-mode)
|
||||||
(save-excursion
|
(add-hook! (c-mode c++-mode) #'+cc|fontify-constants)
|
||||||
(goto-char (c-langelem-pos inclass))
|
|
||||||
(if (or (looking-at "struct")
|
|
||||||
(looking-at "typedef struct"))
|
|
||||||
'+
|
|
||||||
'++)))
|
|
||||||
'+))
|
|
||||||
(c-set-offset 'inclass #'+cc--c-lineup-inclass)
|
|
||||||
|
|
||||||
|
;; Improve indentation of inline lambdas in C++11
|
||||||
|
(advice-add #'c-lineup-arglist :around #'+cc*align-lambda-arglist)
|
||||||
|
|
||||||
;; Certain electric mappings interfere with smartparens and custom bindings,
|
;;; Keybindings
|
||||||
;; so unbind them
|
;; Completely disable electric keys because it interferes with smartparens and
|
||||||
(map! :map c-mode-map
|
;; custom bindings. We'll do this ourselves.
|
||||||
"DEL" nil
|
(setq c-tab-always-indent nil
|
||||||
"#" #'self-insert-command
|
c-electric-flag nil)
|
||||||
"{" #'self-insert-command
|
(dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")"))
|
||||||
"}" #'self-insert-command
|
(define-key c-mode-base-map key nil))
|
||||||
"/" #'self-insert-command
|
;; Smartparens and cc-mode both try to autoclose angle-brackets intelligently.
|
||||||
"*" #'self-insert-command
|
;; The result isn't very intelligent (causes redundant characters), so just do
|
||||||
";" #'self-insert-command
|
;; it ourselves.
|
||||||
"," #'self-insert-command
|
(map! :map c++-mode-map
|
||||||
":" #'self-insert-command
|
|
||||||
"(" #'self-insert-command
|
|
||||||
")" #'self-insert-command
|
|
||||||
|
|
||||||
:map c++-mode-map
|
|
||||||
"}" 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.
|
|
||||||
"<" nil
|
"<" nil
|
||||||
:map (c-mode-base-map c++-mode-map)
|
:i ">" #'+cc/autoclose->-maybe)
|
||||||
: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")))))
|
||||||
|
|
||||||
|
|
||||||
(def-package! modern-cpp-font-lock
|
(def-package! modern-cpp-font-lock
|
||||||
|
@ -114,28 +91,29 @@
|
||||||
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||||
:init
|
:init
|
||||||
(defun +cc|init-irony-mode ()
|
(defun +cc|init-irony-mode ()
|
||||||
|
;; The major-mode check is necessary because some modes derive themselves
|
||||||
|
;; from a c base mode, like java-mode or php-mode.
|
||||||
(when (and (memq major-mode '(c-mode c++-mode objc-mode))
|
(when (and (memq major-mode '(c-mode c++-mode objc-mode))
|
||||||
(file-directory-p irony-server-install-prefix))
|
(file-directory-p irony-server-install-prefix))
|
||||||
(irony-mode +1)))
|
(irony-mode +1)))
|
||||||
(add-hook 'c-mode-common-hook #'+cc|init-irony-mode)
|
(add-hook 'c-mode-common-hook #'+cc|init-irony-mode)
|
||||||
:config
|
:config
|
||||||
(add-hook! 'irony-mode-hook #'(irony-eldoc flycheck-mode))
|
(make-variable-buffer-local 'irony-additional-clang-options)
|
||||||
|
;; Add nearest include/ path to compiler options
|
||||||
|
(add-hook! '(c-mode-hook c++-mode-hook) #'+cc|irony-add-include-paths)
|
||||||
|
;; Use C++11/14 by default
|
||||||
|
(add-hook 'c++-mode-hook #'+cc|use-c++11))
|
||||||
|
|
||||||
(defun +cc|init-c++11-clang-options ()
|
(def-package! irony-eldoc
|
||||||
(make-local-variable 'irony-additional-clang-options)
|
:after irony
|
||||||
(cl-pushnew "-std=c++11" irony-additional-clang-options :test 'equal))
|
:config (add-hook 'irony-mode-hook #'irony-eldoc))
|
||||||
(add-hook 'c++-mode-hook #'+cc|init-c++11-clang-options)
|
|
||||||
|
|
||||||
(map! :map irony-mode-map
|
|
||||||
[remap completion-at-point] #'counsel-irony
|
|
||||||
[remap complete-symbol] #'counsel-irony))
|
|
||||||
|
|
||||||
(def-package! irony-eldoc :after irony)
|
|
||||||
|
|
||||||
(def-package! flycheck-irony
|
(def-package! flycheck-irony
|
||||||
:when (featurep! :feature syntax-checker)
|
:when (featurep! :feature syntax-checker)
|
||||||
:after irony
|
:after irony
|
||||||
:config (flycheck-irony-setup))
|
:config
|
||||||
|
(add-hook 'irony-mode-hook #'flycheck-mode)
|
||||||
|
(flycheck-irony-setup))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue