diff --git a/modules/lang/cc/autoload.el b/modules/lang/cc/autoload.el index e36824136..9deb3b78a 100644 --- a/modules/lang/cc/autoload.el +++ b/modules/lang/cc/autoload.el @@ -224,3 +224,93 @@ header files." (`c-mode 'ffap-c-path) (`c++-mode 'ffap-c++-path)) (expand-file-name dir project-root))))) + + +;; +;; CCLS specific helpers + +;; ccls/vars ccls/base ccls/derived ccls/members have a parameter while others are interactive. +;; (ccls/base 1) direct bases +;; (ccls/derived 1) direct derived +;; (ccls/member 2) => 2 (Type) => nested classes / types in a namespace +;; (ccls/member 3) => 3 (Func) => member functions / functions in a namespace +;; (ccls/member 0) => member variables / variables in a namespace +;; (ccls/vars 1) => field +;; (ccls/vars 2) => local variable +;; (ccls/vars 3) => field or local variable. 3 = 1 | 2 +;; (ccls/vars 4) => parameter + +;;;###autoload +(defun +ccls/callee () + "Show callees of symbol under point." + (interactive) + (lsp-ui-peek-find-custom "$ccls/call" '(:callee t))) + +;;;###autoload +(defun +ccls/caller () + "Show callers of symbol under point." + (interactive) + (lsp-ui-peek-find-custom "$ccls/call")) + +;;;###autoload +(defun ccls/vars (kind) + "Show variables of type KIND as symbol under point. + 1 -> field + 2 -> local variable + 3 -> field or local variables. 3 = 1 | 2. + 4 -> parameter" + (lsp-ui-peek-find-custom "$ccls/vars" `(:kind ,kind))) + +;;;###autoload +(defun ccls/base (levels) + "Show bases of class under point up to LEVELS levels (1 for direct bases)." + (lsp-ui-peek-find-custom "$ccls/inheritance" `(:levels ,levels))) + +;;;###autoload +(defun ccls/derived (levels) + "Show derived classes from class under point down to LEVELS levels (1 for direct derived)." + (lsp-ui-peek-find-custom "$ccls/inheritance" `(:levels ,levels :derived t))) + +;;;###autoload +(defun ccls/member (kind) + "Show member elements of kind KIND for class/namespace under point. + 0 -> member variables/ variables in a namespace + 2 -> nested classes / types in a namespace + 3 -> member functions / functions in a namespace" + (lsp-ui-peek-find-custom "$ccls/member" `(:kind ,kind))) + +;; The meaning of :role corresponds to https://github.com/maskray/ccls/blob/master/src/symbol.h +;;;###autoload +(defun +ccls/references-address () + "References w/ Role::Address bit (e.g. variables explicitly being taken addresses)" + (interactive) + (lsp-ui-peek-find-custom "textDocument/references" + (plist-put (lsp--text-document-position-params) :role 128))) + +;;;###autoload +(defun +ccls/references-macro () + "References w/ Role::Dynamic bit (macro expansions)" + (interactive) + (lsp-ui-peek-find-custom "textDocument/references" + (plist-put (lsp--text-document-position-params) :role 64))) + +;;;###autoload +(defun +ccls/references-not-call () + "References w/o Role::Call bit (e.g. where functions are taken addresses)" + (interactive) + (lsp-ui-peek-find-custom "textDocument/references" + (plist-put (lsp--text-document-position-params) :excludeRole 32))) + +;;;###autoload +(defun +ccls/references-read () + "References w/ Role::Read" + (interactive) + (lsp-ui-peek-find-custom "textDocument/references" + (plist-put (lsp--text-document-position-params) :role 8))) + +;;;###autoload +(defun +ccls/references-write () + "References w/ Role::Write" + (interactive) + (lsp-ui-peek-find-custom "textDocument/references" + (plist-put (lsp--text-document-position-params) :role 16))) diff --git a/modules/lang/cc/config.el b/modules/lang/cc/config.el index 825f04cac..a5d5ccbd9 100644 --- a/modules/lang/cc/config.el +++ b/modules/lang/cc/config.el @@ -230,7 +230,26 @@ If rtags or rdm aren't available, fail silently instead of throwing a breaking e (add-hook! '(c-mode-local-vars-hook c++-mode-local-vars-hook objc-mode-local-vars-hook) - #'lsp!) + #'lsp!) + (map! + (:after ccls + :map (c-mode-map c++-mode-map) + :n "C-h" (λ! (ccls-navigate "U")) + :n "C-j" (λ! (ccls-navigate "R")) + :n "C-k" (λ! (ccls-navigate "L")) + :n "C-l" (λ! (ccls-navigate "D")) + (:localleader + :desc "Preprocess file" :n "lp" #'ccls-preprocess-file + :desc "Reset cache and reload CCLS" :n "lf" #'ccls-reload) + (:after lsp-ui-peek + (:localleader + :desc "Callers list" :n "c" #'+ccls/caller + :desc "Callees list" :n "C" #'+ccls/callee + :desc "References (address)" :n "a" #'+ccls/references-address + :desc "References (not call)" :n "f" #'+ccls/references-not-call + :desc "References (Macro)" :n "m" #'+ccls/references-macro + :desc "References (Read)" :n "r" #'+ccls/references-read + :desc "References (Write)" :n "w" #'+ccls/references-write)))) (when (featurep! :tools lsp +eglot) ;; Map eglot specific helper @@ -249,7 +268,6 @@ If rtags or rdm aren't available, fail silently instead of throwing a breaking e "-isystem/usr/local/include"] :resourceDir (cdr (doom-call-process "clang" "-print-resource-dir")))))))))))) - (use-package! ccls :when (featurep! +lsp) :unless (featurep! :tools lsp +eglot) @@ -260,9 +278,20 @@ If rtags or rdm aren't available, fail silently instead of throwing a breaking e (add-to-list 'projectile-project-root-files-bottom-up ".ccls-root") (add-to-list 'projectile-project-root-files-top-down-recurring "compile_commands.json")) :config + (add-hook 'lsp-after-open-hook #'ccls-code-lens-mode) + (set-evil-initial-state! 'ccls-tree-mode 'emacs) + (setq ccls-sem-highlight-method 'font-lock) + (when (or IS-MAC IS-LINUX) + (let ((cpu-count-command (cond (IS-MAC '("sysctl -n hw.ncpu")) + (IS-LINUX '("nproc")) + (t (error "unreachable code"))))) + (setq ccls-initialization-options + `(:index (:trackDependency 1 + :threads ,(max 1 (/ (string-to-number (cdr (apply #'doom-call-process cpu-count-command))) 2))))))) (when IS-MAC (setq ccls-initialization-options - `(:clang ,(list :extraArgs ["-isystem/Library/Developer/CommandLineTools/usr/include/c++/v1" - "-isystem/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" - "-isystem/usr/local/include"] - :resourceDir (cdr (doom-call-process "clang" "-print-resource-dir"))))))) + (append ccls-initialization-options + `(:clang ,(list :extraArgs ["-isystem/Library/Developer/CommandLineTools/usr/include/c++/v1" + "-isystem/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" + "-isystem/usr/local/include"] + :resourceDir (cdr (doom-call-process "clang" "-print-resource-dir"))))))))