]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-cmds.el
* progmodes/octave.el (inferior-octave-prompt): Use shy groups.
[gnu-emacs] / lisp / progmodes / cc-cmds.el
index 5ce936da6b1b259e179180a35f7a3f014bcdf6ce..dc6ed1348d145f932d4b79974a3f4411fec795d8 100644 (file)
@@ -1,8 +1,6 @@
 ;;; cc-cmds.el --- user level commands for CC Mode
 
-;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1987, 1992-2013 Free Software Foundation, Inc.
 
 ;; Authors:    2003- Alan Mackenzie
 ;;             1998- Martin Stjernholm
@@ -12,8 +10,8 @@
 ;;             1985 Richard M. Stallman
 ;; Maintainer: bug-cc-mode@gnu.org
 ;; Created:    22-Apr-1997 (split from cc-mode.el)
-;; Version:    See cc-mode.el
-;; Keywords:   c languages oop
+;; Keywords:   c languages
+;; Package:    cc-mode
 
 ;; This file is part of GNU Emacs.
 
@@ -47,7 +45,6 @@
 (cc-require 'cc-engine)
 
 ;; Silence the compiler.
-(cc-bytecomp-defun delete-forward-p)   ; XEmacs
 (cc-bytecomp-defvar filladapt-mode)    ; c-fill-paragraph contains a kludge
                                        ; which looks at this.
 \f
@@ -266,8 +263,10 @@ With universal argument, inserts the analysis as a comment on that line."
                          (symbol-value 'subword-mode))
                         "w"
                       "")))
+        ;; FIXME: Derived modes might want to use something else
+        ;; than a string for `mode-name'.
        (bare-mode-name (if (string-match "\\(^[^/]*\\)/" mode-name)
-                           (substring mode-name (match-beginning 1) (match-end 1))
+                           (match-string 1 mode-name)
                          mode-name)))
 ;;     (setq c-submode-indicators
 ;;       (if (> (length fmt) 1)
@@ -310,7 +309,7 @@ left out.
 Turning on auto-newline automatically enables electric indentation.
 
 When the auto-newline feature is enabled (indicated by \"/la\" on the
-modeline after the mode name) newlines are automatically inserted
+mode line after the mode name) newlines are automatically inserted
 after special characters such as brace, comma, semi-colon, and colon."
   (interactive "P")
   (setq c-auto-newline
@@ -329,7 +328,7 @@ positive, turns it off when negative, and just toggles it when zero or
 left out.
 
 When the hungry-delete-key feature is enabled (indicated by \"/h\" on
-the modeline after the mode name) the delete key gobbles all preceding
+the mode line after the mode name) the delete key gobbles all preceding
 whitespace in one fell swoop."
   (interactive "P")
   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
@@ -475,7 +474,7 @@ inside a literal or a macro, nothing special happens."
          (bolp (bolp)))
       (beginning-of-line)
       (delete-horizontal-space)
-      (insert last-command-event)
+      (insert (c-last-command-char))
       (and (not bolp)
           (goto-char (- (point-max) pos)))
       )))
@@ -493,13 +492,16 @@ inside a literal or a macro, nothing special happens."
       (insert-char ?\n 1)
       ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed
       ;; the syntax.  (There might already be an escaped NL there.)
-      (when (or (c-at-vsemi-p (1- (point)))
-               (let ((pt (point)))
-                 (save-excursion
-                   (backward-char)
-                   (and (c-beginning-of-macro)
-                        (progn (c-end-of-macro)
-                               (< (point) pt))))))
+      (when (or
+            (save-excursion
+              (c-skip-ws-backward (c-point 'bopl))
+              (c-at-vsemi-p))
+            (let ((pt (point)))
+              (save-excursion
+                (backward-char)
+                (and (c-beginning-of-macro)
+                     (progn (c-end-of-macro)
+                            (< (point) pt))))))
        (backward-char)
        (insert-char ?\\ 1)
        (forward-char))
@@ -679,7 +681,7 @@ settings of `c-cleanup-list' are done."
        ;; We want to inhibit blinking the paren since this would be
        ;; most disruptive.  We'll blink it ourselves later on.
        (old-blink-paren blink-paren-function)
-       blink-paren-function)
+       blink-paren-function case-fold-search)
 
     (c-save-buffer-state ()
       (setq safepos (c-safe-position (point) (c-parse-state))
@@ -734,7 +736,7 @@ settings of `c-cleanup-list' are done."
              ;; `}': clean up empty defun braces
              (when (c-save-buffer-state ()
                      (and (memq 'empty-defun-braces c-cleanup-list)
-                          (eq last-command-event ?\})
+                          (eq (c-last-command-char) ?\})
                           (c-intersect-lists '(defun-close class-close inline-close)
                                              syntax)
                           (progn
@@ -750,14 +752,14 @@ settings of `c-cleanup-list' are done."
              ;; `}': compact to a one-liner defun?
              (save-match-data
                (when
-                   (and (eq last-command-event ?\})
+                   (and (eq (c-last-command-char) ?\})
                         (memq 'one-liner-defun c-cleanup-list)
                         (c-intersect-lists '(defun-close) syntax)
                         (c-try-one-liner))
                  (setq here (- (point-max) pos))))
 
              ;; `{': clean up brace-else-brace and brace-elseif-brace
-             (when (eq last-command-event ?\{)
+             (when (eq (c-last-command-char) ?\{)
                (cond
                 ((and (memq 'brace-else-brace c-cleanup-list)
                       (re-search-backward
@@ -811,7 +813,7 @@ settings of `c-cleanup-list' are done."
            ))))
 
     ;; blink the paren
-    (and (eq last-command-event ?\})
+    (and (eq (c-last-command-char) ?\})
         (not executing-kbd-macro)
         old-blink-paren
         (save-excursion
@@ -848,7 +850,7 @@ is inhibited."
     (when (and (not arg)
               (eq literal 'c)
               (memq 'comment-close-slash c-cleanup-list)
-              (eq last-command-event ?/)
+              (eq (c-last-command-char) ?/)
               (looking-at (concat "[ \t]*\\("
                                   (regexp-quote comment-end) "\\)?$"))
        ; (eq c-block-comment-ender "*/") ; C-style comments ALWAYS end in */
@@ -864,7 +866,7 @@ is inhibited."
     (setq indentp (and (not arg)
                       c-syntactic-indentation
                       c-electric-flag
-                      (eq last-command-event ?/)
+                      (eq (c-last-command-char) ?/)
                       (eq (char-before) (if literal ?* ?/))))
     (self-insert-command (prefix-numeric-value arg))
     (if indentp
@@ -938,10 +940,10 @@ settings of `c-cleanup-list'."
          (let ((pos (- (point-max) (point))))
            (if (c-save-buffer-state ()
                  (and (or (and
-                           (eq last-command-event ?,)
+                           (eq (c-last-command-char) ?,)
                            (memq 'list-close-comma c-cleanup-list))
                           (and
-                           (eq last-command-event ?\;)
+                           (eq (c-last-command-char) ?\;)
                            (memq 'defun-close-semi c-cleanup-list)))
                       (progn
                         (forward-char -1)
@@ -1042,7 +1044,7 @@ reindented unless `c-syntactic-indentation' is nil.
                  (setcar (car elem) 'label))
              (setq elem (cdr elem)))
            ;; some language elements can only be determined by checking
-           ;; the following line.  Lets first look for ones that can be
+           ;; the following line.  Let's first look for ones that can be
            ;; found when looking on the line with the colon
            (setq newlines
                  (and c-auto-newline
@@ -1086,104 +1088,76 @@ numeric argument is supplied, or the point is inside a literal."
 
   (interactive "*P")
   (let ((c-echo-syntactic-information-p nil)
-       final-pos close-paren-inserted)
+       final-pos close-paren-inserted found-delim case-fold-search)
 
     (self-insert-command (prefix-numeric-value arg))
     (setq final-pos (point))
 
-    (c-save-buffer-state (c-parse-and-markup-<>-arglists
-                         c-restricted-<>-arglists
-                         <-pos)
+;;;; 2010-01-31: There used to be code here to put a syntax-table text
+;;;; property on the new < or > and its mate (if any) when they are template
+;;;; parens.  This is now done in an after-change function.
 
-      (when c-recognize-<>-arglists
-       (if (eq last-command-event ?<)
-           (when (and (progn
-                        (backward-char)
-                        (= (point)
-                           (progn
-                             (c-beginning-of-current-token)
-                             (point))))
+    ;; Indent the line if appropriate.
+    (when (and c-electric-flag c-syntactic-indentation c-recognize-<>-arglists)
+      (setq found-delim
+           (if (eq (c-last-command-char) ?<)
+               ;; If a <, basically see if it's got "template" before it .....
+               (or (and (progn
+                          (backward-char)
+                          (= (point)
+                             (progn (c-beginning-of-current-token) (point))))
+                        (progn
+                          (c-backward-token-2)
+                          (looking-at c-opt-<>-sexp-key)))
+                   ;; ..... or is a C++ << operator.
+                   (and (c-major-mode-is 'c++-mode)
+                        (progn
+                          (goto-char (1- final-pos))
+                          (c-beginning-of-current-token)
+                          (looking-at "<<"))
+                        (>= (match-end 0) final-pos)))
+
+             ;; It's a >.  Either a C++ >> operator. ......
+             (or (and (c-major-mode-is 'c++-mode)
                       (progn
-                        (c-backward-token-2)
-                        (looking-at c-opt-<>-sexp-key)))
-             (c-mark-<-as-paren (1- final-pos)))
-
-         ;; It's a ">".  Check if there's an earlier "<" which either has
-         ;; open paren syntax already or that can be recognized as an arglist
-         ;; together with this ">".  Note that this won't work in cases like
-         ;; "template <x, a < b, y>" but they ought to be rare.
-
-         (save-restriction
-           ;; Narrow to avoid that `c-forward-<>-arglist' below searches past
-           ;; our position.
-           (narrow-to-region (point-min) final-pos)
-
-           (while (and
-                   (progn
-                     (goto-char final-pos)
-                     (c-syntactic-skip-backward "^<;}" nil t)
-                     (eq (char-before) ?<))
-                   (progn
-                     (backward-char)
-                     ;; If the "<" already got open paren syntax we know we
-                     ;; have the matching closer.  Handle it and exit the
-                     ;; loop.
-                     (if (looking-at "\\s\(")
-                         (progn
-                           (c-mark->-as-paren (1- final-pos))
-                           (setq close-paren-inserted t)
-                           nil)
-                       t))
+                        (goto-char (1- final-pos))
+                        (c-beginning-of-current-token)
+                        (looking-at ">>"))
+                      (>= (match-end 0) final-pos))
+                 ;; ...., or search back for a < which isn't already marked as an
+                 ;; opening template delimiter.
+                 (save-restriction
+                   (widen)
+                   ;; Narrow to avoid `c-forward-<>-arglist' below searching past
+                   ;; our position.
+                   (narrow-to-region (point-min) final-pos)
+                   (goto-char final-pos)
+                   (while
+                       (and
+                        (progn
+                          (c-syntactic-skip-backward "^<;}" nil t)
+                          (eq (char-before) ?<))
+                        (progn
+                          (backward-char)
+                          (looking-at "\\s\("))))
+                   (and (eq (char-after) ?<)
+                        (not (looking-at "\\s\("))
+                        (progn (c-backward-syntactic-ws)
+                               (c-simple-skip-symbol-backward))
+                        (or (looking-at c-opt-<>-sexp-key)
+                            (not (looking-at c-keywords-regexp)))))))))
 
-                   (progn
-                     (setq <-pos (point))
-                     (c-backward-syntactic-ws)
-                     (c-simple-skip-symbol-backward))
-                   (or (looking-at c-opt-<>-sexp-key)
-                       (not (looking-at c-keywords-regexp)))
-
-                   (let ((c-parse-and-markup-<>-arglists t)
-                         c-restricted-<>-arglists
-                         (containing-sexp
-                          (c-most-enclosing-brace (c-parse-state))))
-                     (when (and containing-sexp
-                                (progn (goto-char containing-sexp)
-                                       (eq (char-after) ?\())
-                                (not (eq (get-text-property (point) 'c-type)
-                                         'c-decl-arg-start)))
-                       (setq c-restricted-<>-arglists t))
-                     (goto-char <-pos)
-                     (c-forward-<>-arglist nil))
-
-                   ;; Loop here if the "<" we found above belongs to a nested
-                   ;; angle bracket sexp.  When we start over we'll find the
-                   ;; previous or surrounding sexp.
-                   (if (< (point) final-pos)
-                       t
-                     (setq close-paren-inserted t)
-                     nil)))))))
     (goto-char final-pos)
-
-    ;; Indent the line if appropriate.
-    (when (and c-electric-flag c-syntactic-indentation)
-      (backward-char)
-      (when (prog1 (or (looking-at "\\s\(\\|\\s\)")
-                      (and (c-major-mode-is 'c++-mode)
-                           (progn
-                             (c-beginning-of-current-token)
-                             (looking-at "<<\\|>>"))
-                           (= (match-end 0) final-pos)))
-             (goto-char final-pos))
-       (indent-according-to-mode)))
-
-    (when (and close-paren-inserted
-              (not executing-kbd-macro)
-              blink-paren-function)
-      ;; Note: Most paren blink functions, such as the standard
-      ;; `blink-matching-open', currently doesn't handle paren chars
-      ;; marked with text properties very well.  Maybe we should avoid
-      ;; this call for the time being?
-      (funcall blink-paren-function))))
+    (when found-delim
+      (indent-according-to-mode)
+      (when (and (eq (char-before) ?>)
+                (not executing-kbd-macro)
+                blink-paren-function)
+           ;; Note: Most paren blink functions, such as the standard
+           ;; `blink-matching-open', currently doesn't handle paren chars
+           ;; marked with text properties very well.  Maybe we should avoid
+           ;; this call for the time being?
+           (funcall blink-paren-function)))))
 
 (defun c-electric-paren (arg)
   "Insert a parenthesis.
@@ -1200,7 +1174,8 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
   (interactive "*P")
   (let ((literal (c-save-buffer-state () (c-in-literal)))
        ;; shut this up
-       (c-echo-syntactic-information-p nil))
+       (c-echo-syntactic-information-p nil)
+       case-fold-search)
     (self-insert-command (prefix-numeric-value arg))
 
     (if (and (not arg) (not literal))
@@ -1219,7 +1194,7 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
            ;; clean up brace-elseif-brace
            (when
                (and (memq 'brace-elseif-brace c-cleanup-list)
-                    (eq last-command-event ?\()
+                    (eq (c-last-command-char) ?\()
                     (re-search-backward
                      (concat "}"
                              "\\([ \t\n]\\|\\\\\n\\)*"
@@ -1237,7 +1212,7 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
            ;; clean up brace-catch-brace
            (when
                (and (memq 'brace-catch-brace c-cleanup-list)
-                    (eq last-command-event ?\()
+                    (eq (c-last-command-char) ?\()
                     (re-search-backward
                      (concat "}"
                              "\\([ \t\n]\\|\\\\\n\\)*"
@@ -1258,7 +1233,7 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
 
             ;; space-before-funcall clean-up?
             ((and (memq 'space-before-funcall c-cleanup-list)
-                  (eq last-command-event ?\()
+                  (eq (c-last-command-char) ?\()
                   (save-excursion
                     (backward-char)
                     (skip-chars-backward " \t")
@@ -1276,7 +1251,7 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
             ;; compact-empty-funcall clean-up?
                  ((c-save-buffer-state ()
                     (and (memq 'compact-empty-funcall c-cleanup-list)
-                         (eq last-command-event ?\))
+                         (eq (c-last-command-char) ?\))
                          (save-excursion
                            (c-safe (backward-char 2))
                            (when (looking-at "()")
@@ -1305,7 +1280,7 @@ keyword on the line, the keyword is not inserted inside a literal, and
     (when (c-save-buffer-state ()
            (and c-electric-flag
                 c-syntactic-indentation
-                (not (eq last-command-event ?_))
+                (not (eq (c-last-command-char) ?_))
                 (= (save-excursion
                      (skip-syntax-backward "w")
                      (point))
@@ -1388,7 +1363,7 @@ No indentation or other \"electric\" behavior is performed."
   ;; Determine where we are with respect to functions (or other brace
   ;; constructs, included in the term "function" in the rest of this comment).
   ;; Point is assumed to be outside any macro or literal.
-  ;; This is used by c-\(begining\|end\)-of-defun.
+  ;; This is used by c-\(beginning\|end\)-of-defun.
   ;;
   ;; Return one of these symbols:
   ;; at-header       : we're at the start of a function's header.
@@ -1513,6 +1488,78 @@ No indentation or other \"electric\" behavior is performed."
       (setq n (1- n))))
    n)
 
+(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive)
+  ;; If we are inside a decl-block (in the sense of c-looking-at-decl-block),
+  ;; i.e. something like namespace{} or extern{}, narrow to the insides of
+  ;; that block (NOT including the enclosing braces) if INCLUSIVE is nil,
+  ;; otherwise include the braces.  If the closing brace is missing,
+  ;; (point-max) is used instead.
+  (let ((paren-state (c-parse-state))
+       encl-decl)
+    (setq encl-decl (and paren-state (c-most-enclosing-decl-block paren-state)))
+    (if encl-decl
+       (save-excursion
+         (narrow-to-region
+          (if inclusive
+              (progn (goto-char encl-decl)
+                     (c-beginning-of-decl-1)
+                     (point))
+            (1+ encl-decl))
+          (progn
+            (goto-char encl-decl)
+            (or (c-safe (forward-list)
+                        (if inclusive
+                            (point)
+                          (1- (point))))
+                (point-max))))))))
+
+(defun c-widen-to-enclosing-decl-scope (paren-state orig-point-min orig-point-max)
+  ;; Narrow the buffer to the innermost declaration scope (e.g. a class, a
+  ;; namespace or the "whole buffer") recorded in PAREN-STATE, the bounding
+  ;; braces NOT being included in the resulting region.  On no account may the
+  ;; final region exceed that bounded by ORIG-POINT-MIN, ORIG-POINT-MAX.
+  ;; PAREN-STATE is a list of buffer positions in the style of
+  ;; (c-parse-state), one of which will be that of the desired opening brace,
+  ;; if there is one.
+  ;;
+  ;; Return the position of the enclosing opening brace, or nil
+  (let (encl-decl)         ; putative position of decl-scope's opening brace.
+    (save-restriction
+      (narrow-to-region orig-point-min orig-point-max)
+      (setq encl-decl (and paren-state
+                          (c-most-enclosing-decl-block paren-state))))
+    (if encl-decl
+       (progn
+         (widen)
+         (narrow-to-region (1+ encl-decl)
+                           (save-excursion
+                             (goto-char encl-decl)
+                             (or (c-safe (forward-list)
+                                         (1- (point)))
+                                 orig-point-max)))
+         encl-decl)
+      (narrow-to-region orig-point-min orig-point-max)
+      nil)))
+
+(eval-and-compile
+  (defmacro c-while-widening-to-decl-block (condition)
+    ;; Repeatedly evaluate CONDITION until it returns nil.  After each
+    ;; evaluation, if `c-defun-tactic' is set appropriately, widen to innards
+    ;; of the next enclosing declaration block (e.g. namespace, class), or the
+    ;; buffer's original restriction.
+    ;;
+    ;; This is a very special purpose macro, which assumes the existence of
+    ;; several variables.  It is for use only in c-beginning-of-defun and
+    ;; c-end-of-defun.
+    `(while
+        (and ,condition
+             (eq c-defun-tactic 'go-outward)
+             lim)
+       (setq paren-state (c-whack-state-after lim paren-state))
+       (setq lim (c-widen-to-enclosing-decl-scope
+                 paren-state orig-point-min orig-point-max))
+       (setq where 'in-block))))
+
 (defun c-beginning-of-defun (&optional arg)
   "Move backward to the beginning of a defun.
 Every top level declaration that contains a brace paren block is
@@ -1529,53 +1576,74 @@ defun."
   (interactive "p")
   (or arg (setq arg 1))
 
+  (or (not (eq this-command 'c-beginning-of-defun))
+      (eq last-command 'c-beginning-of-defun)
+      (and transient-mark-mode mark-active)
+      (push-mark))
+
   (c-save-buffer-state
       (beginning-of-defun-function end-of-defun-function
        (start (point))
-       where paren-state pos)
-
-    ;; Move back out of any macro/comment/string we happen to be in.
-    (c-beginning-of-macro)
-    (setq pos (c-literal-limits))
-    (if pos (goto-char (car pos)))
+       (paren-state (copy-tree (c-parse-state))) ; This must not share list
+                                       ; structure with other users of c-state-cache.
+       (orig-point-min (point-min)) (orig-point-max (point-max))
+       lim                         ; Position of { which has been widened to.
+       where pos case-fold-search)
 
-    (setq where (c-where-wrt-brace-construct))
-
-    (if (< arg 0)
-       ;; Move forward to the closing brace of a function.
-       (progn
-         (if (memq where '(at-function-end outwith-function))
-             (setq arg (1+ arg)))
-         (if (< arg 0)
-             (setq arg (c-forward-to-nth-EOF-} (- arg) where)))
-         ;; Move forward to the next opening brace....
-         (when (and (= arg 0)
-                    (c-syntactic-re-search-forward "{" nil 'eob))
-           (backward-char)
-           ;; ... and backward to the function header.
-           (c-beginning-of-decl-1)
-           t))
-
-      ;; Move backward to the opening brace of a function.
-      (when (and (> arg 0)
-                (eq (setq arg (c-backward-to-nth-BOF-{ arg where)) 0))
+    (save-restriction
+      (if (eq c-defun-tactic 'go-outward)
+         (setq lim (c-widen-to-enclosing-decl-scope ; e.g. class, namespace.
+                    paren-state orig-point-min orig-point-max)))
 
-       ;; Go backward to this function's header.
-       (c-beginning-of-decl-1)
+      ;; Move back out of any macro/comment/string we happen to be in.
+      (c-beginning-of-macro)
+      (setq pos (c-literal-limits))
+      (if pos (goto-char (car pos)))
 
-       (setq pos (point))
-       ;; We're now there, modulo comments and whitespace.
-       ;; Try to be line oriented; position point at the closest
-       ;; preceding boi that isn't inside a comment, but if we hit
-       ;; the previous declaration then we use the current point
-       ;; instead.
-       (while (and (/= (point) (c-point 'boi))
-                   (c-backward-single-comment)))
-       (if (/= (point) (c-point 'boi))
-           (goto-char pos)))
+      (setq where (c-where-wrt-brace-construct))
 
-      (c-keep-region-active)
-      (= arg 0))))
+      (if (< arg 0)
+         ;; Move forward to the closing brace of a function.
+         (progn
+           (if (memq where '(at-function-end outwith-function))
+               (setq arg (1+ arg)))
+           (if (< arg 0)
+               (c-while-widening-to-decl-block
+                (< (setq arg (- (c-forward-to-nth-EOF-} (- arg) where))) 0)))
+           ;; Move forward to the next opening brace....
+           (when (and (= arg 0)
+                      (progn
+                        (c-while-widening-to-decl-block
+                         (not (c-syntactic-re-search-forward "{" nil 'eob)))
+                        (eq (char-before) ?{)))
+             (backward-char)
+             ;; ... and backward to the function header.
+             (c-beginning-of-decl-1)
+             t))
+
+       ;; Move backward to the opening brace of a function, making successively
+       ;; larger portions of the buffer visible as necessary.
+       (when (> arg 0)
+         (c-while-widening-to-decl-block
+          (> (setq arg (c-backward-to-nth-BOF-{ arg where)) 0)))
+
+       (when (eq arg 0)
+         ;; Go backward to this function's header.
+         (c-beginning-of-decl-1)
+
+         (setq pos (point))
+         ;; We're now there, modulo comments and whitespace.
+         ;; Try to be line oriented; position point at the closest
+         ;; preceding boi that isn't inside a comment, but if we hit
+         ;; the previous declaration then we use the current point
+         ;; instead.
+         (while (and (/= (point) (c-point 'boi))
+                     (c-backward-single-comment)))
+         (if (/= (point) (c-point 'boi))
+             (goto-char pos)))
+
+       (c-keep-region-active)
+       (= arg 0)))))
 
 (defun c-forward-to-nth-EOF-} (n where)
   ;; Skip to the closing brace of the Nth function after point.  If
@@ -1632,53 +1700,71 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
   (interactive "p")
   (or arg (setq arg 1))
 
+  (or (not (eq this-command 'c-end-of-defun))
+      (eq last-command 'c-end-of-defun)
+      (and transient-mark-mode mark-active)
+      (push-mark))
+
   (c-save-buffer-state
       (beginning-of-defun-function end-of-defun-function
        (start (point))
-       where paren-state pos)
+       (paren-state (copy-tree (c-parse-state))) ; This must not share list
+                                 ; structure with other users of c-state-cache.
+       (orig-point-min (point-min)) (orig-point-max (point-max))
+       lim
+       where pos case-fold-search)
 
-    ;; Move back out of any macro/comment/string we happen to be in.
-    (c-beginning-of-macro)
-    (setq pos (c-literal-limits))
-    (if pos (goto-char (car pos)))
+    (save-restriction
+      (if (eq c-defun-tactic 'go-outward)
+         (setq lim (c-widen-to-enclosing-decl-scope ; e.g. class, namespace
+                    paren-state orig-point-min orig-point-max)))
 
-    (setq where (c-where-wrt-brace-construct))
+      ;; Move back out of any macro/comment/string we happen to be in.
+      (c-beginning-of-macro)
+      (setq pos (c-literal-limits))
+      (if pos (goto-char (car pos)))
 
-    (if (< arg 0)
-       ;; Move backwards to the } of a function
-       (progn
-         (if (memq where '(at-header outwith-function))
-             (setq arg (1+ arg)))
-         (if (< arg 0)
-             (setq arg (c-backward-to-nth-BOF-{ (- arg) where)))
-         (if (= arg 0)
-             (c-syntactic-skip-backward "^}")))
-
-      ;; Move forward to the } of a function
-      (if (> arg 0)
-         (setq arg (c-forward-to-nth-EOF-} arg where))))
-
-    ;; Do we need to move forward from the brace to the semicolon?
-    (when (eq arg 0)
-      (if (c-in-function-trailer-p)    ; after "}" of struct/enum, etc.
-         (c-syntactic-re-search-forward ";"))
-
-      (setq pos (point))
-      ;; We're there now, modulo comments and whitespace.
-      ;; Try to be line oriented; position point after the next
-      ;; newline that isn't inside a comment, but if we hit the
-      ;; next declaration then we use the current point instead.
-      (while (and (not (bolp))
-                 (not (looking-at "\\s *$"))
-                 (c-forward-single-comment)))
-      (cond ((bolp))
-           ((looking-at "\\s *$")
-            (forward-line 1))
-           (t
-            (goto-char pos))))
+      (setq where (c-where-wrt-brace-construct))
 
-    (c-keep-region-active)
-    (= arg 0)))
+      (if (< arg 0)
+         ;; Move backwards to the } of a function
+         (progn
+           (if (memq where '(at-header outwith-function))
+               (setq arg (1+ arg)))
+           (if (< arg 0)
+               (c-while-widening-to-decl-block
+                (< (setq arg (- (c-backward-to-nth-BOF-{ (- arg) where))) 0)))
+           (if (= arg 0)
+               (c-while-widening-to-decl-block
+                (progn (c-syntactic-skip-backward "^}")
+                       (not (eq (char-before) ?}))))))
+
+       ;; Move forward to the } of a function
+       (if (> arg 0)
+           (c-while-widening-to-decl-block
+            (> (setq arg (c-forward-to-nth-EOF-} arg where)) 0))))
+
+      ;; Do we need to move forward from the brace to the semicolon?
+      (when (eq arg 0)
+       (if (c-in-function-trailer-p) ; after "}" of struct/enum, etc.
+           (c-syntactic-re-search-forward ";"))
+
+       (setq pos (point))
+       ;; We're there now, modulo comments and whitespace.
+       ;; Try to be line oriented; position point after the next
+       ;; newline that isn't inside a comment, but if we hit the
+       ;; next declaration then we use the current point instead.
+       (while (and (not (bolp))
+                   (not (looking-at "\\s *$"))
+                   (c-forward-single-comment)))
+       (cond ((bolp))
+             ((looking-at "\\s *$")
+              (forward-line 1))
+             (t
+              (goto-char pos))))
+
+      (c-keep-region-active)
+      (= arg 0))))
 
 (defun c-defun-name ()
   "Return the name of the current defun, or NIL if there isn't one.
@@ -1687,8 +1773,8 @@ with a brace block."
   (interactive)
   (c-save-buffer-state
       (beginning-of-defun-function end-of-defun-function
-       where pos name-end)
-
+       where pos name-end case-fold-search)
     (save-restriction
       (widen)
       (save-excursion
@@ -1742,6 +1828,17 @@ with a brace block."
            ;; DEFFLAGSET(syslog_opt_flags,LOG_PID ...) ==> syslog_opt_flags
            (match-string-no-properties 1))
 
+          ;; Objc selectors.
+          ((assq 'objc-method-intro (c-guess-basic-syntax))
+           (let ((bound (save-excursion (c-end-of-statement) (point)))
+                 (kw-re (concat "\\(?:" c-symbol-key "\\)?:"))
+                 (stretches))
+             (when (c-syntactic-re-search-forward c-symbol-key bound t t t)
+               (push (match-string-no-properties 0) stretches)
+               (while (c-syntactic-re-search-forward kw-re bound t t t)
+                 (push (match-string-no-properties 0) stretches)))
+             (apply 'concat (nreverse stretches))))
+
           (t
            ;; Normal function or initializer.
            (when (c-syntactic-re-search-forward "[{(]" nil t)
@@ -1764,6 +1861,11 @@ with a brace block."
   ;;
   ;; This function might do hidden buffer changes.
   (save-excursion
+    (save-restriction
+      (when (eq c-defun-tactic 'go-outward)
+       (c-narrow-to-most-enclosing-decl-block t)  ; e.g. class, namespace
+       (or (save-restriction
+             (c-narrow-to-most-enclosing-decl-block nil)
 
     ;; Note: Some code duplication in `c-beginning-of-defun' and
     ;; `c-end-of-defun'.
@@ -1773,11 +1875,12 @@ with a brace block."
            lim pos end-pos)
        (unless (c-safe
                  (goto-char (c-least-enclosing-brace paren-state))
-                 ;; If we moved to the outermost enclosing paren then we
-                 ;; can use c-safe-position to set the limit.  Can't do
-                 ;; that otherwise since the earlier paren pair on
-                 ;; paren-state might very well be part of the
-                 ;; declaration we should go to.
+                           ;; If we moved to the outermost enclosing paren
+                           ;; then we can use c-safe-position to set the
+                           ;; limit. Can't do that otherwise since the
+                           ;; earlier paren pair on paren-state might very
+                           ;; well be part of the declaration we should go
+                           ;; to.
                  (setq lim (c-safe-position (point) paren-state))
                  t)
          ;; At top level.  Make sure we aren't inside a literal.
@@ -1861,18 +1964,27 @@ with a brace block."
                         (forward-line 1)
                         (point))
                        (t
-                        pos)))))
-       ))))
+                                  pos))))))))
+           (and (not near)
+                (goto-char (point-min))
+                (c-forward-decl-or-cast-1 -1 nil nil)
+                (eq (char-after) ?\{)
+                (cons (point-min) (point-max))))))))
 
 (defun c-mark-function ()
   "Put mark at end of the current top-level declaration or macro, point at beginning.
-If point is not inside any then the closest following one is chosen.
+If point is not inside any then the closest following one is
+chosen.  Each successive call of this command extends the marked
+region by one function.
+
+A mark is left where the command started, unless the region is already active
+\(in Transient Mark mode).
 
 As opposed to \\[c-beginning-of-defun] and \\[c-end-of-defun], this
 function does not require the declaration to contain a brace block."
   (interactive)
 
-  (let (decl-limits)
+  (let (decl-limits case-fold-search)
     (c-save-buffer-state nil
       ;; We try to be line oriented, unless there are several
       ;; declarations on the same line.
@@ -1882,17 +1994,34 @@ function does not require the declaration to contain a brace block."
 
     (if (not decl-limits)
        (error "Cannot find any declaration")
-      (goto-char (car decl-limits))
-      (push-mark (cdr decl-limits) nil t))))
+      (let* ((extend-region-p
+             (and (eq this-command 'c-mark-function)
+                  (eq last-command 'c-mark-function)))
+            (push-mark-p (and (eq this-command 'c-mark-function)
+                              (not extend-region-p)
+                              (not (and transient-mark-mode mark-active)))))
+       (if push-mark-p (push-mark (point)))
+       (if extend-region-p
+           (progn
+             (exchange-point-and-mark)
+             (setq decl-limits (c-declaration-limits t))
+             (when (not decl-limits)
+               (exchange-point-and-mark)
+               (error "Cannot find any declaration"))
+             (goto-char (cdr decl-limits))
+             (exchange-point-and-mark))
+         (goto-char (car decl-limits))
+         (push-mark (cdr decl-limits) nil t))))))
 
 (defun c-cpp-define-name ()
   "Return the name of the current CPP macro, or NIL if we're not in one."
   (interactive)
-  (save-excursion
-    (and c-opt-cpp-macro-define-start
-        (c-beginning-of-macro)
-        (looking-at c-opt-cpp-macro-define-start)
-        (match-string-no-properties 1))))
+  (let (case-fold-search)
+    (save-excursion
+      (and c-opt-cpp-macro-define-start
+          (c-beginning-of-macro)
+          (looking-at c-opt-cpp-macro-define-start)
+          (match-string-no-properties 1)))))
 
 \f
 ;; Movement by statements.
@@ -1959,7 +2088,7 @@ function does not require the declaration to contain a brace block."
        (c-narrow-to-comment-innards range) ; This may move point back.
        (let* ((here (point))
               last
-              (here-filler        ; matches WS and comment-prefices at point.
+              (here-filler        ; matches WS and comment-prefixes at point.
                (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)"
                        "\\|[ \t\n\r\f]\\)*"))
               (prefix-at-bol-here ; matches WS and prefix at BOL, just before point
@@ -1979,7 +2108,7 @@ function does not require the declaration to contain a brace block."
 
          ;; Now seek successively earlier sentence ends between PAR-BEG and
          ;; HERE, until the "start of sentence" following it is earlier than
-         ;; HERE, or we hit PAR-BEG.  Beware of comment prefices!
+         ;; HERE, or we hit PAR-BEG.  Beware of comment prefixes!
          (while (and (re-search-backward (c-sentence-end) par-beg 'limit)
                      (setq last (point))
                      (goto-char (match-end 0)) ; tentative beginning of sentence
@@ -2086,7 +2215,7 @@ function does not require the declaration to contain a brace block."
           (end (1- (cdr range)))
           (here-filler            ; matches WS and escaped newlines at point.
            "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*")
-          ;; Enhance paragraph-start and paragraph-separate also to recognise
+          ;; Enhance paragraph-start and paragraph-separate also to recognize
           ;; blank lines terminated by escaped EOLs.  IT MAY WELL BE that
           ;; these values should be customizable user options, or something.
           (paragraph-start c-string-par-start)
@@ -2142,7 +2271,7 @@ function does not require the declaration to contain a brace block."
   (save-match-data
     (let* ((here (point))
           last
-          ;; Enhance paragraph-start and paragraph-separate to recognise
+          ;; Enhance paragraph-start and paragraph-separate to recognize
           ;; blank lines terminated by escaped EOLs.
           (paragraph-start c-string-par-start)
           (paragraph-separate c-string-par-separate)
@@ -2224,7 +2353,7 @@ function does not require the declaration to contain a brace block."
 
 (defun c-after-statement-terminator-p () ; Should we pass in LIM here?
   ;; Does point immediately follow a statement "terminator"?  A virtual
-  ;; semicolon is regarded here as such.  So is a an opening brace ;-)
+  ;; semicolon is regarded here as such.  So is an opening brace ;-)
   ;;
   ;; This function might do hidden buffer changes.
   (or (save-excursion
@@ -2775,7 +2904,8 @@ See `c-indent-comment-alist' for a description."
                        (eq (match-end 0) eot))
                   'cpp-end-block)
                  (t
-                  'other))))
+                  'other)))
+          case-fold-search)
       (if (and (memq line-type '(anchored-comment empty-line))
               c-indent-comments-syntactically-p)
          (let ((c-syntactic-context (c-guess-basic-syntax)))
@@ -2877,7 +3007,7 @@ A prefix argument acts as a repeat count.  With a negative argument,
 move backward across a preprocessor conditional.
 
 If there aren't enough conditionals after \(or before) point, an
-error is signalled.
+error is signaled.
 
 \"#elif\" is treated like \"#else\" followed by \"#if\", except that
 the nesting level isn't changed when tracking subconditionals.
@@ -2911,7 +3041,7 @@ are treated as conditional clause limits.  Normally they are ignored."
   (let* ((forward (> count 0))
         (increment (if forward -1 1))
         (search-function (if forward 're-search-forward 're-search-backward))
-        new)
+        new case-fold-search)
     (unless (integerp target-depth)
       (setq target-depth (if target-depth -1 0)))
     (save-excursion
@@ -3113,7 +3243,7 @@ balanced expression is found."
 In the macro case this also has the effect of realigning any line
 continuation backslashes, unless `c-auto-align-backslashes' is nil."
   (interactive "*")
-  (let ((here (point-marker)) decl-limits)
+  (let ((here (point-marker)) decl-limits case-fold-search)
     (unwind-protect
        (progn
          (c-save-buffer-state nil
@@ -3999,16 +4129,19 @@ command to conveniently insert and align the necessary backslashes."
                    ;; "Invalid search bound (wrong side of point)"
                    ;; error in the subsequent re-search.  Maybe
                    ;; another fix would be needed (2007-12-08).
-                   (and (> (- (cdr c-lit-limits) 2) (point))
-                        (search-forward-regexp
-                         (concat "\\=[ \t]*\\(" c-current-comment-prefix "\\)")
-                         (- (cdr c-lit-limits) 2) t)
-                        (not (search-forward-regexp
-                              "\\(\\s \\|\\sw\\)"
-                              (- (cdr c-lit-limits) 2) 'limit))
-                            ;; The comment ender IS on its own line.  Exclude
-                            ;; this line from the filling.
-                        (set-marker end (c-point 'bol))))
+;                  (or (<= (- (cdr c-lit-limits) 2) (point))
+; 2010-10-17  Construct removed.
+;                  (or (< (- (cdr c-lit-limits) 2) (point))
+                   (and
+                    (search-forward-regexp
+                     (concat "\\=[ \t]*\\(" c-current-comment-prefix "\\)")
+                     (- (cdr c-lit-limits) 2) t)
+                    (not (search-forward-regexp
+                          "\\(\\s \\|\\sw\\)"
+                          (- (cdr c-lit-limits) 2) 'limit))
+                    ;; The comment ender IS on its own line.  Exclude this
+                    ;; line from the filling.
+                    (set-marker end (c-point 'bol))));)
 
                ;; The comment ender is hanging.  Replace all space between it
                ;; and the last word either by one or two 'x's (when
@@ -4025,6 +4158,14 @@ command to conveniently insert and align the necessary backslashes."
                                       (goto-char ender-start)
                                       (current-column)))
                       (point-rel (- ender-start here))
+                      (sentence-ends-comment
+                       (save-excursion
+                         (goto-char ender-start)
+                         (and (search-backward-regexp
+                               (c-sentence-end) (c-point 'bol) t)
+                              (goto-char (match-end 0))
+                         (looking-at "[ \t]*")
+                         (= (match-end 0) ender-start))))
                       spaces)
 
                  (save-excursion
@@ -4067,7 +4208,9 @@ command to conveniently insert and align the necessary backslashes."
                              (setq spaces
                                    (max
                                     (min spaces
-                                         (if sentence-end-double-space 2 1))
+                                         (if (and sentence-ends-comment
+                                                  sentence-end-double-space)
+                                             2 1))
                                     1)))
                          ;; Insert the filler first to keep marks right.
                          (insert-char ?x spaces t)
@@ -4512,7 +4655,8 @@ inside a preprocessor directive."
 
   (interactive "*")
   (let* (c-lit-limits c-lit-type
-        (c-macro-start c-macro-start))
+        (c-macro-start c-macro-start)
+        case-fold-search)
 
     (c-save-buffer-state ()
       (setq c-lit-limits (c-literal-limits nil nil t)
@@ -4581,5 +4725,4 @@ normally bound to C-o.  See `c-context-line-break' for the details."
 \f
 (cc-provide 'cc-cmds)
 
-;; arch-tag: bf0611dc-d1f4-449e-9e45-4ec7c6936677
 ;;; cc-cmds.el ends here