;;; Thanks to Barry A. Warsaw for the cc-mode package. Thanks to ;;; Chris Lee for some of these customizations, which I copied from ;;; his .emacs file. Check out the cool *dlr-c-auto-punctuate* stuff, ;;; which may still be slightly broken. (fmakunbound 'c-mode) (makunbound 'c-mode-map) (fmakunbound 'c++-mode) (makunbound 'c++-mode-map) (makunbound 'c-style-alist) ;;; The completion package I'm using needs c-mode-map, but doesn't ;;; load it. Autoloading here would cause a problem, since c-mode-map ;;; wouldn't be defined until after the first call to (c-mode). ;; (autoload 'c++-mode "cc-mode" "C++ Editing Mode" t) ;; (autoload 'c-mode "cc-mode" "C Editing Mode" t) (load "cc-mode") (setq auto-mode-alist (append '(("\\.C$" . c++-mode) ("\\.cc$" . c++-mode) ("\\.c$" . c-mode) ; to edit C code ("\\.h$" . c++-mode) ; to edit C code ) auto-mode-alist)) ;; Customizations for both c-mode and c++-mode ;; Indentation... I want a style which does this on CR immediately after ;; '(' : ;; ;; someVeryLongFunctionNameSoTheresNoRoomForArguments( ;; argument); ;; ;; instead of the default gnu style behavior: ;; ;; someVeryLongFunctionNameSoTheresNoRoomForArguments( ;; argument); ;; ;; stroustrup style does this, but it defaults to basic-offset of 4, ;; so we reset that manually. (defvar *dlr-c-auto-punctuate* t "Non-nil means auto-insert C punctuation in c-mode and c++-mode") (defun my-c-mode-common-hook () ;; Indentation style ;; (c-set-style "GNU") (c-set-style "stroustrup") (setq c-basic-offset 2) ;; offset customizations not in the selected style ;; (c-set-offset 'member-init-intro (* 2 c-basic-offset)) ;; other customizations ;; we like auto-newline and hungry-delete ;; (not true... we don't like auto-newline) ;; (don't like hungry-delete either). ;;(c-toggle-auto-hungry-state 1) ;;(c-toggle-hungry-state 1) ;; add cleanup stuff (setq c-cleanup-list (append '(brace-else-brace) c-cleanup-list)) ;; I'm going to change the key binding for SPC. Better ;; remember it now so I can call it from within ;; dlr-electric-spc , i.e. not break previous packages. ;; (setq *dlr-c-old-spc-func* (or (lookup-key c-mode-map " ") ;; (global-key-binding " "))) (let ((oldfunc (key-binding " "))) (if (not (eq oldfunc 'dlr-c-electric-spc)) (setq *dlr-c-old-spc-func* oldfunc))) ;; keybindings for both C and C++. We can put these in c-mode-map (define-key c-mode-map "\C-m" 'newline-and-indent) ;; don't bash my auto-completion key (define-key c-mode-map "\C-j" nil) (define-key c-mode-map " " 'dlr-c-electric-spc) (define-key c++-mode-map "\C-m" 'newline-and-indent) ;; don't bash my auto-completion key (define-key c++-mode-map "\C-j" nil) (define-key c++-mode-map " " 'dlr-c-electric-spc) ) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) ;; Here's my redefinition of the space key binding. (defun dlr-c-electric-spc (arg) "Insert a space and check if the last thing typed was a keyword. Call appropriate functions to complete the syntax for any keywords identified. The space is inserted by the function bound to *dlr-c-old-spc-func*, and keywords are completed by functions like dlr-c-insert-for. Completion is only done if the variable *dlr-c-auto-punctuate* is non-nil." (interactive "p") (funcall *dlr-c-old-spc-func* arg) (let* ((here (point)) (pos (- (point-max) here)) (search-bound (max (- here 40) 0)) mbeg mend) (if *dlr-c-auto-punctuate* (cond ((and (re-search-backward "\n[ \t]*for " search-bound t) (progn (setq mbeg (match-beginning 0) mend (match-end 0)) (goto-char here) (= mend here))) (delete-region mbeg mend) (insert "\n") (dlr-c-insert-for)) ((and (re-search-backward "\n[ \t]*if " search-bound t) (progn (setq mbeg (match-beginning 0) mend (match-end 0)) (goto-char here) (= mend here))) (delete-region mbeg mend) (insert "\n") (dlr-c-insert-if)) ;; ((and (re-search-backward "\n[ \t]*exit " search-bound t) ;; (progn (setq mbeg (match-beginning 0) ;; mend (match-end 0)) ;; (goto-char here) ;; (= mend here))) ;; (delete-region mbeg mend) ;; (insert "\n") ;; (dlr-c-insert-exit)) (t (goto-char (- (point-max) pos)))))) ) (defun dlr-c-insert-for () "Insert a _for_ clause with appropriate punctuation, prompting for appropriate parameters." (dlr-c-indent) (insert "for(") (let* ((st (read-from-minibuffer "initializer: ")) (increment-loop (string-match " *=" st)) (st2 (substring st 0 increment-loop)) (offsetInt (string-match "int " st2)) (endInt (match-end 0)) (offsetSizeT (string-match "size_t " st2)) (endSizeT (match-end 0)) (st3 (if offsetInt (substring st endInt increment-loop) (if offsetSizeT (substring st endSizeT increment-loop) st2))) pos) (insert st "; ") (insert (read-from-minibuffer "termination: " (if increment-loop (format "%s < " st3))) "; ") (insert (read-from-minibuffer "update: " (if increment-loop (format "++%s" st3))) ") {\n") (dlr-c-indent) (setq pos (point)) (insert "\n}") (dlr-c-indent) (goto-char pos)) ) (defun dlr-c-insert-if () "Insert an _if_ clause with appropriate punctuation, prompting for appropriate parameters." (dlr-c-indent) (insert "if(") (insert (read-from-minibuffer "condition: ") ") {\n") (dlr-c-indent) (setq pos (point)) (insert "\n}") (dlr-c-indent) (goto-char pos) ) (defun dlr-c-insert-exit () "Insert an _exit_, checking to see if stdlib.h has been included." (let ((pos (- (point-max) (point)))) (dlr-c-indent) (insert "exit") (if (and (eq (re-search-backward "stdlib.h" nil t) nil) (y-or-n-p "include stdlib.h?")) (progn (goto-char 1) (insert "#include \n"))) (goto-char (- (point-max) pos))) ) (defun dlr-c-indent () "Indent the current line by calling whatever function is bound to the TAB key" (funcall (key-binding "\t")) )