summaryrefslogtreecommitdiffstats
path: root/lisp/ravi-init-cpp.el
diff options
context:
space:
mode:
authorRavi R Kiran <aine.marina@gmail.com>2015-03-17 04:17:17 (GMT)
committerRavi R Kiran <aine.marina@gmail.com>2015-03-17 04:17:17 (GMT)
commita6e94a30a835ea389fe8fc40df162ff327035ccb (patch)
treecf695ab8c77b2c78434b2c6913295641a9287110 /lisp/ravi-init-cpp.el
parentb94602dccfa28b997b1fc1f2e0373d997f4b95ce (diff)
downloaddotemacs-a6e94a30a835ea389fe8fc40df162ff327035ccb.zip
dotemacs-a6e94a30a835ea389fe8fc40df162ff327035ccb.tar.gz
dotemacs-a6e94a30a835ea389fe8fc40df162ff327035ccb.tar.bz2
Move main emacs directory out of load path
This follows the official emacs recommendation for lisp code inside emacs.d.
Diffstat (limited to 'lisp/ravi-init-cpp.el')
-rw-r--r--lisp/ravi-init-cpp.el418
1 files changed, 418 insertions, 0 deletions
diff --git a/lisp/ravi-init-cpp.el b/lisp/ravi-init-cpp.el
new file mode 100644
index 0000000..5fe9e8f
--- /dev/null
+++ b/lisp/ravi-init-cpp.el
@@ -0,0 +1,418 @@
+;;; 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 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
+ )
+
+ (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))
+
+ (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)
+ )
+ (add-hook 'c++-mode-hook 'my-c++-mode-hook)
+
+ ;; 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