diff options
| author | Ravi R Kiran <aine.marina@gmail.com> | 2015-10-23 18:57:59 (GMT) |
|---|---|---|
| committer | Ravi R Kiran <aine.marina@gmail.com> | 2015-10-23 18:57:59 (GMT) |
| commit | cd1924466152177ea06b17c843f256463c1b91b8 (patch) | |
| tree | af90afe028e5e392f242a3ea36302aafe1c1769d /lisp/ravi-init-cpp.el | |
| parent | 5561df232cfa49822f322196d98170f95aa1139e (diff) | |
| parent | 74c319ef12dd3130f6afc17abc59404b59d601d1 (diff) | |
| download | dotemacs-cd1924466152177ea06b17c843f256463c1b91b8.zip dotemacs-cd1924466152177ea06b17c843f256463c1b91b8.tar.gz dotemacs-cd1924466152177ea06b17c843f256463c1b91b8.tar.bz2 | |
Merge branch 'master' into rtags-attempt
* master: (139 commits)
Add pdf-tools as a nicer replacement for doc-view
Add pdf-tools submodule
Fix maildir data with correct path
Add desktop notifications for email
Potential use for modes without repls
Attach files more easily in mu
Update to newest version of mu
Please remove tooltips after a while, please
ace-window gets confused when tooltips are present
Sometimes the dispatch list does come in handy
Pre-populate searches
Succumb to muscle memory of control keys
Remove ropemacs due to disuse
Do not let company-quickhelp steal a global key
Manage word navigation
Use proper helm function to replace completing-read
Electric operators on python mode
Use which-key in preference to guide-key
Navigate easier
Simplify config with magit 2.1.0
...
Diffstat (limited to 'lisp/ravi-init-cpp.el')
| -rw-r--r-- | lisp/ravi-init-cpp.el | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/lisp/ravi-init-cpp.el b/lisp/ravi-init-cpp.el new file mode 100644 index 0000000..ffa9790 --- /dev/null +++ b/lisp/ravi-init-cpp.el @@ -0,0 +1,451 @@ +;;; ravi-init-cpp.el --- C/C++ handling + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; C/C++ initialization + +;;; Code: + +; Generate a random string (of letters and numbers) of a given length +(defun ravi-random-ucn-string (len) + (coerce (loop for i below len for x = (random 36) collect + (+ x + (cond ((< x 10) 48) + ((< x 36) (- 65 10)) + ))) + 'string)) + +(use-package cmake-mode + :mode (("CMakeLists\\.txt\\'" . cmake-mode) + ("\\.cmake\\'" . cmake-mode)) + ;:ensure t + ) + +(defvar get-buffer-compile-command (lambda (file) (cons file 1))) +(make-variable-buffer-local 'get-buffer-compile-command) + +(setq-default compile-command "") + +(defun compile-dwim (&optional arg) + "Compile Do What I Mean. + Compile using `compile-command'. + When `compile-command' is empty prompt for its default value. + With prefix C-u always prompt for the default value of + `compile-command'. + With prefix C-u C-u prompt for buffer local compile command with + suggestion from `get-buffer-compile-command'. An empty input removes + the local compile command for the current buffer." + (interactive "P") + (cond + ((and arg (> (car arg) 4)) + (let ((cmd (read-from-minibuffer + "Buffer local compile command: " + (funcall get-buffer-compile-command + (or (file-relative-name (buffer-file-name)) "")) + nil nil 'compile-history))) + (cond ((equal cmd "") + (kill-local-variable 'compile-command) + (kill-local-variable 'compilation-directory)) + (t + (set (make-local-variable 'compile-command) cmd) + (set (make-local-variable 'compilation-directory) + default-directory)))) + (when (not (equal compile-command "")) + ;; `compile' changes the default value of + ;; compilation-directory but this is a buffer local + ;; compilation + (let ((dirbak (default-value 'compilation-directory))) + (compile compile-command) + (setq-default compilation-directory dirbak)))) + ((or (and arg (<= (car arg) 4)) + (equal compile-command "")) + (setq-default compile-command (read-shell-command + "Compile command: " + (if (equal compile-command "") + "make " compile-command) + 'compile-history)) + (setq-default compilation-directory default-directory) + (when (not (equal (default-value 'compile-command) "")) + (compile (default-value 'compile-command)))) + (t + (recompile)))) + + +(use-package dummy-h-mode + :mode (("\\.h\\'" . dummy-h-mode)) + :config + (progn + ;; Hack to avoid ObjC files since we do not use it + (defun ravi/do-not-allow-objc (mode-val) + (if (eq mode-val 'objc-mode) + nil + mode-val)) + (mapc (lambda (x) (advice-add x :filter-return #'ravi/do-not-allow-objc)) + '(dummy-h-mode-get-major-mode-by-source-file + ;dummy-h-mode-get-major-mode-by-keywords + dummy-h-mode-get-major-mode-by-files-directory)) + + (setq dummy-h-mode-default-major-mode 'c++-mode)) + :ensure t) + +(use-package cc-mode + + :mode (("\\.h\\(h\\|xx\\|pp\\)\\'" . c++-mode) + ("\\.ccfg\\'" . c++-mode) + ("\\.m\\'" . c-mode) + ("\\.mm\\'" . c++-mode)) + :init + (progn + (use-package doxymacs + :load-path (lambda () (ravi/emacs-file "site-lisp/doxymacs/lisp")) + :config + (progn + (doxymacs-mode) + (setq doxymacs-file-comment-template + '("/**" > n + " * " (doxymacs-doxygen-command-char) "file" > n + " * " > n + " * " (doxymacs-doxygen-command-char) "brief " + (p "Brief description of this file: ") > n + " */" > n) + ) + (setq doxymacs-external-xml-parser-executable + (ravi/emacs-file "site-lisp/doxymacs/c/doxymacs_parser")) + (setq doxymacs-use-external-xml-parser t) + (setq doxymacs-command-character "\\") + ) + :diminish doxymacs-mode + ) + + (use-package rtags + :load-path ,(ravi/emacs-file "site-lisp/rtags/src") + :init + (progn + (setq rtags-path (ravi/emacs-file "site-lisp/rtags")) + (rtags-enable-standard-keybindings c-mode-base-map) + + (use-package rtags-ac) + )) + + (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)) + + ) + + :config + (progn + + (defun my-c-mode-common-hook () + (hs-minor-mode 1) + (hs-hide-initial-comment-block) + (hide-ifdef-mode 1) + (which-function-mode 1) + + (diminish 'hs-minor-mode) + (diminish 'hide-ifdef-mode) + + (bind-key "C-c p" 'insert-counting-printf c-mode-base-map) + + (doxymacs-mode 1) + (doxymacs-font-lock) + + ;(define-key c-mode-base-map [return] 'c-context-line-break) + (bind-key "<return>" 'c-context-line-break 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 (and (featurep 'ravi-ergodox-mode) ravi-ergodox-mode) + (bind-key "H-h" 'compile-dwim c-mode-base-map)) + (when (functionp 'helm-dash) + (setq-local helm-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) + + (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)))) + + (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) + + (defun my-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 `((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 helm-dash-docsets '("C" "C++" "Boost" "Qt"))) + ) + (defun ravi/c++-hook-adder () + (add-hook 'c++-mode-hook 'my-c++-mode-hook)) + (ravi/c++-hook-adder) + + ;; 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 + (concat + (upcase (replace-regexp-in-string "[\\.-]" "_" part)) + (if (not first-iter) "_" "") + definablestring + ) + ) + (setq first-iter nil) + ) + ) + definablestring + ) + ) + + ;; Creates the ifndef/define/endif statements necessary for a header file + (defun header-protection () + (interactive) + (let ((s (kde-header-protection-definable-string))) + (save-excursion + (goto-char (point-min)) + (insert "#ifndef " s "\n#define " s "\n\n") + (goto-char (point-max)) + (insert "\n#endif\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) + (insert "\n") + (beginning-of-buffer) + + (save-excursion + (let ((start (point-min)) + (comment-style 'box) + (end) + ) + (goto-char start) + (insert (ravi-license-header)) + (setq end (point)) + (comment-region start end) + ) + ) + + (end-of-buffer) + (next-line -3) + (insert "\n") + (doxymacs-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-license-insert () + (progn + (let ((start (point-min)) + (comment-style 'box) + (end) + ) + (goto-char start) + (insert (ravi-license-header)) + (insert "\n") + (setq end (point)) + (comment-region start end)))) + + (defun ravi-auto-insert-cpp () + (progn + (ravi-license-insert) + (doxymacs-insert-file-comment))) + + (defun ravi/add-space-before-paren-c (&rest ignored) + (message "Handler invoked") + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\)(") + (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:]]*") + (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\\)") + (insert-char ?\s))) + (if (and (looking-at " ") (not (looking-at " )"))) + (forward-char) + (insert-char ?\s)) + ) + ) + ((looking-back ")[[:space:]]*") + ;; Closing parenthesis was the last command; add spaces if necessary + (progn + ;; Compact empty function calls + (when (looking-back "([[:space:]]+)[[:space:]]*") + (save-excursion + (re-search-backward ")[[:space:]]*") + (delete-horizontal-space) + ) + ) + + ;; Add space before closing parenthesis + (unless (looking-back "()[[:space:]]*") + (save-excursion + (re-search-backward ")[[:space:]]*") + (unless (looking-at ")") (message "Logic error; closing paren not found")) + (unless (looking-back " ") (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\\)")) + ) + (when need-to-add-newline (c-newline-and-indent))) + ) + ) + )) + ) + + (defadvice c-electric-semi&comma (after ravi/add-space-after-comma activate) + (cond + ((looking-back ",") + (if (looking-at " [^)]") (forward-char) (insert-char ?\s))) + ((looking-back ") ;[[:space:]\n]*") + (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)) + + (defmacro ravi/fake-send-key (key-to-bind char-to-bind) + (let ((command (key-binding key-to-bind))) + (setq last-command-event char-to-bind) + (setq this-command command) + (call-interactively command)) + ) + + (defun ravi/insert-closing-delimiter() + (interactive) + (if (c-in-literal) + (self-insert-command) + (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)) + )) + (cond + ((eq brace-type 'brace-type-brace) (ravi/fake-send-key "}" ?\})) + ((eq brace-type 'brace-type-paren) (ravi/fake-send-key ")" ?\))) + ; Uncommenting the line below would lead to infinite recursion + ;((eq 'brace-type 'brace-type-square) (ravi/fake-send-key "]" ?\])) + (t (self-insert-command 1)) + ) + )))) + + (bind-key "]" 'ravi/insert-closing-delimiter c-mode-base-map) + + (bind-key "<M-f8>" 'compile-dwim c-mode-base-map) + + (bind-key "<M-f5>" 'hs-hide-block c-mode-base-map) + (bind-key "<M-f11>" 'hs-show-block c-mode-base-map) + + (setq hide-ifdef-initially nil) + (bind-key "<S-f5>" 'hide-ifdef-block c-mode-base-map) + (bind-key "<S-f11>" 'show-ifdef-block c-mode-base-map) + + ;; (setq c-syntactic-indentation nil) + ) + ) + +(provide 'ravi-init-cpp) +;;; ravi-init-cpp.el ends here |
