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".
Probably introduced at or before Emacs version 19.20.
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-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))))