diff options
| author | Ravi R Kiran <aine.marina@gmail.com> | 2015-03-17 04:17:17 (GMT) |
|---|---|---|
| committer | Ravi R Kiran <aine.marina@gmail.com> | 2015-03-17 04:17:17 (GMT) |
| commit | a6e94a30a835ea389fe8fc40df162ff327035ccb (patch) | |
| tree | cf695ab8c77b2c78434b2c6913295641a9287110 /lisp/ravi-init-cpp.el | |
| parent | b94602dccfa28b997b1fc1f2e0373d997f4b95ce (diff) | |
| download | dotemacs-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.el | 418 |
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 |
