Function: c-end-of-defun

c-end-of-defun is an interactive and byte-compiled function defined in cc-cmds.el.gz.

Signature

(c-end-of-defun &optional ARG)

Documentation

Move forward to the end of a top level declaration.

With argument, do it that many times. Negative argument -N means move back to Nth preceding end. Returns t unless search stops due to beginning or end of buffer.

An end of a defun occurs right after the close-parenthesis that matches the open-parenthesis that starts a defun; see beginning-of-defun.

View in manual

Probably introduced at or before Emacs version 20.3.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-cmds.el.gz
(defun c-end-of-defun (&optional arg)
  "Move forward to the end of a top level declaration.
With argument, do it that many times.  Negative argument -N means move
back to Nth preceding end.  Returns t unless search stops due to
beginning or end of buffer.

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")
  (or arg (setq arg 1))

  (or (not (eq this-command 'c-end-of-defun))
      (eq last-command 'c-end-of-defun)
      (c-region-is-active-p)
      (push-mark))

  (c-with-string-fences
   (c-save-buffer-state
       (beginning-of-defun-function
	end-of-defun-function
	(paren-state (c-parse-state))
	(orig-point-min (point-min)) (orig-point-max (point-max))
	lim
	where pos case-fold-search)

     (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)))

       ;; Move back out of any macro/comment/string we happen to be in.
       (c-beginning-of-macro)
       (setq pos (c-literal-start))
       (if pos (goto-char pos))

       (setq where (c-where-wrt-brace-construct))

       (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-\;-or-} 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)))))