| ;;; google-c-style.el --- Google's C/C++ style for c-mode |
| |
| ;; Keywords: c, tools |
| |
| ;; google-c-style.el is Copyright (C) 2008 Google Inc. All Rights Reserved. |
| ;; |
| ;; It is free software; you can redistribute it and/or modify it under the |
| ;; terms of either: |
| ;; |
| ;; a) the GNU General Public License as published by the Free Software |
| ;; Foundation; either version 1, or (at your option) any later version, or |
| ;; |
| ;; b) the "Artistic License". |
| |
| ;;; Commentary: |
| |
| ;; Provides the google C/C++ coding style. You may wish to add |
| ;; `google-set-c-style' to your `c-mode-common-hook' after requiring this |
| ;; file. For example: |
| ;; |
| ;; (add-hook 'c-mode-common-hook 'google-set-c-style) |
| ;; |
| ;; If you want the RETURN key to go to the next line and space over |
| ;; to the right place, add this to your .emacs right after the load-file: |
| ;; |
| ;; (add-hook 'c-mode-common-hook 'google-make-newline-indent) |
| |
| ;;; Code: |
| |
| ;; For some reason 1) c-backward-syntactic-ws is a macro and 2) under Emacs 22 |
| ;; bytecode cannot call (unexpanded) macros at run time: |
| (eval-when-compile (require 'cc-defs)) |
| |
| ;; Wrapper function needed for Emacs 21 and XEmacs (Emacs 22 offers the more |
| ;; elegant solution of composing a list of lineup functions or quantities with |
| ;; operators such as "add") |
| (defun google-c-lineup-expression-plus-4 (langelem) |
| "Indents to the beginning of the current C expression plus 4 spaces. |
| |
| This implements title \"Function Declarations and Definitions\" |
| of the Google C++ Style Guide for the case where the previous |
| line ends with an open parenthese. |
| |
| \"Current C expression\", as per the Google Style Guide and as |
| clarified by subsequent discussions, means the whole expression |
| regardless of the number of nested parentheses, but excluding |
| non-expression material such as \"if(\" and \"for(\" control |
| structures. |
| |
| Suitable for inclusion in `c-offsets-alist'." |
| (save-excursion |
| (back-to-indentation) |
| ;; Go to beginning of *previous* line: |
| (c-backward-syntactic-ws) |
| (back-to-indentation) |
| (cond |
| ;; We are making a reasonable assumption that if there is a control |
| ;; structure to indent past, it has to be at the beginning of the line. |
| ((looking-at "\\(\\(if\\|for\\|while\\)\\s *(\\)") |
| (goto-char (match-end 1))) |
| ;; For constructor initializer lists, the reference point for line-up is |
| ;; the token after the initial colon. |
| ((looking-at ":\\s *") |
| (goto-char (match-end 0)))) |
| (vector (+ 4 (current-column))))) |
| |
| (defconst google-c-style |
| `((c-recognize-knr-p . nil) |
| (c-enable-xemacs-performance-kludge-p . t) ; speed up indentation in XEmacs |
| (c-basic-offset . 2) |
| (indent-tabs-mode . nil) |
| (c-comment-only-line-offset . 0) |
| (c-hanging-braces-alist . ((defun-open after) |
| (defun-close before after) |
| (class-open after) |
| (class-close before after) |
| (inexpr-class-open after) |
| (inexpr-class-close before) |
| (namespace-open after) |
| (inline-open after) |
| (inline-close before after) |
| (block-open after) |
| (block-close . c-snug-do-while) |
| (extern-lang-open after) |
| (extern-lang-close after) |
| (statement-case-open after) |
| (substatement-open after))) |
| (c-hanging-colons-alist . ((case-label) |
| (label after) |
| (access-label after) |
| (member-init-intro before) |
| (inher-intro))) |
| (c-hanging-semi&comma-criteria |
| . (c-semi&comma-no-newlines-for-oneline-inliners |
| c-semi&comma-inside-parenlist |
| c-semi&comma-no-newlines-before-nonblanks)) |
| (c-indent-comments-syntactically-p . t) |
| (comment-column . 40) |
| (c-indent-comment-alist . ((other . (space . 2)))) |
| (c-cleanup-list . (brace-else-brace |
| brace-elseif-brace |
| brace-catch-brace |
| empty-defun-braces |
| defun-close-semi |
| list-close-comma |
| scope-operator)) |
| (c-offsets-alist . ((arglist-intro google-c-lineup-expression-plus-4) |
| (func-decl-cont . ++) |
| (member-init-intro . ++) |
| (inher-intro . ++) |
| (comment-intro . 0) |
| (arglist-close . c-lineup-arglist) |
| (topmost-intro . 0) |
| (block-open . 0) |
| (inline-open . 0) |
| (substatement-open . 0) |
| (statement-cont |
| . |
| (,(when (fboundp 'c-no-indent-after-java-annotations) |
| 'c-no-indent-after-java-annotations) |
| ,(when (fboundp 'c-lineup-assignments) |
| 'c-lineup-assignments) |
| ++)) |
| (label . /) |
| (case-label . +) |
| (statement-case-open . +) |
| (statement-case-intro . +) ; case w/o { |
| (access-label . /) |
| (innamespace . 0)))) |
| "Google C/C++ Programming Style.") |
| |
| (defun google-set-c-style () |
| "Set the current buffer's c-style to Google C/C++ Programming |
| Style. Meant to be added to `c-mode-common-hook'." |
| (interactive) |
| (make-local-variable 'c-tab-always-indent) |
| (setq c-tab-always-indent t) |
| (c-add-style "Google" google-c-style t)) |
| |
| (defun google-make-newline-indent () |
| "Sets up preferred newline behavior. Not set by default. Meant |
| to be added to `c-mode-common-hook'." |
| (interactive) |
| (define-key c-mode-base-map "\C-m" 'newline-and-indent) |
| (define-key c-mode-base-map [ret] 'newline-and-indent)) |
| |
| (provide 'google-c-style) |
| ;;; google-c-style.el ends here |