diff options
Diffstat (limited to 'lisp/ravi-init-cpp.el')
| -rw-r--r-- | lisp/ravi-init-cpp.el | 856 |
1 files changed, 413 insertions, 443 deletions
diff --git a/lisp/ravi-init-cpp.el b/lisp/ravi-init-cpp.el index f2b1e6e..4f3327d 100644 --- a/lisp/ravi-init-cpp.el +++ b/lisp/ravi-init-cpp.el @@ -104,477 +104,450 @@ (setq dummy-h-mode-default-major-mode 'c++-mode))) (use-package cc-mode - + :defer t :mode (("\\.h\\(h\\|xx\\|pp\\)\\'" . c++-mode) ("\\.ccfg\\'" . c++-mode) ("\\.m\\'" . c-mode) ("\\.mm\\'" . c++-mode)) - :init - (progn - (defvar printf-index 0) - - (defun insert-counting-printf (arg) - (interactive "P") - (if arg - (setq printf-index 0)) - (if t - (insert (format "std::cerr << \"step %d..\" << std::endl;\n" - (setq printf-index (1+ printf-index)))) - (insert (format "printf(\"step %d..\\n\");\n" - (setq printf-index (1+ printf-index))))) - (forward-line -1) - (indent-according-to-mode) - (forward-line)) - - ) + :hook ((c-mode-common-hook . ravi/c-mode-common-hook) + (c-mode-hook . ravi/c-mode-hook) + (c++-mode-hook . ravi/c++-mode-hook) + ) + :bind (:map c-mode-base-map + ("C-c P" . insert-counting-printf) + ("<return>" . c-context-line-break) + ("RET" . c-context-line-break) ; needed on non-X + ("<f5>" . compile-dwim) + ("C-c C-i" . c-includes-current-file) + ("M-q" . c-fill-paragraph) + ("]" . ravi/insert-closing-delimiter) + ("<f6>" . ravi/hydra-cextra/body) + ("M-<f8>" . compile-dwim) ; repeated: needed? + ) :config - (progn - (use-package highlight-doxygen - :diminish highlight-doxygen-mode) - - (defun my-c-mode-common-hook () - (hs-minor-mode 1) - (hs-hide-initial-comment-block) - (hide-ifdef-mode 1) - - (highlight-doxygen-mode) - (diminish 'hs-minor-mode) - (diminish 'hide-ifdef-mode) - - (bind-key "C-c P" 'insert-counting-printf c-mode-base-map) - - ;; (define-key c-mode-base-map [return] 'c-context-line-break) - (bind-key "<return>" 'c-context-line-break c-mode-base-map) - (bind-key "RET" 'c-context-line-break c-mode-base-map) ; needed on non-X - (bind-key "<f5>" 'compile-dwim c-mode-base-map) - - (unbind-key "M-j" c-mode-base-map) - (bind-key "C-c C-i" 'c-includes-current-file c-mode-base-map) - (when (functionp 'helm-dash) (setq-local dash-docs-docsets '("C"))) - (when (functionp 'consult-dash) (setq-local consult-dash-docsets '("C"))) - - (set (make-local-variable 'parens-require-spaces) t) - (setq fill-column 88) - - (bind-key "M-q" 'c-fill-paragraph c-mode-base-map) - - (c-toggle-electric-state 1) - (c-toggle-auto-newline 1) - (c-toggle-hungry-state 1) - (setq-local lsp-enable-on-type-formatting nil) - - (c-set-style "stroustrup") - (setq c-basic-offset 2) - (setq c-recognize-knr-p nil) - (modify-syntax-entry ?_ "w" c-mode-syntax-table) - (add-to-list 'c-cleanup-list 'empty-defun-braces) - (add-to-list 'c-cleanup-list 'defun-close-semi) - (add-to-list 'c-cleanup-list 'list-close-comma) - (add-to-list 'c-cleanup-list 'scope-operator) - ;; one-liner-defun and comment-close-slash found to be annoying - - (when (bound-and-true-p ravi/use-cquery-mode) - (setq-local company-transformers nil)) - (font-lock-add-keywords 'c++-mode '(("\\<\\(assert\\|DEBUG\\)(" - 1 font-lock-warning-face t)))) - - (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) - - (defun my-c++-mode-hook () + (defvar printf-index 0) + (defun insert-counting-printf (arg) + (interactive "P") + (when arg (setq printf-index 0)) ; reset index + (insert + (format (if (equal major-mode 'c++-mode) + "std::cerr << \"step %d..\" << std::endl;\n" + "printf(\"step %d..\\n\");\n") + (setq printf-index (1+ printf-index)))) + (forward-line -1) + (indent-according-to-mode) + (forward-line)) + + (use-package highlight-doxygen + :diminish highlight-doxygen-mode) + + (defun ravi/c-mode-common-hook () + (hs-minor-mode 1) + (hs-hide-initial-comment-block) + (hide-ifdef-mode 1) + + (highlight-doxygen-mode) + (diminish 'hs-minor-mode) + (diminish 'hide-ifdef-mode) + + (unbind-key "M-j" c-mode-base-map) + + (set (make-local-variable 'parens-require-spaces) t) + (setq fill-column 88) + + (c-toggle-electric-state 1) + (c-toggle-auto-newline 1) + (c-toggle-hungry-state 1) + (setq-local lsp-enable-on-type-formatting nil) + + (c-set-style "stroustrup") + (setq c-basic-offset 2) + (setq c-recognize-knr-p nil) + (modify-syntax-entry ?_ "w" c-mode-syntax-table) + (add-to-list 'c-cleanup-list 'empty-defun-braces) + (add-to-list 'c-cleanup-list 'defun-close-semi) + (add-to-list 'c-cleanup-list 'list-close-comma) + (add-to-list 'c-cleanup-list 'scope-operator) + ;; one-liner-defun and comment-close-slash found to be annoying + + (font-lock-add-keywords 'c++-mode '(("\\<\\(assert\\|DEBUG\\)(" + 1 font-lock-warning-face t)))) + + (defun ravi/c-mode-hook () + (when (functionp 'helm-dash) (setq-local dash-docs-docsets '("C"))) + (when (functionp 'consult-dash) (setq-local consult-dash-docsets '("C")))) + + (defun ravi/c++-mode-hook () + (setq c-offsets-alist + (append '((statement-cont . c-lineup-math) + (inline-open . 0)) + c-offsets-alist)) + (let ((innamespaceindent (if (and (buffer-file-name) + (string-equal "ccfg" (file-name-extension (buffer-file-name)))) + 2 0))) (setq c-offsets-alist - (append '((statement-cont . c-lineup-math) - (inline-open . 0)) - c-offsets-alist)) - (let ((innamespaceindent (if (and (buffer-file-name) - (string-equal "ccfg" (file-name-extension (buffer-file-name)))) - 2 0)) - ) - (setq c-offsets-alist - (append `((innamespace . ,innamespaceindent) - ) - c-offsets-alist)) - ) + (append `((innamespace . ,innamespaceindent)) c-offsets-alist))) - (modify-syntax-entry ?_ "w" c++-mode-syntax-table) - (setq c-macro-cppflags "-x c++") - (setq c-macro-prompt-flag t) - (when (functionp 'helm-dash) (setq-local dash-docs-docsets '("C" "C++" "Boost" "Qt"))) - (when (functionp 'consult-dash) (setq-local consult-dash-docsets '("C" "C++" "Boost" "Qt"))) - ) - (defun ravi/c++-hook-adder () - (add-hook 'c++-mode-hook 'my-c++-mode-hook)) - (ravi/c++-hook-adder) + (modify-syntax-entry ?_ "w" c++-mode-syntax-table) + (setq c-macro-cppflags "-x c++") + (setq c-macro-prompt-flag t) + (when (functionp 'helm-dash) (setq-local dash-docs-docsets '("C" "C++" "Boost" "Qt"))) + (when (functionp 'consult-dash) (setq-local consult-dash-docsets '("C" "C++" "Boost" "Qt")))) - ;; Annoyance in emacs 25.1+: c-tnt-chng-cleanup calls set-mark/deactivate-mark - (advice-add 'c-tnt-chng-cleanup :around #'ravi/without-region-bindings-mode) + ;; Annoyance in emacs 25.1+: c-tnt-chng-cleanup calls set-mark/deactivate-mark + (advice-add 'c-tnt-chng-cleanup :around #'ravi/without-region-bindings-mode) - ;; Stuff from kde-emacs - (defvar kde-header-protection-parts-to-show 1 - "Set this variable to the number of parts from the file name you want to + ;; Stuff from kde-emacs + (defvar kde-header-protection-parts-to-show 1 + "Set this variable to the number of parts from the file name you want to be used for the defined word in the header-protection function.. E.g. setting this to 3 makes header-protection define KIG_MISC_NEWTYPE_H for a file named /home/domi/src/kdenonbeta/kig/misc/newtype.h") - (defun kde-header-protection-definable-string () - (let* ((definablestring (concat "_" (ravi-random-ucn-string 6)) ) - (f (buffer-file-name)) - (parts (nreverse (split-string f "/"))) - (i) - (first-iter t) - (iters (min (length parts) kde-header-protection-parts-to-show))) - (dotimes (i iters) - (let ((part (pop parts))) - (setq definablestring + (defun kde-header-protection-definable-string () + (let* ((definablestring (concat "_" (ravi-random-ucn-string 6)) ) + (f (buffer-file-name)) + (parts (nreverse (split-string f "/"))) + (i) + (first-iter t) + (iters (min (length parts) kde-header-protection-parts-to-show))) + (dotimes (i iters) + (let ((part (pop parts))) + (setq definablestring (concat (upcase (replace-regexp-in-string "[\\.-]" "_" part)) (if (not first-iter) "_" "") - definablestring - ) - ) - (setq first-iter nil) + definablestring)) + (setq first-iter nil))) + definablestring)) + + ;; Creates the ifndef/define/endif statements necessary for a header file + (defun header-protection () + (interactive) + (save-excursion + (goto-char (point-min)) + (insert "#pragma once\n\n"))) + + (defun ravi-license-insert () + "Insert license header from `ravi-license-header'" + (let ((start (point-min)) + (comment-style 'box) + (license-header (ravi-license-header)) + (end)) + (when license-header + (goto-char start) + (insert license-header) + (setq end (point)) + (comment-region start end) + (insert ?\n)))) + + (defun ravi-insert-file-comment () + (insert "/**\n * \\file\n *\n * \n */\n")) + + (defun ravi-start-c++-header () + "Start a new C++ header by inserting include guards ( see \ + header-protection function ), inserting a license statement \ + and putting (point) at the correct position" + (interactive) + (header-protection) + (save-excursion (ravi-license-insert)) + (end-of-buffer) + (ravi-insert-file-comment)) + + (setq auto-insert-query nil) + (define-auto-insert "\\.\\([Cc]\\|cc\\|cpp\\|cxx\\|tcc\\)\\'" + 'ravi-auto-insert-cpp) + (define-auto-insert "\\.\\([Hh]\\|hh\\|hpp\\)\\'" 'ravi-start-c++-header) + + (defun ravi-auto-insert-cpp () + (ravi-license-insert) + (ravi-insert-file-comment)) + + (defun ravi/add-space-before-paren-c (&rest ignored) + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\)(" nil) + (save-excursion + (backward-char) + (insert-char ?\s)))) + + (defadvice c-electric-paren (after ravi/add-space-around-parens activate) + (unless (c-in-literal) + (cond + ((looking-back "([[:space:]]*" nil) + (progn + ;; Open parenthesis was the last command; add a space before it if + ;; necessary, and ensure that the point is placed after a space + (save-excursion + (re-search-backward "([[:space:]]*") + (unless (looking-at "(") (message "Logic error; opening paren not found")) + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)" nil) + (insert-char ?\s))) + (if (and (looking-at " ") (not (looking-at " )"))) + (forward-char) + (insert-char ?\s)) + ) + ) + ((looking-back ")[[:space:]]*" nil) + ;; Closing parenthesis was the last command; add spaces if necessary + (progn + ;; Compact empty function calls + (when (looking-back "([[:space:]]+)[[:space:]]*" nil) + (save-excursion + (re-search-backward ")[[:space:]]*") + (delete-horizontal-space) + ) + ) + + ;; Add space before closing parenthesis + (unless (looking-back "()[[:space:]]*" nil) + (save-excursion + (re-search-backward ")[[:space:]]*") + (unless (looking-at ")") (message "Logic error; closing paren not found")) + (unless (looking-back " " nil) (insert-char ?\s))) ) + + (let (need-to-add-newline) + (save-excursion + (c-backward-sexp) + (c-backward-syntactic-ws) + ;; FIXME: do-while loops are not handled correctly + (setq need-to-add-newline (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)" nil)) + ) + (when need-to-add-newline (c-newline-and-indent))) ) - definablestring ) + )) ) - ;; Creates the ifndef/define/endif statements necessary for a header file - (defun header-protection () - (interactive) + (defadvice c-electric-semi&comma (after ravi/add-space-after-comma activate) + (cond + ((looking-back "," nil) + (if (looking-at " [^)]") (forward-char) (insert-char ?\s))) + ((looking-back ") ;[[:space:]\n]*" nil) (save-excursion - (goto-char (point-min)) - (insert "#pragma once\n\n"))) - - (defun ravi-license-insert () - "Insert license header from `ravi-license-header'" - (let ((start (point-min)) - (comment-style 'box) - (license-header (ravi-license-header)) - (end)) - (when license-header - (goto-char start) - (insert license-header) - (setq end (point)) - (comment-region start end) - (insert ?\n)))) - - (defun ravi-insert-file-comment () - (insert "/**\n * \\file\n *\n * \n */\n")) - - (defun ravi-start-c++-header () - "Start a new C++ header by inserting include guards ( see \ - header-protection function ), inserting a license statement \ - and putting (point) at the correct position" - (interactive) - (header-protection) - (save-excursion (ravi-license-insert)) - (end-of-buffer) - (ravi-insert-file-comment)) + (re-search-backward " ;[[:space:]\n]*") + (delete-char 1))))) - (setq auto-insert-query nil) - (define-auto-insert "\\.\\([Cc]\\|cc\\|cpp\\|cxx\\|tcc\\)\\'" - 'ravi-auto-insert-cpp) - (define-auto-insert "\\.\\([Hh]\\|hh\\|hpp\\)\\'" 'ravi-start-c++-header) + ;; Do not activate region as it interferes with region-bindings-mode + (defadvice c-electric-brace (after ravi/do-not-activate-region activate) + (deactivate-mark)) - (defun ravi-auto-insert-cpp () + (defun ravi/insert-closing-delimiter(arg) + (interactive "p") + (if (c-in-literal) + (self-insert-command arg) (progn - (ravi-license-insert) - (ravi-insert-file-comment))) - - (defun ravi/add-space-before-paren-c (&rest ignored) - (message "Handler invoked") - (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\)(" nil) - (save-excursion - (backward-char) - (insert-char ?\s) - ) - )) - - (defadvice c-electric-paren (after ravi/add-space-around-parens activate) - (unless (c-in-literal) - (cond - ((looking-back "([[:space:]]*" nil) - (progn - ;; Open parenthesis was the last command; add a space before it if - ;; necessary, and ensure that the point is placed after a space - (save-excursion - (re-search-backward "([[:space:]]*") - (unless (looking-at "(") (message "Logic error; opening paren not found")) - (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)" nil) - (insert-char ?\s))) - (if (and (looking-at " ") (not (looking-at " )"))) - (forward-char) - (insert-char ?\s)) - ) - ) - ((looking-back ")[[:space:]]*" nil) - ;; Closing parenthesis was the last command; add spaces if necessary - (progn - ;; Compact empty function calls - (when (looking-back "([[:space:]]+)[[:space:]]*" nil) - (save-excursion - (re-search-backward ")[[:space:]]*") - (delete-horizontal-space) - ) - ) - - ;; Add space before closing parenthesis - (unless (looking-back "()[[:space:]]*" nil) - (save-excursion - (re-search-backward ")[[:space:]]*") - (unless (looking-at ")") (message "Logic error; closing paren not found")) - (unless (looking-back " " nil) (insert-char ?\s))) - ) - - (let (need-to-add-newline) - (save-excursion - (c-backward-sexp) - (c-backward-syntactic-ws) - ;; FIXME: do-while loops are not handled correctly - (setq need-to-add-newline (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)" nil)) - ) - (when need-to-add-newline (c-newline-and-indent))) + ;; Find nearest unmatched opening delimiter + (let (brace-type) + (save-excursion + (backward-up-list) + (cond + ((looking-at "{") (setq brace-type 'brace-type-brace)) + ((looking-at "(") (setq brace-type 'brace-type-paren)) + ((looking-at "\\[") (setq brace-type 'brace-type-square)) + (t (setq brace-type 'brace-type-none)) + )) + (cond + ((eq brace-type 'brace-type-brace) (setq unread-command-events (listify-key-sequence "}"))) + ((eq brace-type 'brace-type-paren) (setq unread-command-events (listify-key-sequence ")"))) + ; Uncommenting the line below would lead to infinite recursion + ;((eq 'brace-type 'brace-type-square) (setq unread-command-events (listify-key-sequence "]"))) + (t (self-insert-command 1)) ) - ) - )) - ) - - (defadvice c-electric-semi&comma (after ravi/add-space-after-comma activate) - (cond - ((looking-back "," nil) - (if (looking-at " [^)]") (forward-char) (insert-char ?\s))) - ((looking-back ") ;[[:space:]\n]*" nil) - (save-excursion - (re-search-backward " ;[[:space:]\n]*") - (delete-char 1))))) - - ;; Do not activate region as it interferes with region-bindings-mode - (defadvice c-electric-brace (after ravi/do-not-activate-region activate) - (deactivate-mark)) - - (defun ravi/insert-closing-delimiter(arg) - (interactive "p") - (if (c-in-literal) - (self-insert-command arg) - (progn - ;; Find nearest unmatched opening delimiter - (let (brace-type) - (save-excursion - (backward-up-list) - (cond - ((looking-at "{") (setq brace-type 'brace-type-brace)) - ((looking-at "(") (setq brace-type 'brace-type-paren)) - ((looking-at "\\[") (setq brace-type 'brace-type-square)) - (t (setq brace-type 'brace-type-none)) - )) + )))) + + (use-package rtags + :load-path (lambda () (ravi/emacs-file "site-lisp/rtags/build/src")) + :hook ((c-mode-hook . ravi/rtags-add-hook) + (c++-mode-hook . ravi/rtags-add-hook)) + :init + (setq use-rtags-hydra t) + :config + (defvar ravi/rtags-path nil "Path to RTags binary") + (setq rtags-path (or ravi/rtags-path (ravi/emacs-file "site-lisp/rtags/build/bin"))) + (setq rtags-autostart-diagnostics t) + (setq rtags-completions-enabled t) + (when (equal ravi/use-selection-system 'helm) + (setq rtags-display-result-backend 'helm)) + + ;; Extra support for company-c-headers if we can get include paths + ;; from the compilation command line from rtags + ;; (require 'dash) (require 's) + (defun ravi/set-company-c-headers-paths-from-rtags () + (interactive) + (let* ((compile-flags (rtags-compilation-flags)) + (nostdinc (-contains? compile-flags "-nostdinc")) + (isystem-found) + (i-found) + (system-dirs) + (user-dirs)) + (when compile-flags + (setq isystem-found nil + i-found nil + system-dirs (list) + user-dirs (list)) + (dolist (flag compile-flags) (cond - ((eq brace-type 'brace-type-brace) (setq unread-command-events (listify-key-sequence "}"))) - ((eq brace-type 'brace-type-paren) (setq unread-command-events (listify-key-sequence ")"))) - ; Uncommenting the line below would lead to infinite recursion - ;((eq 'brace-type 'brace-type-square) (setq unread-command-events (listify-key-sequence "]"))) - (t (self-insert-command 1)) - ) - )))) - - (bind-key "]" 'ravi/insert-closing-delimiter c-mode-base-map) - - (use-package rtags - :load-path (lambda () (ravi/emacs-file "site-lisp/rtags/build/src")) - :config - (progn - (setq use-rtags-hydra t) - (defvar ravi/rtags-path nil "Path to RTags binary") - (setq rtags-path (or ravi/rtags-path (ravi/emacs-file "site-lisp/rtags/build/bin"))) - (setq rtags-autostart-diagnostics t) - (setq rtags-completions-enabled t) - (when (equal ravi/use-selection-system 'helm) - (setq rtags-display-result-backend 'helm)) - - ;; Extra support for company-c-headers if we can get include paths - ;; from the compilation command line from rtags - ;; (require 'dash) (require 's) - (defun ravi/set-company-c-headers-paths-from-rtags () - (interactive) - (let* ((compile-flags (rtags-compilation-flags)) - (nostdinc (-contains? compile-flags "-nostdinc")) - (isystem-found) - (i-found) - (system-dirs) - (user-dirs)) - (when compile-flags - (setq isystem-found nil - i-found nil - system-dirs (list) - user-dirs (list)) - (dolist (flag compile-flags) - (cond - (isystem-found (add-to-list 'system-dirs flag t) - (setq isystem-found nil)) - (i-found (add-to-list 'user-dirs flag t) - (setq i-found nil)) - ((s-equals? "-isystem" flag) (setq isystem-found t)) - ((s-equals? "-I" flag) (setq i-found t)) - ((s-starts-with? "-I" flag) (add-to-list 'user-dirs (s-chop-prefix "-I" flag) t)) - (t nil))) - (setq user-dirs (-concat (-difference user-dirs system-dirs) system-dirs)) - ;(message "User dirs: %s" user-dirs) - (if nostdinc - (set (make-local-variable 'company-c-headers-path-system) user-dirs) - (when user-dirs - (make-local-variable 'company-c-headers-path-system) - (setq company-c-headers-path-system (-concat user-dirs company-c-headers-path-system))))))) - - (defun ravi/rtags-add-hook () - (unless (file-remote-p default-directory) - (rtags-start-process-unless-running) - ;; Set company C headers from rtags only after rtags starts running - (ravi/set-company-c-headers-paths-from-rtags))) - (add-hook 'c-mode-hook 'ravi/rtags-add-hook) - (add-hook 'c++-mode-hook 'ravi/rtags-add-hook) - - (use-package company-rtags - :config - (progn - (bind-key "C-<tab>" 'company-rtags c-mode-base-map) - (add-to-list 'company-backends 'company-rtags))))) - - ;; Choices of different LSP backends - (setq ravi/use-cpp-lsp-backends '(ravi/use-cpp-ccls ravi/use-cpp-none)) - (setq ravi/use-cpp-lsp-backend 'ravi/use-cpp-ccls) - (unless (memq ravi/use-cpp-lsp-backend ravi/use-cpp-lsp-backends) - (message "Invalid value for C++ LSP backend") - (setq ravi/use-cpp-lsp-backend 'ravi/use-cpp-none)) - - (use-package ccls - :if (eq ravi/use-cpp-lsp-backend 'ravi/use-cpp-ccls) - :config - (defvar ravi/ccls-executable nil "CCLS executable") - (setq ccls-executable (or ravi/ccls-executable (ravi/emacs-file "site-lisp/ccls/Release/ccls"))) - (setq ccls-args `(,(concat "--log-file=" (ravi/past-file "ccls.log")))) ; to do: use relative path - ) - - (setq hide-ifdef-initially nil) - - (pretty-hydra-define ravi/hydra-cextra (:color blue :hint nil) - ("Hide" - (("i" hide-ifdef-block "hide ifdef") - ("C-i" show-ifdef-block "show ifdef") - ("b" hs-toggle-hiding "hide/show block") - ("o" ff-find-other-file "other file")))) - (when (bound-and-true-p use-rtags-hydra) - (pretty-hydra-define+ ravi/hydra-cextra () - ("At point" - (("." rtags-find-symbol-at-point "symbol") - ("," rtags-find-references-at-point "references") - ("v" rtags-find-virtuals-at-point "virtuals") - ("V" rtags-print-enum-value-at-point "enum value") - ("/" rtags-find-all-references-at-point "all references") - ("G" rtags-guess-function-at-point "guess function") - ("X" rtags-fix-fixit-at-point "fix fixit") - ("M" rtags-symbol-info "symbol info")) - - "Location" - (("[" rtags-location-stack-back "back" :exit nil) - ("]" rtags-location-stack-forward "forward" :exit nil) - ("L" rtags-copy-and-print-current-location "copy") - ("O" rtags-goto-offset "to offset") - ("F" rtags-fixit "fixit") - ("K" rtags-make-member "member") - ("Z" rtags-location-stack-visualize "stach") - ("A" rtags-find-functions-called-by-this-function "functions")) - - "File" - (("p" rtags-dependency-tree "dependencies") - ("e" rtags-reparse-file "reparse") - ("E" rtags-preprocess-file "preprocess") - ("C" rtags-compile-file "compile") - ("I" rtags-imenu "imenu") - ("T" rtags-taglist "tag list") - (";" rtags-find-file "find file") - ("a" rtags-print-source-arguments "source args")) - - "Information" - (("D" rtags-diagnostics "diagnostics") - ("S" rtags-display-summary-as-message "summary") - ("B" rtags-show-rtags-buffer "rtags buffer") - ("h" rtags-print-class-hierarchy "class hierarchy") - (">" rtags-find-symbol "find symbol") - ("<" rtags-find-references "find references") - ("R" rtags-rename-symbol "rename symbol") - ("P" rtags-dependency-tree-all "all deps")) - )) - (bind-key "<f6>" 'ravi/hydra-cextra/body c-mode-base-map)) - - (bind-key "<M-f8>" 'compile-dwim c-mode-base-map) - (use-package multi-compile - :commands multi-compile-run + (isystem-found (add-to-list 'system-dirs flag t) + (setq isystem-found nil)) + (i-found (add-to-list 'user-dirs flag t) + (setq i-found nil)) + ((s-equals? "-isystem" flag) (setq isystem-found t)) + ((s-equals? "-I" flag) (setq i-found t)) + ((s-starts-with? "-I" flag) (add-to-list 'user-dirs (s-chop-prefix "-I" flag) t)) + (t nil))) + (setq user-dirs (-concat (-difference user-dirs system-dirs) system-dirs)) + ;(message "User dirs: %s" user-dirs) + (if nostdinc + (set (make-local-variable 'company-c-headers-path-system) user-dirs) + (when user-dirs + (make-local-variable 'company-c-headers-path-system) + (setq company-c-headers-path-system (-concat user-dirs company-c-headers-path-system))))))) + + (defun ravi/rtags-add-hook () + (unless (file-remote-p default-directory) + (rtags-start-process-unless-running) + ;; Set company C headers from rtags only after rtags starts running + (ravi/set-company-c-headers-paths-from-rtags))) + + (use-package company-rtags + :bind (:map c-mode-base-map + ("C-<tab>" . company-rtags)) :init - (bind-key (if ravi-ergodox-mode "<M-f5>" "<M-S-f8>") 'multi-compile-run c-mode-base-map) - :config - (progn - (when (fboundp 'ravi/multi-compile-local-setup) - (ravi/multi-compile-local-setup)))) - - ;; Enable Malinka - (use-package malinka - :disabled t - :config - (progn - ;; At this point, malinka has been loaded, so f.el has also - ;; been loaded and is ready for use. - (defun ravi/get-project-name-and-build-dir (proj-root-dir) - (interactive "D") - (let* ((proj-parent (and (f-exists? (f-dirname proj-root-dir)) - (f-dirname proj-root-dir))) - (proj-build (and proj-parent (f-exists? (f-join proj-parent "build")) - (f-join proj-parent "build"))) - (proj-root-dir-last (car (last (f-split proj-root-dir)))) - (proj-name (if (and (s-equals? proj-root-dir-last "source") - proj-parent) - (car (last (f-split proj-parent))) - proj-root-dir-last))) - (list proj-name proj-build))) - - (defun ravi/find-current-project () - (interactive) - (unless (or (not (buffer-file-name)) (malinka--file-belongs-to-project (buffer-file-name))) - (message "Searching for project for %s" (buffer-file-name)) - (let* ((proj-root (or (and (boundp 'ravi-project-root) ravi-project-root) - (malinka--project-detect-root))) - (proj-name-and-build-dir (and proj-root (ravi/get-project-name-and-build-dir proj-root))) - (proj-name (or (and (boundp 'ravi-project-name) ravi-project-name) - (and proj-root (nth 0 proj-name-and-build-dir)))) - (proj-build-dir (or (and (boundp 'ravi-project-build-dir) ravi-project-build-dir) - (and proj-root (nth 1 proj-name-and-build-dir)))) - (proj-compilation-database (and (boundp 'ravi-project-compilation-database) - ravi-project-compilation-database)) - (proj-configure-cmd (or (and (boundp 'ravi-project-configure-cmd) - ravi-project-configure-cmd) - (and proj-root - (f-exists? (f-join proj-root "CMakeLists.txt")) - "cmake")))) - (when proj-root - (message "%s %s %s %s" proj-root proj-name proj-build-dir proj-compilation-database) - (malinka-define-project :name proj-name - :root-directory proj-root - :build-directory proj-build-dir - :configure-cmd proj-configure-cmd))))) - - (defun ravi/setup-malinka () - (interactive) - (unless (file-remote-p default-directory) - (malinka-mode 1) - (ravi/find-current-project))) - (add-hook 'c-mode-common-hook 'ravi/setup-malinka))) - ) + (add-to-list 'company-backends 'company-rtags))) + + ;; Choices of different LSP backends + (setq ravi/use-cpp-lsp-backends '(ravi/use-cpp-ccls ravi/use-cpp-none)) + (setq ravi/use-cpp-lsp-backend 'ravi/use-cpp-ccls) + (unless (memq ravi/use-cpp-lsp-backend ravi/use-cpp-lsp-backends) + (message "Invalid value for C++ LSP backend") + (setq ravi/use-cpp-lsp-backend 'ravi/use-cpp-none)) + + (use-package ccls + :if (eq ravi/use-cpp-lsp-backend 'ravi/use-cpp-ccls) + :config + (defvar ravi/ccls-executable nil "CCLS executable") + (setq ccls-executable (or ravi/ccls-executable (ravi/emacs-file "site-lisp/ccls/Release/ccls"))) + (setq ccls-args `(,(concat "--log-file=" (ravi/past-file "ccls.log"))))) ; to do: use relative path + + (setq hide-ifdef-initially nil) + + (pretty-hydra-define ravi/hydra-cextra (:color blue :hint nil) + ("Hide" + (("i" hide-ifdef-block "hide ifdef") + ("C-i" show-ifdef-block "show ifdef") + ("b" hs-toggle-hiding "hide/show block") + ("o" ff-find-other-file "other file")))) + (when (bound-and-true-p use-rtags-hydra) + (pretty-hydra-define+ ravi/hydra-cextra () + ("At point" + (("." rtags-find-symbol-at-point "symbol") + ("," rtags-find-references-at-point "references") + ("v" rtags-find-virtuals-at-point "virtuals") + ("V" rtags-print-enum-value-at-point "enum value") + ("/" rtags-find-all-references-at-point "all references") + ("G" rtags-guess-function-at-point "guess function") + ("X" rtags-fix-fixit-at-point "fix fixit") + ("M" rtags-symbol-info "symbol info")) + + "Location" + (("[" rtags-location-stack-back "back" :exit nil) + ("]" rtags-location-stack-forward "forward" :exit nil) + ("L" rtags-copy-and-print-current-location "copy") + ("O" rtags-goto-offset "to offset") + ("F" rtags-fixit "fixit") + ("K" rtags-make-member "member") + ("Z" rtags-location-stack-visualize "stach") + ("A" rtags-find-functions-called-by-this-function "functions")) + + "File" + (("p" rtags-dependency-tree "dependencies") + ("e" rtags-reparse-file "reparse") + ("E" rtags-preprocess-file "preprocess") + ("C" rtags-compile-file "compile") + ("I" rtags-imenu "imenu") + ("T" rtags-taglist "tag list") + (";" rtags-find-file "find file") + ("a" rtags-print-source-arguments "source args")) + + "Information" + (("D" rtags-diagnostics "diagnostics") + ("S" rtags-display-summary-as-message "summary") + ("B" rtags-show-rtags-buffer "rtags buffer") + ("h" rtags-print-class-hierarchy "class hierarchy") + (">" rtags-find-symbol "find symbol") + ("<" rtags-find-references "find references") + ("R" rtags-rename-symbol "rename symbol") + ("P" rtags-dependency-tree-all "all deps")) + ))) + + (use-package multi-compile + :commands multi-compile-run + :init + (bind-key (if ravi-ergodox-mode "<M-f5>" "<M-S-f8>") 'multi-compile-run c-mode-base-map) + :config + (when (fboundp 'ravi/multi-compile-local-setup) + (ravi/multi-compile-local-setup))) + + ;; Enable Malinka + (use-package malinka + :disabled t + :config + (progn + ;; At this point, malinka has been loaded, so f.el has also + ;; been loaded and is ready for use. + (defun ravi/get-project-name-and-build-dir (proj-root-dir) + (interactive "D") + (let* ((proj-parent (and (f-exists? (f-dirname proj-root-dir)) + (f-dirname proj-root-dir))) + (proj-build (and proj-parent (f-exists? (f-join proj-parent "build")) + (f-join proj-parent "build"))) + (proj-root-dir-last (car (last (f-split proj-root-dir)))) + (proj-name (if (and (s-equals? proj-root-dir-last "source") + proj-parent) + (car (last (f-split proj-parent))) + proj-root-dir-last))) + (list proj-name proj-build))) + + (defun ravi/find-current-project () + (interactive) + (unless (or (not (buffer-file-name)) (malinka--file-belongs-to-project (buffer-file-name))) + (message "Searching for project for %s" (buffer-file-name)) + (let* ((proj-root (or (and (boundp 'ravi-project-root) ravi-project-root) + (malinka--project-detect-root))) + (proj-name-and-build-dir (and proj-root (ravi/get-project-name-and-build-dir proj-root))) + (proj-name (or (and (boundp 'ravi-project-name) ravi-project-name) + (and proj-root (nth 0 proj-name-and-build-dir)))) + (proj-build-dir (or (and (boundp 'ravi-project-build-dir) ravi-project-build-dir) + (and proj-root (nth 1 proj-name-and-build-dir)))) + (proj-compilation-database (and (boundp 'ravi-project-compilation-database) + ravi-project-compilation-database)) + (proj-configure-cmd (or (and (boundp 'ravi-project-configure-cmd) + ravi-project-configure-cmd) + (and proj-root + (f-exists? (f-join proj-root "CMakeLists.txt")) + "cmake")))) + (when proj-root + (message "%s %s %s %s" proj-root proj-name proj-build-dir proj-compilation-database) + (malinka-define-project :name proj-name + :root-directory proj-root + :build-directory proj-build-dir + :configure-cmd proj-configure-cmd))))) + + (defun ravi/setup-malinka () + (interactive) + (unless (file-remote-p default-directory) + (malinka-mode 1) + (ravi/find-current-project))) + (add-hook 'c-mode-common-hook 'ravi/setup-malinka))) ) (use-package gud :commands gud-gdb - :bind ("C-x H-g" . show-debugger) - :init - (defun show-debugger () + :bind (("C-x H-g" . ravi/show-debugger) + ("M-g u" . ravi/gud-gdb-hydra/body)) + :config + (defun ravi/show-debugger () (interactive) (let ((gud-buf (catch 'found @@ -584,8 +557,7 @@ this to 3 makes header-protection define KIG_MISC_NEWTYPE_H for a file named (if gud-buf (switch-to-buffer-other-window gud-buf) (call-interactively 'gud-gdb)))) - :config - (defhydra gud-gdb-hydra (:color red) + (defhydra ravi/gud-gdb-hydra (:color red) "gdb" ("l" gud-refresh "refresh") ("s" gud-step "step") @@ -599,9 +571,7 @@ this to 3 makes header-protection define KIG_MISC_NEWTYPE_H for a file named (">" gud-down "down frame") ("u" gud-until "until") ("f" gud-finish "finish") - ("j" gud-jump "jump to line")) - (bind-key "M-g u" 'gud-gdb-hydra/body) - ) + ("j" gud-jump "jump to line"))) (provide 'ravi-init-cpp) ;;; ravi-init-cpp.el ends here |
