Function: c-beginning-of-statement

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

Signature

(c-beginning-of-statement &optional COUNT LIM SENTENCE-FLAG)

Documentation

Go to the beginning of the innermost C statement.

With prefix arg, go back N - 1 statements. If already at the beginning of a statement then go to the beginning of the closest preceding one, moving into nested blocks if necessary (use C-M-b (backward-sexp) to skip over a block). If within or next to a comment or multiline string, move by sentences instead of statements.

When called from a program, this function takes 3 optional args: the repetition count, a buffer position limit which is the farthest back to search for the syntactic context, and a flag saying whether to do sentence motion in or near comments and multiline strings.

Note that for use in programs, c-beginning-of-statement-1 is usually better. It has much better defined semantics than this one, which is intended for interactive use, and might therefore change to be more "DWIM:ey".

View in manual

Probably introduced at or before Emacs version 19.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-cmds.el.gz
(defun c-beginning-of-statement (&optional count lim sentence-flag)
  "Go to the beginning of the innermost C statement.
With prefix arg, go back N - 1 statements.  If already at the
beginning of a statement then go to the beginning of the closest
preceding one, moving into nested blocks if necessary (use
\\[backward-sexp] to skip over a block).  If within or next to a
comment or multiline string, move by sentences instead of statements.

When called from a program, this function takes 3 optional args: the
repetition count, a buffer position limit which is the farthest back
to search for the syntactic context, and a flag saying whether to do
sentence motion in or near comments and multiline strings.

Note that for use in programs, `c-beginning-of-statement-1' is
usually better.  It has much better defined semantics than this one,
which is intended for interactive use, and might therefore change to
be more \"DWIM:ey\"."
  (interactive (list (prefix-numeric-value current-prefix-arg)
		     nil t))
  (if (< count 0)
      (c-end-of-statement (- count) lim sentence-flag)
  (c-with-string-fences
   (c-save-buffer-state
       ((count (or count 1))
	last ; start point for going back ONE chunk.  Updated each chunk movement.
	(macro-fence
	 (save-excursion (and (not (bobp)) (c-beginning-of-macro) (point))))
	res				; result from sub-function call
	not-bos				; "not beginning-of-statement"
	(range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL

     ;; Go back one statement at each iteration of the following loop.
     (while (and (/= count 0)
		 (or (not lim) (> (point) lim)))
       ;; Go back one "chunk" each time round the following loop, stopping
       ;; when we reach a statement boundary, etc.
       (setq last (point))
       (while
	   (cond     ; Each arm of this cond returns NIL on reaching a desired
					; statement boundary, non-NIL otherwise.
	    ((bobp)
	     (setq count 0)
	     nil)

	    (range		   ; point is within or approaching a literal.
	     (cond
	      ;; Single line string or sentence-flag is null => skip the
	      ;; entire literal.
	      ((or (null sentence-flag)
		   (c-one-line-string-p range))
	       (goto-char (car range))
	       (setq range (c-ascertain-preceding-literal))
	       ;; N.B. The following is essentially testing for an AWK regexp
	       ;; at BOS:
	       ;; Was the previous non-ws thing an end of statement?
	       (save-excursion
		 (if macro-fence
		     (c-backward-comments)
		   (c-backward-syntactic-ws))
		 (not (or (bobp) (c-after-statement-terminator-p)))))

	      ;; Comment inside a statement or a multi-line string.
	      (t (when (setq res ; returns non-nil when we go out of the literal
			     (if (eq (c-literal-type range) 'string)
				 (c-beginning-of-sentence-in-string range)
			       (c-beginning-of-sentence-in-comment range)))
		   (setq range (c-ascertain-preceding-literal)))
		 res)))

	    ;; Non-literal code.
	    (t (setq res (c-back-over-illiterals macro-fence))
	       (setq not-bos	       ; "not reached beginning-of-statement".
		     (or (= (point) last)
			 (memq (char-after) '(?\) ?\}))
			 (and
			  (car res)
			  ;; We're at a tentative BOS.  The next form goes
			  ;; back over WS looking for an end of previous
			  ;; statement.
			  (not (save-excursion
				 (if macro-fence
				     (c-backward-comments)
				   (c-backward-syntactic-ws))
				 (or (bobp) (c-after-statement-terminator-p)))))))
	       ;; Are we about to move backwards into or out of a
	       ;; preprocessor command?  If so, locate its beginning.
	       (when (eq (cdr res) 'macro-boundary)
		 (save-excursion
		   (beginning-of-line)
		   (setq macro-fence
			 (and (not (bobp))
			      (progn (c-skip-ws-backward) (c-beginning-of-macro))
			      (point)))))
	       ;; Are we about to move backwards into a literal?
	       (when (memq (cdr res) '(macro-boundary literal))
		 (setq range (c-ascertain-preceding-literal)))
	       not-bos))
	 (setq last (point)))

       (if (/= count 0) (setq count (1- count))))
     (c-keep-region-active)))))