Refactor lang/cc

+ Fix ffap integration
+ Code reduction for irony, rtags and lsp init hooks
+ Use c-add-style instead of unless+push
+ Log that irony server isn't installed
This commit is contained in:
Henrik Lissner 2019-03-02 01:51:51 -05:00
parent e11ea611cf
commit 0bd576673c
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
2 changed files with 83 additions and 50 deletions

View file

@ -93,6 +93,14 @@ simpler."
(funcall +cc-default-header-file-mode))
((c-mode)))))
(defun +cc-resolve-include-paths ()
(cl-loop with path = (or buffer-file-name default-directory)
for dir in +cc-default-include-paths
if (file-name-absolute-p dir)
collect dir
else if (projectile-locate-dominating-file path dir)
collect (expand-file-name dir it)))
;;
;; Commands
@ -139,8 +147,9 @@ simpler."
("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face))
t)))
(defvar +cc--project-includes-alist nil)
;;;###autoload
(defun +cc|irony-init-compile-options ()
(defun +cc|init-irony-compile-options ()
"Initialize compiler options for irony-mode. It searches for the nearest
compilation database and initailizes it, otherwise falling back on
`+cc-default-compiler-options' and `+cc-default-include-paths'.
@ -150,33 +159,47 @@ compilation dbs."
(when (memq major-mode '(c-mode c++-mode objc-mode))
(require 'irony-cdb)
(unless (irony-cdb-autosetup-compile-options)
(let ((project-root (doom-project-root))
(include-paths (+cc-resolve-include-paths)))
(setf (alist-get project-root +cc--project-includes-alist)
include-paths)
(irony-cdb--update-compile-options
(delq nil
(append (cdr-safe (assq major-mode +cc-default-compiler-options))
(cl-loop with path = (or buffer-file-name default-directory)
for dir in '("include" "includes")
if (projectile-locate-dominating-file path dir)
collect it)
(cl-loop for path in +cc-default-include-paths
if (stringp path)
nconc (list "-I" path))))
(doom-project-root)))
;; Make ffap aware of include paths
(when irony--working-directory
(append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))
(cl-loop for path in include-paths
collect (format "-I%s" path)))
project-root)))))
;; ;;;###autoload
;; (defun +cc|init-ccls-compile-options ()
;; "TODO"
;; (when (memq major-mode '(c-mode c++-mode objc-mode))
;; (when-let* ((include-paths (+cc-resolve-include-paths)))
;; (let ((args (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))))
;; (setf (alist-get (or (lsp-workspace-root)
;; (lsp--suggest-project-root)
;; (doom-project-root))
;; +cc--project-includes-alist)
;; include-paths)
;; (setq ccls-initialization-options
;; `(:clang (:extraArgs
;; [,@(cl-loop for path in include-paths
;; collect (format "-I%s" path))])))))))
;;;###autoload
(defun +cc|init-ffap-integration ()
"Takes the local project include paths and registers them with ffap.
This way, `find-file-at-point' (and `+lookup/file') will know where to find most
header files."
(when-let* ((project-root (or (bound-and-true-p irony--working-directory)
(and (featurep 'lsp)
(or (lsp-workspace-root)
(doom-project-root))))))
(require 'ffap)
(make-local-variable 'ffap-c-path)
(make-local-variable 'ffap-c++-path)
(cl-loop for opt in irony--compile-options
if (and (stringp opt)
(string-match "^-I\\(.+\\)" opt))
(cl-loop for dir in (or (cdr (assoc project-root +cc--project-includes-alist))
(+cc-resolve-include-paths))
do (add-to-list (pcase major-mode
(`c-mode 'ffap-c-path)
(`c++-mode 'ffap-c++-path))
(expand-file-name (match-string 1 opt)
irony--working-directory))))))
;;;###autoload
(defun +cc|cleanup-rtags ()
"Kill rtags server(s) if there are no C/C++ buffers open."
(unless (doom-buffers-in-mode '(c-mode c++-mode) (buffer-list))
(rtags-cancel-process)))
(expand-file-name dir project-root)))))

View file

@ -1,9 +1,13 @@
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
(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 compilation
database.")
(defvar +cc-default-include-paths
(list "include"
"includes")
"A list of default relative paths which will be searched for up from the
current file, to be passed to irony as extra header search paths. Paths can be
absolute. This is ignored if your project has a compilation database.
This is ignored by ccls.")
(defvar +cc-default-header-file-mode 'c-mode
"Fallback major mode for .h files if all other heuristics fail (in
@ -20,7 +24,9 @@ database.")
"-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.")
compilation database is present in the project.
This is ignored by ccls.")
;;
@ -42,6 +48,11 @@ compilation database is present in the project.")
;; Activate `c-mode', `c++-mode' or `objc-mode' depending on heuristics
(add-to-list 'auto-mode-alist '("\\.h\\'" . +cc-c-c++-objc-mode))
;; Ensure find-file-at-point works in C modes, must be added before irony
;; and/or lsp hooks are run.
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
#'+cc|init-ffap-integration)
:config
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
(set-docsets! 'c-mode "C")
@ -69,12 +80,11 @@ compilation database is present in the project.")
;;; Better fontification (also see `modern-cpp-font-lock')
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
(add-hook! '(c-mode-hook c++-mode-hook) #'+cc|fontify-constants)
(add-hook! (c-mode c++-mode) #'+cc|fontify-constants)
;; Custom style, based off of linux
(unless (assoc "doom" c-style-alist)
(push '("doom"
(c-basic-offset . tab-width)
(c-add-style
"doom" '((c-basic-offset . tab-width)
(c-comment-only-line-offset . 0)
(c-hanging-braces-alist (brace-list-open)
(brace-entry-open)
@ -102,8 +112,7 @@ compilation database is present in the project.")
;; another level
(access-label . -)
(inclass +cc-c++-lineup-inclass +)
(label . 0)))
c-style-alist))
(label . 0))))
;;; Keybindings
;; Smartparens and cc-mode both try to autoclose angle-brackets intelligently.
@ -131,16 +140,17 @@ compilation database is present in the project.")
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
:init
(defun +cc|init-irony-mode ()
(when (and (memq major-mode '(c-mode c++-mode objc-mode))
(file-directory-p irony-server-install-prefix))
(irony-mode +1)))
(add-hook 'c-mode-common-hook #'+cc|init-irony-mode)
(if (file-directory-p irony-server-install-prefix)
(irony-mode +1)
(message "Irony server isn't installed")))
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
#'+cc|init-irony-mode)
:config
(setq irony-cdb-search-directory-list '("." "build" "build-conda"))
;; Initialize compilation database, if present. Otherwise, fall back on
;; `+cc-default-compiler-options'.
(add-hook 'irony-mode-hook #'+cc|irony-init-compile-options)
(add-hook 'irony-mode-hook #'+cc|init-irony-compile-options)
(def-package! irony-eldoc
:hook (irony-mode . irony-eldoc))
@ -188,11 +198,11 @@ compilation database is present in the project.")
:init
(defun +cc|init-rtags ()
"Start an rtags server in c-mode and c++-mode buffers."
(when (and (memq major-mode '(c-mode c++-mode))
(require 'rtags nil t)
(when (and (require 'rtags nil t)
(rtags-executable-find rtags-rdm-binary-name))
(rtags-start-process-unless-running)))
(add-hook 'c-mode-common-hook #'+cc|init-rtags)
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
#'+cc|init-rtags)
:config
(setq rtags-autostart-diagnostics t
rtags-use-bookmarks nil
@ -226,9 +236,9 @@ compilation database is present in the project.")
(def-package! ccls
:when (featurep! +lsp)
:hook ((c-mode c++-mode objc-mode) . +lsp|init-ccls)
:hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc|init-ccls)
:config
(defun +lsp|init-ccls ()
(defun +cc|init-ccls ()
(setq-local company-transformers nil)
(setq-local company-lsp-async t)
(setq-local company-lsp-cache-candidates nil)