# HG changeset patch # User Barry A. Warsaw # Date 918492798 0 # Node ID 5b0864259a4b3fa59d59804627fb545ac3e5f6d9 # Parent d03b1e915af1128a68fab4cfd3b986820a88daf2 Installed CC Mode 5.25. diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-align.el --- a/lisp/progmodes/cc-align.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-align.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -28,6 +29,7 @@ ;; Boston, MA 02111-1307, USA. (eval-when-compile + (require 'cc-defs) (require 'cc-vars) (require 'cc-engine) (require 'cc-langs)) @@ -57,7 +59,7 @@ (beginning-of-line) (looking-at "[ \t]*)")) (progn (goto-char (match-end 0)) - (forward-sexp -1) + (c-forward-sexp -1) (forward-char 1) (c-forward-syntactic-ws) (- (current-column) langelem-col)) @@ -111,9 +113,8 @@ (let (opencol spec) (beginning-of-line) (backward-up-list 1) - (setq spec (if (fboundp 'c-looking-at-special-brace-list) - (c-looking-at-special-brace-list))) - (if spec (goto-char (car spec))) + (setq spec (c-looking-at-special-brace-list)) + (if spec (goto-char (car (car spec)))) (setq opencol (current-column)) (forward-char 1) (if spec (progn @@ -194,9 +195,7 @@ (beginning-of-line) (skip-chars-forward " \t") (if (and (eq (following-char) ?{) - (condition-case nil - (progn (forward-sexp) t) - (error nil)) + (c-safe (progn (c-forward-sexp) t)) (<= (point) eol) (eq (preceding-char) ?})) c-basic-offset @@ -291,7 +290,11 @@ (if (c-in-literal (cdr langelem)) (forward-char 1) (setq donep t))) - (if (not (eq (char-after) ?=)) + (if (or (not (eq (char-after) ?=)) + (save-excursion + (forward-char 1) + (c-forward-syntactic-ws (c-point 'eol)) + (eolp))) ;; there's no equal sign on the line c-basic-offset ;; calculate indentation column after equals and ws, unless @@ -324,7 +327,7 @@ (current-column))) (target-col (progn (forward-char) - (forward-sexp) + (c-forward-sexp) (skip-chars-forward " \t") (if (eolp) (+ open-bracket-col c-basic-offset) @@ -373,6 +376,26 @@ (+ curcol (- prev-col-column (current-column))) c-basic-offset))))) +(defun c-lineup-inexpr-block (langelem) + ;; This function lines up the block for the various constructs that + ;; uses a block inside an expression. For constructs matching + ;; c-lambda-key and c-inexpr-block-key, indentation to the column of + ;; the beginning of the match is added. For standalone statement + ;; blocks, indentation to the column of the opening brace is added. + (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))))) + (if (not res) + 0 + (goto-char (cdr res)) + (- (current-column) + (progn + (back-to-indentation) + (current-column))))))) + (defun c-lineup-dont-change (langelem) ;; Do not change the indentation of the current line (save-excursion @@ -394,7 +417,7 @@ (setq langelem (assq 'block-close c-syntactic-context)) (progn (goto-char (cdr langelem)) (if (eq (char-after) ?{) - (c-safe (forward-sexp -1))) + (c-safe (c-forward-sexp -1))) (looking-at "\\[^_]"))) '(before) '(before after))))) diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-cmds.el --- a/lisp/progmodes/cc-cmds.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-cmds.el Mon Feb 08 16:53:18 1999 +0000 @@ -1,11 +1,12 @@ -;;; cc-cmds.el --- user level commands for CC Mode +;;; cc-cmds.el --- user level commands for CC Mode -;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. +;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Softare Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -29,6 +30,9 @@ +(eval-when-compile + (require 'cc-defs)) + (defun c-calculate-state (arg prevstate) ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If ;; arg is nil or zero, toggle the state. If arg is negative, turn @@ -128,8 +132,10 @@ nil, or point is inside a literal then the function in the variable `c-delete-function' is called." (interactive "*P") - (if (and (boundp 'delete-key-deletes-forward) - delete-key-deletes-forward) + (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21 + (delete-forward-p)) + (and (boundp 'delete-key-deletes-forward) ;XEmacs 20 + delete-key-deletes-forward)) (if (or (not c-hungry-delete-key) arg (c-in-literal)) @@ -148,9 +154,10 @@ `c-electric-pound-behavior'. If a numeric ARG is supplied, or if point is inside a literal, nothing special happens." (interactive "*P") - (if (or (c-in-literal) - arg - (not (memq 'alignleft c-electric-pound-behavior))) + (if (or arg + (not (memq 'alignleft c-electric-pound-behavior)) + (save-excursion (skip-chars-backward " \t") (not (bolp))) + (c-in-literal)) ;; do nothing special (self-insert-command (prefix-numeric-value arg)) ;; place the pound character at the left edge @@ -172,7 +179,10 @@ Also, the line is re-indented unless a numeric ARG is supplied, there are non-whitespace characters present on the line after the brace, or -the brace is inserted inside a literal." +the brace is inserted inside a literal. + +This function does various newline cleanups based on the value of +`c-cleanup-list'." (interactive "*P") (let* ((c-state-cache (c-parse-state)) (safepos (c-safe-position (point) c-state-cache)) @@ -180,8 +190,8 @@ ;; if we're in a literal, or we're not at the end of the line, or ;; a numeric arg is provided, or auto-newlining is turned off, ;; then just insert the character. - (if (or literal arg -; (not c-auto-newline) + (if (or literal + arg (not (looking-at "[ \t]*$"))) (self-insert-command (prefix-numeric-value arg)) (let* ((syms @@ -191,11 +201,12 @@ '(class-open class-close defun-open defun-close inline-open inline-close brace-list-open brace-list-close - brace-list-intro brace-list-entry + brace-list-intro brace-entry-open block-open block-close substatement-open statement-case-open extern-lang-open extern-lang-close namespace-open namespace-close + inexpr-class-open inexpr-class-close )) ;; we want to inhibit blinking the paren since this will ;; be most disruptive. we'll blink it ourselves later on @@ -220,8 +231,32 @@ (c-guess-basic-syntax))) (newlines (and c-auto-newline - (or (c-lookup-lists syms syntax c-hanging-braces-alist) + (or (c-lookup-lists + syms + ;; Substitute inexpr-class and class-open + ;; or class-close with inexpr-class-open + ;; or inexpr-class-close. + (if (assq 'inexpr-class syntax) + (cond ((assq 'class-open syntax) + '((inexpr-class-open))) + ((assq 'class-close syntax) + '((inexpr-class-close))) + (t syntax)) + syntax) + c-hanging-braces-alist) '(ignore before after))))) + ;; Do not try to insert newlines around a special (Pike-style) + ;; brace list. + (if (and c-special-brace-lists + (c-intersect-lists '(brace-list-open brace-list-close + brace-list-intro brace-entry-open) + syntax) + (save-excursion + (c-safe (if (= (char-before) ?{) + (forward-char -1) + (c-forward-sexp -1)) + (c-looking-at-special-brace-list)))) + (setq newlines nil)) ;; If syntax is a function symbol, then call it using the ;; defined semantics. (if (and (not (consp (cdr newlines))) @@ -234,29 +269,26 @@ ;; we leave the newline we've put in there before, ;; but we need to re-indent the line above (let ((pos (- (point-max) (point))) - (here (point)) - (c-state-cache c-state-cache)) + (here (point))) (forward-line -1) - ;; we may need to update the cache. this should still be - ;; faster than recalculating the state in many cases - (save-excursion - (save-restriction - (narrow-to-region here (point)) - (if (and (c-safe (progn (backward-up-list -1) t)) - (memq (char-before) '(?\) ?})) - (progn (widen) - (c-safe (progn (forward-sexp -1) t)))) - (setq c-state-cache - (c-hack-state (point) 'open c-state-cache)) - (if (and (car c-state-cache) - (not (consp (car c-state-cache))) - (<= (point) (car c-state-cache))) - (setq c-state-cache (cdr c-state-cache)) - )))) - (let ((here (point)) - (shift (c-indent-line))) - (setq c-state-cache (c-adjust-state (c-point 'bol) here - (- shift) c-state-cache))) + (let ((c-state-cache (c-whack-state (point) c-state-cache))) + ;; we may need to update the cache. this should + ;; still be faster than recalculating the state + ;; in many cases + (save-excursion + (save-restriction + (narrow-to-region here (point)) + (if (and (c-safe (progn (backward-up-list -1) t)) + (memq (char-before) '(?\) ?})) + (progn (widen) + (c-safe (progn (c-forward-sexp -1) + t)))) + (setq c-state-cache + (c-hack-state (point) 'open c-state-cache))))) + (c-indent-line)) + (setq c-state-cache (c-adjust-state (c-point 'bol) here + (- (point) (c-point 'bol)) + c-state-cache)) (goto-char (- (point-max) pos)) ;; if the buffer has changed due to the indentation, we ;; need to recalculate syntax for the current line, but @@ -291,10 +323,11 @@ ;; now adjust the line's indentation. don't update the state ;; cache since c-guess-basic-syntax isn't called when the ;; syntax is passed to c-indent-line - (let ((here (point)) - (shift (c-indent-line syntax))) + (let* ((here (point))) + (c-indent-line syntax) (setq c-state-cache (c-adjust-state (c-point 'bol) here - (- shift) c-state-cache))) + (- (c-point 'boi) (c-point 'bol)) + c-state-cache))) ;; Do all appropriate clean ups (let ((here (point)) (pos (- (point-max) (point))) @@ -325,22 +358,6 @@ (progn (delete-region mbeg mend) (insert "} else {"))) - ;; clean up brace-elseif-brace - (if (and c-auto-newline - (memq 'brace-elseif-brace c-cleanup-list) - (eq last-command-char ?\{) - (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*" nil t) - (save-excursion - (goto-char (match-end 0)) - (c-safe (forward-sexp 1)) - (skip-chars-forward " \t\n") - (setq mbeg (match-beginning 0) - mend (match-end 0)) - (= here (1+ (point)))) - (not (c-in-literal))) - (progn - (delete-region mbeg mend) - (insert "} else if "))) (goto-char (- (point-max) pos)) ) ;; does a newline go after the brace? @@ -359,7 +376,7 @@ (c-backward-syntactic-ws safepos) (funcall old-blink-paren))) )))) - + (defun c-electric-slash (arg) "Insert a slash character. @@ -422,7 +439,10 @@ When semicolon is inserted, the line is re-indented unless a numeric arg is supplied, point is inside a literal, or there are -non-whitespace characters on the line following the semicolon." +non-whitespace characters on the line following the semicolon. + +Based on the value of `c-cleanup-list', this function cleans up commas +following brace lists and semicolons following defuns." (interactive "*P") (let* ((lim (c-most-enclosing-brace (c-parse-state))) (literal (c-in-literal lim)) @@ -435,9 +455,10 @@ (self-insert-command (prefix-numeric-value arg)) ;; do some special stuff with the character (self-insert-command (prefix-numeric-value arg)) - ;; do all cleanups, reindentations, and newline insertions, but - ;; only if c-auto-newline is turned on - (if (not c-auto-newline) nil + ;; do all cleanups and newline insertions if c-auto-newline is + ;; turned on + (if (not c-auto-newline) + (c-indent-line) ;; clean ups (let ((pos (- (point-max) (point)))) (if (and (or (and @@ -524,10 +545,11 @@ (or (c-lookup-lists '(case-label label access-label) syntax c-hanging-colons-alist) (c-lookup-lists '(member-init-intro inher-intro) - (prog2 - (insert "\n") - (c-guess-basic-syntax) - (delete-char -1)) + (let ((buffer-undo-list t)) + (insert "\n") + (unwind-protect + (c-guess-basic-syntax) + (delete-char -1))) c-hanging-colons-alist)))) ;; indent the current line (c-indent-line syntax) @@ -554,13 +576,10 @@ (defun c-electric-lt-gt (arg) "Insert a less-than, or greater-than character. -When the auto-newline feature is turned on, as evidenced by the \"/a\" -or \"/ah\" string on the mode line, the line will be re-indented if -the character inserted is the second of a C++ style stream operator -and the buffer is in C++ mode. - -The line will also not be re-indented if a numeric argument is -supplied, or point is inside a literal." +The line will be re-indented if the character inserted is the second +of a C++ style stream operator and the buffer is in C++ mode. +Exceptions are when a numeric argument is supplied, or point is inside +a literal, in which case the line will not be re-indented." (interactive "*P") (let ((indentp (and (not arg) (eq (char-before) last-command-char) @@ -571,6 +590,65 @@ (if indentp (c-indent-line)))) +(defun c-electric-paren (arg) + "Insert a parenthesis. + +If the auto-newline feature is turned on, as evidenced by the \"/a\" +or \"/ah\" string on the mode line, some newline cleanups are done if +appropriate; see the variable `c-cleanup-list'. + +Also, the line is re-indented unless a numeric ARG is supplied, there +are non-whitespace characters present on the line after the colon, or +the colon is inserted inside a literal." + (interactive "*P") + (let (;; shut this up + (c-echo-syntactic-information-p nil)) + (if (or arg + (not (looking-at "[ \t]*$")) + (c-in-literal (c-point 'bod))) + (self-insert-command (prefix-numeric-value arg)) + ;; do some special stuff with the character + (let* (;; We want to inhibit blinking the paren since this will + ;; be most disruptive. We'll blink it ourselves + ;; afterwards. + (old-blink-paren blink-paren-function) + blink-paren-function) + (self-insert-command (prefix-numeric-value arg)) + (c-indent-line) + (when c-auto-newline + ;; Do all appropriate clean ups + (let ((here (point)) + (pos (- (point-max) (point))) + mbeg mend) + ;; clean up brace-elseif-brace + (if (and (memq 'brace-elseif-brace c-cleanup-list) + (eq last-command-char ?\() + (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*(" + nil t) + (save-excursion + (setq mbeg (match-beginning 0) + mend (match-end 0)) + (= mend here)) + (not (c-in-literal))) + (progn + (delete-region mbeg mend) + (insert "} else if ("))) + ;; clean up brace-catch-brace + (if (and (memq 'brace-catch-brace c-cleanup-list) + (eq last-command-char ?\() + (re-search-backward "}[ \t\n]*catch[ \t\n]*(" nil t) + (save-excursion + (setq mbeg (match-beginning 0) + mend (match-end 0)) + (= mend here)) + (not (c-in-literal))) + (progn + (delete-region mbeg mend) + (insert "} catch ("))) + (goto-char (- (point-max) pos)) + )) + (funcall old-blink-paren))))) + ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus @@ -639,6 +717,8 @@ An end of a defun occurs right after the close-parenthesis that matches the open-parenthesis that starts a defun; see `beginning-of-defun'." (interactive "p") + (if (not arg) + (setq arg 1)) (if (< arg 0) (c-beginning-of-defun (- arg)) (while (> arg 0) @@ -646,9 +726,9 @@ (while (and (c-safe (down-list 1) t) (not (eq (char-before) ?{))) (forward-char -1) - (forward-sexp)) + (c-forward-sexp)) (c-beginning-of-defun 1) - (forward-sexp 1) + (c-forward-sexp 1) (setq arg (1- arg))) (forward-line 1)) (c-keep-region-active)) @@ -734,20 +814,13 @@ ;; perhaps they should be changed, but that'd likely break a ;; lot in cc-engine. (goto-char here) - ;; Move out of any enclosing non-`{ }' parens. - (let ((last (point))) - (while (and (c-safe (progn (up-list 1) t)) - (/= (char-before) ?\})) - (setq last (point))) - (goto-char last)) (if (> count 0) (if (condition-case nil ;; Stop before `{' and after `;', `{', `}' and - ;; `};' when not followed by `}', but on the other - ;; side of the syntactic ws. Also stop before - ;; `}', but only to catch comments. Move by sexps - ;; and move into `{ }', but not into any other - ;; other type of paren. + ;; `};' when not followed by `}' or `)', but on + ;; the other side of the syntactic ws. Also stop + ;; before `}', but only to catch comments. Move + ;; by sexps and move into parens. (catch 'done (let (last) (while t @@ -767,33 +840,37 @@ ((progn (backward-char) (looking-at "[;{}]")) (if (or (= here last) - (= (char-after last) ?})) + (memq (char-after last) '(?\) ?}))) (if (and (= (char-before) ?}) (= (char-after) ?\;)) (backward-char)) (goto-char last) (throw 'done t))) - ((or (= (char-syntax (char-after)) ?\)) - (= (char-syntax (char-after)) ?\")) + ((= (char-syntax (char-after)) ?\") (forward-char) - (backward-sexp)) + (c-backward-sexp)) )))) (error (goto-char (point-min)) t)) (setq count (1- count))) (if (condition-case nil - ;; Stop before `{' and `}' and after `;', `}' and - ;; `};'. Also stop after `{', but only to catch - ;; comments. Move by sexps and move into `{ }', but - ;; not into any other other type of paren. + ;; Stop before `{' and `}', but on the other side of + ;; the syntactic ws, and after `;', `}' and `};'. + ;; Only stop before `{' if at top level or inside + ;; braces, though. Also stop after `{', but only to + ;; catch comments. Move by sexps and move into + ;; parens. (catch 'done (let (last) (while t (setq last (point)) (c-forward-syntactic-ws) (cond ((= (char-after) ?{) - (if (= here last) + (if (or (= here last) + (save-excursion + (and (c-safe (progn (up-list -1) t)) + (/= (char-after) ?{)))) (progn (forward-char) (throw 'done nil)) (goto-char last) @@ -805,9 +882,8 @@ ((looking-at ";\\|};?") (goto-char (match-end 0)) (throw 'done t)) - ((or (= (char-syntax (char-after)) ?\() - (= (char-syntax (char-after)) ?\")) - (forward-sexp)) + ((= (char-syntax (char-after)) ?\") + (c-forward-sexp)) (t (forward-char)) )))) @@ -855,7 +931,8 @@ c-electric-star c-electric-semi&comma c-electric-lt-gt - c-electric-colon)) + c-electric-colon + c-electric-paren)) (put 'c-electric-delete 'delete-selection 'supersede) ; delsel (put 'c-electric-delete 'pending-delete 'supersede) ; pending-del (put 'c-electric-backspace 'delete-selection 'supersede) ; delsel @@ -883,13 +960,13 @@ ((or (looking-at "^#[ \t]*endif[ \t]*") (looking-at "^#[ \t]*else[ \t]*")) 7) - ;; CASE 3: when comment-column is nil, calculate the offset - ;; according to c-offsets-alist. E.g. identical to hitting - ;; TAB. + ;; CASE 3: when c-indent-comments-syntactically-p is t, + ;; calculate the offset according to c-offsets-alist. + ;; E.g. identical to hitting TAB. ((and c-indent-comments-syntactically-p (save-excursion (skip-chars-forward " \t") - (or (looking-at comment-start) + (or (looking-at c-comment-start-regexp) (eolp)))) (let ((syntax (c-guess-basic-syntax))) ;; BOGOSITY ALERT: if we're looking at the eol, its @@ -944,7 +1021,8 @@ (let ((literal (c-in-literal)) at-comment-col) (cond - ((eq literal 'string)) + ((eq literal 'string) + (insert ?\n)) ((or (not c-comment-continuation-stars) (not literal)) (indent-new-comment-line soft)) @@ -975,15 +1053,15 @@ (c-indent-line)))))) ;; advice for indent-new-comment-line for older Emacsen -(if (boundp 'comment-line-break-function) - nil - (require 'advice) - (defadvice indent-new-comment-line (around c-line-break-advice activate) - (if (or (not c-buffer-is-cc-mode) - (not (c-in-literal)) - (not c-comment-continuation-stars)) - ad-do-it - (c-comment-line-break-function (ad-get-arg 0))))) +(or (boundp 'comment-line-break-function) + (defadvice indent-new-comment-line (around c-line-break-advice + activate preactivate) + "Calls c-comment-line-break-function if in a comment in CC Mode." + (if (or (not c-buffer-is-cc-mode) + (not (c-in-literal)) + (not c-comment-continuation-stars)) + ad-do-it + (c-comment-line-break-function (ad-get-arg 0))))) ;; used by outline-minor-mode (defun c-outline-level () @@ -1093,7 +1171,7 @@ just inserts a tab character, or the equivalent number of spaces, depending on the variable `indent-tabs-mode'." - (interactive "*P") + (interactive "P") (let ((bod (c-point 'bod))) (if whole-exp ;; If arg, always indent this line as C @@ -1104,7 +1182,7 @@ (if (eq c-tab-always-indent t) (beginning-of-line)) (setq beg (point)) - (forward-sexp 1) + (c-forward-sexp 1) (setq end (point)) (goto-char beg) (forward-line 1) @@ -1156,7 +1234,7 @@ (memq (char-after) '(?\( ?\[ ?\{)) (point))))))) ;; find balanced expression end - (setq end (and (c-safe (progn (forward-sexp 1) t)) + (setq end (and (c-safe (progn (c-forward-sexp 1) t)) (point-marker))) ;; sanity check (and (not start) @@ -1247,18 +1325,18 @@ (while (< (point) nextline) (condition-case nil (progn - (forward-sexp 1) + (c-forward-sexp 1) (setq sexpend (point))) (error (setq sexpend nil) (goto-char nextline))) (c-forward-syntactic-ws)) (if sexpend - (progn + (progn ;; make sure the sexp we found really starts on the ;; current line and extends past it (goto-char sexpend) (setq sexpend (point-marker)) - (c-safe (backward-sexp 1)) + (c-safe (c-backward-sexp 1)) (setq sexpbeg (point)))) (if (and sexpbeg (< sexpbeg fence)) (setq sexpbeg fence))) @@ -1295,30 +1373,68 @@ )))) (defun c-mark-function () - "Put mark at end of a C, C++, or Objective-C defun, point at beginning." + "Put mark at end of current top-level defun, point at beginning." (interactive) (let ((here (point)) - ;; there should be a c-point position for 'eod - (eod (save-excursion (end-of-defun) (point))) - (state (c-parse-state)) - brace) - (while state - (setq brace (car state)) - (if (consp brace) - (goto-char (cdr brace)) - (goto-char brace)) - (setq state (cdr state))) - (if (eq (char-after) ?{) - (progn - (forward-line -1) - (while (not (or (bobp) - (looking-at "[ \t]*$"))) - (forward-line -1))) - (forward-line 1) - (skip-chars-forward " \t\n")) + (eod (c-point 'eod)) + (state (c-parse-state))) + ;; Are we sitting at the top level, someplace between either the + ;; beginning of buffer, or the nearest preceding defun? If so, + ;; try first to figure out whether we're sitting on the + ;; introduction to a top-level defun, in which case we want to + ;; mark the entire defun we're sitting on. + ;; + ;; If we're sitting on anything else at the top-level, we want to + ;; just mark the statement that we're on + (if (or (and (consp (car state)) + (= (length state) 1)) + (null state)) + ;; Are we in the whitespace after the nearest preceding defun? + (if (and state + (looking-at "[ \t]*$") + (= (save-excursion + (c-backward-syntactic-ws) + (skip-chars-backward ";") + (point)) + (cdar state))) + (progn + (setq eod (point)) + (goto-char (caar state)) + (c-beginning-of-statement-1)) + (if (= ?{ (save-excursion + (c-end-of-statement-1) + (char-before))) + ;; We must be in a defuns's introduction + (progn + (c-end-of-statement-1) + (skip-chars-backward "{") + (c-beginning-of-statement-1) + (c-forward-syntactic-ws)) + ;; Just mark the statement + (c-end-of-statement-1) + (forward-line 1) + (setq eod (point)) + (c-beginning-of-statement-1))) + ;; We are inside some enclosing brace structure, so we first + ;; need to find our way to the least enclosing brace. Then, in + ;; both cases, we to mark the region from the beginning of the + ;; current statement, until the end of the next following defun + (while (and state) + (or (consp (car state)) + (goto-char (car state))) + (setq state (cdr state))) + (c-beginning-of-statement-1)) (push-mark here) (push-mark eod nil t))) +(defun c-indent-line-or-region () + "When the region is active, indent it. Otherwise indent the current line." + ;; Emacs has a variable called mark-active, XEmacs uses region-active-p + (interactive) + (if (c-region-is-active-p) + (c-indent-region (region-beginning) (region-end)) + (c-indent-command))) + ;; for progress reporting (defvar c-progress-info nil) @@ -1384,7 +1500,7 @@ This function does not modify blank lines at the start of the region. If the region ends at the start of a line, it always deletes the backslash (if any) at the end of the previous line. - + You can put the region around an entire macro definition and use this command to conveniently insert and align the necessary backslashes." (interactive "*r\nP") @@ -1548,65 +1664,69 @@ t))) ;; Inside a comment: fill one comment paragraph. (let ((fill-prefix - ;; The prefix for each line of this paragraph - ;; is the appropriate part of the start of this line, - ;; up to the column at which text should be indented. - (save-excursion - (beginning-of-line) - (if (looking-at ".*/\\*.*\\*/") - (progn (re-search-forward comment-start-skip) - (make-string (current-column) ?\ )) - (if first-line - (forward-line 1) - (if (and (looking-at "[ \t]*\\*/") - (not (save-excursion - (forward-line -1) - (looking-at ".*/\\*")))) - (forward-line -1))) + (or + ;; Keep user set fill prefix if any. + fill-prefix + ;; The prefix for each line of this paragraph + ;; is the appropriate part of the start of this line, + ;; up to the column at which text should be indented. + (save-excursion + (beginning-of-line) + (if (looking-at ".*/\\*.*\\*/") + (progn (re-search-forward comment-start-skip) + (make-string (current-column) ?\ )) + (if first-line + (forward-line 1) + (if (and (looking-at "[ \t]*\\*/") + (not (save-excursion + (forward-line -1) + (looking-at ".*/\\*")))) + (forward-line -1))) - (let ((line-width (progn (end-of-line) (current-column)))) - (beginning-of-line) - (prog1 - (buffer-substring - (point) + (let ((line-width (progn (end-of-line) + (current-column)))) + (beginning-of-line) + (prog1 + (buffer-substring + (point) - ;; How shall we decide where the end of the - ;; fill-prefix is? - (progn - (skip-chars-forward " \t*" (c-point 'eol)) - ;; kludge alert, watch out for */, in - ;; which case fill-prefix should *not* - ;; be "*"! - (if (and (eq (char-after) ?/) - (eq (char-before) ?*)) - (forward-char -1)) - (point))) + ;; How shall we decide where the end of the + ;; fill-prefix is? + (progn + (skip-chars-forward " \t*" (c-point 'eol)) + ;; kludge alert, watch out for */, in + ;; which case fill-prefix should *not* + ;; be "*"! + (if (and (eq (char-after) ?/) + (eq (char-before) ?*)) + (forward-char -1)) + (point))) - ;; If the comment is only one line followed - ;; by a blank line, calling move-to-column - ;; above may have added some spaces and tabs - ;; to the end of the line; the fill-paragraph - ;; function will then delete it and the - ;; newline following it, so we'll lose a - ;; blank line when we shouldn't. So delete - ;; anything move-to-column added to the end - ;; of the line. We record the line width - ;; instead of the position of the old line - ;; end because move-to-column might break a - ;; tab into spaces, and the new characters - ;; introduced there shouldn't be deleted. + ;; If the comment is only one line followed + ;; by a blank line, calling move-to-column + ;; above may have added some spaces and tabs + ;; to the end of the line; the fill-paragraph + ;; function will then delete it and the + ;; newline following it, so we'll lose a + ;; blank line when we shouldn't. So delete + ;; anything move-to-column added to the end + ;; of the line. We record the line width + ;; instead of the position of the old line + ;; end because move-to-column might break a + ;; tab into spaces, and the new characters + ;; introduced there shouldn't be deleted. - ;; If you can see a better way to do this, - ;; please make the change. This seems very - ;; messy to me. - (delete-region (progn (move-to-column line-width) - (point)) - (progn (end-of-line) (point)))))))) + ;; If you can see a better way to do this, + ;; please make the change. This seems very + ;; messy to me. + (delete-region (progn (move-to-column line-width) + (point)) + (progn (end-of-line) (point))))))))) ;; Lines containing just a comment start or just an end ;; should not be filled into paragraphs they are next ;; to. - (paragraph-start (if (eq major-mode 'java-mode) + (paragraph-start (if (c-major-mode-is 'java-mode) (concat paragraph-start re1 "\\(" c-Java-javadoc-paragraph-start @@ -1695,8 +1815,7 @@ (goto-char (car limits)) (end-of-line) (< (point) (cdr limits)))) - (let (fill-prefix - fill-paragraph-function) + (let (fill-paragraph-function) (save-restriction (narrow-to-region (save-excursion (goto-char (1+ (car limits))) diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-compat.el --- a/lisp/progmodes/cc-compat.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-compat.el Mon Feb 08 16:53:18 1999 +0000 @@ -1,9 +1,9 @@ ;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion -;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc. +;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. ;; Author: 1994-1997 Barry A. Warsaw -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: August 1994, split from cc-mode.el ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -40,6 +40,7 @@ ;;; Code: (eval-when-compile + (require 'cc-defs) (require 'cc-styles) (require 'cc-engine)) @@ -114,7 +115,7 @@ ;; line (progn (if (eq (char-before) ?\)) - (forward-sexp -1)) + (c-forward-sexp -1)) ;; Get initial indentation of the line we are on. (current-indentation))))) (- bocm-lossage curcol)))) diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-defs.el --- a/lisp/progmodes/cc-defs.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-defs.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -28,6 +29,25 @@ ;; Boston, MA 02111-1307, USA. +;; Get all the necessary compile time definitions. +(require 'custom) +(require 'cc-menus) +(require 'derived) ;only necessary in Emacs 20 + +;; cc-mode-19.el contains compatibility macros that should be compiled +;; in if needed. +(if (or (not (fboundp 'functionp)) + (not (condition-case nil + (progn (char-before) t) + (error nil))) + (not (condition-case nil + (progn (char-after) t) + (error nil))) + (not (fboundp 'when)) + (not (fboundp 'unless))) + (require 'cc-mode-19)) + + (defsubst c-point (position) ;; Returns the value of point at certain commonly referenced POSITIONs. ;; POSITION can be one of the following symbols: @@ -35,6 +55,7 @@ ;; bol -- beginning of line ;; eol -- end of line ;; bod -- beginning of defun + ;; eod -- end of defun ;; boi -- back to indentation ;; ionl -- indentation of next line ;; iopl -- indentation of previous line @@ -55,14 +76,14 @@ ((eq position 'ionl) (forward-line 1) (back-to-indentation)) + ((eq position 'eod) (c-end-of-defun)) ((eq position 'bod) (if (and (fboundp 'buffer-syntactic-context-depth) c-enable-xemacs-performance-kludge-p) ;; XEmacs only. This can improve the performance of ;; c-parse-state to between 3 and 60 times faster when - ;; braces are hung. It can cause c-parse-state to be - ;; slightly slower when braces are not hung, but general - ;; editing appears to be still about as fast. + ;; braces are hung. It can also degrade performance by + ;; about as much when braces are not hung. (let (pos) (while (not pos) (save-restriction @@ -106,12 +127,31 @@ (point) (goto-char here)))) + (defmacro c-safe (&rest body) ;; safely execute BODY, return nil if an error occurred (` (condition-case nil (progn (,@ body)) (error nil)))) +(defmacro c-forward-sexp (&optional arg) + ;; like forward-sexp except + ;; 1. this is much stripped down from the XEmacs version + ;; 2. this cannot be used as a command, so we're insulated from + ;; XEmacs' losing efforts to make forward-sexp more user + ;; friendly + ;; 3. Preserves the semantics most of CC Mode is based on + (or arg (setq arg 1)) + `(goto-char (or (scan-sexps (point) ,arg) + ,(if (numberp arg) + (if (> arg 0) `(point-max) `(point-min)) + `(if (> ,arg 0) (point-max) (point-min)))))) + +(defmacro c-backward-sexp (&optional arg) + ;; See c-forward-sexp and reverse directions + (or arg (setq arg 1)) + `(c-forward-sexp ,(if (numberp arg) (- arg) `(- ,arg)))) + (defmacro c-add-syntax (symbol &optional relpos) ;; a simple macro to append the syntax in symbol to the syntax list. ;; try to increase performance by using this macro @@ -163,6 +203,22 @@ (and (boundp 'zmacs-region-stays) (setq zmacs-region-stays t))) +(defsubst c-region-is-active-p () + ;; Return t when the region is active. The determination of region + ;; activeness is different in both Emacs and XEmacs. + (cond + ;; XEmacs + ((and (fboundp 'region-active-p) + zmacs-regions) + (region-active-p)) + ;; Emacs + ((boundp 'mark-active) mark-active) + ;; fallback; shouldn't get here + (t (mark t)))) + +(defsubst c-major-mode-is (mode) + (eq (derived-mode-class major-mode) mode)) + (provide 'cc-defs) ;;; cc-defs.el ends here diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-engine.el --- a/lisp/progmodes/cc-engine.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-engine.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -28,6 +29,9 @@ ;; Boston, MA 02111-1307, USA. +(eval-when-compile + (require 'cc-defs)) + ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A ;; better way should be implemented, but this will at least shut up @@ -66,7 +70,7 @@ (if (bobp) (setq donep t) ;; go backwards one balanced expression, but be careful of ;; unbalanced paren being reached - (if (not (c-safe (progn (backward-sexp 1) t))) + (if (not (c-safe (progn (c-backward-sexp 1) t))) (progn (if firstp (backward-up-list 1) @@ -75,7 +79,7 @@ ;; characters appearing at front of identifier (save-excursion (c-backward-syntactic-ws lim) - (skip-chars-backward "-+!*&:.~ \t\n") + (skip-chars-backward "-+!*&:.~@ \t\n") (if (eq (char-before) ?\() (setq last-begin (point)))) (goto-char last-begin) @@ -97,7 +101,7 @@ ((or (looking-at c-conditional-key) (and (eq (char-after) ?\() (save-excursion - (forward-sexp 1) + (c-forward-sexp 1) (c-forward-syntactic-ws) (not (eq (char-after) ?\;))) (let ((here (point)) @@ -117,17 +121,23 @@ ;; are we in the middle of an else-if clause? (if (save-excursion (and (not substmt-p) - (c-safe (progn (forward-sexp -1) t)) + (c-safe (progn (c-forward-sexp -1) t)) (looking-at "\\[ \t\n]+\\") (not (c-in-literal lim)))) (progn - (forward-sexp -1) + (c-forward-sexp -1) (c-backward-to-start-of-if lim))) ;; are we sitting at an else clause, that we are not a ;; substatement of? (if (and (not substmt-p) (looking-at "\\[^_]")) (c-backward-to-start-of-if lim)) + ;; a finally or a series of catches? + (if (not substmt-p) + (while (looking-at "\\<\\(catch\\|finally\\)\\>[^_]") + (c-safe (c-backward-sexp 2)) + (if (eq (char-after) ?\() + (c-safe (c-backward-sexp))))) ;; are we sitting at the while of a do-while? (if (and (looking-at "\\[^_]") (c-backward-to-start-of-do lim)) @@ -142,7 +152,14 @@ (point) last-begin)) last-begin (point))) ;; CASE 6: have we crossed a statement barrier? - ((c-crosses-statement-barrier-p (point) last-begin) + ((save-excursion + ;; Move over in-expression blocks before checking the + ;; barrier + (if (or (memq (char-after) '(?\( ?\[)) + (and (eq (char-after) ?{) + (c-looking-at-inexpr-block lim))) + (c-forward-sexp 1)) + (c-crosses-statement-barrier-p (point) last-begin)) (setq donep t)) ;; CASE 7: ignore labels ((and c-maybe-labelp @@ -167,9 +184,11 @@ (t (setq last-begin (point))) )))) (goto-char last-begin) - ;; we always do want to skip over non-whitespace modifier - ;; characters that didn't get skipped above - (skip-chars-backward "-+!*&:.~" (c-point 'boi)))) + ;; We always want to skip over the non-whitespace modifier + ;; characters that can start a statement. + (let ((lim (point))) + (skip-chars-backward "-+!*&~@ \t\n" (c-point 'boi)) + (skip-chars-forward " \t\n" lim)))) (defun c-end-of-statement-1 () (condition-case nil @@ -177,7 +196,7 @@ (while (and (not (eobp)) (progn (setq beg (point)) - (forward-sexp 1) + (c-forward-sexp 1) (setq end (point)) (goto-char beg) (setq found nil) @@ -208,7 +227,7 @@ (goto-char from) (while (and (not crossedp) (< (point) to)) - (skip-chars-forward "^;{}:" to) + (skip-chars-forward "^;{}:" (1- to)) (if (not (c-in-literal lim)) (progn (if (memq (char-after) '(?\; ?{ ?})) @@ -272,50 +291,101 @@ ;; Moving by tokens, where a token is defined as all symbols and -;; identifiers which aren't syntactic whitespace. COUNT specifies the -;; number of tokens to move forward; a negative COUNT moves backward. -;; If BALANCED is true, move over balanced parens, otherwise move into -;; them. Also, if BALANCED is true, never move out of an enclosing -;; paren. LIM sets the limit for the movement. Point is always left -;; at the beginning of a token or at LIM. Returns the number of +;; identifiers which aren't syntactic whitespace (note that "->" is +;; considered to be two tokens). Point is always either left at the +;; beginning of a token or not moved at all. COUNT specifies the +;; number of tokens to move; a negative COUNT moves in the opposite +;; direction. A COUNT of 0 moves to the next token beginning only if +;; not already at one. If BALANCED is true, move over balanced +;; parens, otherwise move into them. Also, if BALANCED is true, never +;; move out of an enclosing paren. LIM sets the limit for the +;; movement and defaults to the point limit. Returns the number of ;; tokens left to move (positive or negative). If BALANCED is true, a -;; move over a balanced paren counts as one. +;; move over a balanced paren counts as one. Note that if COUNT is 0 +;; and no appropriate token beginning is found, 1 will be returned. +;; Thus, a return value of 0 guarantees that point is at the requested +;; position and a return value less (without signs) than COUNT +;; guarantees that point is at the beginning of some token. (defun c-forward-token-1 (&optional count balanced lim) - (let* ((jump-syntax (if balanced - '(?w ?_ ?\" ?\\ ?/ ?$ ?' ?\( ?\)) - '(?w ?_ ?\" ?\\ ?/ ?$ ?')))) - (or count (setq count 1)) - (condition-case nil - (while (progn - (c-forward-syntactic-ws lim) - (> count 0)) - (if (memq (char-syntax (char-after)) jump-syntax) - (goto-char (scan-sexps (point) 1)) - (forward-char)) - (setq count (1- count))) - (error - (and lim (> (point) lim) (goto-char lim)))) - count)) + (or count (setq count 1)) + (if (< count 0) + (- (c-backward-token-1 (- count) balanced lim)) + (let ((jump-syntax (if balanced + '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?') + '(?w ?_ ?\" ?\\ ?/ ?'))) + (last (point)) + (prev (point))) + (if (/= (point) + (progn (c-forward-syntactic-ws) (point))) + ;; Skip whitespace. Count this as a move if we did in fact + ;; move and aren't out of bounds. + (or (eobp) + (and lim (> (point) lim)) + (setq count (max (1- count) 0)))) + (if (and (= count 0) + (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_)) + (memq (char-syntax (or (char-before) ? )) '(?w ?_))) + (eobp))) + ;; If count is zero we should jump if in the middle of a + ;; token or if there is whitespace between point and the + ;; following token beginning. + (setq count 1)) + ;; Avoid having the limit tests inside the loop. + (save-restriction + (if lim (narrow-to-region (point-min) lim)) + (if (eobp) + (goto-char last) + (condition-case nil + (while (> count 0) + (setq prev last + last (point)) + (if (memq (char-syntax (char-after)) jump-syntax) + (goto-char (scan-sexps (point) 1)) + (forward-char)) + (c-forward-syntactic-ws lim) + (setq count (1- count))) + (error (goto-char last))) + (when (eobp) + (goto-char prev) + (setq count (1+ count))))) + count))) (defun c-backward-token-1 (&optional count balanced lim) - (let* ((jump-syntax (if balanced - '(?w ?_ ?\" ?\\ ?/ ?$ ?' ?\( ?\)) - '(?w ?_ ?\" ?\\ ?/ ?$ ?'))) - last) - (or count (setq count 1)) - (condition-case nil - (while (> count 0) - (setq last (point)) - (c-backward-syntactic-ws lim) - (if (memq (char-syntax (char-before)) jump-syntax) - (goto-char (scan-sexps (point) -1)) - (backward-char)) - (setq count (1- count))) - (error - (goto-char last) - (and lim (< (point) lim) (goto-char lim)))) - count)) + (or count (setq count 1)) + (if (< count 0) + (- (c-forward-token-1 (- count) balanced lim)) + (let ((jump-syntax (if balanced + '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?') + '(?w ?_ ?\" ?\\ ?/ ?'))) + last) + (if (and (= count 0) + (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_)) + (memq (char-syntax (or (char-before) ? )) '(?w ?_))) + (/= (point) + (save-excursion (c-forward-syntactic-ws) (point))) + (eobp))) + ;; If count is zero we should jump if in the middle of a + ;; token or if there is whitespace between point and the + ;; following token beginning. + (setq count 1)) + ;; Avoid having the limit tests inside the loop. + (save-restriction + (if lim (narrow-to-region lim (point-max))) + (or (bobp) + (progn + (condition-case nil + (while (progn + (setq last (point)) + (> count 0)) + (c-backward-syntactic-ws lim) + (if (memq (char-syntax (char-before)) jump-syntax) + (goto-char (scan-sexps (point) -1)) + (backward-char)) + (setq count (1- count))) + (error (goto-char last))) + (if (bobp) (goto-char last))))) + count))) ;; Return `c' if in a C-style comment, `c++' if in a C++ style @@ -358,22 +428,29 @@ (if (fboundp 'buffer-syntactic-context) (defalias 'c-in-literal 'c-fast-in-literal)) -(defun c-literal-limits (&optional lim) +(defun c-literal-limits (&optional lim near) ;; Returns a cons of the beginning and end positions of the comment ;; or string surrounding point (including both delimiters), or nil - ;; if point isn't in one. This is the Emacs 19 version. + ;; if point isn't in one. If LIM is non-nil, it's used as the + ;; "safe" position to start parsing from. If NEAR is non-nil, then + ;; the limits of any literal next to point is returned. "Next to" + ;; means there's only [ \t] between point and the literal. The + ;; search for such a literal is done first in forward direction. + ;; + ;; This is the Emacs 19 version. (save-excursion - (let* ((lim (or lim (c-point 'bod))) + (let* ((pos (point)) + (lim (or lim (c-point 'bod))) (state (parse-partial-sexp lim (point)))) (cond ((nth 3 state) ;; String. Search backward for the start. (while (nth 3 state) (search-backward (make-string 1 (nth 3 state))) (setq state (parse-partial-sexp lim (point)))) - (cons (point) (or (c-safe (forward-sexp 1) (point)) + (cons (point) (or (c-safe (c-forward-sexp 1) (point)) (point-max)))) ((nth 7 state) - ;; C++ comment. Search from bol for the comment starter. + ;; Line comment. Search from bol for the comment starter. (beginning-of-line) (setq state (parse-partial-sexp lim (point)) lim (point)) @@ -385,7 +462,7 @@ (backward-char 2) (cons (point) (progn (forward-comment 1) (point)))) ((nth 4 state) - ;; C comment. Search backward for the comment starter. + ;; Block comment. Search backward for the comment starter. (while (nth 4 state) (search-backward "/*") ; Should never fail. (setq state (parse-partial-sexp lim (point)))) @@ -395,18 +472,43 @@ ;; We're standing in a comment starter. (backward-char 2) (cons (point) (progn (forward-comment 1) (point)))) + (near + (goto-char pos) + ;; Search forward for a literal. + (skip-chars-forward " \t") + (cond + ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String. + (cons (point) (or (c-safe (c-forward-sexp 1) (point)) + (point-max)))) + ((looking-at "/[/*]") ; Line or block comment. + (cons (point) (progn (forward-comment 1) (point)))) + (t + ;; Search backward. + (skip-chars-backward " \t") + (let ((end (point)) beg) + (cond + ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String. + (setq beg (c-safe (c-backward-sexp 1) (point)))) + ((and (c-safe (forward-char -2) t) + (looking-at "*/")) + ;; Block comment. Due to the nature of line + ;; comments, they will always be covered by the + ;; normal case above. + (goto-char end) + (forward-comment -1) + ;; If LIM is bogus, beg will be bogus. + (setq beg (point)))) + (if beg (cons beg end)))))) )))) (defun c-literal-limits-fast (&optional lim) - ;; Returns a cons of the beginning and end positions of the comment - ;; or string surrounding point (including both delimiters), or nil - ;; if point isn't in one. This is for emacsen whose - ;; `parse-partial-sexp' returns the pos of the comment start. + ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp' + ;; returns the pos of the comment start. FIXME: Add NEAR. (save-excursion (let ((state (parse-partial-sexp lim (point)))) (cond ((nth 3 state) ; String. (goto-char (nth 8 state)) - (cons (point) (or (c-safe (forward-sexp 1) (point)) + (cons (point) (or (c-safe (c-forward-sexp 1) (point)) (point-max)))) ((nth 4 state) ; Comment. (goto-char (nth 8 state)) @@ -450,6 +552,19 @@ range) (error range)))) +(defun c-literal-type (range) + ;; Convenience function that given the result of c-literal-limits, + ;; returns nil or the type of literal that the range surrounds. + ;; It's much faster than using c-in-literal and is intended to be + ;; used when you need both the type of a literal and its limits. + (if (consp range) + (save-excursion + (goto-char (car range)) + (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string) + ((looking-at "//") 'c++) + (t 'c))) ; Assuming the range is valid. + range)) + ;; utilities for moving and querying around syntactic elements @@ -470,7 +585,19 @@ (let ((cnt 2)) (while (not (or at-bob (zerop cnt))) (goto-char (c-point 'bod)) - (if (eq (char-after) ?\{) + (if (and + (eq (char-after) ?\{) + ;; The following catches an obscure special + ;; case where the brace is preceded by an + ;; open paren. That can only legally occur + ;; with blocks inside expressions and in + ;; Pike special brace lists. Even so, this + ;; test is still bogus then, but hopefully + ;; good enough. (We don't want to use + ;; up-list here since it might be slow.) + (save-excursion + (c-backward-syntactic-ws) + (not (eq (char-before) ?\()))) (setq cnt (1- cnt))) (if (bobp) (setq at-bob t)))) @@ -591,7 +718,7 @@ (defun c-adjust-state (from to shift state) ;; Adjust all points in state that lie in the region FROM..TO by - ;; SHIFT amount (as would be returned by c-indent-line). + ;; SHIFT amount. (mapcar (function (lambda (e) @@ -669,13 +796,13 @@ ;; check if we are looking at a method def (or (not c-method-key) (progn - (forward-sexp -1) + (c-forward-sexp -1) (forward-char -1) (c-backward-syntactic-ws) (not (or (memq (char-before) '(?- ?+)) ;; or a class category (progn - (forward-sexp -2) + (c-forward-sexp -2) (looking-at c-class-key)) ))))) ))) @@ -695,7 +822,7 @@ ;; while is not associated with a do will throw an error (condition-case nil (progn - (backward-sexp 1) + (c-backward-sexp 1) (cond ;; break infloop for illegal C code ((bobp) (setq do-level 0)) @@ -732,7 +859,7 @@ (not (zerop if-level))) (c-backward-syntactic-ws) (condition-case nil - (backward-sexp 1) + (c-backward-sexp 1) (error (if at-if (throw 'orphan-if nil) @@ -744,7 +871,7 @@ ((looking-at "if\\b[^_]") ;; check for else if... skip over (let ((here (point))) - (c-safe (forward-sexp -1)) + (c-safe (c-forward-sexp -1)) (if (looking-at "\\[ \t]+\\") nil (setq if-level (1- if-level)) @@ -758,13 +885,13 @@ (defun c-skip-conditional () ;; skip forward over conditional at point, including any predicate ;; statements in parentheses. No error checking is performed. - (forward-sexp (cond - ;; else if() - ((looking-at "\\[ \t]+\\") 3) - ;; do, else, try, finally - ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1) - ;; for, if, while, switch, catch, synchronized - (t 2)))) + (c-forward-sexp (cond + ;; else if() + ((looking-at "\\[ \t]+\\") 3) + ;; do, else, try, finally + ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1) + ;; for, if, while, switch, catch, synchronized + (t 2)))) (defun c-skip-case-statement-forward (state &optional lim) ;; skip forward over case/default bodies, with optional maximal @@ -800,8 +927,8 @@ (defun c-search-uplist-for-classkey (brace-state) ;; search for the containing class, returning a 2 element vector if - ;; found. aref 0 contains the bufpos of the class key, and aref 1 - ;; contains the bufpos of the open brace. + ;; found. aref 0 contains the bufpos of the boi of the class key + ;; line, and aref 1 contains the bufpos of the open brace. (if (null brace-state) ;; no brace-state means we cannot be inside a class nil @@ -845,6 +972,9 @@ (goto-char search-start) (let ((search-key (concat c-class-key "\\|" c-extra-toplevel-key)) foundp class match-end) + (if c-inexpr-class-key + (setq search-key (concat search-key "\\|" + c-inexpr-class-key))) (while (and (not foundp) (progn (c-forward-syntactic-ws) @@ -868,8 +998,19 @@ ;; class definition, and not a forward decl, return ;; arg, template arg list, or an ObjC or Java method. ((and c-method-key - (re-search-forward c-method-key search-end t)) + (re-search-forward c-method-key search-end t) + (not (c-in-literal class))) (setq foundp nil)) + ;; Check if this is an anonymous inner class. + ((and c-inexpr-class-key + (looking-at c-inexpr-class-key)) + (while (and (= (c-forward-token-1 1 t) 0) + (looking-at "(\\|\\w\\|\\s_\\|\\."))) + (if (eq (point) search-end) + ;; We're done. Just trap this case in the cond. + nil + ;; False alarm; all conditions aren't satisfied. + (setq foundp nil))) ;; Its impossible to define a regexp for this, and ;; nearly so to do it programmatically. ;; @@ -885,7 +1026,10 @@ (skip-chars-backward "^<>" search-start) (if (eq (char-before) ?<) (setq skipchars (concat skipchars ">")))) - (skip-chars-forward skipchars search-end) + (while (progn + (skip-chars-forward skipchars search-end) + (c-in-literal class)) + (forward-char)) (/= (point) search-end)) (setq foundp nil)) ))) @@ -906,10 +1050,10 @@ (c-safe (save-excursion (goto-char containing-sexp) - (forward-sexp -1) + (c-forward-sexp -1) (let (bracepos) (if (and (or (looking-at "enum[\t\n ]+") - (progn (forward-sexp -1) + (progn (c-forward-sexp -1) (looking-at "enum[\t\n ]+"))) (setq bracepos (c-safe (scan-lists (point) 1 -1))) (not (c-crosses-statement-barrier-p (point) @@ -917,29 +1061,183 @@ (point))))) ;; this will pick up array/aggregate init lists, even if they are nested. (save-excursion - (let (bufpos okp) + (let ((class-key + ;; Pike can have class definitions anywhere, so we must + ;; check for the class key here. + (and (c-major-mode-is 'pike-mode) + (concat c-class-key "\\|" c-extra-toplevel-key))) + bufpos lim braceassignp) (while (and (not bufpos) containing-sexp) (if (consp containing-sexp) (setq containing-sexp (car brace-state) brace-state (cdr brace-state)) - ;; see if the open brace is preceded by a = in this statement (goto-char containing-sexp) - (setq okp t) - (while (and (setq okp (= (c-backward-token-1 1 t) 0)) - (not (memq (char-after) '(?= ?{ ?\;))))) - (if (not (and okp (eq (char-after) ?=))) - ;; lets see if we're nested. find the most nested - ;; containing brace - (setq containing-sexp (car brace-state) - brace-state (cdr brace-state)) - ;; we've hit the beginning of the aggregate list - (c-beginning-of-statement-1 (c-most-enclosing-brace brace-state)) - (setq bufpos (point))) + (if (c-looking-at-inexpr-block) + ;; We're in an in-expression block of some kind. Do + ;; not check nesting. + (setq containing-sexp nil) + ;; see if the open brace is preceded by = or [...] in + ;; this statement, but watch out for operator= + (setq lim (if (consp (car brace-state)) + (cdr (car brace-state)) + (car brace-state)) + braceassignp 'dontknow) + (while (and (eq braceassignp 'dontknow) + (zerop (c-backward-token-1 1 t lim))) + (cond ((eq (char-after) ?\;) + (setq braceassignp nil)) + ((and class-key + (looking-at class-key)) + (setq braceassignp nil)) + ((eq (char-after) ?=) + ;; We've seen a =, but must check earlier tokens so + ;; that it isn't something that should be ignored. + (setq braceassignp 'maybe) + (while (and (eq braceassignp 'maybe) + (zerop (c-backward-token-1 1 t lim))) + (setq braceassignp + (cond + ;; Check for operator = + ((looking-at "operator\\>") nil) + ;; Check for `= (Pike) + ((eq (char-after) ?`) nil) + ((looking-at "\\s.") 'maybe) + ;; make sure we're not in a C++ template + ;; argument assignment + ((save-excursion + (let ((here (point)) + (pos< (progn + (skip-chars-backward "^<") + (point)))) + (and (c-major-mode-is 'c++-mode) + (eq (char-before) ?<) + (not (c-crosses-statement-barrier-p + here pos<)) + (not (c-in-literal)) + ))) + nil) + (t t))))) + ((eq (char-after) ?\[) + ;; In Java, an initialization brace list may + ;; follow "new Foo[]", so check for []. Got to + ;; watch out for the C++ "operator[]" defun, + ;; though. + (setq braceassignp + (save-excursion + (c-backward-token-1) + (not (looking-at "operator\\>"))))) + )) + (if (memq braceassignp '(nil dontknow)) + (if (eq (char-after) ?\;) + ;; Brace lists can't contain a semicolon, so we're done. + (setq containing-sexp nil) + ;; lets see if we're nested. find the most nested + ;; containing brace + (setq containing-sexp (car brace-state) + brace-state (cdr brace-state))) + ;; we've hit the beginning of the aggregate list + (c-beginning-of-statement-1 + (c-most-enclosing-brace brace-state)) + (setq bufpos (point)))) )) bufpos)) )) +(defun c-looking-at-special-brace-list (&optional lim) + ;; If we're looking at the start of a pike-style list, ie `({ })', + ;; `([ ])', `(< >)' etc, a cons of a cons its starting and ending + ;; positions and its entry in c-special-brace-lists is returned, nil + ;; otherwise. The ending position is nil if the list is still open. + ;; LIM is the limit for forward search. The point may either be at + ;; the `(' or at the following paren character. Tries to check the + ;; matching closer, but assumes it's correct if no balanced paren is + ;; found (i.e. the case `({ ... } ... )' is detected as _not_ being + ;; a special brace list). + (if c-special-brace-lists + (condition-case () + (save-excursion + (let ((beg (point)) + end type) + (c-forward-syntactic-ws) + (if (eq (char-after) ?\() + (progn + (forward-char 1) + (c-forward-syntactic-ws) + (setq type (assq (char-after) c-special-brace-lists))) + (if (setq type (assq (char-after) c-special-brace-lists)) + (progn + (c-backward-syntactic-ws) + (forward-char -1) + (setq beg (if (eq (char-after) ?\() + (point) + nil))))) + (if (and beg type) + (if (and (c-safe (goto-char beg) + (c-forward-sexp 1) + (setq end (point)) + (= (char-before) ?\))) + (c-safe (goto-char beg) + (forward-char 1) + (c-forward-sexp 1) + ;; Kludges needed to handle inner + ;; chars both with and without + ;; paren syntax. + (or (/= (char-syntax (char-before)) ?\)) + (= (char-before) (cdr type))))) + (if (or (/= (char-syntax (char-before)) ?\)) + (= (progn + (c-forward-syntactic-ws) + (point)) + (1- end))) + (cons (cons beg end) type)) + (cons (list beg) type))))) + (error nil)))) + +(defun c-looking-at-inexpr-block (&optional lim) + ;; Returns non-nil if we're looking at the beginning of a block + ;; inside an expression. The value returned is actually a cons of + ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the + ;; position of the beginning of the construct. LIM limits the + ;; backward search. + (save-excursion + (or lim (setq lim (point-min))) + (if (and (eq (char-after) ?{) + (progn (c-backward-syntactic-ws) (> (point) lim)) + (eq (char-before) ?\() + (not (and c-special-brace-lists + (c-looking-at-special-brace-list)))) + (cons 'inexpr-statement (point)) + (let (res) + (while (and (not res) + (= (c-backward-token-1 1 t lim) 0) + (>= (point) lim) + (looking-at "(\\|\\w\\|\\s_\\|\\.")) + (setq res + (cond ((and c-inexpr-class-key + (looking-at c-inexpr-class-key)) + (cons 'inexpr-class (point))) + ((and c-inexpr-block-key + (looking-at c-inexpr-block-key)) + (cons 'inexpr-statement (point))) + ((and c-lambda-key + (looking-at c-lambda-key)) + (cons 'inlambda (point)))))) + res)))) + +(defun c-looking-at-inexpr-block-backward (&optional lim) + ;; Returns non-nil if we're looking at the end of an in-expression + ;; block, otherwise the same as `c-looking-at-inexpr-block'. + (save-excursion + (let ((lim (or lim (c-point 'bod)))) + (c-safe + (c-backward-syntactic-ws lim) + (if (eq (char-before) ?}) ; Recognize only a block currently. + (progn + (c-forward-sexp -1) + (if (>= (point) lim) + (c-looking-at-inexpr-block lim)))))))) + (defun c-most-enclosing-brace (state) ;; return the bufpos of the most enclosing brace that hasn't been @@ -997,6 +1295,19 @@ ;; return the class vector inclass-p)) +(defsubst c-add-class-syntax (symbol classkey) + ;; The inclass and class-close syntactic symbols are added in + ;; several places and some work is needed to fix everything. + ;; Therefore it's collected here. + (save-restriction + (widen) + (goto-char (aref classkey 1)) + (if (and (eq symbol 'inclass) (= (point) (c-point 'boi))) + (c-add-syntax symbol (point)) + (c-add-syntax symbol (aref classkey 0)) + (if (and c-inexpr-class-key (c-looking-at-inexpr-block)) + (c-add-syntax 'inexpr-class))))) + ;; This function implements the main decision tree for determining the ;; syntactic analysis of the current line of code. Yes, it's huge and @@ -1010,12 +1321,12 @@ (case-fold-search nil) (fullstate (c-parse-state)) (state fullstate) - (in-method-intro-p (and (eq major-mode 'objc-mode) + (in-method-intro-p (and (c-major-mode-is 'objc-mode) c-method-key (looking-at c-method-key))) literal containing-sexp char-before-ip char-after-ip lim syntax placeholder c-in-literal-cache inswitch-p - tmpsymbol keyword injava-inher + tmpsymbol keyword injava-inher special-brace-list ;; narrow out any enclosing class or extern "C" block (inclass-p (c-narrow-out-enclosing-class state indent-point)) inenclosing-p) @@ -1028,7 +1339,7 @@ (if (and inclass-p (progn (goto-char (aref inclass-p 0)) - (looking-at c-extra-toplevel-key))) + (looking-at (concat c-extra-toplevel-key "[^_]")))) (let ((enclosing (match-string 1))) (cond ((string-equal enclosing "extern") @@ -1104,23 +1415,26 @@ ;; CASE 5: Line is at top level. ((null containing-sexp) (cond - ;; CASE 5A: we are looking at a defun, class, or - ;; inline-inclass method opening brace - ((eq char-after-ip ?{) + ;; CASE 5A: we are looking at a defun, brace list, class, + ;; or inline-inclass method opening brace + ((setq special-brace-list + (or (and c-special-brace-lists + (c-looking-at-special-brace-list)) + (eq char-after-ip ?{))) (cond ;; CASE 5A.1: extern language or namespace construct ((save-excursion (goto-char indent-point) (skip-chars-forward " \t") - (and (c-safe (progn (backward-sexp 2) t)) - (looking-at c-extra-toplevel-key) + (and (c-safe (progn (c-backward-sexp 2) t)) + (looking-at (concat c-extra-toplevel-key "[^_]")) (setq keyword (match-string 1) placeholder (point)) (or (and (string-equal keyword "namespace") (setq tmpsymbol 'namespace-open)) (and (string-equal keyword "extern") (progn - (forward-sexp 1) + (c-forward-sexp 1) (c-forward-syntactic-ws) (eq (char-after) ?\")) (setq tmpsymbol 'extern-lang-open))) @@ -1155,25 +1469,28 @@ (and (bobp) (c-forward-syntactic-ws indent-point)) (if (looking-at "typedef[^_]") - (progn (forward-sexp 1) + (progn (c-forward-sexp 1) (c-forward-syntactic-ws indent-point))) (setq placeholder (c-point 'boi)) - (and (or (looking-at "enum[ \t\n]+") + (or (consp special-brace-list) + (and (or (looking-at "enum[ \t\n]+") + (save-excursion + (goto-char indent-point) + (while (and (> (point) placeholder) + (= (c-backward-token-1 1 t) 0) + (/= (char-after) ?=))) + (eq (char-after) ?=))) (save-excursion - (goto-char indent-point) - (while (and (> (point) placeholder) - (= (c-backward-token-1 1 t) 0) - (/= (char-after) ?=))) - (eq (char-after) ?=))) - (save-excursion - (skip-chars-forward "^;(" indent-point) - (not (memq (char-after) '(?\; ?\())) - ))) + (while (and (< (point) indent-point) + (= (c-forward-token-1 1 t) 0) + (not (memq (char-after) '(?\; ?\())))) + (not (memq (char-after) '(?\; ?\())) + )))) (c-add-syntax 'brace-list-open placeholder)) ;; CASE 5A.4: inline defun open ((and inclass-p (not inenclosing-p)) (c-add-syntax 'inline-open) - (c-add-syntax 'inclass (aref inclass-p 0))) + (c-add-class-syntax 'inclass inclass-p)) ;; CASE 5A.5: ordinary defun open (t (goto-char placeholder) @@ -1199,12 +1516,12 @@ (progn (forward-char -1) (c-backward-syntactic-ws lim))) (if (eq (char-before) ?\)) - (backward-sexp 1)) + (c-backward-sexp 1)) (setq placeholder (point)) (save-excursion - (and (c-safe (backward-sexp 1) t) + (and (c-safe (c-backward-sexp 1) t) (looking-at "throw[^_]") - (c-safe (backward-sexp 1) t) + (c-safe (c-backward-sexp 1) t) (setq placeholder (point)))) (goto-char placeholder) (c-add-syntax 'member-init-intro (c-point 'boi)) @@ -1214,7 +1531,7 @@ ;; CASE 5B.2: K&R arg decl intro (c-recognize-knr-p (c-add-syntax 'knr-argdecl-intro (c-point 'boi)) - (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0)))) + (if inclass-p (c-add-class-syntax 'inclass inclass-p))) ;; CASE 5B.3: Nether region after a C++ or Java func ;; decl, which could include a `throws' declaration. (t @@ -1240,7 +1557,7 @@ (back-to-indentation) (looking-at c-class-key))) ;; for Java - (and (eq major-mode 'java-mode) + (and (c-major-mode-is 'java-mode) (let ((fence (save-excursion (c-beginning-of-statement-1 lim) (point))) @@ -1250,7 +1567,7 @@ (cond ((looking-at c-Java-special-key) (setq injava-inher (cons cont (point)) done t)) - ((or (not (c-safe (forward-sexp -1) t)) + ((or (not (c-safe (c-forward-sexp -1) t)) (<= (point) fence)) (setq done t)) ) @@ -1270,7 +1587,7 @@ ;; CASE 5C.2: hanging colon on an inher intro ((eq char-before-ip ?:) (c-add-syntax 'inher-intro (c-point 'boi)) - (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0)))) + (if inclass-p (c-add-class-syntax 'inclass inclass-p))) ;; CASE 5C.3: in a Java implements/extends (injava-inher (let ((where (cdr injava-inher)) @@ -1305,21 +1622,36 @@ (forward-char -1) (c-backward-syntactic-ws (c-point 'bol)) (if (eq (char-before) ?\)) - (backward-sexp 1)) + (c-backward-sexp 2) + (c-backward-sexp 1)) ;; now continue checking - (beginning-of-line) (c-backward-syntactic-ws lim)) (cond ;; CASE 5D.1: hanging member init colon, but watch out ;; for bogus matches on access specifiers inside classes. - ((and (eq (char-before) ?:) + ((and (save-excursion + ;; There might be member inits on the first line too. + (end-of-line) + (while (and (> (point) lim) + (eq (char-before) ?,) + (= (c-backward-token-1 2 t lim) 0) + (eq (char-after) ?\() + (= (c-backward-token-1 1 t lim) 0)) + (c-backward-syntactic-ws lim)) + (setq placeholder (point)) + (c-backward-syntactic-ws lim) + (eq (char-before) ?:)) (save-excursion - (forward-word -1) - (not (looking-at c-access-key)))) - (goto-char indent-point) - (c-backward-syntactic-ws lim) - (c-safe (backward-sexp 1)) - (c-add-syntax 'member-init-cont (c-point 'boi)) + (goto-char placeholder) + (back-to-indentation) + (and + c-access-key + (not (looking-at c-access-key)) + (not (looking-at c-class-key))) + )) + (goto-char placeholder) + (c-forward-syntactic-ws) + (c-add-syntax 'member-init-cont (point)) ;; we do not need to add class offset since relative ;; point is the member init above us ) @@ -1330,7 +1662,11 @@ (skip-chars-forward " \t:") (c-add-syntax 'member-init-cont (point))) ;; CASE 5D.3: perhaps a multiple inheritance line? - ((looking-at c-inher-key) + ((save-excursion + (c-beginning-of-statement-1 lim) + (setq placeholder (point)) + (looking-at c-inher-key)) + (goto-char placeholder) (c-add-syntax 'inher-cont (c-point 'boi))) ;; CASE 5D.4: perhaps a template list continuation? ((save-excursion @@ -1338,9 +1674,12 @@ (skip-chars-backward "^<" lim) ;; not sure if this is the right test, but it should ;; be fast and mostly accurate. + (setq placeholder (point)) (and (eq (char-before) ?<) (not (c-in-literal lim)))) ;; we can probably indent it just like an arglist-cont + (goto-char placeholder) + (c-beginning-of-statement-1 lim) (c-add-syntax 'template-args-cont (point))) ;; CASE 5D.5: perhaps a top-level statement-cont (t @@ -1358,7 +1697,7 @@ c-access-key (looking-at c-access-key)) (c-add-syntax 'access-label (c-point 'bonl)) - (c-add-syntax 'inclass (aref inclass-p 0))) + (c-add-class-syntax 'inclass inclass-p)) ;; CASE 5F: extern-lang-close or namespace-close? ((and inenclosing-p (eq char-after-ip ?})) @@ -1374,16 +1713,10 @@ (save-restriction (widen) (forward-char 1) - (and - (condition-case nil - (progn (backward-sexp 1) t) - (error nil)) - (= (point) (aref inclass-p 1)) - )))) - (save-restriction - (widen) - (goto-char (aref inclass-p 0)) - (c-add-syntax 'class-close (c-point 'boi)))) + (and (c-safe (progn (c-backward-sexp 1) t)) + (= (point) (aref inclass-p 1)) + )))) + (c-add-class-syntax 'class-close inclass-p)) ;; CASE 5H: we could be looking at subsequent knr-argdecls ((and c-recognize-knr-p ;; here we essentially use the hack that is used in @@ -1405,13 +1738,13 @@ (and (eq (char-before) ?\)) (or (not c-method-key) (progn - (forward-sexp -1) + (c-forward-sexp -1) (forward-char -1) (c-backward-syntactic-ws) (not (or (memq (char-before) '(?- ?+)) ;; or a class category (progn - (forward-sexp -2) + (c-forward-sexp -2) (looking-at c-class-key)) ))))) )) @@ -1428,9 +1761,9 @@ c-access-key (not (bobp)) (save-excursion - (c-safe (progn (backward-sexp 1) t)) + (c-safe (progn (c-backward-sexp 1) t)) (looking-at c-access-key))) - (backward-sexp 1) + (c-backward-sexp 1) (c-backward-syntactic-ws lim)) (or (bobp) (memq (char-before) '(?\; ?\})))) @@ -1449,7 +1782,7 @@ (c-add-syntax 'inextern-lang (c-point 'boi))) ((eq inenclosing-p 'namespace) (c-add-syntax 'innamespace (c-point 'boi))) - (t (c-add-syntax 'inclass (c-point 'boi)))) + (t (c-add-class-syntax 'inclass inclass-p))) )) )) ;; CASE 5J: we are at an ObjC or Java method definition @@ -1466,28 +1799,66 @@ (c-forward-syntactic-ws) (c-add-syntax 'topmost-intro-cont (c-point 'boi))) )) ; end CASE 5 - ;; CASE 6: line is an expression, not a statement. Most + ;; CASE 6: In-expression statement. + ((and (or c-inexpr-class-key c-inexpr-block-key c-lambda-key) + (setq placeholder (c-looking-at-inexpr-block))) + (setq tmpsymbol (assq (car placeholder) + '((inexpr-class . class-open) + (inexpr-statement . block-open)))) + (if tmpsymbol + ;; It's a statement block or an anonymous class. + (setq tmpsymbol (cdr tmpsymbol)) + ;; It's a Pike lambda. Check whether we are between the + ;; lambda keyword and the argument list or at the defun + ;; opener. + (setq tmpsymbol + (if (save-excursion + (and (c-safe (c-forward-sexp -1) t) + (looking-at c-lambda-key))) + 'lambda-intro-cont + 'inline-open))) + (goto-char (cdr placeholder)) + (c-add-syntax tmpsymbol (c-point 'boi)) + (c-add-syntax (car placeholder))) + ;; CASE 7: line is an expression, not a statement. Most ;; likely we are either in a function prototype or a function ;; call argument list - ((not (eq (char-after containing-sexp) ?{)) + ((not (or (and c-special-brace-lists + (save-excursion + (goto-char containing-sexp) + (c-looking-at-special-brace-list))) + (eq (char-after containing-sexp) ?{))) (c-backward-syntactic-ws containing-sexp) (cond - ;; CASE 6A: we are looking at the arglist closing paren + ;; CASE 7A: we are looking at the arglist closing paren ((and (not (eq char-before-ip ?,)) (memq char-after-ip '(?\) ?\]))) (goto-char containing-sexp) (c-add-syntax 'arglist-close (c-point 'boi))) - ;; CASE 6B: we are looking at the first argument in an empty + ;; CASE 7B: Looking at the opening brace of an + ;; in-expression block or brace list. + ((eq char-after-ip ?{) + (goto-char indent-point) + (setq placeholder (c-point 'boi)) + (goto-char containing-sexp) + (if (c-inside-bracelist-p placeholder + (cons containing-sexp state)) + (progn + (c-add-syntax 'brace-list-open (c-point 'boi)) + (c-add-syntax 'inexpr-class)) + (c-add-syntax 'block-open (c-point 'boi)) + (c-add-syntax 'inexpr-statement))) + ;; CASE 7C: we are looking at the first argument in an empty ;; argument list. Use arglist-close if we're actually ;; looking at a close paren or bracket. ((memq char-before-ip '(?\( ?\[)) (goto-char containing-sexp) (c-add-syntax 'arglist-intro (c-point 'boi))) - ;; CASE 6C: we are inside a conditional test clause. treat + ;; CASE 7D: we are inside a conditional test clause. treat ;; these things as statements ((save-excursion (goto-char containing-sexp) - (and (c-safe (progn (forward-sexp -1) t)) + (and (c-safe (progn (c-forward-sexp -1) t)) (looking-at "\\[^_]"))) (goto-char (1+ containing-sexp)) (c-forward-syntactic-ws indent-point) @@ -1496,7 +1867,7 @@ (c-add-syntax 'statement (point)) (c-add-syntax 'statement-cont (point)) )) - ;; CASE 6D: maybe a continued method call. This is the case + ;; CASE 7E: maybe a continued method call. This is the case ;; when we are inside a [] bracketed exp, and what precede ;; the opening bracket is not an identifier. ((and c-method-key @@ -1507,7 +1878,7 @@ (if (not (looking-at c-symbol-key)) (c-add-syntax 'objc-method-call-cont containing-sexp)) ))) - ;; CASE 6E: we are looking at an arglist continuation line, + ;; CASE 7F: we are looking at an arglist continuation line, ;; but the preceding argument is on the same line as the ;; opening paren. This case includes multi-line ;; mathematical paren groupings, but we could be on a @@ -1522,14 +1893,14 @@ (<= (point) containing-sexp))) (goto-char containing-sexp) (c-add-syntax 'arglist-cont-nonempty (c-point 'boi))) - ;; CASE 6F: we are looking at just a normal arglist + ;; CASE 7G: we are looking at just a normal arglist ;; continuation line (t (c-beginning-of-statement-1 containing-sexp) (forward-char 1) (c-forward-syntactic-ws indent-point) (c-add-syntax 'arglist-cont (c-point 'boi))) )) - ;; CASE 7: func-local multi-inheritance line + ;; CASE 8: func-local multi-inheritance line ((and c-baseclass-key (save-excursion (goto-char indent-point) @@ -1538,50 +1909,96 @@ (goto-char indent-point) (skip-chars-forward " \t") (cond - ;; CASE 7A: non-hanging colon on an inher intro + ;; CASE 8A: non-hanging colon on an inher intro ((eq char-after-ip ?:) (c-backward-syntactic-ws lim) (c-add-syntax 'inher-intro (c-point 'boi))) - ;; CASE 7B: hanging colon on an inher intro + ;; CASE 8B: hanging colon on an inher intro ((eq char-before-ip ?:) (c-add-syntax 'inher-intro (c-point 'boi))) - ;; CASE 7C: a continued inheritance line + ;; CASE 8C: a continued inheritance line (t (c-beginning-of-inheritance-list lim) (c-add-syntax 'inher-cont (point)) ))) - ;; CASE 8: we are inside a brace-list - ((setq placeholder (c-inside-bracelist-p containing-sexp state)) + ;; CASE 9: we are inside a brace-list + ((setq special-brace-list + (or (and c-special-brace-lists + (save-excursion + (goto-char containing-sexp) + (c-looking-at-special-brace-list))) + (c-inside-bracelist-p containing-sexp state))) (cond - ;; CASE 8A: brace-list-close brace - ((and (eq char-after-ip ?}) - (c-safe (progn (forward-char 1) - (backward-sexp 1) - t)) - (= (point) containing-sexp)) + ;; CASE 9A: In the middle of a special brace list opener. + ((and (consp special-brace-list) + (eq char-after-ip (car (cdr special-brace-list)))) + (goto-char (car (car special-brace-list))) + (c-beginning-of-statement-1 lim) + (c-forward-token-1 0) + (if (looking-at "typedef\\>") (c-forward-token-1 1)) + (c-add-syntax 'brace-list-open (c-point 'boi))) + ;; CASE 9B: brace-list-close brace + ((if (consp special-brace-list) + ;; Check special brace list closer. + (progn + (goto-char (car (car special-brace-list))) + (save-excursion + (goto-char indent-point) + (back-to-indentation) + (or + ;; We were between the special close char and the `)'. + (and (eq (char-after) ?\)) + (eq (1+ (point)) (cdr (car special-brace-list)))) + ;; We were before the special close char. + (and (eq (char-after) (cdr (cdr special-brace-list))) + (= (c-forward-token-1) 0) + (eq (1+ (point)) (cdr (car special-brace-list))))))) + ;; Normal brace list check. + (and (eq char-after-ip ?}) + (c-safe (progn (forward-char 1) + (c-backward-sexp 1) + t)) + (= (point) containing-sexp))) (c-add-syntax 'brace-list-close (c-point 'boi))) - ;; CASE 8B: we're looking at the first line in a brace-list - ((save-excursion - (goto-char indent-point) - (c-backward-syntactic-ws containing-sexp) - (= (point) (1+ containing-sexp))) - (goto-char containing-sexp) - (c-add-syntax 'brace-list-intro (c-point 'boi)) - ) - ;;)) ; end CASE 8B - ;; CASE 8C: this is just a later brace-list-entry - (t (goto-char (1+ containing-sexp)) + (t + ;; Prepare for the rest of the cases below by going to the + ;; token following the opening brace + (if (consp special-brace-list) + (progn + (goto-char (car (car special-brace-list))) + (c-forward-token-1 1 nil indent-point)) + (goto-char containing-sexp)) + (forward-char) + (let ((start (point))) (c-forward-syntactic-ws indent-point) - (if (eq char-after-ip ?{) - (c-add-syntax 'brace-list-open (point)) - (c-add-syntax 'brace-list-entry (point)) - )) ; end CASE 8C - )) ; end CASE 8 - ;; CASE 9: A continued statement - ((and (not (memq char-before-ip '(?\; ?} ?:))) + (goto-char (max start (c-point 'bol)))) + (skip-chars-forward " \t\n\r" indent-point) + (cond + ;; CASE 9C: we're looking at the first line in a brace-list + ((= (point) indent-point) + (goto-char containing-sexp) + (c-add-syntax 'brace-list-intro (c-point 'boi)) + ) ; end CASE 9C + ;; CASE 9D: this is just a later brace-list-entry or + ;; brace-entry-open + (t (if (or (eq char-after-ip ?{) + (and c-special-brace-lists + (save-excursion + (goto-char indent-point) + (c-forward-syntactic-ws (c-point 'eol)) + (c-looking-at-special-brace-list (point))))) + (c-add-syntax 'brace-entry-open (point)) + (c-add-syntax 'brace-list-entry (point)) + )) ; end CASE 9D + )))) ; end CASE 9 + ;; CASE 10: A continued statement + ((and (not (memq char-before-ip '(?\; ?:))) + (or (not (eq char-before-ip ?})) + (c-looking-at-inexpr-block-backward containing-sexp)) (> (point) (save-excursion (c-beginning-of-statement-1 containing-sexp) + (c-forward-syntactic-ws) (setq placeholder (point)))) (/= placeholder containing-sexp)) (goto-char indent-point) @@ -1600,17 +2017,20 @@ (point)) nil)))) (cond - ;; CASE 9A: substatement + ;; CASE 10A: substatement ((and after-cond-placeholder (>= after-cond-placeholder indent-point)) (goto-char placeholder) (if (eq char-after-ip ?{) (c-add-syntax 'substatement-open (c-point 'boi)) (c-add-syntax 'substatement (c-point 'boi)))) - ;; CASE 9B: open braces for class or brace-lists - ((eq char-after-ip ?{) + ;; CASE 10B: open braces for class or brace-lists + ((setq special-brace-list + (or (and c-special-brace-lists + (c-looking-at-special-brace-list)) + (eq char-after-ip ?{))) (cond - ;; CASE 9B.1: class-open + ;; CASE 10B.1: class-open ((save-excursion (goto-char indent-point) (skip-chars-forward " \t{") @@ -1619,8 +2039,9 @@ (setq placeholder (aref decl 0))) )) (c-add-syntax 'class-open placeholder)) - ;; CASE 9B.2: brace-list-open - ((or (save-excursion + ;; CASE 10B.2: brace-list-open + ((or (consp special-brace-list) + (save-excursion (goto-char placeholder) (looking-at "\\")) (save-excursion @@ -1630,7 +2051,7 @@ (/= (char-after) ?=))) (eq (char-after) ?=))) (c-add-syntax 'brace-list-open placeholder)) - ;; CASE 9B.3: catch-all for unknown construct. + ;; CASE 10B.3: catch-all for unknown construct. (t ;; Can and should I add an extensibility hook here? ;; Something like c-recognize-hook so support for @@ -1640,7 +2061,7 @@ (c-add-syntax 'statement-cont (c-point 'boi)) (c-add-syntax 'block-open)) )) - ;; CASE 9C: iostream insertion or extraction operator + ;; CASE 10C: iostream insertion or extraction operator ((looking-at "<<\\|>>") (goto-char placeholder) (and after-cond-placeholder @@ -1654,7 +2075,7 @@ (c-add-syntax 'stream-op (c-point 'boi)) (c-backward-syntactic-ws lim) (c-add-syntax 'statement-cont (c-point 'boi)))) - ;; CASE 9D: continued statement. find the accurate + ;; CASE 10D: continued statement. find the accurate ;; beginning of statement or substatement (t (c-beginning-of-statement-1 after-cond-placeholder) @@ -1667,11 +2088,11 @@ (point))) (c-add-syntax 'statement-cont (point))) ))) - ;; CASE 10: an else clause? + ;; CASE 11: an else clause? ((looking-at "\\[^_]") (c-backward-to-start-of-if containing-sexp) (c-add-syntax 'else-clause (c-point 'boi))) - ;; CASE 11: Statement. But what kind? Lets see if its a + ;; CASE 12: Statement. But what kind? Lets see if its a ;; while closure of a do/while construct ((progn (goto-char indent-point) @@ -1683,18 +2104,38 @@ (looking-at "do\\b[^_]")) )) (c-add-syntax 'do-while-closure placeholder)) - ;; CASE 12: A case or default label + ;; CASE 13: A catch or finally clause? This case is simpler + ;; than if-else and do-while, because a block is required + ;; after every try, catch and finally. + ((save-excursion + (and (cond ((c-major-mode-is 'c++-mode) + (looking-at "\\[^_]")) + ((c-major-mode-is 'java-mode) + (looking-at "\\<\\(catch\\|finally\\)\\>[^_]"))) + (c-safe (c-backward-sexp) t) + (eq (char-after) ?{) + (c-safe (c-backward-sexp) t) + (if (eq (char-after) ?\() + (c-safe (c-backward-sexp) t) + t) + (looking-at "\\<\\(try\\|catch\\)\\>[^_]") + (setq placeholder (c-point 'boi)))) + (c-add-syntax 'catch-clause placeholder)) + ;; CASE 14: A case or default label ((looking-at c-switch-label-key) (goto-char containing-sexp) ;; check for hanging braces (if (/= (point) (c-point 'boi)) - (forward-sexp -1)) + (c-forward-sexp -1)) (c-add-syntax 'case-label (c-point 'boi))) - ;; CASE 13: any other label + ;; CASE 15: any other label ((looking-at c-label-key) (goto-char containing-sexp) + ;; check for hanging braces + (if (/= (point) (c-point 'boi)) + (c-forward-sexp -1)) (c-add-syntax 'label (c-point 'boi))) - ;; CASE 14: block close brace, possibly closing the defun or + ;; CASE 16: block close brace, possibly closing the defun or ;; the class ((eq char-after-ip ?}) (let* ((lim (c-safe-position containing-sexp fullstate)) @@ -1704,32 +2145,47 @@ (c-beginning-of-statement-1 lim)) (c-point 'boi)))) (cond - ;; CASE 14A: does this close an inline or a function in + ;; CASE 16A: closing a lambda defun or an in-expression + ;; block? + ((save-excursion + (goto-char containing-sexp) + (setq placeholder (c-looking-at-inexpr-block))) + (setq tmpsymbol (if (eq (car placeholder) 'inlambda) + 'inline-close + 'block-close)) + (goto-char containing-sexp) + (back-to-indentation) + (if (= containing-sexp (point)) + (c-add-syntax tmpsymbol (point)) + (goto-char (cdr placeholder)) + (c-add-syntax tmpsymbol (c-point 'boi)) + (c-add-syntax (car placeholder)))) + ;; CASE 16B: does this close an inline or a function in ;; an extern block or namespace? ((progn (goto-char containing-sexp) (setq placeholder (c-search-uplist-for-classkey state))) (goto-char (aref placeholder 0)) - (if (looking-at c-extra-toplevel-key) + (if (looking-at (concat c-extra-toplevel-key "[^_]")) (c-add-syntax 'defun-close relpos) (c-add-syntax 'inline-close relpos))) - ;; CASE 14B: if there an enclosing brace that hasn't + ;; CASE 16C: if there an enclosing brace that hasn't ;; been narrowed out by a class, then this is a ;; block-close ((and (not inenclosing-p) (c-most-enclosing-brace state)) (c-add-syntax 'block-close relpos)) - ;; CASE 14C: find out whether we're closing a top-level + ;; CASE 16D: find out whether we're closing a top-level ;; class or a defun (t (save-restriction (narrow-to-region (point-min) indent-point) (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) (if decl - (c-add-syntax 'class-close (aref decl 0)) + (c-add-class-syntax 'class-close decl) (c-add-syntax 'defun-close relpos))))) ))) - ;; CASE 15: statement catchall + ;; CASE 17: statement catchall (t ;; we know its a statement, but we need to find out if it is ;; the first statement in a block @@ -1746,7 +2202,7 @@ (goto-char (match-end 0))) (c-forward-syntactic-ws indent-point)) (cond - ;; CASE 15A: we are inside a case/default clause inside a + ;; CASE 17A: we are inside a case/default clause inside a ;; switch statement. find out if we are at the statement ;; just after the case/default label. ((and inswitch-p @@ -1761,10 +2217,10 @@ (if (eq (char-after) ?{) (c-add-syntax 'statement-case-open placeholder) (c-add-syntax 'statement-case-intro placeholder))) - ;; CASE 15B: continued statement + ;; CASE 17B: continued statement ((eq char-before-ip ?,) (c-add-syntax 'statement-cont (c-point 'boi))) - ;; CASE 15C: a question/colon construct? But make sure + ;; CASE 17C: a question/colon construct? But make sure ;; what came before was not a label, and what comes after ;; is not a globally scoped function call! ((or (and (memq char-before-ip '(?: ??)) @@ -1780,7 +2236,7 @@ ;; watch out for scope operator (not (looking-at "::"))))) (c-add-syntax 'statement-cont (c-point 'boi))) - ;; CASE 15D: any old statement + ;; CASE 17D: any old statement ((< (point) indent-point) (let ((safepos (c-most-enclosing-brace fullstate)) relpos done) @@ -1798,7 +2254,7 @@ (progn (goto-char placeholder) (end-of-line) - (forward-sexp -1))) + (c-forward-sexp -1))) (setq relpos (c-point 'boi)) (while (and (not done) (<= safepos (point)) @@ -1810,7 +2266,21 @@ (c-add-syntax 'statement relpos) (if (eq char-after-ip ?{) (c-add-syntax 'block-open)))) - ;; CASE 15E: first statement in an inline, or first + ;; CASE 17E: first statement in an in-expression block + ((setq placeholder + (save-excursion + (goto-char containing-sexp) + (c-looking-at-inexpr-block))) + (goto-char containing-sexp) + (back-to-indentation) + (if (= containing-sexp (point)) + (c-add-syntax 'statement-block-intro (point)) + (goto-char (cdr placeholder)) + (c-add-syntax 'statement-block-intro (c-point 'boi)) + (c-add-syntax (car placeholder))) + (if (eq char-after-ip ?{) + (c-add-syntax 'block-open))) + ;; CASE 17F: first statement in an inline, or first ;; statement in a top-level defun. we can tell this is it ;; if there are no enclosing braces that haven't been ;; narrowed out by a class (i.e. don't use bod here!) @@ -1826,14 +2296,14 @@ (if (/= (point) (c-point 'boi)) (progn (c-backward-syntactic-ws) - (c-safe (forward-sexp (if (eq (char-before) ?\)) - -1 -2))) + (c-safe (c-forward-sexp (if (eq (char-before) ?\)) + -1 -2))) ;; looking at a Java throws clause following a ;; method's parameter list (c-beginning-of-statement-1) )) (c-add-syntax 'defun-block-intro (c-point 'boi))) - ;; CASE 15F: first statement in a block + ;; CASE 17G: first statement in a block (t (goto-char containing-sexp) (if (/= (point) (c-point 'boi)) (c-beginning-of-statement-1 @@ -1852,7 +2322,7 @@ (if (looking-at c-comment-start-regexp) (c-add-syntax 'comment-intro)) ;; we might want to give additional offset to friends (in C++). - (if (and (eq major-mode 'c++-mode) + (if (and (c-major-mode-is 'c++-mode) (looking-at c-C++-friend-key)) (c-add-syntax 'friend)) ;; return the syntax @@ -1871,7 +2341,7 @@ (defun c-indent-line (&optional syntax) ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the ;; syntactic information for the current line. Returns the amount of - ;; indentation change + ;; indentation change (in columns). (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax))) (pos (- (point-max) (point))) (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context))) diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-langs.el --- a/lisp/progmodes/cc-langs.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-langs.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -29,7 +30,8 @@ -(require 'cc-defs) +(eval-when-compile + (require 'cc-defs)) ;; Regular expressions and other values which must be parameterized on ;; a per-language basis. @@ -54,8 +56,10 @@ ;; keywords introducing class definitions. language specific (defconst c-C-class-key "\\(struct\\|union\\)") (defconst c-C++-class-key "\\(class\\|struct\\|union\\)") -(defconst c-C-extra-toplevel-key "\\(extern\\)[^_]") -(defconst c-C++-extra-toplevel-key "\\(extern\\|namespace\\)[^_]") +(defconst c-IDL-class-key "\\(class\\|struct\\|union\\|interface\\)") +(defconst c-C-extra-toplevel-key "\\(extern\\)") +(defconst c-C++-extra-toplevel-key "\\(extern\\|namespace\\)") +(defconst c-IDL-extra-toplevel-key "\\(module\\)") (defconst c-ObjC-class-key (concat @@ -70,10 +74,12 @@ "\\(" c-protection-key "\\s +\\)?" "\\(interface\\|class\\)\\s +" c-symbol-key ;name of the class - "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass + "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass ;;"\\(\\s *implements *[^{]+{\\)?" ;maybe the adopted protocols list )) +(defconst c-Pike-class-key "class") + (defvar c-class-key c-C-class-key) (make-variable-buffer-local 'c-class-key) @@ -87,12 +93,14 @@ (defconst c-C++-access-key (concat c-protection-key "[ \t]*:")) (defconst c-ObjC-access-key (concat "@" c-protection-key)) (defconst c-Java-access-key nil) +(defconst c-Pike-access-key nil) ;; keywords introducing conditional blocks (defconst c-C-conditional-key nil) (defconst c-C++-conditional-key nil) (defconst c-Java-conditional-key nil) +(defconst c-Pike-conditional-key nil) (let ((all-kws "for\\|if\\|do\\|else\\|while\\|switch") (exc-kws "\\|try\\|catch") @@ -101,7 +109,8 @@ (back "\\)\\b[^_]")) (setq c-C-conditional-key (concat front all-kws back) c-C++-conditional-key (concat front all-kws exc-kws back) - c-Java-conditional-key (concat front all-kws exc-kws thr-kws back))) + c-Java-conditional-key (concat front all-kws exc-kws thr-kws back) + c-Pike-conditional-key (concat front all-kws "\\|foreach" back))) (defvar c-conditional-key c-C-conditional-key) (make-variable-buffer-local 'c-conditional-key) @@ -166,6 +175,30 @@ (defconst c-Java-javadoc-paragraph-start "@\\(author\\|exception\\|param\\|return\\|see\\|version\\)") +;; Regexp that starts lambda constructs. +(defvar c-lambda-key nil) +(make-variable-buffer-local 'c-lambda-key) +(defconst c-Pike-lambda-key "\\") + +;; Regexp that are followed by a statement block in expressions. +(defvar c-inexpr-block-key nil) +(make-variable-buffer-local 'c-inexpr-block-key) +(defconst c-Pike-inexpr-block-key "\\<\\(catch\\|gauge\\)\\>") + +;; Regexp that may be followed by an anonymous class in expressions. +(defvar c-inexpr-class-key nil) +(make-variable-buffer-local 'c-inexpr-class-key) +(defconst c-Java-inexpr-class-key "\\") + +;; List of open- and close-chars that makes up a pike-style brace +;; list, ie for a `([ ])' list there should be a cons (?\[ . ?\]) in +;; this list. +(defvar c-special-brace-lists nil) +(make-variable-buffer-local 'c-special-brace-lists) +(defconst c-Pike-special-brace-lists '((?{ . ?}) + (?\[ . ?\]) + (?< . ?>))) + ;; internal state variables @@ -188,11 +221,6 @@ -(defun c-use-java-style () - "Institutes `java' indentation style. -For use with the variable `java-mode-hook'." - (c-set-style "java")) - (defun c-common-init () ;; Common initializations for all modes. ;; these variables should always be buffer local; they do not affect @@ -212,6 +240,7 @@ (make-local-variable 'outline-regexp) (make-local-variable 'outline-level) (make-local-variable 'adaptive-fill-regexp) + (make-local-variable 'adaptive-fill-mode) (make-local-variable 'imenu-generic-expression) ;set in the mode functions ;; X/Emacs 20 only (and (boundp 'comment-line-break-function) @@ -235,7 +264,8 @@ comment-start-skip "/\\*+ *\\|// *" comment-multi-line nil comment-line-break-function 'c-comment-line-break-function - adaptive-fill-regexp nil) + adaptive-fill-regexp nil + adaptive-fill-mode nil) ;; we have to do something special for c-offsets-alist so that the ;; buffer local value has its own alist structure. (setq c-offsets-alist (copy-alist c-offsets-alist)) @@ -249,7 +279,17 @@ (or (assq 'c-auto-hungry-string minor-mode-alist) (setq minor-mode-alist (cons '(c-auto-hungry-string c-auto-hungry-string) - minor-mode-alist)))) + minor-mode-alist))) + ;; now set the mode style based on c-default-style + (c-set-style (if (stringp c-default-style) + (if (c-major-mode-is 'java-mode) + "java" + c-default-style) + (or (cdr (assq major-mode c-default-style)) + (cdr (assq 'other c-default-style)) + "gnu"))) + ) + (defun c-postprocess-file-styles () "Function that post processes relevant file local variables. @@ -277,6 +317,9 @@ (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles) +(defvar c-mode-base-map () + "Keymap shared by all CC Mode related modes.") + ;; Common routines (defun c-make-inherited-keymap () (let ((map (make-sparse-keymap))) @@ -325,9 +368,6 @@ (modify-syntax-entry ?\^m "> b" table)) -(defvar c-mode-base-map () - "Keymap shared by all CC Mode related modes.") - (if c-mode-base-map nil ;; TBD: should we even worry about naming this keymap. My vote: no, @@ -340,6 +380,8 @@ (define-key c-mode-base-map ";" 'c-electric-semi&comma) (define-key c-mode-base-map "#" 'c-electric-pound) (define-key c-mode-base-map ":" 'c-electric-colon) + (define-key c-mode-base-map "(" 'c-electric-paren) + (define-key c-mode-base-map ")" 'c-electric-paren) ;; Separate M-BS from C-M-h. The former should remain ;; backward-kill-word. (define-key c-mode-base-map [(control meta h)] 'c-mark-function) @@ -396,26 +438,27 @@ (defvar c-c++-menu nil) (defvar c-objc-menu nil) (defvar c-java-menu nil) +(defvar c-pike-menu nil) (defun c-mode-menu (modestr) (let ((m - '(["Comment Out Region" comment-region (mark t)] + '(["Comment Out Region" comment-region (c-region-is-active-p)] ["Uncomment Region" (comment-region (region-beginning) (region-end) '(4)) - (mark t)] + (c-region-is-active-p)] ["Fill Comment Paragraph" c-fill-paragraph t] "---" ["Indent Expression" c-indent-exp (memq (char-after) '(?\( ?\[ ?\{))] - ["Indent Line" c-indent-command t] + ["Indent Line or Region" c-indent-line-or-region t] ["Up Conditional" c-up-conditional t] ["Backward Conditional" c-backward-conditional t] ["Forward Conditional" c-forward-conditional t] ["Backward Statement" c-beginning-of-statement t] ["Forward Statement" c-end-of-statement t] "---" - ["Macro Expand Region" c-macro-expand (mark t)] - ["Backslashify" c-backslash-region (mark t)] + ["Macro Expand Region" c-macro-expand (c-region-is-active-p)] + ["Backslashify" c-backslash-region (c-region-is-active-p)] ))) (cons modestr m))) @@ -564,6 +607,33 @@ (easy-menu-define c-idl-menu idl-mode-map "IDL Mode Commands" (c-mode-menu "IDL")) + +;; Support for Pike + +(defvar pike-mode-abbrev-table nil + "Abbreviation table used in pike-mode buffers.") +(define-abbrev-table 'pike-mode-abbrev-table ()) + +(defvar pike-mode-map () + "Keymap used in pike-mode buffers.") +(if pike-mode-map + nil + (setq pike-mode-map (c-make-inherited-keymap)) + ;; additional bindings + (define-key pike-mode-map "\C-c\C-e" 'c-macro-expand)) + +;;;###autoload +(defvar pike-mode-syntax-table nil + "Syntax table used in pike-mode buffers.") +(if pike-mode-syntax-table + () + (setq pike-mode-syntax-table (make-syntax-table)) + (c-populate-syntax-table pike-mode-syntax-table) + (modify-syntax-entry ?@ "." pike-mode-syntax-table)) + +(easy-menu-define c-pike-menu pike-mode-map "Pike Mode Commands" + (c-mode-menu "Pike")) + (provide 'cc-langs) diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-menus.el --- a/lisp/progmodes/cc-menus.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-menus.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -27,10 +28,14 @@ ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. +;; Pull in Imenu when compiling, if it exists +(eval-when-compile + (condition-case nil + (require 'imenu) + (error nil))) + ;; imenu integration -(eval-when-compile (require 'imenu)) - (defvar cc-imenu-c-prototype-macro-regexp nil "RE matching macro names used to conditionally specify function prototypes. @@ -117,7 +122,10 @@ "^" ; beginning of line is required "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template <...>' "class[ \t]+" - "\\([a-zA-Z0-9_]+\\)" ; the string we want to get + "\\(" ; the string we want to get + "[a-zA-Z0-9_]+" ; class name + "\\(<[^>]+>\\)?" ; possibly explicitely specialized + "\\)" "[ \t]*[:{]" )) 2))) "Imenu generic expression for C++ mode. See `imenu-generic-expression'.") @@ -137,8 +145,8 @@ "\\([A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)" "\\([ \t]\\)" "\\([A-Za-z0-9_-]+\\)" ; the string we want to get - "\\([ \t]*\\)(" - "\\([][a-zA-Z,_1-9\n \t]*\\)" ; arguments + "\\([ \t]*\\)+(" + "\\([a-zA-Z,_1-9\n \t]*[[]?[]]?\\)*" ; arguments ")[ \t]*" ; "[^;(]" "[,a-zA-Z_1-9\n \t]*{" @@ -307,7 +315,7 @@ (if (fboundp 'buffer-substring-no-properties) 'buffer-substring-no-properties 'buffer-substring))) - (goto-char (point-max)) + (goto-char (point-max)) (imenu-progress-message stupid 0) ;; (while (re-search-backward cc-imenu-objc-generic-expression nil t) @@ -386,6 +394,10 @@ toplist )) +;(defvar cc-imenu-pike-generic-expression +; ()) +; FIXME: Please contribute one! + (provide 'cc-menus) ;;; cc-menus.el ends here diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-mode.el --- a/lisp/progmodes/cc-mode.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-mode.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,14 +2,15 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: a long, long, time ago. adapted from the original c-mode.el ;; Keywords: c languages oop -(defconst c-version "5.21" +(defconst c-version "5.25" "CC Mode version number.") ;; NOTE: Read the commentary below for the right way to submit bug reports! @@ -35,13 +36,15 @@ ;;; Commentary: ;; This package provides GNU Emacs major modes for editing C, C++, -;; Objective-C, Java and IDL code. As of the latest Emacs and XEmacs -;; releases, it is the default package for editing these languages. -;; This package is called "CC Mode", and should be spelled exactly -;; this way. It supports K&R and ANSI C, ANSI C++, Objective-C, Java, -;; and CORBA's IDL with a consistent indentation model across all -;; modes. This indentation model is intuitive and very flexible, so -;; that almost any desired style of indentation can be supported. +;; Objective-C, Java, IDL and Pike code. As of the latest Emacs and +;; XEmacs releases, it is the default package for editing these +;; languages. This package is called "CC Mode", and should be spelled +;; exactly this way. + +;; CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, Java, +;; CORBA's IDL, and Pike with a consistent indentation model across +;; all modes. This indentation model is intuitive and very flexible, +;; so that almost any desired style of indentation can be supported. ;; Installation, usage, and programming details are contained in an ;; accompanying texinfo manual. @@ -51,17 +54,20 @@ ;; NOTE: This mode does not perform font-locking (a.k.a syntactic ;; coloring, keyword highlighting, etc.) for any of the supported ;; modes. Typically this is done by a package called font-lock.el -;; which I do *not* maintain. You should contact the Emacs +;; which we do *not* maintain. You should contact the Emacs or XEmacs ;; maintainers for questions about coloring or highlighting in any ;; language mode. ;; To submit bug reports, type "C-c C-b". These will be sent to -;; bug-gnu-emacs@prep.ai.mit.edu as well as cc-mode-help@python.org, -;; and I'll read about them there (the former is mirrored as the -;; Usenet newsgroup gnu.emacs.bug). Questions can sent to -;; help-gnu-emacs@prep.ai.mit.edu (mirrored as gnu.emacs.help) and/or -;; cc-mode-help@python.org. Please do not send bugs or questions to -;; my personal account. +;; bug-gnu-emacs@gnu.org (mirrored as the Usenet newsgroup +;; gnu.emacs.bug) as well as bug-cc-mode@gnu.org, which directly +;; contacts the CC Mode maintainers. Questions can sent to +;; help-gnu-emacs@gnu.org (mirrored as gnu.emacs.help) and/or +;; bug-cc-mode@gnu.org. The old CC Mode contact address, +;; cc-mode-help@python.org is currently still active, but its use is +;; discouraged. Please use bug-cc-mode@gnu.org instead. Please do +;; not send bugs or questions to our personal accounts; we reserve the +;; right to ignore such email! ;; Many, many thanks go out to all the folks on the beta test list. ;; Without their patience, testing, insight, code contributions, and @@ -70,27 +76,27 @@ ;; You can get the latest version of CC Mode, including PostScript ;; documentation and separate individual files from: ;; -;; http://www.python.org/ftp/emacs/ - -;; Or if you don't have access to the World Wide Web, through -;; anonymous ftp from: +;; http://www.python.org/emacs/cc-mode/ ;; -;; ftp://ftp.python.org/pub/emacs +;; You can join a moderated CC Mode announcement-only mailing list by +;; visiting +;; +;; http://www.python.org/mailman/listinfo/cc-mode-announce ;;; Code: -(require 'cc-defs) +(defvar c-buffer-is-cc-mode nil + "Non-nil for all buffers with a `major-mode' derived from CC Mode. +Otherwise, this variable is nil. I.e. this variable is non-nil for +`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode', +`pike-mode', and any other non-CC Mode mode that calls +`c-initialize-cc-mode' (e.g. `awk-mode').") +(make-variable-buffer-local 'c-buffer-is-cc-mode) +(put 'c-buffer-is-cc-mode 'permanent-local t) -;; sigh. give in to the pressure, but make really sure all the -;; definitions we need are here -(if (or (not (fboundp 'functionp)) - (not (fboundp 'char-before)) - (not (c-safe (char-after) t)) - (not (fboundp 'when)) - (not (fboundp 'unless))) - (require 'cc-mode-19)) - +(eval-and-compile + (require 'cc-defs)) (require 'cc-menus) (require 'cc-vars) (require 'cc-engine) @@ -99,15 +105,6 @@ (require 'cc-styles) (require 'cc-cmds) -(defvar c-buffer-is-cc-mode nil - "Non-nil for all buffers with a `major-mode' derived from CC Mode. -Otherwise, this variable is nil. I.e. this variable is non-nil for -`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode', and any -other non-CC Mode mode that calls `c-initialize-cc-mode' -\(e.g. `awk-mode').") -(make-variable-buffer-local 'c-buffer-is-cc-mode) -(put 'c-buffer-is-cc-mode 'permanent-local t) - ;; Other modes and packages which depend on CC Mode should do the @@ -118,16 +115,20 @@ ;; (c-initialize-cc-mode) ;;;###autoload -(defun c-initialize-cc-mode (&optional skip-styles) +(defun c-initialize-cc-mode () (setq c-buffer-is-cc-mode t) - (let ((initprop 'cc-mode-is-initialized)) - ;; run the initialization hook, but only once - (or (get 'c-initialize-cc-mode initprop) - (progn - (or skip-styles - (c-initialize-builtin-style)) - (run-hooks 'c-initialization-hook) - (put 'c-initialize-cc-mode initprop t))) + (let ((initprop 'cc-mode-is-initialized) + c-initialization-ok) + (unless (get 'c-initialize-cc-mode initprop) + (put 'c-initialize-cc-mode initprop t) + (c-initialize-builtin-style) + (unwind-protect + (progn + (run-hooks 'c-initialization-hook) + (setq c-initialization-ok t)) + ;; Will try initialization hooks again if they failed. + (unless c-initialization-ok + (put 'c-initialize-cc-mode initprop nil)))) )) @@ -163,7 +164,8 @@ c-baseclass-key nil c-comment-start-regexp c-C++-comment-start-regexp imenu-generic-expression cc-imenu-c-generic-expression - imenu-case-fold-search nil) + imenu-case-fold-search nil + ) (run-hooks 'c-mode-common-hook) (run-hooks 'c-mode-hook) (c-update-modeline)) @@ -200,10 +202,12 @@ c-conditional-key c-C++-conditional-key c-comment-start-regexp c-C++-comment-start-regexp c-class-key c-C++-class-key + c-extra-toplevel-key c-C++-extra-toplevel-key c-access-key c-C++-access-key c-recognize-knr-p nil imenu-generic-expression cc-imenu-c++-generic-expression - imenu-case-fold-search nil) + imenu-case-fold-search nil + ) (run-hooks 'c-mode-common-hook) (run-hooks 'c++-mode-hook) (c-update-modeline)) @@ -288,11 +292,11 @@ c-baseclass-key nil c-recognize-knr-p nil c-access-key c-Java-access-key + c-inexpr-class-key c-Java-inexpr-class-key ;defun-prompt-regexp c-Java-defun-prompt-regexp imenu-generic-expression cc-imenu-java-generic-expression - imenu-case-fold-search nil + imenu-case-fold-search nil ) - (c-set-style "java") (run-hooks 'c-mode-common-hook) (run-hooks 'java-mode-hook) (c-update-modeline)) @@ -328,7 +332,8 @@ comment-end "" c-conditional-key c-C++-conditional-key c-comment-start-regexp c-C++-comment-start-regexp - c-class-key c-C++-class-key + c-class-key c-IDL-class-key + c-extra-toplevel-key c-IDL-extra-toplevel-key c-access-key c-C++-access-key c-recognize-knr-p nil ;; imenu-generic-expression cc-imenu-c++-generic-expression @@ -339,11 +344,56 @@ (c-update-modeline)) +;;;###autoload +(defun pike-mode () + "Major mode for editing Pike code. +To submit a problem report, enter `\\[c-submit-bug-report]' from an +idl-mode buffer. This automatically sets up a mail buffer with +version information already added. You just need to add a description +of the problem, including a reproducible test case, and send the +message. + +To see what version of CC Mode you are running, enter `\\[c-version]'. + +The hook variable `pike-mode-hook' is run with no args, if that value +is bound and has a non-nil value. Also the common hook +`c-mode-common-hook' is run first. + +Key bindings: +\\{pike-mode-map}" + (interactive) + (c-initialize-cc-mode) + (kill-all-local-variables) + (set-syntax-table pike-mode-syntax-table) + (setq major-mode 'pike-mode + mode-name "Pike" + local-abbrev-table pike-mode-abbrev-table) + (use-local-map pike-mode-map) + (c-common-init) + (setq comment-start "// " + comment-end "" + c-conditional-key c-Pike-conditional-key + c-class-key c-Pike-class-key + c-method-key nil + c-baseclass-key nil + c-recognize-knr-p nil + c-access-key c-Pike-access-key + c-lambda-key c-Pike-lambda-key + c-inexpr-block-key c-Pike-inexpr-block-key + c-special-brace-lists c-Pike-special-brace-lists + ;imenu-generic-expression cc-imenu-java-generic-expression ;FIXME + ;imenu-case-fold-search nil ;FIXME + ) + (run-hooks 'c-mode-common-hook) + (run-hooks 'pike-mode-hook) + (c-update-modeline)) + + ;; bug reporting (defconst c-mode-help-address - "bug-gnu-emacs@prep.ai.mit.edu, cc-mode-help@python.org" - "Address for CC Mode bug reports.") + "bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org" + "Addresses for CC Mode bug reports.") (defun c-version () "Echo the current version of CC Mode in the minibuffer." @@ -373,6 +423,7 @@ ((eq major-mode 'c-mode) "C") ((eq major-mode 'objc-mode) "ObjC") ((eq major-mode 'java-mode) "Java") + ((eq major-mode 'pike-mode) "Pike") ) ")") (let ((vars (list @@ -394,6 +445,10 @@ 'c-label-minimum-indentation 'defun-prompt-regexp 'tab-width + 'comment-column + ;; A brain-damaged XEmacs only variable that, if + ;; set to nil can cause all kinds of chaos. + 'signal-error-on-buffer-boundary ))) (if (not (boundp 'defun-prompt-regexp)) (delq 'defun-prompt-regexp vars) @@ -402,7 +457,10 @@ (lambda () (insert "Buffer Style: " style "\n\n" - (if hook + (if (and hook + (or (/= (length hook) 1) + (not (eq (car hook) 'c-gnu-impose-minimum)) + )) (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" "c-special-indent-hook is set to '" (format "%s" hook) diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-styles.el --- a/lisp/progmodes/cc-styles.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-styles.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -28,7 +29,12 @@ ;; Boston, MA 02111-1307, USA. +;; explicit compile-time dependencies +(eval-when-compile + (require 'cc-defs)) + +;; Warning: don't eval-defun this constant or you'll break style inheritance. (defconst c-style-alist '(("gnu" (c-basic-offset . 2) @@ -41,6 +47,7 @@ (statement-cont . +) (arglist-intro . c-lineup-arglist-intro-after-paren) (arglist-close . c-lineup-arglist) + (inline-open . 0) )) (c-special-indent-hook . c-gnu-impose-minimum) (c-comment-continuation-stars . "") @@ -104,6 +111,7 @@ (c-basic-offset . 8) (c-comment-only-line-offset . 0) (c-hanging-braces-alist . ((brace-list-open) + (brace-entry-open) (substatement-open after) (block-close . c-snug-do-while))) (c-cleanup-list . (brace-else-brace)) @@ -126,6 +134,7 @@ (c-hanging-braces-alist . ((brace-list-open) (brace-list-intro) (brace-list-close) + (brace-entry-open) (substatement-open after) (block-close . c-snug-do-while) )) @@ -284,7 +293,7 @@ (defconst c-offsets-alist - '((string . -1000) + '((string . c-lineup-dont-change) (c . c-lineup-C-comments) (defun-open . 0) (defun-close . 0) @@ -308,6 +317,7 @@ (brace-list-close . 0) (brace-list-intro . +) (brace-list-entry . 0) + (brace-entry-open . 0) (statement . 0) ;; some people might prefer ;;(statement . c-lineup-runin-statements) @@ -324,6 +334,7 @@ (label . 2) (do-while-closure . 0) (else-clause . 0) + (catch-clause . 0) (comment-intro . c-lineup-comment) (arglist-intro . +) (arglist-cont . 0) @@ -344,6 +355,10 @@ (namespace-close . 0) (innamespace . +) (template-args-cont . +) + (inlambda . c-lineup-inexpr-block) + (lambda-intro-cont . +) + (inexpr-statement . 0) + (inexpr-class . +) ) "Association list of syntactic element symbols and indentation offsets. As described below, each cons cell in this list has the form: @@ -380,6 +395,13 @@ element symbol and the relative indent point. The function should return an integer offset. +OFFSET can also be a list, in which case it is recursively evaluated +using the semantics described above. The first element of the list to +return a non-nil value succeeds. If none of the elements returns a +non-nil value, then what happends depends on the value of +`c-strict-syntax-p'. When `c-strict-syntax-p' is nil, then an offset +of zero is used, otherwise an error is generated. + Here is the current list of valid syntactic element symbols: string -- inside multi-line string @@ -411,6 +433,8 @@ brace-list-close -- close brace of an enum or static array list brace-list-intro -- first line in an enum or static array list brace-list-entry -- subsequent lines in an enum or static array list + brace-entry-open -- subsequent lines in an enum or static array + list that start with an open brace. statement -- a C (or like) statement statement-cont -- a continuation of a C (or like) statement statement-block-intro -- the first line in a new statement block @@ -423,6 +447,7 @@ label -- any ordinary label do-while-closure -- the `while' that ends a do/while construct else-clause -- the `else' of an if/else construct + catch-clause -- the `catch' or `finally' of a try/catch construct comment-intro -- a line containing only a comment introduction arglist-intro -- the first line in an argument list arglist-cont -- subsequent argument list lines when no @@ -450,8 +475,38 @@ innamespace -- analogous to `inextern-lang' syntactic symbol, but used inside C++ namespace constructs template-args-cont -- C++ template argument list continuations + inlambda -- in the header or body of a lambda function + lambda-intro-cont -- continuation of the header of a lambda function + inexpr-statement -- the statement is inside an expression + inexpr-class -- the class is inside an expression ") +(defun c-evaluate-offset (offset langelem symbol) + ;; offset can be a number, a function, a variable, a list, or one of + ;; the symbols + or - + (cond + ((eq offset '+) (setq offset c-basic-offset)) + ((eq offset '-) (setq offset (- c-basic-offset))) + ((eq offset '++) (setq offset (* 2 c-basic-offset))) + ((eq offset '--) (setq offset (* 2 (- c-basic-offset)))) + ((eq offset '*) (setq offset (/ c-basic-offset 2))) + ((eq offset '/) (setq offset (/ (- c-basic-offset) 2))) + ((functionp offset) (setq offset (funcall offset langelem))) + ((listp offset) + (setq offset + (let (done) + (while (and (not done) offset) + (setq done (c-evaluate-offset (car offset) langelem symbol) + offset (cdr offset))) + (if (not done) + (if c-strict-syntax-p + (error "No offset found for syntactic symbol %s" symbol) + 0) + done)))) + ((not (numberp offset)) (setq offset (symbol-value offset))) + ) + offset) + (defun c-get-offset (langelem) ;; Get offset from LANGELEM which is a cons cell of the form: ;; (SYMBOL . RELPOS). The symbol is matched against @@ -462,30 +517,20 @@ (relpos (cdr langelem)) (match (assq symbol c-offsets-alist)) (offset (cdr-safe match))) - ;; offset can be a number, a function, a variable, or one of the - ;; symbols + or - - (cond - ((not match) - (if c-strict-syntax-p - (error "don't know how to indent a %s" symbol) - (setq offset 0 - relpos 0))) - ((eq offset '+) (setq offset c-basic-offset)) - ((eq offset '-) (setq offset (- c-basic-offset))) - ((eq offset '++) (setq offset (* 2 c-basic-offset))) - ((eq offset '--) (setq offset (* 2 (- c-basic-offset)))) - ((eq offset '*) (setq offset (/ c-basic-offset 2))) - ((eq offset '/) (setq offset (/ (- c-basic-offset) 2))) - ((functionp offset) (setq offset (funcall offset langelem))) - ((not (numberp offset)) (setq offset (symbol-value offset))) - ) + (if (not match) + (if c-strict-syntax-p + (error "No offset found for syntactic symbol %s" symbol) + (setq offset 0 + relpos 0)) + (setq offset (c-evaluate-offset offset langelem symbol))) (+ (if (and relpos (< relpos (c-point 'bol))) (save-excursion (goto-char relpos) (current-column)) 0) - offset))) + (c-evaluate-offset offset langelem symbol)) + )) (defvar c-read-offset-history nil) @@ -493,12 +538,13 @@ (defun c-read-offset (langelem) ;; read new offset value for LANGELEM from minibuffer. return a ;; legal value only - (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist))) - (defstr (format "(default %s): " oldoff)) - (errmsg (concat "Offset must be int, func, var, " - "or in [+,-,++,--,*,/] " - defstr)) - (prompt (concat "Offset " defstr)) + (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist))) + (symname (symbol-name langelem)) + (defstr (format "(default %s): " oldoff)) + (errmsg (concat "Offset must be int, func, var, list, " + "or [+,-,++,--,*,/] " + defstr)) + (prompt (concat symname " offset " defstr)) offset input interned raw) (while (not offset) (setq input (completing-read prompt obarray 'fboundp nil nil @@ -563,8 +609,9 @@ (eq offset '/) (integerp offset) (functionp offset) + (listp offset) (boundp offset) - (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s" + (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s" offset)) (let ((entry (assq symbol c-offsets-alist))) (if entry @@ -574,50 +621,46 @@ (error "%s is not a valid syntactic symbol." symbol)))) (c-keep-region-active)) + +(defun c-copy-tree (tree) + (if (consp tree) + (cons (c-copy-tree (car tree)) + (c-copy-tree (cdr tree))) + tree)) - (defun c-initialize-builtin-style () ;; Dynamically append the default value of most variables. This is ;; crucial because future c-set-style calls will always reset the ;; variables first to the `cc-mode' style before instituting the new ;; style. Only do this once! - (c-initialize-cc-mode t) - (or (assoc "cc-mode" c-style-alist) - (assoc "user" c-style-alist) - (progn - (c-add-style "user" - (mapcar - (function - (lambda (var) - (let ((val (symbol-value var))) - (cons var (c-copy-tree val))))) - '(c-backslash-column - c-basic-offset - c-cleanup-list - c-comment-only-line-offset - c-electric-pound-behavior - c-hanging-braces-alist - c-hanging-colons-alist - c-hanging-comment-starter-p - c-hanging-comment-ender-p - c-offsets-alist - ))) - (c-add-style "cc-mode" '("user")) - ;; the default style is now GNU. This can be overridden in - ;; c-mode-common-hook or {c,c++,objc,java}-mode-hook. - (c-set-style c-default-style))) - (if c-style-variables-are-local-p - (c-make-styles-buffer-local))) + (unless (get 'c-initialize-builtin-style 'is-run) + (put 'c-initialize-builtin-style 'is-run t) + (c-initialize-cc-mode) + (or (assoc "cc-mode" c-style-alist) + (assoc "user" c-style-alist) + (progn + (c-add-style "user" + (mapcar + (function + (lambda (var) + (let ((val (symbol-value var))) + (cons var (c-copy-tree val))))) + '(c-backslash-column + c-basic-offset + c-cleanup-list + c-comment-only-line-offset + c-electric-pound-behavior + c-hanging-braces-alist + c-hanging-colons-alist + c-hanging-comment-starter-p + c-hanging-comment-ender-p + c-offsets-alist + ))) + (c-add-style "cc-mode" '("user")) + )) + (if c-style-variables-are-local-p + (c-make-styles-buffer-local)))) -(defun c-copy-tree (tree) - (if (consp tree) - (if (consp (cdr tree)) - (cons (c-copy-tree (car tree)) - (cons (c-copy-tree (cadr tree)) - (c-copy-tree (cddr tree)))) - (cons (c-copy-tree (car tree)) - (c-copy-tree (cdr tree)))) - tree)) (defun c-make-styles-buffer-local (&optional this-buf-only-p) "Make all CC Mode style variables buffer local. diff -r d03b1e915af1 -r 5b0864259a4b lisp/progmodes/cc-vars.el --- a/lisp/progmodes/cc-vars.el Mon Feb 08 16:52:35 1999 +0000 +++ b/lisp/progmodes/cc-vars.el Mon Feb 08 16:53:18 1999 +0000 @@ -2,10 +2,11 @@ ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. -;; Authors: 1992-1997 Barry A. Warsaw +;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm +;; 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman -;; Maintainer: cc-mode-help@python.org +;; Maintainer: bug-cc-mode@gnu.org ;; Created: 22-Apr-1997 (split from cc-mode.el) ;; Version: See cc-mode.el ;; Keywords: c languages oop @@ -27,14 +28,18 @@ ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. +(eval-when-compile + (require 'cc-defs)) + (require 'custom) (defcustom c-strict-syntax-p nil "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'. If the syntactic symbol for a particular line does not match a symbol -in the offsets alist, an error is generated, otherwise no error is -reported and the syntactic symbol is ignored." +in the offsets alist, or if no non-nil offset value can be determined +for a symbol, an error is generated, otherwise no error is reported +and the syntactic symbol is ignored." :type 'boolean :group 'c) @@ -48,14 +53,23 @@ :type 'integer :group 'c) +;; This widget will show up in newer versions of the Custom library +(or (get 'other 'widget-type) + (define-widget 'other 'sexp + "Matches everything, but doesn't let the user edit the value. +Useful as last item in a `choice' widget." + :tag "Other" + :format "%t%n" + :value 'other)) + (defcustom c-tab-always-indent t "*Controls the operation of the TAB key. If t, hitting TAB always just indents the current line. If nil, hitting TAB indents the current line if point is at the left margin or in the line's indentation, otherwise it insert a `real' tab character -\(see note\). If other than nil or t, then tab is inserted only -within literals -- defined as comments and strings -- and inside -preprocessor directives, but line is always reindented. +\(see note\). If the symbol `other', then tab is inserted only within +literals -- defined as comments and strings -- and inside preprocessor +directives, but the line is always reindented. Note: The value of `indent-tabs-mode' will determine whether a real tab character will be inserted, or the equivalent number of space. @@ -69,7 +83,7 @@ :format "%{C Tab Always Indent%}:\n The TAB key:\n%v" (const :tag "always indents, never inserts TAB" t) (const :tag "indents in left margin, otherwise inserts TAB" nil) - (const :tag "inserts TAB in literals, otherwise indent" other)) + (other :tag "inserts TAB in literals, otherwise indent" other)) :group 'c) (defcustom c-insert-tab-function 'insert-tab @@ -129,7 +143,11 @@ Clean up occurs when the open-brace after the `else' is typed. brace-elseif-brace -- similar to brace-else-brace, but cleans up - `} else if {' constructs. + `} else if (...) {' constructs. Clean up occurs + both after the open parenthesis and after the + open brace. + brace-catch-brace -- similar to brace-elseif-brace, but cleans up + `} catch (...) {' constructs. empty-defun-braces -- cleans up empty defun braces by placing the braces on the same line. Clean up occurs when the defun closing brace is typed. @@ -150,16 +168,20 @@ :type '(set :extra-offset 8 (const :tag "Put `} else {' on one line" brace-else-brace) - (const :tag "Put `} else if {' on one line" brace-elseif-brace) + (const :tag "Put `} else if (...) {' on one line" brace-elseif-brace) + (const :tag "Put `} catch (...) {' on one line" brace-catch-brace) (const :tag "Put empty defun braces on one line" empty-defun-braces) (const :tag "Put `},' in aggregates on one line" list-close-comma) (const :tag "Put C++ style `::' on one line" scope-operator)) :group 'c) (defcustom c-hanging-braces-alist '((brace-list-open) + (brace-entry-open) (substatement-open after) (block-close . c-snug-do-while) (extern-lang-open after) + (inexpr-class-open after) + (inexpr-class-close before) ) "*Controls the insertion of newlines before and after braces. This variable contains an association list with elements of the @@ -175,8 +197,12 @@ class-close, inline-open, inline-close, block-open, block-close, substatement-open, statement-case-open, extern-lang-open, extern-lang-close, brace-list-open, brace-list-close, -brace-list-intro, or brace-list-entry. See `c-offsets-alist' for -details. +brace-list-intro, brace-entry-open, inexpr-class-open, or +inexpr-class-close. See `c-offsets-alist' for details, except for +inexpr-class-open and inexpr-class-close, which doesn't have any +corresponding symbols there. Those two symbols are used for the +opening and closing braces, respectively, of anonymous inner classes +in Java. ACTION can be either a function symbol or a list containing any combination of the symbols `before' or `after'. If the list is empty, @@ -198,7 +224,8 @@ (const substatement-open) (const statement-case-open) (const extern-lang-open) (const extern-lang-close) (const brace-list-open) (const brace-list-close) - (const brace-list-intro) (const brace-list-entry)) + (const brace-list-intro) (const brace-entry-open) + (const inexpr-class-open) (const inexpr-class-close)) (choice :tag "Action" (set :format "Insert a newline %v" :extra-offset 38 @@ -310,19 +337,42 @@ :group 'c) (defcustom c-default-style "gnu" - "*Style which gets installed by default. + "*Style which gets installed by default when a file is visited. The value of this variable can be any style defined in -`c-style-alist', including styles you add, if you add them before CC -Mode gets initialized. Note that if you set any CC Mode variables in -the top-level of your .emacs file (i.e. *not* in a hook), these get -incorporated into the `user' style so you would need to add: +`c-style-alist', including styles you add. The value can also be an +association list of major mode symbols to style names. + +When the value is a string, all CC Mode major modes will install this +style by default, except `java-mode', which always installs the +\"java\" style (this is for backwards compatibility). - (setq c-default-style \"user\") +When the value is an alist, the named style is installed. If the +major mode is not listed in the alist, then the symbol `other' is +looked up in the alist, and if found, the associated style is used. +If `other' is not found in the alist, then \"gnu\" style is used. + +Note that if you set any CC Mode variables in the top-level of your +.emacs file (i.e. *not* in a hook), these get incorporated into the +`user' style, so you would need to add: + + (setq c-default-style '((other . \"user\"))) to see your customizations. This is also true if you use the Custom -interface -- be sure to set the default style to `user'." - :type 'string +interface -- be sure to set the default style to `user'. + +Finally, the default style gets installed before your mode hooks run, +so you can always override the use of `c-default-style' by making +calls to `c-set-style' in the appropriate mode hook." + :type '(choice string + (repeat :tag "" :menu-tag "Major mode list" + (cons :tag "" + (choice :tag "Mode" + (const c-mode) (const c++-mode) (const objc-mode) + (const java-mode) (const idl-mode) + (const pike-mode) (const other)) + (string :tag "Style") + ))) :group 'c) (defcustom c-style-variables-are-local-p nil @@ -387,15 +437,14 @@ :type 'hook :group 'c) -(defcustom c-enable-xemacs-performance-kludge-p t +(defcustom c-enable-xemacs-performance-kludge-p nil "*Enables a XEmacs only hack that may improve speed for some coding styles. For styles that hang top-level opening braces (as is common with JDK Java coding styles) this can improve performance between 3 and 60 times for core indentation functions (e.g. `c-parse-state'). For styles that conform to the Emacs recommendation of putting these -braces in column zero, this may slightly degrade performance in some -situations, but only by a few percentage points. This variable only -has effect in XEmacs.") +braces in column zero, this can degrade performance about as much. +This variable only has effect in XEmacs.") ;; Non-customizable variables, still part of the interface to CC Mode