Function: c-beginning-of-defun

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

Signature

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

Documentation

Move backward to the beginning of a defun.

Every top level declaration that contains a brace paren block is considered to be a defun.

With a positive argument, move backward that many defuns. A negative argument -N means move forward to the Nth following beginning. Return t unless search stops due to beginning or end of buffer.

Unlike the built-in beginning-of-defun this tries to be smarter about finding the char with open-parenthesis syntax that starts the 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-beginning-of-defun (&optional arg)
  "Move backward to the beginning of a defun.
Every top level declaration that contains a brace paren block is
considered to be a defun.

With a positive argument, move backward that many defuns.  A negative
argument -N means move forward to the Nth following beginning.  Return
t unless search stops due to beginning or end of buffer.

Unlike the built-in `beginning-of-defun' this tries to be smarter
about finding the char with open-parenthesis syntax that starts the
defun."

  (interactive "p")
  (or arg (setq arg 1))

  (or (not (eq this-command 'c-beginning-of-defun))
      (eq last-command 'c-beginning-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		    ; Position of { which has been widened to.
	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 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-\;-or-} (- arg) where))) 0)))
	     (prog1
		 ;; 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)
	       (c-keep-region-active)))

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