changeset 75372:a1962c941648

(add-log-current-defun): Use CC Mode functions to find the beginning and end of a defun.
author Richard M. Stallman <rms@gnu.org>
date Mon, 22 Jan 2007 00:09:22 +0000
parents 7267980a2f42
children f636c357cd5d
files lisp/add-log.el
diffstat 1 files changed, 123 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/add-log.el	Sun Jan 21 23:30:02 2007 +0000
+++ b/lisp/add-log.el	Mon Jan 22 00:09:22 2007 +0000
@@ -813,51 +813,56 @@
 						 (progn (forward-sexp 1)
 							(point))))
 		((memq major-mode add-log-c-like-modes)
-		 (beginning-of-line)
-		 ;; See if we are in the beginning part of a function,
-		 ;; before the open brace.  If so, advance forward.
-		 (while (not (looking-at "{\\|\\(\\s *$\\)"))
-		   (forward-line 1))
-		 (or (eobp)
-		     (forward-char 1))
-		 (let (maybe-beg)
-		   ;; Try to find the containing defun.
-		   (beginning-of-defun)
-		   (end-of-defun)
-		   ;; If the defun we found ends before the desired position,
-		   ;; see if there's a DEFUN construct
-		   ;; between that end and the desired position.
-		   (when (save-excursion
-			   (and (> location (point))
-				(re-search-forward "^DEFUN"
-						   (save-excursion
-						     (goto-char location)
-						     (line-end-position))
-						   t)
-				(re-search-forward "^{" nil t)
-				(setq maybe-beg (point))))
-		     ;; If so, go to the end of that instead.
-		     (goto-char maybe-beg)
-		     (end-of-defun)))
-		 ;; If the desired position is within the defun we found,
-		 ;; find the function name.
-		 (when (< location (point))
-		   ;; Move back over function body.
-		   (backward-sexp 1)
-		   (let (beg)
-		     ;; Skip back over typedefs and arglist.
-		     ;; Stop at the function definition itself
-		     ;; or at the line that follows end of function doc string.
-		     (forward-line -1)
-		     (while (and (not (bobp))
-				 (looking-at "[ \t\n]")
-				 (not (looking-back "[*]/)\n" (- (point) 4))))
-		       (forward-line -1))
-		     ;; If we found a doc string, this must be the DEFUN macro
-		     ;; used in Emacs.  Move back to the DEFUN line.
-		     (when (looking-back "[*]/)\n" (- (point) 4))
-		       (backward-sexp 1)
-		       (beginning-of-line))
+		 ;; See whether the point is inside a defun.
+		 (let (having-previous-defun
+		       having-next-defun
+		       previous-defun-end
+		       next-defun-beginning)
+		     
+		   (save-excursion
+		     (setq having-previous-defun
+			   (c-beginning-of-defun))
+		     (c-end-of-defun)
+		     ;; `c-end-of-defun' moves point to the line after
+		     ;; the function close, but the position we prefer
+		     ;; here is the position after the final }.
+		     (backward-sexp 1)
+		     (forward-sexp 1)
+		     (setq previous-defun-end (point)))
+
+		   (save-excursion
+		     (setq having-next-defun
+			   (c-end-of-defun))
+		     (c-beginning-of-defun)
+		     (setq next-defun-beginning (point)))
+
+		   (if (and having-next-defun
+			    (< location next-defun-beginning))
+		       (skip-syntax-forward " "))
+		   (if (and having-previous-defun
+			    (> location previous-defun-end))
+		       (skip-syntax-backward " "))
+		   (unless (or
+			    ;; When there is no previous defun, the
+			    ;; point is not in a defun if it is not at
+			    ;; the beginning of the next defun.
+			    (and (not having-previous-defun)
+				 (not (= (point)
+					 next-defun-beginning)))
+			    ;; When there is no next defun, the point
+			    ;; is not in a defun if it is not at the
+			    ;; end of the previous defun.
+			    (and (not having-next-defun)
+				 (not (= (point)
+					 previous-defun-end)))
+			    ;; If the point is between two defuns, it
+			    ;; is not in a defun.
+			    (and (> (point) previous-defun-end)
+				 (< (point) next-defun-beginning)))
+		     ;; If the point is already at the beginning of a
+		     ;; defun, there is no need to move point again.
+		     (if (not (= (point) next-defun-beginning))
+			 (c-beginning-of-defun))
 		     ;; Is this a DEFUN construct?  And is LOCATION in it?
 		     (if (and (looking-at "DEFUN\\b")
 			      (>= location (point)))
@@ -879,82 +884,82 @@
 			   ;; Objective-C
 			   (change-log-get-method-definition)
 			 ;; Ordinary C function syntax.
-			 (setq beg (point))
-			 (if (and
-			      ;; Protect against "Unbalanced parens" error.
-			      (condition-case nil
-				  (progn
-				    (down-list 1) ; into arglist
-				    (backward-up-list 1)
-				    (skip-chars-backward " \t")
-				    t)
-				(error nil))
-			      ;; Verify initial pos was after
-			      ;; real start of function.
-			      (save-excursion
-				(goto-char beg)
-				;; For this purpose, include the line
-				;; that has the decl keywords.  This
-				;; may also include some of the
-				;; comments before the function.
-				(while (and (not (bobp))
-					    (save-excursion
-					      (forward-line -1)
-					      (looking-at "[^\n\f]")))
-				  (forward-line -1))
-				(>= location (point)))
-			      ;; Consistency check: going down and up
-			      ;; shouldn't take us back before BEG.
-			      (> (point) beg))
-			     (let (end middle)
-			       ;; Don't include any final whitespace
-			       ;; in the name we use.
-			       (skip-chars-backward " \t\n")
-			       (setq end (point))
-			       (backward-sexp 1)
-			       ;; Now find the right beginning of the name.
-			       ;; Include certain keywords if they
-			       ;; precede the name.
-			       (setq middle (point))
-			       ;; Single (forward-sexp -1) invocation is
-			       ;; not enough for C++ member function defined 
-			       ;; as part of nested class and/or namespace 
-			       ;; like:
-			       ;;
-			       ;;   void 
-			       ;;   foo::bar::baz::bazz ()
-			       ;;   { ...
-			       ;; 
-			       ;; Here we have to move the point to 
-			       ;; the beginning of foo, not bazz.
-			       (while (not (looking-back "\\(^\\|[ \t]\\)"))
-				 (forward-sexp -1))
-			       ;; Is this C++ method?
-			       (when (and (< 2 middle)
-					  (string= (buffer-substring (- middle 2)
-								     middle)
-						   "::"))
-				 ;; Include "classname::".
-				 (setq middle (point)))
-			       ;; Ignore these subparts of a class decl
-			       ;; and move back to the class name itself.
-			       (while (looking-at "public \\|private ")
-				 (skip-chars-backward " \t:")
+			 (let ((beg (point)))
+			   (if (and
+				;; Protect against "Unbalanced parens" error.
+				(condition-case nil
+				    (progn
+				      (down-list 1) ; into arglist
+				      (backward-up-list 1)
+				      (skip-chars-backward " \t")
+				      t)
+				  (error nil))
+				;; Verify initial pos was after
+				;; real start of function.
+				(save-excursion
+				  (goto-char beg)
+				  ;; For this purpose, include the line
+				  ;; that has the decl keywords.  This
+				  ;; may also include some of the
+				  ;; comments before the function.
+				  (while (and (not (bobp))
+					      (save-excursion
+						(forward-line -1)
+						(looking-at "[^\n\f]")))
+				    (forward-line -1))
+				  (>= location (point)))
+				;; Consistency check: going down and up
+				;; shouldn't take us back before BEG.
+				(> (point) beg))
+			       (let (end middle)
+				 ;; Don't include any final whitespace
+				 ;; in the name we use.
+				 (skip-chars-backward " \t\n")
 				 (setq end (point))
 				 (backward-sexp 1)
+				 ;; Now find the right beginning of the name.
+				 ;; Include certain keywords if they
+				 ;; precede the name.
 				 (setq middle (point))
-				 (forward-word -1))
-			       (and (bolp)
-				    (looking-at
-				     "enum \\|struct \\|union \\|class ")
-				    (setq middle (point)))
-			       (goto-char end)
-			       (when (eq (preceding-char) ?=)
-				 (forward-char -1)
-				 (skip-chars-backward " \t")
-				 (setq end (point)))
-			       (buffer-substring-no-properties
-				middle end))))))))
+				 ;; Single (forward-sexp -1) invocation is
+				 ;; not enough for C++ member function defined 
+				 ;; as part of nested class and/or namespace 
+				 ;; like:
+				 ;;
+				 ;;   void 
+				 ;;   foo::bar::baz::bazz ()
+				 ;;   { ...
+				 ;; 
+				 ;; Here we have to move the point to 
+				 ;; the beginning of foo, not bazz.
+				 (while (not (looking-back "\\(^\\|[ \t]\\)"))
+				   (forward-sexp -1))
+				 ;; Is this C++ method?
+				 (when (and (< 2 middle)
+					    (string= (buffer-substring (- middle 2)
+								       middle)
+						     "::"))
+				   ;; Include "classname::".
+				   (setq middle (point)))
+				 ;; Ignore these subparts of a class decl
+				 ;; and move back to the class name itself.
+				 (while (looking-at "public \\|private ")
+				   (skip-chars-backward " \t:")
+				   (setq end (point))
+				   (backward-sexp 1)
+				   (setq middle (point))
+				   (forward-word -1))
+				 (and (bolp)
+				      (looking-at
+				       "enum \\|struct \\|union \\|class ")
+				      (setq middle (point)))
+				 (goto-char end)
+				 (when (eq (preceding-char) ?=)
+				   (forward-char -1)
+				   (skip-chars-backward " \t")
+				   (setq end (point)))
+				 (buffer-substring-no-properties
+				  middle end)))))))))
 		((memq major-mode add-log-tex-like-modes)
 		 (if (re-search-backward
 		      "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)"