Templateを多用するコードのインデント
Emacs 22.1になっても、Templateを多用するコードをcc-modeできれいに整形してくれません。
Boostのメーリングリストを検索していたら、Dave Abrahamsさんの.emacsが公開されていたので、流用しみました。もともとはhttp://www.boost-consulting.com/.emacsとして公開されていたのですが、現在消えてしまっています。Template周りのコードは、以下のとおりです。
;; ;; C++ template indentation code by Dave Abrahams ;; (defun my-c-leading-comma-p () (save-excursion (beginning-of-line) (c-forward-token-2 0 nil (c-point 'eol)) (eq (char-after) ?,))) (defun my-c-namespace-indent (langelem) "Used with c-set-offset, indents namespace scope elements 2 spaces from the namespace declaration iff the open brace sits on a line by itself." (save-excursion (if (progn (goto-char (cdr langelem)) (setq column (current-column)) (end-of-line) (while (and (search-backward "{" nil t) (assoc 'incomment (c-guess-basic-syntax)))) (skip-chars-backward " \t") (bolp)) 2))) (defun my-c-backward-template-prelude () "Back up over expressions that end with a template argument list. Examples include: typename foo<bar>::baz::mumble foo(bar, baz).template bing " (while (save-excursion ;; Inspect the previous token or balanced pair to ;; see whether to skip backwards over it (c-backward-syntactic-ws) (or ;; is it the end of a nested template argument list? (and (eq (char-before) ?>) (c-backward-token-2 1 t) ;; skips over balanced "<>" pairs (eq (char-after) ?<)) (and (c-backward-token-2 1 t) (looking-at "[A-Za-z_\\[(.]\\|::\\|->")))) (c-backward-token-2 1 t))) (defun my-c-namespace-open-indent (langelem) "Used with c-set-offset, indents namespace opening braces to the same indentation as the line on which the namespace declaration starts." (save-excursion (goto-char (cdr langelem)) (let ((column (current-column))) (beginning-of-line) (skip-chars-forward " \t") (- (current-column) column)))) (defun my-lineup-first-template-args (langelem) "Align lines beginning with the first template argument. To allow this function to be used in a list expression, nil is returned if we don't appear to be in a template argument list. Works with: template-args-cont." (let ((leading-comma (my-c-leading-comma-p))) (save-excursion (c-with-syntax-table c++-template-syntax-table (beginning-of-line) (backward-up-list 1) (if (eq (char-after) ?<) (progn (my-c-backward-template-prelude) (vector (+ (current-column) (if leading-comma (/ c-basic-offset 2) c-basic-offset))))))))) (defun my-lineup-more-template-args (langelem) "Line up template argument lines under the first argument, adjusting for leading commas. To allow this function to be used in a list expression, nil is returned if there's no template argument on the first line. Works with: template-args-cont." (let ((result (c-lineup-template-args langelem))) (if (not (eq result nil)) (if (my-c-leading-comma-p) (vector (- (aref result 0) (/ c-basic-offset 2))) result)))) (defun my-lineup-template-close (langelem) (save-excursion (c-with-syntax-table c++-template-syntax-table (beginning-of-line) (c-forward-syntactic-ws (c-point 'eol)) (if (and (eq (char-after) ?>) (progn (forward-char) (c-backward-token-2 1 t) (eq (char-after) ?<))) (progn (my-c-backward-template-prelude) (vector (current-column))))))) (defun my-c++-mode-hook () (setq c-default-style "bsd" c-backspace-function 'backward-delete-char c-basic-offset 4 c-tab-always-indent t) ;; Add 2 spaces of indentation when the open brace is on a line by itself (c-set-offset 'innamespace 'my-c-namespace-indent) ;; indent solo opening braces to the same indentation as the line on ;; which the namespace starts (c-set-offset 'namespace-open 'my-c-namespace-open-indent) ;; indent access labels public/private/protected by 1 space, as in 'M'. I ;; kinda like that. (c-set-offset 'access-label -3) ;; ;;fixup template indentation ;; (c-set-offset 'template-args-cont (quote (my-lineup-more-template-args my-lineup-template-close my-lineup-first-template-args +))) (set-variable 'c-backslash-max-column 200) (show-paren-mode t) (make-local-variable 'parens-require-spaces) (setq parens-require-spaces nil) )