diff options
author | Martin Stjernholm <mast@lysator.liu.se> | 2002-04-22 00:35:36 +0000 |
---|---|---|
committer | Martin Stjernholm <mast@lysator.liu.se> | 2002-04-22 00:35:36 +0000 |
commit | a66cd3ee16d68ab874793226f0a74e08fbc81056 (patch) | |
tree | ca089daba3b962490ba70784cf684820e8b8ad83 /lisp/progmodes/cc-align.el | |
parent | 9211d0538379a887ae318bcb281e0d73ec691e24 (diff) | |
download | emacs-a66cd3ee16d68ab874793226f0a74e08fbc81056.tar.gz |
CC Mode update to version 5.29. This is for testing; it's not a released
version.
Diffstat (limited to 'lisp/progmodes/cc-align.el')
-rw-r--r-- | lisp/progmodes/cc-align.el | 465 |
1 files changed, 362 insertions, 103 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el index 58af08520ad..50e38bcefeb 100644 --- a/lisp/progmodes/cc-align.el +++ b/lisp/progmodes/cc-align.el @@ -25,7 +25,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to +;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. @@ -49,47 +49,107 @@ ;; Standard indentation line-ups +(defun c-lineup-topmost-intro-cont (langelem) + "Line up declaration continuation lines zero or one indentation step. +For lines in the \"header\" of a definition, zero is used. For other +lines, `c-basic-offset' is added to the indentation. E.g: + +int +neg (int i) <- c-lineup-topmost-intro-cont +{ + return -i; +} + +struct +larch <- c-lineup-topmost-intro-cont +{ + double height; +} + the_larch, <- c-lineup-topmost-intro-cont + another_larch; <- c-lineup-topmost-intro-cont +<--> c-basic-offset + +struct larch +the_larch, <- c-lineup-topmost-intro-cont + another_larch; <- c-lineup-topmost-intro-cont + +\(This function is mainly provided to mimic the behavior of CC Mode +5.28 and earlier where this case wasn't handled consistently so that +these lines could be analyzed as either topmost-intro-cont or +statement-cont.) + +Works with: topmost-intro-cont." + (save-excursion + (beginning-of-line) + (c-backward-syntactic-ws (cdr langelem)) + (if (memq (char-before) '(?} ?,)) + c-basic-offset))) + (defun c-lineup-arglist (langelem) "Line up the current argument line under the first argument. -Works with: arglist-cont-nonempty." +Works with: arglist-cont-nonempty, arglist-close." (save-excursion - (let* ((containing-sexp - (save-excursion - ;; arglist-cont-nonempty gives relpos == - ;; to boi of containing-sexp paren. This - ;; is good when offset is +, but bad - ;; when it is c-lineup-arglist, so we - ;; have to special case a kludge here. - (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty)) - (progn - (beginning-of-line) - (backward-up-list 1) - (skip-chars-forward " \t" (c-point 'eol))) - (goto-char (cdr langelem))) - (point))) - (langelem-col (c-langelem-col langelem t))) - (if (save-excursion - (beginning-of-line) - (looking-at "[ \t]*)")) - (progn (goto-char (match-end 0)) - (c-forward-sexp -1) - (forward-char 1) - (c-forward-syntactic-ws) - (- (current-column) langelem-col)) - (goto-char containing-sexp) - (or (eolp) - (not (memq (char-after) '(?{ ?\( ?\[))) - (let ((eol (c-point 'eol)) - (here (progn - (forward-char 1) - (skip-chars-forward " \t") - (point)))) - (c-forward-syntactic-ws) - (if (< (point) eol) - (goto-char here)))) - (- (current-column) langelem-col) - )))) + (beginning-of-line) + (let ((containing-sexp (c-most-enclosing-brace (c-parse-state)))) + (goto-char (1+ containing-sexp)) + (let ((eol (c-point 'eol))) + (c-forward-syntactic-ws) + (when (< (point) eol) + (goto-char (1+ containing-sexp)) + (skip-chars-forward " \t"))) + (vector (current-column))))) + +;; Contributed by Kevin Ryde <user42@zip.com.au>. +(defun c-lineup-argcont (elem) + "Line up a continued argument. + +foo (xyz, aaa + bbb + ccc + + ddd + eee + fff); <- c-lineup-argcont + +Only continuation lines like this are touched, `nil' is returned on lines +which are the start of an argument. + +Within a gcc asm block, \":\" is recognised as an argument separator, +but of course only between operand specifications, not in the expressions +for the operands. + +Works with: arglist-cont, arglist-cont-nonempty." + + (save-excursion + (beginning-of-line) + (let ((bol (point))) + + ;; Previous line ending in a comma means we're the start of an + ;; argument. This should quickly catch most cases not for us. + (c-backward-syntactic-ws) + (let ((c (char-before))) + (unless (eq c ?,) + + ;; In a gcc asm, ":" on the previous line means the start of an + ;; argument. And lines starting with ":" are not for us, don't + ;; want them to indent to the preceding operand. + (let ((gcc-asm (save-excursion + (goto-char bol) + (c-in-gcc-asm-p)))) + (unless (and gcc-asm + (or (eq c ?:) + (save-excursion + (goto-char bol) + (looking-at "[ \t]*:")))) + + (c-lineup-argcont-scan (if gcc-asm ?:)) + (vector (current-column))))))))) + +(defun c-lineup-argcont-scan (&optional other-match) + ;; Find the start of an argument, for `c-lineup-argcont'. + (when (eq 0 (c-backward-token-1 1 t)) + (let ((c (char-after))) + (if (or (eq c ?,) (eq c other-match)) + (progn + (forward-char) + (c-forward-syntactic-ws)) + (c-lineup-argcont-scan other-match))))) (defun c-lineup-arglist-intro-after-paren (langelem) "Line up a line just after the open paren of the surrounding paren or @@ -98,13 +158,10 @@ brace block. Works with: defun-block-intro, brace-list-intro, statement-block-intro, statement-case-intro, arglist-intro." (save-excursion - (let ((langelem-col (c-langelem-col langelem t)) - (ce-curcol (save-excursion - (beginning-of-line) - (backward-up-list 1) - (skip-chars-forward " \t" (c-point 'eol)) - (current-column)))) - (- ce-curcol langelem-col -1)))) + (beginning-of-line) + (backward-up-list 1) + (skip-chars-forward " \t" (c-point 'eol)) + (vector (1+ (current-column))))) (defun c-lineup-arglist-close-under-paren (langelem) "Line up a closing paren line under the corresponding open paren. @@ -114,12 +171,9 @@ brace-list-close, arglist-close, extern-lang-close, namespace-close \(for most of these, a zero offset will normally produce the same result, though)." (save-excursion - (let ((langelem-col (c-langelem-col langelem t)) - (ce-curcol (save-excursion - (beginning-of-line) - (backward-up-list 1) - (current-column)))) - (- ce-curcol langelem-col)))) + (beginning-of-line) + (backward-up-list 1) + (vector (current-column)))) (defun c-lineup-close-paren (langelem) "Line up the closing paren under its corresponding open paren if the @@ -147,7 +201,7 @@ brace-list-close, arglist-close, extern-lang-close, namespace-close." (c-forward-syntactic-ws (c-point 'eol)) (if (eolp) 0 - (- opencol (c-langelem-col langelem t)))) + (vector opencol))) (error nil)))) (defun c-lineup-streamop (langelem) @@ -155,10 +209,10 @@ brace-list-close, arglist-close, extern-lang-close, namespace-close." Works with: stream-op." (save-excursion - (let ((langelem-col (c-langelem-col langelem))) - (re-search-forward "<<\\|>>" (c-point 'eol) 'move) - (goto-char (match-beginning 0)) - (- (current-column) langelem-col)))) + (goto-char (cdr langelem)) + (re-search-forward "<<\\|>>" (c-point 'eol) 'move) + (goto-char (match-beginning 0)) + (vector (current-column)))) (defun c-lineup-multi-inher (langelem) "Line up the classes in C++ multiple inheritance clauses and member @@ -182,8 +236,8 @@ Works with: inher-cont, member-init-cont." (here (point)) (char-after-ip (progn (skip-chars-forward " \t") - (char-after))) - (langelem-col (c-langelem-col langelem))) + (char-after)))) + (if (cdr langelem) (goto-char (cdr langelem))) ;; This kludge is necessary to support both inher-cont and ;; member-init-cont, since they have different anchor positions. @@ -199,7 +253,7 @@ Works with: inher-cont, member-init-cont." (if (or (eolp) (looking-at c-comment-start-regexp)) (c-forward-syntactic-ws here)) - (- (current-column) langelem-col) + (vector (current-column)) ))) (defun c-lineup-java-inher (langelem) @@ -216,12 +270,12 @@ class Foo class Foo Works with: inher-cont." (save-excursion - (let ((langelem-col (c-langelem-col langelem))) - (forward-word 1) - (if (looking-at "[ \t]*$") - c-basic-offset - (c-forward-syntactic-ws) - (- (current-column) langelem-col))))) + (goto-char (cdr langelem)) + (forward-word 1) + (if (looking-at "[ \t]*$") + c-basic-offset + (c-forward-syntactic-ws) + (vector (current-column))))) (defun c-lineup-java-throws (langelem) "Line up Java throws declarations. @@ -246,10 +300,9 @@ Works with: func-decl-cont." (throw 'done t)))))) (if throws (if (zerop (c-forward-token-1 1 nil (c-point 'eol))) - (- (current-column) (c-langelem-col langelem)) + (vector (current-column)) (back-to-indentation) - (+ (- (current-column) (c-langelem-col langelem)) - c-basic-offset)) + (vector (+ (current-column) c-basic-offset))) c-basic-offset)))) (defun c-indent-one-line-block (langelem) @@ -332,21 +385,33 @@ Works with: The `c' syntactic symbol." (if (looking-at c-current-comment-prefix) (- (match-end 0) (point)) 0))) - (starterlen (save-excursion - (goto-char (cdr langelem)) - (looking-at comment-start-skip) - (- (save-excursion - (goto-char (match-end 0)) - (skip-chars-backward " \t") - (point)) - (or (match-end 1) (point)) - 1))) ; Don't count the first '/'. - (langelem-col (save-excursion (c-langelem-col langelem)))) + (starterlen + ;; Get the length of the comment starter, not including + ;; the first '/'. We check if the comment prefix matched + ;; on the current line matches the starter or if it + ;; matches comment-start-skip, and choose whichever is + ;; longest. + (max (save-excursion + (goto-char (1+ (cdr langelem))) + (if (and (match-string 0) + (looking-at (regexp-quote (match-string 0)))) + (- (match-end 0) (match-beginning 0)) + 0)) + (save-excursion + (goto-char (cdr langelem)) + (looking-at comment-start-skip) + (- (or (match-end 1) + (save-excursion + (goto-char (match-end 0)) + (skip-chars-backward " \t") + (point))) + (point) + 1))))) (if (and (> starterlen 10) (zerop prefixlen)) ;; The comment has a long starter and the line doesn't have ;; a nonempty comment prefix. Treat it as free form text ;; and don't change the indentation. - (- (current-column) langelem-col) + (vector (current-column)) (forward-line -1) (back-to-indentation) (if (>= (cdr langelem) (point)) @@ -356,11 +421,14 @@ Works with: The `c' syntactic symbol." ;; starter. (progn (goto-char (match-end 0)) - (if (looking-at "\\([ \t]+\\).+$") - ;; Align with the text that hangs after the - ;; comment starter. - (goto-char (match-end 1))) - (- (current-column) langelem-col)) + ;; The following should not be necessary, since + ;; comment-start-skip should match everything (i.e. + ;; typically whitespace) that leads up to the text. + ;;(if (looking-at "\\([ \t]+\\).+$") + ;; ;; Align with the text that hangs after the + ;; ;; comment starter. + ;; (goto-char (match-end 1))) + (vector (current-column))) ;; How long is the comment starter? if greater than the ;; length of the comment prefix, align left. if less ;; than or equal, align right. this should also pick up @@ -368,10 +436,9 @@ Works with: The `c' syntactic symbol." (if (> starterlen prefixlen) (progn (goto-char (cdr langelem)) - (- (current-column) -1 langelem-col)) - (goto-char (match-end 0)) - (skip-chars-backward " \t") - (- (current-column) prefixlen langelem-col))) + (vector (1+ (current-column)))) + (goto-char (+ (cdr langelem) starterlen 1)) + (vector (- (current-column) prefixlen)))) ;; Not on the second line in the comment. If the previous ;; line has a nonempty comment prefix, align with it. ;; Otherwise, align with the previous nonempty line, but @@ -389,7 +456,7 @@ Works with: The `c' syntactic symbol." ;; Align with the comment starter rather than ;; with the code before it. (goto-char (cdr langelem))))) - (- (current-column) langelem-col)))))) + (vector (current-column))))))) (defun c-lineup-comment (langelem) "Line up a comment start according to `c-comment-only-line-offset'. @@ -416,6 +483,30 @@ Works with: comment-intro." -1000)) ;jam it against the left side )))) +(defun c-lineup-knr-region-comment (langelem) + "Line up a comment in the \"K&R region\" with the declaration. +That is the region between the function or class header and the +beginning of the block. E.g: + +int main() +/* This is the main function. */ <- c-lineup-knr-region-comment +{ + return 0; +} + +Return nil if called in any other situation, to be useful in list +expressions. + +Works with: comment-intro." + (when (or (assq 'topmost-intro-cont c-syntactic-context) + (assq 'func-decl-cont c-syntactic-context) + (assq 'knr-argdecl-intro c-syntactic-context) + (assq 'lambda-intro-cont c-syntactic-context)) + (save-excursion + (beginning-of-line) + (c-beginning-of-statement-1) + (vector (current-column))))) + (defun c-lineup-runin-statements (langelem) "Line up statements when the first statement is on the same line as the block opening brace. E.g: @@ -431,11 +522,11 @@ returned. This makes the function usable in list expressions. Works with: The `statement' syntactic symbol." (if (eq (char-after (cdr langelem)) ?{) (save-excursion - (let ((langelem-col (c-langelem-col langelem))) - (forward-char 1) - (skip-chars-forward " \t") - (unless (eolp) - (- (current-column) langelem-col)))))) + (if (cdr langelem) (goto-char (cdr langelem))) + (forward-char 1) + (skip-chars-forward " \t") + (unless (eolp) + (vector (current-column)))))) (defun c-lineup-math (langelem) "Line up the current line after the equal sign on the first line in @@ -443,7 +534,7 @@ the statement. If there isn't any, indent with `c-basic-offset'. If the current line contains an equal sign too, try to align it with the first one. -Works with: statement-cont." +Works with: statement-cont, arglist-cont, arglist-cont-nonempty." (save-excursion (let ((equalp (save-excursion (goto-char (c-point 'boi)) @@ -453,8 +544,8 @@ Works with: statement-cont." (= (c-forward-token-1 1 t eol) 0)))) (and (eq (char-after) ?=) (- (point) (c-point 'boi))))) - (langelem-col (c-langelem-col langelem)) donep) + (if (cdr langelem) (goto-char (cdr langelem))) (while (and (not donep) (< (point) (c-point 'eol))) (skip-chars-forward "^=" (c-point 'eol)) @@ -475,9 +566,39 @@ Works with: statement-cont." (forward-char 1) (skip-chars-forward " \t") (setq equalp 0))) - (- (current-column) equalp langelem-col)) + (vector (- (current-column) equalp))) ))) +(defun c-lineup-cascaded-calls (langelem) + "Line up \"cascaded calls\" under each other. +If the line begins with \"->\" and the preceding line ends with one or +more function calls preceded by \"->\", then the arrow is lined up with +the first of those \"->\". E.g: + +result = proc->add(17)->add(18) + ->add(19) + <- c-lineup-cascaded-calls + offset; <- c-lineup-cascaded-calls (inactive) + +In any other situation nil is returned to allow use in list +expressions. + +Works with: statement-cont, arglist-cont, arglist-cont-nonempty." + (save-excursion + (let ((bopl (c-point 'bopl)) col) + (back-to-indentation) + (when (and (looking-at "->") + (= (c-backward-token-1 1 t bopl) 0) + (eq (char-after) ?\() + (= (c-backward-token-1 3 t bopl) 0) + (looking-at "->")) + (setq col (current-column)) + (while (and (= (c-backward-token-1 1 t bopl) 0) + (eq (char-after) ?\() + (= (c-backward-token-1 3 t bopl) 0) + (looking-at "->")) + (setq col (current-column))) + (vector col))))) + (defun c-lineup-template-args (langelem) "Line up template argument lines under the first argument. To allow this function to be used in a list expression, nil is @@ -490,7 +611,7 @@ Works with: template-args-cont." (backward-up-list 1) (if (and (eq (char-after) ?<) (zerop (c-forward-token-1 1 nil (c-point 'eol)))) - (- (current-column) (c-langelem-col langelem)))))) + (vector (current-column)))))) (defun c-lineup-ObjC-method-call (langelem) "Line up selector args as elisp-mode does with function args: @@ -579,10 +700,20 @@ construct. Works with: inlambda, inexpr-statement, inexpr-class." (save-excursion (back-to-indentation) - (let ((res (or (c-looking-at-inexpr-block) - (if (c-safe (backward-up-list 1) - (eq (char-after) ?{)) - (c-looking-at-inexpr-block))))) + (let* ((paren-state (c-parse-state)) + (containing-sexp (c-most-enclosing-brace paren-state)) + (res (or (c-looking-at-inexpr-block + (c-safe-position containing-sexp paren-state) + containing-sexp) + (and containing-sexp + (progn (goto-char containing-sexp) + (eq (char-after) ?{)) + (progn (setq containing-sexp + (c-most-enclosing-brace paren-state + (point))) + (c-looking-at-inexpr-block + (c-safe-position containing-sexp paren-state) + containing-sexp)))))) (when res (goto-char (cdr res)) (- (current-column) @@ -614,6 +745,134 @@ inextern-lang, innamespace." 0 c-basic-offset))) +(defun c-lineup-cpp-define (langelem) + "Line up macro continuation lines according to the indentation of +the construct preceding the macro. E.g: + +v beg of preceding constr v beg of preceding constr + int dribble() { +const char msg[] = if (!running) + \"Some text.\"; error(\"Not running!\"); + +#define X(A, B) \ #define X(A, B) \ +do { \ <-> do { \ <- c-lineup-cpp-define + printf (A, B); \ printf (A, B); \ +} while (0) } while (0) + +If `c-syntactic-indentation-in-macros' is non-nil, the function +returns the relative indentation to the macro start line to allow +accumulation with other offsets. E.g. in the following cases, +cpp-define-intro is combined with the statement-block-intro that comes +from the \"do {\" that hangs on the \"#define\" line: + + int dribble() { +const char msg[] = if (!running) + \"Some text.\"; error(\"Not running!\"); + +#define X(A, B) do { \ #define X(A, B) do { \ + printf (A, B); \ <-> printf (A, B); \ <- c-lineup-cpp-define + this->refs++; \ this->refs++; \ +} while (0) <-> } while (0) <- c-lineup-cpp-define + +The relative indentation returned by `c-lineup-cpp-define' is zero and +two, respectively, in these two examples. They are then added to the +two column indentation that statement-block-intro gives in both cases +here. + +If the relative indentation is zero, then nil is returned instead. +This useful in a list expression to specify the default indentation on +the top level. + +If `c-syntactic-indentation-in-macros' is nil then this function keeps +the current indentation, except for empty lines \(ignoring the ending +backslash) where it takes the indentation from the closest preceding +nonempty line in the macro. If there's no such line in the macro then +the indentation is taken from the construct preceding it, as described +above. + +Works with: cpp-define-intro." + (let (offset) + (if c-syntactic-indentation-in-macros + ;; Go to the macro start and do a syntactic analysis of it. + ;; Then remove the cpp-macro element it should contain and + ;; calculate the indentation it then would get. + (save-excursion + (c-beginning-of-macro) + (setq offset (- (c-get-syntactic-indentation + (delete '(cpp-macro) (c-guess-basic-syntax))) + (save-excursion + (back-to-indentation) + (current-column)))) + (if (zerop offset) + nil + offset)) + ;; Do not indent syntactically inside the macro. + (save-excursion + (let ((macro-start-line (save-excursion + (goto-char (c-query-macro-start)) + (beginning-of-line) + (point)))) + (beginning-of-line) + ;; Check every line while inside the macro. + (while (and (> (point) macro-start-line) + (looking-at "[ \t]*\\\\?$") + (= (forward-line -1) 0))) + (if (<= (point) macro-start-line) + ;; If we've stepped out of the macro we take the + ;; syntactic offset. + (setq offset (c-get-syntactic-indentation + (delete '(cpp-macro) (c-guess-basic-syntax)))) + (setq offset (current-indentation))) + (if (zerop offset) + nil + (vector offset))))))) + +;; Contributed by Kevin Ryde <user42@zip.com.au>. +(defun c-lineup-gcc-asm-reg (elem) + "Line up a gcc asm register under one on a previous line. + + asm (\"foo %1, %0\\n\" + \"bar %0, %1\" + : \"=r\" (w), + \"=r\" (x) + : \"0\" (y), + \"1\" (z)); + +The \"x\" line is aligned to the text after the \":\" on the \"w\" line, and +similarly \"z\" under \"y\". + +This is done only in an \"asm\" or \"__asm__\" block, and only to those +lines mentioned. Anywhere else `nil' is returned. The usual arrangement is +to have this routine as an extra feature at the start of arglist lineups, e.g. + + (c-lineup-gcc-asm-reg c-lineup-arglist) + +Works with: arglist-cont, arglist-cont-nonempty." + + (let ((orig-pos (point)) + alignto) + (save-excursion + (and + c-opt-asm-stmt-key + + ;; Find the ":" to align to. Look for this first so as to quickly + ;; eliminate pretty much all cases which are not for us. + (re-search-backward "^[ \t]*:[ \t]*\\(.\\)?" (cdr elem) t) + + ;; Must have something after the ":". + (setq alignto (match-beginning 1)) + + ;; Don't touch ":" lines themselves. + (progn (goto-char orig-pos) + (beginning-of-line) + (not (looking-at "^[ \t]*:"))) + + ;; Only operate in an asm statement. + (progn (goto-char orig-pos) + (c-in-gcc-asm-p)) + + (vector (progn (goto-char alignto) (current-column))))))) + (defun c-lineup-dont-change (langelem) "Do not change the indentation of the current line. @@ -663,7 +922,7 @@ indentation amount." (setq syntax nil) (back-to-indentation) (if (zerop (current-column)) - (insert (make-string c-label-minimum-indentation 32))) + (insert-char ?\ c-label-minimum-indentation t)) )) )))) |