summaryrefslogtreecommitdiffstats
path: root/lisp/ravi-init-cpp.el
diff options
context:
space:
mode:
authorRavi R Kiran <aine.marina@gmail.com>2015-10-23 18:57:59 (GMT)
committerRavi R Kiran <aine.marina@gmail.com>2015-10-23 18:57:59 (GMT)
commitcd1924466152177ea06b17c843f256463c1b91b8 (patch)
treeaf90afe028e5e392f242a3ea36302aafe1c1769d /lisp/ravi-init-cpp.el
parent5561df232cfa49822f322196d98170f95aa1139e (diff)
parent74c319ef12dd3130f6afc17abc59404b59d601d1 (diff)
downloaddotemacs-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.el451
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