(eval-when-compile
(let ((load-path
(if (and (boundp 'byte-compile-dest-file)
(stringp byte-compile-dest-file))
(cons (file-name-directory byte-compile-dest-file) load-path)
load-path)))
(load "cc-bytecomp" nil t)))
(cc-require 'cc-defs)
(cc-require 'cc-vars)
(cc-require 'cc-engine)
(cc-bytecomp-defun delete-forward-p) (cc-bytecomp-defvar filladapt-mode) (cc-bytecomp-defun c-forward-subword)
(cc-bytecomp-defun c-backward-subword)
(defvar c-fix-backslashes t)
(defun c-indent-line (&optional syntax quiet ignore-point-pos)
"Indent the current line according to the syntactic context,
if `c-syntactic-indentation' is non-nil. Optional SYNTAX is the
syntactic information for the current line. Be silent about syntactic
errors if the optional argument QUIET is non-nil, even if
`c-report-syntactic-errors' is non-nil. Normally the position of
point is used to decide where the old indentation is on a lines that
is otherwise empty \(ignoring any line continuation backslash), but
that's not done if IGNORE-POINT-POS is non-nil. Returns the amount of
indentation change \(in columns)."
(let ((line-cont-backslash (save-excursion
(end-of-line)
(eq (char-before) ?\\)))
(c-fix-backslashes c-fix-backslashes)
bs-col
shift-amt)
(when (and (not ignore-point-pos)
(save-excursion
(beginning-of-line)
(looking-at (if line-cont-backslash
"\\([ \t]*\\)\\\\$"
"\\([ \t]*\\)$")))
(<= (point) (match-end 1)))
(unless c-auto-align-backslashes
(save-excursion
(goto-char (match-end 0))
(setq bs-col (1- (current-column)))))
(delete-region (point) (match-end 0))
(setq c-fix-backslashes t))
(if c-syntactic-indentation
(setq c-parsing-error
(or (let ((c-parsing-error nil)
(c-syntactic-context
(or syntax
(and (boundp 'c-syntactic-context)
c-syntactic-context))))
(c-save-buffer-state (indent)
(unless c-syntactic-context
(setq c-syntactic-context (c-guess-basic-syntax)))
(setq indent (c-get-syntactic-indentation
c-syntactic-context))
(and (not (c-echo-parsing-error quiet))
c-echo-syntactic-information-p
(message "syntax: %s, indent: %d"
c-syntactic-context indent))
(setq shift-amt (- indent (current-indentation))))
(c-shift-line-indentation shift-amt)
(run-hooks 'c-special-indent-hook)
c-parsing-error)
c-parsing-error))
(let ((indent 0))
(save-excursion
(while (and (= (forward-line -1) 0)
(if (looking-at "\\s *\\\\?$")
t
(setq indent (current-indentation))
nil))))
(setq shift-amt (- indent (current-indentation)))
(c-shift-line-indentation shift-amt)))
(when (and c-fix-backslashes line-cont-backslash)
(if bs-col
(save-excursion
(indent-to bs-col)
(insert ?\\))
(when c-auto-align-backslashes
(c-backslash-region (point) (point) nil t))))
shift-amt))
(defun c-newline-and-indent (&optional newline-arg)
"Insert a newline and indent the new line.
This function fixes line continuation backslashes if inside a macro,
and takes care to set the indentation before calling
`indent-according-to-mode', so that lineup functions like
`c-lineup-dont-change' works better."
(let ((c-macro-start (c-query-macro-start))
(c-fix-backslashes nil)
has-backslash insert-backslash
start col)
(save-excursion
(beginning-of-line)
(setq start (point))
(while (and (looking-at "[ \t]*\\\\?$")
(= (forward-line -1) 0)))
(setq col (current-indentation)))
(when c-macro-start
(if (and (eolp) (eq (char-before) ?\\))
(setq insert-backslash t
has-backslash t)
(setq has-backslash (eq (char-before (c-point 'eol)) ?\\))))
(newline newline-arg)
(indent-to col)
(when c-macro-start
(if insert-backslash
(progn
(insert ?\\)
(backward-char)
(c-backslash-region (point) (point) nil t))
(c-backslash-region start (if has-backslash (point) start) nil t)))
(when c-syntactic-indentation
(let ((c-syntactic-context (c-save-buffer-state nil
(c-guess-basic-syntax))))
(insert ?\n)
(delete-horizontal-space)
(setq start (- (point-max) (point)))
(unwind-protect
(progn
(backward-char)
(indent-according-to-mode))
(goto-char (- (point-max) start))
(delete-char -1)))
(when has-backslash
(c-backslash-region (point) (point) nil t)))))
(defun c-show-syntactic-information (arg)
"Show syntactic information for current line.
With universal argument, inserts the analysis as a comment on that line."
(interactive "P")
(let* ((c-parsing-error nil)
(syntax (if (boundp 'c-syntactic-context)
c-syntactic-context
(c-save-buffer-state nil
(c-guess-basic-syntax)))))
(if (not (consp arg))
(let (elem pos ols)
(message "Syntactic analysis: %s" syntax)
(unwind-protect
(progn
(while syntax
(setq elem (pop syntax))
(when (setq pos (c-langelem-pos elem))
(push (c-put-overlay pos (1+ pos)
'face 'highlight)
ols))
(when (setq pos (c-langelem-2nd-pos elem))
(push (c-put-overlay pos (1+ pos)
'face 'secondary-selection)
ols)))
(sit-for 10))
(while ols
(c-delete-overlay (pop ols)))))
(indent-for-comment)
(insert-and-inherit (format "%s" syntax))
))
(c-keep-region-active))
(defun c-syntactic-information-on-region (from to)
"Insert a comment with the syntactic analysis on every line in the region."
(interactive "*r")
(save-excursion
(save-restriction
(narrow-to-region from to)
(goto-char (point-min))
(while (not (eobp))
(c-show-syntactic-information '(0))
(forward-line)))))
(defun c-update-modeline ()
(let ((fmt (format "/%s%s%s%s"
(if c-electric-flag "l" "")
(if (and c-electric-flag c-auto-newline)
"a" "")
(if c-hungry-delete-key "h" "")
(if (and
(boundp 'c-subword-mode)
(symbol-value 'c-subword-mode))
"w"
"")))
(bare-mode-name (if (string-match "\\(^[^/]*\\)/" mode-name)
(substring mode-name (match-beginning 1) (match-end 1))
mode-name)))
(setq mode-name
(if (> (length fmt) 1)
(concat bare-mode-name fmt)
bare-mode-name))
(force-mode-line-update)))
(defun c-toggle-syntactic-indentation (&optional arg)
"Toggle syntactic indentation.
Optional numeric ARG, if supplied, turns on syntactic indentation when
positive, turns it off when negative, and just toggles it when zero or
left out.
When syntactic indentation is turned on (the default), the indentation
functions and the electric keys indent according to the syntactic
context keys, when applicable.
When it's turned off, the electric keys don't reindent, the indentation
functions indents every new line to the same level as the previous
nonempty line, and \\[c-indent-command] adjusts the indentation in steps
specified by `c-basic-offset'. The indentation style has no effect in
this mode, nor any of the indentation associated variables,
e.g. `c-special-indent-hook'.
This command sets the variable `c-syntactic-indentation'."
(interactive "P")
(setq c-syntactic-indentation
(c-calculate-state arg c-syntactic-indentation))
(c-keep-region-active))
(defun c-toggle-auto-newline (&optional arg)
"Toggle auto-newline feature.
Optional numeric ARG, if supplied, turns on auto-newline when
positive, turns it off when negative, and just toggles it when zero or
left out.
Turning on auto-newline automatically enables electric indentation.
When the auto-newline feature is enabled (indicated by \"/la\" on the
modeline after the mode name) newlines are automatically inserted
after special characters such as brace, comma, semi-colon, and colon."
(interactive "P")
(setq c-auto-newline
(c-calculate-state arg (and c-auto-newline c-electric-flag)))
(if c-auto-newline (setq c-electric-flag t))
(c-update-modeline)
(c-keep-region-active))
(defalias 'c-toggle-auto-state 'c-toggle-auto-newline)
(make-obsolete 'c-toggle-auto-state 'c-toggle-auto-newline)
(defun c-toggle-hungry-state (&optional arg)
"Toggle hungry-delete-key feature.
Optional numeric ARG, if supplied, turns on hungry-delete when
positive, turns it off when negative, and just toggles it when zero or
left out.
When the hungry-delete-key feature is enabled (indicated by \"/h\" on
the modeline after the mode name) the delete key gobbles all preceding
whitespace in one fell swoop."
(interactive "P")
(setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
(c-update-modeline)
(c-keep-region-active))
(defun c-toggle-auto-hungry-state (&optional arg)
"Toggle auto-newline and hungry-delete-key features.
Optional numeric ARG, if supplied, turns on auto-newline and
hungry-delete when positive, turns them off when negative, and just
toggles them when zero or left out.
See `c-toggle-auto-newline' and `c-toggle-hungry-state' for details."
(interactive "P")
(setq c-auto-newline (c-calculate-state arg c-auto-newline))
(setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
(c-update-modeline)
(c-keep-region-active))
(defun c-toggle-electric-state (&optional arg)
"Toggle the electric indentation feature.
Optional numeric ARG, if supplied, turns on electric indentation when
positive, turns it off when negative, and just toggles it when zero or
left out."
(interactive "P")
(setq c-electric-flag (c-calculate-state arg c-electric-flag))
(c-update-modeline)
(c-keep-region-active))
(defun c-electric-backspace (arg)
"Delete the preceding character or whitespace.
If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
line) then all preceding whitespace is consumed. If however a prefix
argument is supplied, or `c-hungry-delete-key' is nil, or point is
inside a literal then the function in the variable
`c-backspace-function' is called."
(interactive "*P")
(if (c-save-buffer-state ()
(or (not c-hungry-delete-key)
arg
(c-in-literal)))
(funcall c-backspace-function (prefix-numeric-value arg))
(c-hungry-delete-backwards)))
(defun c-hungry-delete-backwards ()
"Delete the preceding character or all preceding whitespace
back to the previous non-whitespace character.
See also \\[c-hungry-delete-forward]."
(interactive)
(let ((here (point)))
(c-skip-ws-backward)
(if (/= (point) here)
(delete-region (point) here)
(funcall c-backspace-function 1))))
(defalias 'c-hungry-backspace 'c-hungry-delete-backwards)
(defun c-electric-delete-forward (arg)
"Delete the following character or whitespace.
If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
line) then all following whitespace is consumed. If however a prefix
argument is supplied, or `c-hungry-delete-key' is nil, or point is
inside a literal then the function in the variable `c-delete-function'
is called."
(interactive "*P")
(if (c-save-buffer-state ()
(or (not c-hungry-delete-key)
arg
(c-in-literal)))
(funcall c-delete-function (prefix-numeric-value arg))
(c-hungry-delete-forward)))
(defun c-hungry-delete-forward ()
"Delete the following character or all following whitespace
up to the next non-whitespace character.
See also \\[c-hungry-delete-backwards]."
(interactive)
(let ((here (point)))
(c-skip-ws-forward)
(if (/= (point) here)
(delete-region (point) here)
(funcall c-delete-function 1))))
(defun c-electric-delete (arg)
"Deletes preceding or following character or whitespace.
This function either deletes forward as `c-electric-delete-forward' or
backward as `c-electric-backspace', depending on the configuration: If
the function `delete-forward-p' is defined and returns non-nil, it
deletes forward. Otherwise it deletes backward.
Note: This is the way in XEmacs to choose the correct action for the
\[delete] key, whichever key that means. Other flavors don't use this
function to control that."
(interactive "*P")
(if (and (fboundp 'delete-forward-p)
(delete-forward-p))
(c-electric-delete-forward arg)
(c-electric-backspace arg)))
(defun c-hungry-delete ()
"Delete a non-whitespace char, or all whitespace up to the next non-whitespace char.
The direction of deletion depends on the configuration: If the
function `delete-forward-p' is defined and returns non-nil, it deletes
forward using `c-hungry-delete-forward'. Otherwise it deletes
backward using `c-hungry-backspace'.
Note: This is the way in XEmacs to choose the correct action for the
\[delete] key, whichever key that means. Other flavors don't use this
function to control that."
(interactive)
(if (and (fboundp 'delete-forward-p)
(delete-forward-p))
(c-hungry-delete-forward)
(c-hungry-delete-backwards)))
(defun c-electric-pound (arg)
"Insert a \"#\".
If `c-electric-flag' is set, handle it specially according to the variable
`c-electric-pound-behavior'. If a numeric ARG is supplied, or if point is
inside a literal or a macro, nothing special happens."
(interactive "*P")
(if (c-save-buffer-state ()
(or arg
(not c-electric-flag)
(not (memq 'alignleft c-electric-pound-behavior))
(save-excursion
(skip-chars-backward " \t")
(not (bolp)))
(save-excursion
(and (= (forward-line -1) 0)
(progn (end-of-line)
(eq (char-before) ?\\))))
(c-in-literal)))
(self-insert-command (prefix-numeric-value arg))
(let ((pos (- (point-max) (point)))
(bolp (bolp)))
(beginning-of-line)
(delete-horizontal-space)
(insert last-command-char)
(and (not bolp)
(goto-char (- (point-max) pos)))
)))
(defun c-point-syntax ()
(c-save-buffer-state ( (c-echo-syntactic-information-p nil)
syntax)
(c-tentative-buffer-changes
(insert-char ?\n 1)
(when (or (c-at-vsemi-p (1- (point)))
(let ((pt (point)))
(save-excursion
(backward-char)
(and (c-beginning-of-macro)
(progn (c-end-of-macro)
(< (point) pt))))))
(backward-char)
(insert-char ?\\ 1)
(forward-char))
(let ((c-syntactic-indentation-in-macros t)
(c-auto-newline-analysis t))
(setq syntax (c-guess-basic-syntax))
nil))
syntax))
(defun c-brace-newlines (syntax)
(c-save-buffer-state
((syms
'(class-open class-close defun-open defun-close
inline-open inline-close
brace-list-open brace-list-close
brace-list-intro brace-entry-open
block-open block-close
substatement-open statement-case-open
extern-lang-open extern-lang-close
namespace-open namespace-close
module-open module-close
composition-open composition-close
inexpr-class-open inexpr-class-close
statement-cont))
(c-echo-syntactic-information-p nil)
symb-newlines)
(setq symb-newlines
(if (and c-special-brace-lists
(save-excursion
(c-safe (if (= (char-before) ?{)
(forward-char -1)
(c-forward-sexp -1))
(c-looking-at-special-brace-list))))
nil
(or (c-lookup-lists
syms
(if (assq 'inexpr-class syntax)
(cond ((assq 'class-open syntax)
'((inexpr-class-open)))
((assq 'class-close syntax)
'((inexpr-class-close)))
(t syntax))
syntax)
c-hanging-braces-alist)
'(ignore before after))))
(if (and (not (consp (cdr symb-newlines)))
(functionp (cdr symb-newlines)))
(let ((c-syntactic-context syntax))
(funcall (cdr symb-newlines)
(car symb-newlines)
(point)))
(cdr symb-newlines))))
(defun c-try-one-liner ()
(let ((here (point))
(pos (- (point-max) (point)))
mbeg1 mend1 mbeg4 mend4
eol-col cmnt-pos cmnt-col cmnt-gap)
(when
(save-excursion
(save-restriction
(narrow-to-region (save-excursion
(forward-line -2)
(point))
(point))
(and (c-safe (c-backward-sexp))
(progn
(forward-char)
(narrow-to-region (point) (1- here)) (looking-at
(cc-eval-when-compile
(concat
"\\(" "[ \t]*\\([\r\n][ \t]*\\)?" "\\)" "[^ \t\r\n]+\\([ \t]+[^ \t\r\n]+\\)*" "\\(" "[ \t]*\\([\r\n][ \t]*\\)?" "\\)\\'")))))))
(if (c-tentative-buffer-changes
(setq mbeg1 (match-beginning 1) mend1 (match-end 1)
mbeg4 (match-beginning 4) mend4 (match-end 4))
(backward-char) (save-excursion
(setq cmnt-pos (and (c-backward-single-comment)
(- (point) (- mend1 mbeg1)))))
(delete-region mbeg4 mend4)
(delete-region mbeg1 mend1)
(setq eol-col (save-excursion (end-of-line) (current-column)))
(when cmnt-pos
(delete-char 1) (goto-char cmnt-pos)
(setq cmnt-col (1+ (current-column)))
(setq cmnt-pos (1+ cmnt-pos)) (c-skip-ws-backward)
(insert-char ?\} 1) (setq cmnt-gap (- cmnt-col (current-column)))
(when (zerop cmnt-gap)
(insert-char ?\ 1) (setq cmnt-gap 1)))
(or (null c-max-one-liner-length)
(zerop c-max-one-liner-length)
(<= eol-col c-max-one-liner-length)
(and cmnt-gap
(< (- eol-col cmnt-gap) c-max-one-liner-length)
(progn (goto-char cmnt-pos)
(backward-delete-char-untabify
(- eol-col c-max-one-liner-length))
t))))
(goto-char (- (point-max) pos))))))
(defun c-electric-brace (arg)
"Insert a brace.
If `c-electric-flag' is non-nil, the brace is not inside a literal and a
numeric ARG hasn't been supplied, the command performs several electric
actions:
\(a) If the auto-newline feature is turned on (indicated by \"/la\" on
the mode line) newlines are inserted before and after the brace as
directed by the settings in `c-hanging-braces-alist'.
\(b) Any auto-newlines are indented. The original line is also
reindented unless `c-syntactic-indentation' is nil.
\(c) If auto-newline is turned on, various newline cleanups based on the
settings of `c-cleanup-list' are done."
(interactive "*P")
(let (safepos literal
(old-blink-paren blink-paren-function)
blink-paren-function)
(c-save-buffer-state ()
(setq safepos (c-safe-position (point) (c-parse-state))
literal (c-in-literal safepos)))
(self-insert-command (prefix-numeric-value arg))
(when (and c-electric-flag (not literal) (not arg))
(if (not (looking-at "[ \t]*\\\\?$"))
(if c-syntactic-indentation
(indent-according-to-mode))
(let ( (c-echo-syntactic-information-p nil)
newlines
ln-syntax br-syntax syntax) (c-save-buffer-state ((c-syntactic-indentation-in-macros t)
(c-auto-newline-analysis t))
(setq ln-syntax (c-guess-basic-syntax)))
(if c-syntactic-indentation
(c-indent-line ln-syntax))
(when c-auto-newline
(backward-char)
(setq br-syntax (c-point-syntax)
newlines (c-brace-newlines br-syntax))
(if (and (memq 'before newlines)
(> (current-column) (current-indentation)))
(if c-syntactic-indentation
(newline)
(c-newline-and-indent)))
(forward-char)
(setq syntax (if (memq 'before newlines) br-syntax ln-syntax))
(let ((here (point))
(pos (- (point-max) (point)))
mbeg mend
)
(when (c-save-buffer-state ()
(and (memq 'empty-defun-braces c-cleanup-list)
(eq last-command-char ?\})
(c-intersect-lists '(defun-close class-close inline-close)
syntax)
(progn
(forward-char -1)
(c-skip-ws-backward)
(eq (char-before) ?\{))
(not (c-in-literal))))
(delete-region (point) (1- here))
(setq here (- (point-max) pos)))
(goto-char here)
(save-match-data
(when
(and (eq last-command-char ?\})
(memq 'one-liner-defun c-cleanup-list)
(c-intersect-lists '(defun-close) syntax)
(c-try-one-liner))
(setq here (- (point-max) pos))))
(when (eq last-command-char ?\{)
(cond
((and (memq 'brace-else-brace c-cleanup-list)
(re-search-backward
(concat "}"
"\\([ \t\n]\\|\\\\\n\\)*"
"else"
"\\([ \t\n]\\|\\\\\n\\)*"
"{"
"\\=")
nil t))
(delete-region (match-beginning 0) (match-end 0))
(insert-and-inherit "} else {"))
((and (memq 'brace-elseif-brace c-cleanup-list)
(progn
(goto-char (1- here))
(setq mend (point))
(c-skip-ws-backward)
(setq mbeg (point))
(eq (char-before) ?\)))
(zerop (c-save-buffer-state nil (c-backward-token-2 1 t)))
(eq (char-after) ?\()
(re-search-backward
(concat "}"
"\\([ \t\n]\\|\\\\\n\\)*"
"else"
"\\([ \t\n]\\|\\\\\n\\)+"
"if"
"\\([ \t\n]\\|\\\\\n\\)*"
"\\=")
nil t) )
(delete-region mbeg mend)
(goto-char mbeg)
(insert ?\ ))))
(goto-char (- (point-max) pos))
(when c-syntactic-indentation
(c-indent-line)))
(if (memq 'after newlines)
(c-newline-and-indent))
))))
(and (eq last-command-char ?\})
(not executing-kbd-macro)
old-blink-paren
(save-excursion
(c-save-buffer-state nil
(c-backward-syntactic-ws safepos))
(funcall old-blink-paren)))))
(defun c-electric-slash (arg)
"Insert a slash character.
If the slash is inserted immediately after the comment prefix in a c-style
comment, the comment might get closed by removing whitespace and possibly
inserting a \"*\". See the variable `c-cleanup-list'.
Indent the line as a comment, if:
1. The slash is second of a \"//\" line oriented comment introducing
token and we are on a comment-only-line, or
2. The slash is part of a \"*/\" token that closes a block oriented
comment.
If a numeric ARG is supplied, point is inside a literal, or
`c-syntactic-indentation' is nil or `c-electric-flag' is nil, indentation
is inhibited."
(interactive "*P")
(let ((literal (c-save-buffer-state () (c-in-literal)))
indentp
(c-echo-syntactic-information-p nil))
(when (and (not arg)
(eq literal 'c)
(memq 'comment-close-slash c-cleanup-list)
(eq last-command-char ?/)
(looking-at (concat "[ \t]*\\("
(regexp-quote comment-end) "\\)?$"))
(save-excursion
(save-restriction
(narrow-to-region (point-min) (point))
(back-to-indentation)
(looking-at (concat c-current-comment-prefix "[ \t]*$")))))
(delete-region (progn (forward-line 0) (point))
(progn (end-of-line) (point)))
(insert-char ?* 1))
(setq indentp (and (not arg)
c-syntactic-indentation
c-electric-flag
(eq last-command-char ?/)
(eq (char-before) (if literal ?* ?/))))
(self-insert-command (prefix-numeric-value arg))
(if indentp
(indent-according-to-mode))))
(defun c-electric-star (arg)
"Insert a star character.
If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, and
the star is the second character of a C style comment starter on a
comment-only-line, indent the line as a comment. If a numeric ARG is
supplied, point is inside a literal, or `c-syntactic-indentation' is nil,
this indentation is inhibited."
(interactive "*P")
(self-insert-command (prefix-numeric-value arg))
(if (c-save-buffer-state ()
(and c-syntactic-indentation
c-electric-flag
(not arg)
(eq (c-in-literal) 'c)
(eq (char-before) ?*)
(save-excursion
(forward-char -1)
(skip-chars-backward "*")
(if (eq (char-before) ?/)
(forward-char -1))
(skip-chars-backward " \t")
(bolp))))
(let (c-echo-syntactic-information-p) (indent-according-to-mode))
))
(defun c-electric-semi&comma (arg)
"Insert a comma or semicolon.
If `c-electric-flag' is non-nil, point isn't inside a literal and a
numeric ARG hasn't been supplied, the command performs several electric
actions:
\(a) When the auto-newline feature is turned on (indicated by \"/la\" on
the mode line) a newline might be inserted. See the variable
`c-hanging-semi&comma-criteria' for how newline insertion is determined.
\(b) Any auto-newlines are indented. The original line is also
reindented unless `c-syntactic-indentation' is nil.
\(c) If auto-newline is turned on, a comma following a brace list or a
semicolon following a defun might be cleaned up, depending on the
settings of `c-cleanup-list'."
(interactive "*P")
(let* (lim literal c-syntactic-context
(here (point))
(c-echo-syntactic-information-p nil))
(c-save-buffer-state ()
(setq lim (c-most-enclosing-brace (c-parse-state))
literal (c-in-literal lim)))
(self-insert-command (prefix-numeric-value arg))
(if (and c-electric-flag (not literal) (not arg))
(if (or (not c-auto-newline)
(not (looking-at "[ \t]*\\\\?$")))
(if c-syntactic-indentation
(c-indent-line))
(let ((pos (- (point-max) (point))))
(if (c-save-buffer-state ()
(and (or (and
(eq last-command-char ?,)
(memq 'list-close-comma c-cleanup-list))
(and
(eq last-command-char ?\ (memq 'defun-close-semi c-cleanup-list)))
(progn
(forward-char -1)
(c-skip-ws-backward)
(eq (char-before) ?}))
(not (c-in-literal lim))))
(delete-region (point) here))
(goto-char (- (point-max) pos)))
(when c-syntactic-indentation
(setq c-syntactic-context (c-guess-basic-syntax))
(c-indent-line c-syntactic-context))
(let ((criteria c-hanging-semi&comma-criteria)
answer add-newline-p)
(while criteria
(setq answer (funcall (car criteria)))
(if (not answer)
(setq criteria (cdr criteria))
(setq criteria nil)
(setq add-newline-p (not (eq answer 'stop)))
))
(if add-newline-p
(c-newline-and-indent))
)))))
(defun c-electric-colon (arg)
"Insert a colon.
If `c-electric-flag' is non-nil, the colon is not inside a literal and a
numeric ARG hasn't been supplied, the command performs several electric
actions:
\(a) If the auto-newline feature is turned on (indicated by \"/la\" on
the mode line) newlines are inserted before and after the colon based on
the settings in `c-hanging-colons-alist'.
\(b) Any auto-newlines are indented. The original line is also
reindented unless `c-syntactic-indentation' is nil.
\(c) If auto-newline is turned on, whitespace between two colons will be
\"cleaned up\" leaving a scope operator, if this action is set in
`c-cleanup-list'."
(interactive "*P")
(let* ((bod (c-point 'bod))
(literal (c-save-buffer-state () (c-in-literal bod)))
newlines is-scope-op
(c-echo-syntactic-information-p nil))
(self-insert-command (prefix-numeric-value arg))
(if (and c-electric-flag (not literal) (not arg))
(if (not (looking-at "[ \t]*\\\\?$"))
(if c-syntactic-indentation
(indent-according-to-mode))
(let ((pos (- (point-max) (point)))
(here (point)))
(if (c-save-buffer-state () (and c-auto-newline
(memq 'scope-operator c-cleanup-list)
(eq (char-before) ?:)
(progn
(forward-char -1)
(c-skip-ws-backward)
(eq (char-before) ?:))
(not (c-in-literal))
(not (eq (char-after (- (point) 2)) ?:))))
(progn
(delete-region (point) (1- here))
(setq is-scope-op t)))
(goto-char (- (point-max) pos)))
(if c-syntactic-indentation
(indent-according-to-mode))
(c-save-buffer-state
((c-syntactic-indentation-in-macros t)
(c-auto-newline-analysis t)
(syntax (c-guess-basic-syntax))
(elem syntax))
(while elem
(if (eq (car (car elem)) 'substatement-label)
(setcar (car elem) 'label))
(setq elem (cdr elem)))
(setq newlines
(and c-auto-newline
(or (c-lookup-lists '(case-label label access-label)
syntax c-hanging-colons-alist)
(c-lookup-lists '(member-init-intro inher-intro)
(progn
(insert ?\n)
(unwind-protect
(c-guess-basic-syntax)
(delete-char -1)))
c-hanging-colons-alist)))))
(if (and (memq 'before newlines)
(not is-scope-op)
(save-excursion
(skip-chars-backward ": \t")
(not (bolp))))
(let ((pos (- (point-max) (point))))
(forward-char -1)
(c-newline-and-indent)
(goto-char (- (point-max) pos))))
(if (and (memq 'after (cdr-safe newlines))
(not is-scope-op))
(c-newline-and-indent))
))))
(defun c-electric-lt-gt (arg)
"Insert a \"<\" or \">\" character.
If the current language uses angle bracket parens (e.g. template
arguments in C++), try to find out if the inserted character is a
paren and give it paren syntax if appropriate.
If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, the
line will be reindented if the inserted character is a paren or if it
finishes a C++ style stream operator in C++ mode. Exceptions are when a
numeric argument is supplied, or the point is inside a literal."
(interactive "*P")
(let ((c-echo-syntactic-information-p nil)
final-pos close-paren-inserted)
(self-insert-command (prefix-numeric-value arg))
(setq final-pos (point))
(c-save-buffer-state (c-parse-and-markup-<>-arglists
c-restricted-<>-arglists
<-pos)
(when c-recognize-<>-arglists
(if (eq last-command-char ?<)
(when (and (progn
(backward-char)
(= (point)
(progn
(c-beginning-of-current-token)
(point))))
(progn
(c-backward-token-2)
(looking-at c-opt-<>-sexp-key)))
(c-mark-<-as-paren (1- final-pos)))
(save-restriction
(narrow-to-region (point-min) final-pos)
(while (and
(progn
(goto-char final-pos)
(c-syntactic-skip-backward "^<;}" nil t)
(eq (char-before) ?<))
(progn
(backward-char)
(if (looking-at "\\s\(")
(progn
(c-mark->-as-paren (1- final-pos))
(setq close-paren-inserted t)
nil)
t))
(progn
(setq <-pos (point))
(c-backward-syntactic-ws)
(c-simple-skip-symbol-backward))
(or (looking-at c-opt-<>-sexp-key)
(not (looking-at c-keywords-regexp)))
(let ((c-parse-and-markup-<>-arglists t)
c-restricted-<>-arglists
(containing-sexp
(c-most-enclosing-brace (c-parse-state))))
(when (and containing-sexp
(progn (goto-char containing-sexp)
(eq (char-after) ?\())
(not (eq (get-text-property (point) 'c-type)
'c-decl-arg-start)))
(setq c-restricted-<>-arglists t))
(goto-char <-pos)
(c-forward-<>-arglist nil))
(if (< (point) final-pos)
t
(setq close-paren-inserted t)
nil)))))))
(goto-char final-pos)
(when (and c-electric-flag c-syntactic-indentation)
(backward-char)
(when (prog1 (or (looking-at "\\s\(\\|\\s\)")
(and (c-major-mode-is 'c++-mode)
(progn
(c-beginning-of-current-token)
(looking-at "<<\\|>>"))
(= (match-end 0) final-pos)))
(goto-char final-pos))
(indent-according-to-mode)))
(when (and close-paren-inserted
(not executing-kbd-macro)
blink-paren-function)
(funcall blink-paren-function))))
(defun c-electric-paren (arg)
"Insert a parenthesis.
If `c-syntactic-indentation' and `c-electric-flag' are both non-nil, the
line is reindented unless a numeric ARG is supplied, or the parenthesis
is inserted inside a literal.
Whitespace between a function name and the parenthesis may get added or
removed; see the variable `c-cleanup-list'.
Also, if `c-electric-flag' and `c-auto-newline' are both non-nil, some
newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
(interactive "*P")
(let ((literal (c-save-buffer-state () (c-in-literal)))
(c-echo-syntactic-information-p nil))
(self-insert-command (prefix-numeric-value arg))
(if (and (not arg) (not literal))
(let* ( (old-blink-paren blink-paren-function)
blink-paren-function)
(if (and c-syntactic-indentation c-electric-flag)
(indent-according-to-mode))
(when (and c-electric-flag c-auto-newline
(looking-at "[ \t]*\\\\?$"))
(when
(and (memq 'brace-elseif-brace c-cleanup-list)
(eq last-command-char ?\()
(re-search-backward
(concat "}"
"\\([ \t\n]\\|\\\\\n\\)*"
"else"
"\\([ \t\n]\\|\\\\\n\\)+"
"if"
"\\([ \t\n]\\|\\\\\n\\)*"
"("
"\\=")
nil t)
(not (c-save-buffer-state () (c-in-literal))))
(delete-region (match-beginning 0) (match-end 0))
(insert-and-inherit "} else if ("))
(when
(and (memq 'brace-catch-brace c-cleanup-list)
(eq last-command-char ?\()
(re-search-backward
(concat "}"
"\\([ \t\n]\\|\\\\\n\\)*"
"catch"
"\\([ \t\n]\\|\\\\\n\\)*"
"("
"\\=")
nil t)
(not (c-save-buffer-state () (c-in-literal))))
(delete-region (match-beginning 0) (match-end 0))
(insert-and-inherit "} catch (")))
(let (beg (end (1- (point))))
(cond
((and (memq 'space-before-funcall c-cleanup-list)
(eq last-command-char ?\()
(save-excursion
(backward-char)
(skip-chars-backward " \t")
(setq beg (point))
(and (c-save-buffer-state () (c-on-identifier))
(not (and (c-beginning-of-macro)
(c-forward-over-cpp-define-id)
(eq (point) beg))))))
(save-excursion
(delete-region beg end)
(goto-char beg)
(insert ?\ )))
((c-save-buffer-state ()
(and (memq 'compact-empty-funcall c-cleanup-list)
(eq last-command-char ?\))
(save-excursion
(c-safe (backward-char 2))
(when (looking-at "()")
(setq end (point))
(skip-chars-backward " \t")
(setq beg (point))
(c-on-identifier)))))
(delete-region beg end))))
(and (eq last-input-event ?\))
(not executing-kbd-macro)
old-blink-paren
(funcall old-blink-paren))))))
(defun c-electric-continued-statement ()
"Reindent the current line if appropriate.
This function is used to reindent the line after a keyword which
continues an earlier statement is typed, e.g. an \"else\" or the
\"while\" in a do-while block.
The line is reindented if there is nothing but whitespace before the
keyword on the line, the keyword is not inserted inside a literal, and
`c-electric-flag' and `c-syntactic-indentation' are both non-nil."
(let ( (c-echo-syntactic-information-p nil))
(when (c-save-buffer-state ()
(and c-electric-flag
c-syntactic-indentation
(not (eq last-command-char ?_))
(= (save-excursion
(skip-syntax-backward "w")
(point))
(c-point 'boi))
(not (c-in-literal (c-point 'bod)))))
(insert-and-inherit " x")
(unwind-protect
(indent-according-to-mode)
(delete-char -2)))))
(defun c-forward-into-nomenclature (&optional arg)
"Compatibility alias for `c-forward-subword'."
(interactive "p")
(require 'cc-subword)
(c-forward-subword arg))
(make-obsolete 'c-forward-into-nomenclature 'c-forward-subword)
(defun c-backward-into-nomenclature (&optional arg)
"Compatibility alias for `c-backward-subword'."
(interactive "p")
(require 'cc-subword)
(c-backward-subword arg))
(make-obsolete 'c-backward-into-nomenclature 'c-backward-subword)
(defun c-scope-operator ()
"Insert a double colon scope operator at point.
No indentation or other \"electric\" behavior is performed."
(interactive "*")
(insert-and-inherit "::"))
(defun c-in-function-trailer-p (&optional lim)
(and c-opt-block-decls-with-vars-key
(save-excursion
(c-syntactic-skip-backward "^;}" lim)
(let ((eo-block (point))
bod)
(and (eq (char-before) ?\})
(eq (car (c-beginning-of-decl-1 lim)) 'previous)
(setq bod (point))
(c-syntactic-re-search-forward
(concat "[;=\(\[{]\\|\\("
c-opt-block-decls-with-vars-key
"\\)")
eo-block t t t)
(match-beginning 1) (not (eq (char-before) ?_))
(c-syntactic-re-search-forward "[;=\(\[{]" eo-block t t t)
(eq (char-before) ?\{)
bod)))))
(defun c-where-wrt-brace-construct ()
(save-excursion
(let* (kluge-start
decl-result brace-decl-p
(start (point))
(paren-state (c-parse-state))
(least-enclosing (c-least-enclosing-brace paren-state)))
(cond
((and least-enclosing
(eq (char-after least-enclosing) ?\{))
'in-block)
((c-in-function-trailer-p)
'in-trailer)
((and (not least-enclosing)
(consp paren-state)
(consp (car paren-state))
(eq start (cdar paren-state)))
'at-function-end)
(t
(if least-enclosing (goto-char least-enclosing))
(if (or (and (eolp) (not (eobp))) (not (looking-at
"\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\|\\s!\\)")))
(forward-char))
(setq kluge-start (point))
(setq decl-result
(car (c-beginning-of-decl-1
(and least-enclosing (c-safe-position least-enclosing paren-state)))))
(setq brace-decl-p
(save-excursion
(and (c-syntactic-re-search-forward "[;{]" nil t t)
(or (eq (char-before) ?\{)
(and c-recognize-knr-p
(c-in-knr-argdecl))))))
(cond
((= (point) kluge-start) 'outwith-function)
((eq decl-result 'same)
(if brace-decl-p
(if (eq (point) start)
'at-header
'in-header)
'outwith-function))
((eq decl-result 'previous)
(if (and (not brace-decl-p)
(c-in-function-trailer-p))
'at-function-end
'outwith-function))
(t (error
"c-where-wrt-brace-construct: c-beginning-of-decl-1 returned %s"
decl-result))))))))
(defun c-backward-to-nth-BOF-{ (n where)
(cond
((bobp))
((eq where 'in-block)
(goto-char (c-least-enclosing-brace (c-parse-state)))
(setq n (1- n)))
((eq where 'in-header)
(c-syntactic-re-search-forward "{")
(backward-char)
(setq n (1- n)))
((memq where '(at-header outwith-function at-function-end in-trailer))
(c-syntactic-skip-backward "^}")
(when (eq (char-before) ?\})
(backward-sexp)
(setq n (1- n))))
(t (error "Unknown `where' %s in c-backward-to-nth-EOF-{" where)))
(while (and (> n 0) (not (bobp)))
(c-parse-state) (c-syntactic-skip-backward "^}")
(when (eq (char-before) ?\})
(backward-sexp)
(setq n (1- n))))
n)
(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))
(c-save-buffer-state
(beginning-of-defun-function end-of-defun-function
(start (point))
where paren-state pos)
(c-beginning-of-macro)
(setq pos (c-literal-limits))
(if pos (goto-char (car pos)))
(setq where (c-where-wrt-brace-construct))
(if (< arg 0)
(progn
(if (memq where '(at-function-end outwith-function))
(setq arg (1+ arg)))
(if (< arg 0)
(setq arg (c-forward-to-nth-EOF-} (- arg) where)))
(when (and (= arg 0)
(c-syntactic-re-search-forward "{" nil 'eob))
(backward-char)
(c-beginning-of-decl-1)
t))
(when (and (> arg 0)
(eq (setq arg (c-backward-to-nth-BOF-{ arg where)) 0))
(c-beginning-of-decl-1)
(setq pos (point))
(while (and (/= (point) (c-point 'boi))
(c-backward-single-comment)))
(if (/= (point) (c-point 'boi))
(goto-char pos)))
(c-keep-region-active)
(= arg 0))))
(defun c-forward-to-nth-EOF-} (n where)
(cond
((eobp))
((eq where 'in-block)
(goto-char (c-least-enclosing-brace (c-parse-state)))
(forward-sexp)
(setq n (1- n)))
((eq where 'in-trailer)
(c-syntactic-skip-backward "^}")
(setq n (1- n)))
((memq where '(at-function-end outwith-function at-header in-header))
(when (c-syntactic-re-search-forward "{" nil 'eob)
(backward-char)
(forward-sexp)
(setq n (1- n))))
(t (error "c-forward-to-nth-EOF-}: `where' is %s" where)))
(while (and (> n 0) (not (eobp)))
(when (c-syntactic-re-search-forward "{" nil 'eob)
(backward-char)
(forward-sexp))
(setq n (1- n)))
n)
(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))
(c-save-buffer-state
(beginning-of-defun-function end-of-defun-function
(start (point))
where paren-state pos)
(c-beginning-of-macro)
(setq pos (c-literal-limits))
(if pos (goto-char (car pos)))
(setq where (c-where-wrt-brace-construct))
(if (< arg 0)
(progn
(if (memq where '(at-header outwith-function))
(setq arg (1+ arg)))
(if (< arg 0)
(setq arg (c-backward-to-nth-BOF-{ (- arg) where)))
(if (= arg 0)
(c-syntactic-skip-backward "^}")))
(if (> arg 0)
(setq arg (c-forward-to-nth-EOF-} arg where))))
(when (eq arg 0)
(if (c-in-function-trailer-p) (c-syntactic-re-search-forward ";"))
(setq pos (point))
(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)))
(defun c-declaration-limits (near)
(save-excursion
(catch 'exit
(let ((start (point))
(paren-state (c-parse-state))
lim pos end-pos)
(unless (c-safe
(goto-char (c-least-enclosing-brace paren-state))
(setq lim (c-safe-position (point) paren-state))
t)
(setq pos (c-literal-limits
(c-safe-position (point) paren-state)))
(if pos (goto-char (car pos))))
(when (c-beginning-of-macro)
(throw 'exit
(cons (point)
(save-excursion
(c-end-of-macro)
(forward-line 1)
(point)))))
(setq pos (point))
(when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous)
(= pos (point)))
(goto-char pos)
(c-forward-comments)
(when (and near (c-beginning-of-macro))
(throw 'exit
(cons (point)
(save-excursion
(c-end-of-macro)
(forward-line 1)
(point))))))
(if (eobp) (throw 'exit nil))
(setq pos (point))
(if (and c-opt-block-decls-with-vars-key
(progn
(c-backward-syntactic-ws)
(eq (char-before) ?}))
(eq (car (c-beginning-of-decl-1))
'previous)
(save-excursion
(c-end-of-decl-1)
(and (> (point) pos)
(setq end-pos (point)))))
nil
(goto-char pos))
(if (and (not near) (> (point) start))
nil
(cons (progn
(setq pos (point))
(while (and (/= (point) (c-point 'boi))
(c-backward-single-comment)))
(if (/= (point) (c-point 'boi))
pos
(point)))
(progn
(if end-pos
(goto-char end-pos)
(c-end-of-decl-1))
(setq pos (point))
(while (and (not (bolp))
(not (looking-at "\\s *$"))
(c-forward-single-comment)))
(cond ((bolp)
(point))
((looking-at "\\s *$")
(forward-line 1)
(point))
(t
pos)))))
))))
(defun c-mark-function ()
"Put mark at end of the current top-level declaration or macro, point at beginning.
If point is not inside any then the closest following one is chosen.
As opposed to \\[c-beginning-of-defun] and \\[c-end-of-defun], this
function does not require the declaration to contain a brace block."
(interactive)
(let (decl-limits)
(c-save-buffer-state nil
(if (looking-at c-syntactic-eol)
(c-backward-token-2 1 nil (c-point 'bol)))
(setq decl-limits (c-declaration-limits t)))
(if (not decl-limits)
(error "Cannot find any declaration")
(goto-char (car decl-limits))
(push-mark (cdr decl-limits) nil t))))
(defun c-in-comment-line-prefix-p ()
(let ((here (point)))
(save-excursion
(beginning-of-line)
(skip-chars-forward " \t")
(and (looking-at c-current-comment-prefix)
(/= (match-beginning 0) (match-end 0))
(< here (match-end 0))))))
(defun c-narrow-to-comment-innards (range)
(let* ((lit-type (c-literal-type range))
(beg (if (eq lit-type 'c) (+ (car range) 2) (car range)))
(end (if (eq lit-type 'c)
(if (and (eq (char-before (cdr range)) ?/)
(eq (char-before (1- (cdr range))) ?*))
(- (cdr range) 2)
(point-max))
(if (eq (cdr range) (point-max))
(point-max)
(- (cdr range) 1)))))
(if (> (point) end)
(goto-char end)) (if (< (point) beg)
(goto-char beg)) (narrow-to-region beg end)))
(defun c-beginning-of-sentence-in-comment (range)
(save-match-data
(let ((start-point (point)))
(save-restriction
(c-narrow-to-comment-innards range) (let* ((here (point))
last
(here-filler (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)"
"\\|[ \t\n\r\f]\\)*"))
(prefix-at-bol-here (concat "^[ \t]*\\(" c-current-comment-prefix "\\)[ \t\n\r\f]*\\="))
(par-beg (save-excursion
(forward-paragraph -1) (if (> (re-search-forward here-filler nil t) here)
(goto-char here))
(when (>= (point) here)
(forward-paragraph -2)
(if (> (re-search-forward here-filler nil t) here)
(goto-char here)))
(point))))
(while (and (re-search-backward (c-sentence-end) par-beg 'limit)
(setq last (point))
(goto-char (match-end 0)) (or (>= (point) here)
(and (not (bolp)) (save-excursion
(if (re-search-backward prefix-at-bol-here nil t)
(/= (match-beginning 1) (match-end 1)))))
(progn (if (c-in-comment-line-prefix-p)
(beginning-of-line))
(re-search-forward here-filler) (>= (point) here))))
(goto-char last))
(re-search-forward here-filler)))
(if (< (point) start-point)
nil
(goto-char (car range))
t))))
(defun c-end-of-sentence-in-comment (range)
(save-match-data
(let ((start-point (point))
)
(save-restriction
(c-narrow-to-comment-innards range) (let* ((here (point))
(par-end (save-excursion
(forward-paragraph 1)
(if (eq (preceding-char) ?\n) (forward-char -1))
(when (<= (point) here) (goto-char here)
(forward-paragraph 2)
(if (eq (preceding-char) ?\n) (forward-char -1)))
(point)))
last
(prefix-at-bol-here
(concat "^[ \t]*\\(" c-current-comment-prefix "\\)\\=")))
(while (and (re-search-forward (c-sentence-end) par-end 'limit)
(progn
(setq last (point))
(skip-chars-backward " \t\n")
(or (and (not (bolp))
(re-search-backward prefix-at-bol-here nil t)
(/= (match-beginning 1) (match-end 1)))
(<= (point) here))))
(goto-char last))
(if (eq (point) (point-max))
(while (or (/= (skip-chars-backward " \t\n") 0)
(and (re-search-backward prefix-at-bol-here nil t)
(/= (match-beginning 1) (match-end 1))))))))
(if (> (point) start-point)
nil
(goto-char (cdr range))
t))))
(defun c-beginning-of-sentence-in-string (range)
(save-match-data
(let* ((here (point)) last
(end (1- (cdr range)))
(here-filler "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*")
(paragraph-start c-string-par-start)
(paragraph-separate c-string-par-separate)
(par-beg (save-excursion
(save-restriction
(narrow-to-region (1+ (car range)) end)
(forward-paragraph -1) (if (> (re-search-forward here-filler nil t) here)
(goto-char here))
(when (>= (point) here)
(forward-paragraph -2)
(if (> (re-search-forward here-filler nil t) here)
(goto-char here)))
(point)))))
(while (and (re-search-backward c-sentence-end-with-esc-eol par-beg 'limit)
(setq last (point))
(goto-char (match-end 0))
(or (> (point) end)
(progn
(re-search-forward
here-filler end t) (>= (point) here))))
(goto-char last))
(re-search-forward here-filler here t)
(if (< (point) here)
nil
(goto-char (car range))
t))))
(defun c-end-of-sentence-in-string (range)
(save-match-data
(let* ((here (point))
last
(paragraph-start c-string-par-start)
(paragraph-separate c-string-par-separate)
(par-end (save-excursion
(save-restriction
(narrow-to-region (car range) (1- (cdr range)))
(forward-paragraph 1)
(setq last (point))
(while (or (/= (skip-chars-backward " \t\n\r\f") 0)
(re-search-backward "\\\\\\($\\)\\=" nil t)))
(unless (> (point) here)
(goto-char last)
(forward-paragraph 1)
(while (or (/= (skip-chars-backward " \t\n\r\f") 0)
(re-search-backward "\\\\\\($\\)\\=" nil t))))
(point)))))
(when (re-search-forward c-sentence-end-with-esc-eol par-end 'limit)
(setq last (point))
(while (or (/= (skip-chars-backward " \t\n") 0)
(re-search-backward "\\\\\\($\\)\\=" nil t))))
(if (> (point) here)
nil
(goto-char (cdr range))
t))))
(defun c-ascertain-preceding-literal ()
(save-excursion
(c-collect-line-comments
(let ((here (point))
pos)
(if (c-backward-single-comment)
(cons (point) (progn (c-forward-single-comment) (point)))
(save-restriction
(narrow-to-region (point-min) here)
(when
(or
(looking-at c-ws*-string-limit-regexp)
(and (not (bobp))
(progn (backward-char)
(looking-at c-string-limit-regexp))))
(goto-char (match-end 0)) (setq pos (point))
(c-safe (c-backward-sexp 1) (cons (point) pos)))))))))
(defun c-ascertain-following-literal ()
(save-excursion
(c-collect-line-comments
(let (pos)
(c-skip-ws-forward)
(if (looking-at c-string-limit-regexp) (cons (point) (or (c-safe (progn (c-forward-sexp 1) (point)))
(point-max)))
(setq pos (point))
(if (c-forward-single-comment)
(cons pos (point))))))))
(defun c-after-statement-terminator-p () (or (save-excursion
(backward-char)
(and (looking-at "[;{}]")
(not (and c-special-brace-lists (eq (char-after) ?{)
(c-looking-at-special-brace-list)))))
(c-at-vsemi-p)
(let (eom)
(save-excursion
(if (c-beginning-of-macro)
(setq eom (progn (c-end-of-macro)
(point)))))
(when eom
(save-excursion
(c-forward-comments)
(>= (point) eom))))))
(defun c-back-over-illiterals (macro-start)
(save-match-data
(let ((here (point))
last) (catch 'done
(while t (setq last (point))
(cond
((c-backward-single-comment) (goto-char last)
(throw 'done '(t . literal)))
((and (save-excursion
(beginning-of-line)
(re-search-forward "\\(^\\|[^\\]\\)[\n\r]" last t))
(if macro-start
(< (point) macro-start)
(c-beginning-of-macro)))
(goto-char last)
(throw 'done (cons (or (eq (point) here)
(not macro-start))
'macro-boundary)))
((and (c-at-vsemi-p)
(< last here)
(not (memq (char-after last) '(?\) ?})))) (goto-char last)
(throw 'done '(nil . nil)))
((bobp)
(if (/= here last)
(goto-char last))
(throw 'done '(nil . nil)))
((progn (backward-char) nil))
((eq (char-after) ?\{)
(if (and c-special-brace-lists
(c-looking-at-special-brace-list))
(skip-syntax-backward "w_") (if (/= here last)
(goto-char last))
(throw 'done '(nil . nil))))
((and macro-start (eq (point) macro-start))
(throw 'done (cons (eq (point) here) 'macro-boundary)))
((looking-at "[;}]")
(if (or (= here last)
(memq (char-after last) '(?\) ?}))) (if (and (eq (char-before) ?}) (eq (char-after) ?\ (backward-char))
(goto-char last) (throw 'done '(nil . nil))))
((looking-at c-string-limit-regexp) (goto-char last)
(throw 'done '(t . literal)))
(t (skip-syntax-backward "w_")) ))))))
(defun c-forward-over-illiterals (macro-end allow-early-stop)
(let ((here (point))
last)
(catch 'done
(while t (setq last (point))
(if (and (> last here) (c-at-vsemi-p))
(throw 'done '(nil . nil)))
(c-skip-ws-forward)
(cond
((and macro-end (> (point) macro-end))
(goto-char last)
(throw 'done (cons (eq (point) here) 'macro-boundary)))
((save-excursion (c-forward-single-comment))
(goto-char last)
(throw 'done '(t . literal)))
((eobp)
(if (/= here last)
(goto-char last))
(throw 'done '(nil . nil)))
((and (eq (char-after) ?{)
(not (and c-special-brace-lists
(c-looking-at-special-brace-list)))
(or allow-early-stop (/= here last))
(save-excursion (or (not (c-safe (up-list -1) t))
(= (char-after) ?{))))
(goto-char last)
(throw 'done '(nil . nil)))
((and c-special-brace-lists
(eq (char-after) ?})
(save-excursion
(and (c-safe (up-list -1) t)
(c-looking-at-special-brace-list))))
(forward-char)
(skip-syntax-forward "w_"))
((and (eq (char-after) ?})
(/= here last))
(goto-char last)
(throw 'done '(nil . nil)))
((and (not macro-end)
(eq (char-after) ?#)
(= (point) (c-point 'boi)))
(goto-char last)
(throw 'done '(t . macro-boundary)))
((looking-at ";\\|};?")
(goto-char (match-end 0))
(throw 'done '(nil . nil)))
((looking-at c-string-limit-regexp)
(goto-char last)
(throw 'done '(t . literal)))
(t
(forward-char) (skip-syntax-forward "w_") (when (and macro-end (> (point) macro-end))
(goto-char last)
(throw 'done (cons (eq (point) here) 'macro-boundary))))
)))))
(defun c-one-line-string-p (range)
(save-excursion
(goto-char (car range))
(and (looking-at c-string-limit-regexp)
(progn (skip-chars-forward "^\n" (cdr range))
(eq (point) (cdr range))))))
(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 (macro-fence
(save-excursion (and (not (bobp)) (c-beginning-of-macro) (point))))
res not-bos (range (c-collect-line-comments (c-literal-limits lim))))
(while (and (/= count 0)
(or (not lim) (> (point) lim)))
(setq last (point))
(while
(cond ((bobp)
(setq count 0)
nil)
(range (cond
((or (null sentence-flag)
(c-one-line-string-p range))
(goto-char (car range))
(setq range (c-ascertain-preceding-literal))
(save-excursion
(if macro-fence
(c-backward-comments)
(c-backward-syntactic-ws))
(not (or (bobp) (c-after-statement-terminator-p)))))
(t (when (setq res (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)))
(t (setq res (c-back-over-illiterals macro-fence))
(setq not-bos (or (= (point) last)
(memq (char-after) '(?\) ?\}))
(and
(car res)
(not (save-excursion
(if macro-fence
(c-backward-comments)
(c-backward-syntactic-ws))
(or (bobp) (c-after-statement-terminator-p)))))))
(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)))))
(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))))
(defun c-end-of-statement (&optional count lim sentence-flag)
"Go to the end of the innermost C statement.
With prefix arg, go forward N - 1 statements. Move forward to the end
of the next statement if already at end, and move into nested blocks
\(use \\[forward-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."
(interactive (list (prefix-numeric-value current-prefix-arg)
nil t))
(setq count (or count 1))
(if (< count 0) (c-beginning-of-statement (- count) lim sentence-flag)
(c-save-buffer-state
(here (macro-fence
(save-excursion
(and (not (eobp)) (c-beginning-of-macro)
(progn (c-end-of-macro) (point)))))
res
(range (c-collect-line-comments (c-literal-limits lim))))
(while (and (/= count 0)
(or (not lim) (< (point) lim)))
(setq here (point))
(while
(cond ((eobp)
(setq count 0)
nil)
(range (cond
((or (null sentence-flag)
(c-one-line-string-p range))
(goto-char (cdr range))
(setq range (c-ascertain-following-literal))
(not (c-at-vsemi-p)))
(t (when (setq res (if (eq (c-literal-type range) 'string)
(c-end-of-sentence-in-string range)
(c-end-of-sentence-in-comment range)))
(setq range (c-ascertain-following-literal)))
(and res
(not (c-at-vsemi-p))))))
(t (setq res (c-forward-over-illiterals macro-fence
(> (point) here)))
(when (eq (cdr res) 'macro-boundary)
(save-excursion
(end-of-line)
(setq macro-fence
(and (not (eobp))
(progn (c-skip-ws-forward)
(c-beginning-of-macro))
(progn (c-end-of-macro)
(point))))))
(when (memq (cdr res) '(macro-boundary literal))
(setq range (c-ascertain-following-literal)))
(car res))))
(if (/= count 0) (setq count (1- count))))
(c-keep-region-active))))
(mapcar
(function
(lambda (sym)
(put sym 'delete-selection t) (put sym 'pending-delete t))) '(c-electric-pound
c-electric-brace
c-electric-slash
c-electric-star
c-electric-semi&comma
c-electric-lt-gt
c-electric-colon
c-electric-paren))
(put 'c-electric-delete 'delete-selection 'supersede) (put 'c-electric-delete 'pending-delete 'supersede) (put 'c-electric-backspace 'delete-selection 'supersede) (put 'c-electric-backspace 'pending-delete 'supersede) (put 'c-electric-delete-forward 'delete-selection 'supersede) (put 'c-electric-delete-forward 'pending-delete 'supersede)
(defun c-calc-comment-indent (entry)
(if (symbolp entry)
(setq entry (or (assq entry c-indent-comment-alist)
(assq 'other c-indent-comment-alist)
'(default . (column . nil)))))
(let ((action (car (cdr entry)))
(value (cdr (cdr entry)))
(col (current-column)))
(cond ((eq action 'space)
(+ col value))
((eq action 'column)
(unless value (setq value comment-column))
(if (bolp)
value
(max (1+ col) value)))
((eq action 'align)
(or (save-excursion
(beginning-of-line)
(unless (bobp)
(backward-char)
(let ((lim (c-literal-limits (c-point 'bol) t)))
(when (consp lim)
(goto-char (car lim))
(when (looking-at "/[/*]") (if (bolp)
0
(max (1+ col) (current-column))))))))
(c-calc-comment-indent (cdr entry)))))))
(defun c-comment-indent ()
"Used by `indent-for-comment' to create and indent comments.
See `c-indent-comment-alist' for a description."
(save-excursion
(end-of-line)
(c-save-buffer-state
((eot (let ((lim (c-literal-limits (c-point 'bol) t)))
(or (when (consp lim)
(goto-char (car lim))
(when (looking-at "/[/*]")
(skip-chars-backward " \t")
(point)))
(progn
(skip-chars-backward " \t")
(point)))))
(line-type
(cond ((looking-at "^/[/*]")
'anchored-comment)
((progn (beginning-of-line)
(eq (point) eot))
'empty-line)
((progn (back-to-indentation)
(and (eq (char-after) ?})
(eq (point) (1- eot))))
'end-block)
((and (looking-at "#[ \t]*\\(endif\\|else\\)")
(eq (match-end 0) eot))
'cpp-end-block)
(t
'other))))
(if (and (memq line-type '(anchored-comment empty-line))
c-indent-comments-syntactically-p)
(let ((c-syntactic-context (c-guess-basic-syntax)))
(if (eolp)
(c-add-syntax 'comment-intro))
(let ((c-comment-only-line-offset
(if (consp c-comment-only-line-offset)
c-comment-only-line-offset
(cons c-comment-only-line-offset
c-comment-only-line-offset))))
(c-get-syntactic-indentation c-syntactic-context)))
(goto-char eot)
(c-calc-comment-indent line-type)))))
(defun c-outline-level ()
(let (buffer-invisibility-spec) (save-excursion
(skip-chars-forward "\t ")
(current-column))))
(defun c-up-conditional (count)
"Move back to the containing preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
move forward to the end of the containing preprocessor conditional.
\"#elif\" is treated like \"#else\" followed by \"#if\", so the
function stops at them when going backward, but not when going
forward."
(interactive "p")
(c-forward-conditional (- count) -1)
(c-keep-region-active))
(defun c-up-conditional-with-else (count)
"Move back to the containing preprocessor conditional, including \"#else\".
Just like `c-up-conditional', except it also stops at \"#else\"
directives."
(interactive "p")
(c-forward-conditional (- count) -1 t)
(c-keep-region-active))
(defun c-down-conditional (count)
"Move forward into the next preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
move backward into the previous preprocessor conditional.
\"#elif\" is treated like \"#else\" followed by \"#if\", so the
function stops at them when going forward, but not when going
backward."
(interactive "p")
(c-forward-conditional count 1)
(c-keep-region-active))
(defun c-down-conditional-with-else (count)
"Move forward into the next preprocessor conditional, including \"#else\".
Just like `c-down-conditional', except it also stops at \"#else\"
directives."
(interactive "p")
(c-forward-conditional count 1 t)
(c-keep-region-active))
(defun c-backward-conditional (count &optional target-depth with-else)
"Move back across a preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
move forward across a preprocessor conditional."
(interactive "p")
(c-forward-conditional (- count) target-depth with-else)
(c-keep-region-active))
(defun c-forward-conditional (count &optional target-depth with-else)
"Move forward across a preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
move backward across a preprocessor conditional.
\"#elif\" is treated like \"#else\" followed by \"#if\", except that
the nesting level isn't changed when tracking subconditionals.
The optional argument TARGET-DEPTH specifies the wanted nesting depth
after each scan. I.e. if TARGET-DEPTH is -1, the function will move
out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH
counts as -1.
If the optional argument WITH-ELSE is non-nil, \"#else\" directives
are treated as conditional clause limits. Normally they are ignored."
(interactive "p")
(let* ((forward (> count 0))
(increment (if forward -1 1))
(search-function (if forward 're-search-forward 're-search-backward))
(new))
(unless (integerp target-depth)
(setq target-depth (if target-depth -1 0)))
(save-excursion
(while (/= count 0)
(let ((depth 0)
(subdepth 0)
found)
(save-excursion
(while (and (not found)
(funcall search-function
"#[ \t]*\\(if\\|elif\\|endif\\|else\\)"
nil t))
(beginning-of-line)
(if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\|else\\)")
(let (dchange (directive (match-string 1)))
(cond ((string= directive "if")
(setq dchange (- increment)))
((string= directive "endif")
(setq dchange increment))
((= subdepth 0)
(if (cond (with-else
(setq dchange
(if (> target-depth 0) 1 -1)))
((string= directive "elif")
(setq dchange (- increment))))
(if (eq (> dchange 0) (<= target-depth 0))
(setq dchange nil)))))
(when dchange
(when (or (/= subdepth 0)
(eq (> dchange 0) (<= target-depth 0)))
(setq subdepth (+ subdepth dchange)))
(setq depth (+ depth dchange))
(if (and (< depth target-depth) (< dchange 0))
(error (if forward
"No following conditional at this level"
"No previous conditional at this level"))))
(if forward (forward-line 1))
(if (and dchange (= depth target-depth))
(setq found (point))))
(if forward (forward-line 1)))))
(or found
(error "No containing preprocessor conditional"))
(goto-char (setq new found)))
(setq count (+ count increment))))
(push-mark)
(goto-char new))
(c-keep-region-active))
(defun c-indent-command (&optional arg)
"Indent current line as C code, and/or insert some whitespace.
If `c-tab-always-indent' is t, always just indent the current line.
If nil, indent the current line only if point is at the left margin or
in the line's indentation; otherwise insert some whitespace[*]. If
other than nil or t, then some whitespace[*] is inserted only within
literals (comments and strings), but the line is always reindented.
If `c-syntactic-indentation' is t, indentation is done according to
the syntactic context. A numeric argument, regardless of its value,
means indent rigidly all the lines of the expression starting after
point so that this line becomes properly indented. The relative
indentation among the lines of the expression is preserved.
If `c-syntactic-indentation' is nil, the line is just indented one
step according to `c-basic-offset'. In this mode, a numeric argument
indents a number of such steps, positive or negative, and an empty
prefix argument is equivalent to -1.
[*] The amount and kind of whitespace inserted is controlled by the
variable `c-insert-tab-function', which is called to do the actual
insertion of whitespace. Normally the function in this variable
just inserts a tab character, or the equivalent number of spaces,
depending on the variable `indent-tabs-mode'."
(interactive "P")
(let ((indent-function
(if c-syntactic-indentation
(symbol-function 'indent-according-to-mode)
(lambda ()
(let ((c-macro-start c-macro-start)
(steps (if (equal arg '(4))
-1
(prefix-numeric-value arg))))
(c-shift-line-indentation (* steps c-basic-offset))
(when (and c-auto-align-backslashes
(save-excursion
(end-of-line)
(eq (char-before) ?\\))
(c-query-and-set-macro-start))
(c-backslash-region (point) (point) nil t)))
))))
(if (and c-syntactic-indentation arg)
(let ((shift-amt (save-excursion
(back-to-indentation)
(current-column)))
beg end)
(c-indent-line)
(setq shift-amt (- (save-excursion
(back-to-indentation)
(current-column))
shift-amt))
(save-excursion
(if (eq c-tab-always-indent t)
(beginning-of-line)) (setq beg (point))
(c-forward-sexp 1)
(setq end (point))
(goto-char beg)
(forward-line 1)
(setq beg (point)))
(if (> end beg)
(indent-code-rigidly beg end shift-amt "#")))
(cond
((not c-tab-always-indent)
(if (save-excursion
(skip-chars-backward " \t")
(not (bolp)))
(funcall c-insert-tab-function)
(funcall indent-function)))
((eq c-tab-always-indent t)
(funcall indent-function))
(t
(if (c-save-buffer-state () (c-in-literal))
(funcall c-insert-tab-function))
(funcall indent-function)
)))))
(defun c-indent-exp (&optional shutup-p)
"Indent each line in the balanced expression following point syntactically.
If optional SHUTUP-P is non-nil, no errors are signaled if no
balanced expression is found."
(interactive "*P")
(let ((here (point-marker))
end)
(set-marker-insertion-type here t)
(unwind-protect
(let ((start (save-restriction
(narrow-to-region (point-min) (c-point 'eol))
(let (beg (end (point)))
(while (and (setq beg (c-down-list-forward end))
(setq end (c-up-list-forward beg))))
(and beg
(eq (char-syntax (char-before beg)) ?\()
(1- beg))))))
(if (not start)
(unless shutup-p
(error "Cannot find start of balanced expression to indent"))
(goto-char start)
(setq end (c-safe (scan-sexps (point) 1)))
(if (not end)
(unless shutup-p
(error "Cannot find end of balanced expression to indent"))
(forward-line)
(if (< (point) end)
(c-indent-region (point) end)))))
(goto-char here)
(set-marker here nil))))
(defun c-indent-defun ()
"Indent the current top-level declaration or macro syntactically.
In the macro case this also has the effect of realigning any line
continuation backslashes, unless `c-auto-align-backslashes' is nil."
(interactive "*")
(let ((here (point-marker)) decl-limits)
(unwind-protect
(progn
(c-save-buffer-state nil
(if (looking-at c-syntactic-eol)
(c-backward-token-2 1 nil (c-point 'bol))
(c-forward-token-2 0 nil (c-point 'eol)))
(setq decl-limits (c-declaration-limits nil)))
(if decl-limits
(c-indent-region (car decl-limits)
(cdr decl-limits))))
(goto-char here)
(set-marker here nil))))
(defun c-indent-region (start end &optional quiet)
"Indent syntactically every line whose first char is between START
and END inclusive. If the optional argument QUIET is non-nil then no
syntactic errors are reported, even if `c-report-syntactic-errors' is
non-nil."
(save-excursion
(goto-char end)
(skip-chars-backward " \t\n\r\f\v")
(setq end (point))
(goto-char start)
(beginning-of-line)
(skip-chars-forward " \t\n\r\f\v")
(setq start (point))
(beginning-of-line)
(setq c-parsing-error
(or (let ((endmark (copy-marker end))
(c-parsing-error nil)
(c-echo-syntactic-information-p nil)
(in-macro (and c-auto-align-backslashes
(c-save-buffer-state ()
(save-excursion (c-beginning-of-macro)))
start))
(c-fix-backslashes nil)
syntax)
(unwind-protect
(progn
(c-progress-init start end 'c-indent-region)
(while (and (bolp)
(not (eobp))
(< (point) endmark))
(c-progress-update)
(skip-chars-forward " \t\n")
(beginning-of-line)
(c-save-buffer-state nil
(setq syntax (c-guess-basic-syntax)))
(if (and c-auto-align-backslashes
(assq 'cpp-macro syntax))
(setq in-macro (point)))
(if in-macro
(if (looking-at "\\s *\\\\$")
(forward-line)
(c-indent-line syntax t t)
(if (progn (end-of-line)
(not (eq (char-before) ?\\)))
(progn
(forward-line)
(c-backslash-region in-macro (point) nil)
(setq in-macro nil))
(forward-line)))
(c-indent-line syntax t t)
(forward-line)))
(if in-macro
(c-backslash-region in-macro (c-point 'bopl) nil t)))
(set-marker endmark nil)
(c-progress-fini 'c-indent-region))
(c-echo-parsing-error quiet))
c-parsing-error))))
(defun c-fn-region-is-active-p ()
(c-region-is-active-p))
(defun c-indent-line-or-region ()
"When the region is active, indent it syntactically. Otherwise
indent the current line syntactically."
(interactive)
(if (c-region-is-active-p)
(c-indent-region (region-beginning) (region-end))
(c-indent-line)))
(defvar c-progress-info nil)
(defun c-progress-init (start end context)
(cond
((not c-progress-interval))
((not (fboundp 'current-time))
(message "Indenting region... (this may take a while)"))
(c-progress-info)
(t (setq c-progress-info (vector start
(save-excursion
(goto-char end)
(point-marker))
(nth 1 (current-time))
context))
(message "Indenting region..."))
))
(defun c-progress-update ()
(if (not (and c-progress-info c-progress-interval))
nil
(let ((now (nth 1 (current-time)))
(start (aref c-progress-info 0))
(end (aref c-progress-info 1))
(lastsecs (aref c-progress-info 2)))
(if (< c-progress-interval (- now lastsecs))
(progn
(message "Indenting region... (%d%% complete)"
(/ (* 100 (- (point) start)) (- end start)))
(aset c-progress-info 2 now)))
)))
(defun c-progress-fini (context)
(if (not c-progress-interval)
nil
(if (or (eq context (aref c-progress-info 3))
(eq context t))
(progn
(set-marker (aref c-progress-info 1) nil)
(setq c-progress-info nil)
(message "Indenting region... done")))))
(defun c-backslash-region (from to delete-flag &optional line-mode)
"Insert, align, or delete end-of-line backslashes on the lines in the region.
With no argument, inserts backslashes and aligns existing backslashes.
With an argument, deletes the backslashes. The backslash alignment is
done according to the settings in `c-backslash-column',
`c-backslash-max-column' and `c-auto-align-backslashes'.
This function does not modify blank lines at the start of the region.
If the region ends at the start of a line and the macro doesn't
continue below it, the backslash (if any) at the end of the previous
line is deleted.
You can put the region around an entire macro definition and use this
command to conveniently insert and align the necessary backslashes."
(interactive "*r\nP")
(let ((endmark (make-marker))
(point-pos (if (save-excursion
(skip-chars-backward " \t")
(and (bolp) (looking-at "[ \t]*\\\\?$")))
(point-marker)
(point-min)))
column longest-line-col bs-col-after-end)
(save-excursion
(goto-char to)
(if (and (not line-mode) (bobp))
nil
(when (and (not line-mode) (bolp))
(backward-char)
(setq to (point)))
(if delete-flag
(progn
(set-marker endmark (point))
(goto-char from)
(c-delete-backslashes-forward endmark point-pos))
(setq bs-col-after-end
(and (progn (end-of-line)
(eq (char-before) ?\\))
(= (forward-line 1) 0)
(progn (end-of-line)
(eq (char-before) ?\\))
(1- (current-column))))
(when line-mode
(setq to (max from (or (c-safe (c-point 'eopl)) from)))
(unless bs-col-after-end
(setq bs-col-after-end t)))
(if (and line-mode
(not c-auto-align-backslashes))
(goto-char from)
(setq longest-line-col 0)
(goto-char to)
(if bs-col-after-end
(forward-line 1))
(end-of-line)
(while (and (>= (point) from)
(progn
(if (eq (char-before) ?\\)
(forward-char -1))
(skip-chars-backward " \t")
(setq longest-line-col (max longest-line-col
(1+ (current-column))))
(beginning-of-line)
(not (bobp))))
(backward-char))
(goto-char from)
(beginning-of-line)
(if (and (not (bobp))
(progn (backward-char)
(eq (char-before) ?\\)))
(progn
(setq column (1- (current-column)))
(if (numberp bs-col-after-end)
(setq column (max column bs-col-after-end)))
(goto-char from))
(if (numberp bs-col-after-end)
(setq column bs-col-after-end))
(goto-char from)
(while (and (< (point) to) (bolp) (eolp))
(forward-line 1)))
(if (and column (< column longest-line-col))
(setq column nil))
(unless column
(if (> (% longest-line-col tab-width) 0)
(setq longest-line-col
(* (/ (+ longest-line-col tab-width -1)
tab-width)
tab-width)))
(setq column (max c-backslash-column
longest-line-col)))
(setq column (min column c-backslash-max-column)))
(if bs-col-after-end
(progn
(set-marker endmark to)
(c-append-backslashes-forward endmark column point-pos))
(if (save-excursion
(goto-char to)
(beginning-of-line)
(if (not (bobp))
(set-marker endmark (1- (point)))))
(progn
(c-append-backslashes-forward endmark column point-pos)
(set-marker endmark (point)))
(set-marker endmark to))
(c-delete-backslashes-forward endmark point-pos)))))
(set-marker endmark nil)
(if (markerp point-pos)
(set-marker point-pos nil))))
(defun c-append-backslashes-forward (to-mark column point-pos)
(let ((state (parse-partial-sexp (c-point 'bol) (point))))
(if column
(while
(and
(<= (point) to-mark)
(let ((start (point)) (inserted nil) end col)
(end-of-line)
(unless (eq (char-before) ?\\)
(insert ?\\)
(setq inserted t))
(setq state (parse-partial-sexp
start (point) nil nil state))
(backward-char)
(setq col (current-column))
(cond ((and (not inserted) (nth 3 state))
)
((< col column)
(delete-region
(point)
(progn
(skip-chars-backward
" \t" (if (>= (point) point-pos) point-pos))
(point)))
(indent-to column))
((and (= col column)
(memq (char-before) '(?\ ?\t))))
((progn
(setq end (point))
(or (/= (skip-chars-backward
" \t" (if (>= (point) point-pos) point-pos))
-1)
(/= (char-after) ?\ )))
(delete-region (point) end)
(indent-to column 1)))
(zerop (forward-line 1)))
(bolp)))
(while
(and
(<= (point) to-mark)
(let ((start (point)))
(end-of-line)
(setq state (parse-partial-sexp
start (point) nil nil state))
(if (eq (char-before) ?\\)
(unless (nth 3 state)
(backward-char)
(unless (and (memq (char-before) '(?\ ?\t))
(/= (point) point-pos))
(insert ?\ )))
(if (and (memq (char-before) '(?\ ?\t))
(/= (point) point-pos))
(insert ?\\)
(insert ?\ ?\\)))
(zerop (forward-line 1)))
(bolp))))))
(defun c-delete-backslashes-forward (to-mark point-pos)
(while
(and (<= (point) to-mark)
(progn
(end-of-line)
(if (eq (char-before) ?\\)
(delete-region
(point)
(progn (backward-char)
(skip-chars-backward " \t" (if (>= (point) point-pos)
point-pos))
(point))))
(zerop (forward-line 1)))
(bolp))))
(defvar c-auto-fill-prefix t)
(defvar c-lit-limits nil)
(defvar c-lit-type nil)
(defun c-guess-fill-prefix (lit-limits lit-type)
(let* ((here (point))
(prefix-regexp (concat "[ \t]*\\("
c-current-comment-prefix
"\\)[ \t]*"))
(comment-start-regexp (if (eq lit-type 'c++)
prefix-regexp
comment-start-skip))
prefix-line comment-prefix res comment-text-end)
(cond
(fill-prefix
(setq res (cons fill-prefix
(let ((start (point)))
(unwind-protect
(progn
(insert-and-inherit "\n" fill-prefix)
(current-column))
(delete-region start (point)))))))
((eq lit-type 'c++)
(save-excursion
(setq comment-prefix "// "
comment-text-end (cdr lit-limits))
(beginning-of-line)
(if (> (point) (car lit-limits))
(setq prefix-line (point))
(goto-char (car lit-limits))
(if (and (= (forward-line 1) 0)
(< (point) (cdr lit-limits)))
(setq prefix-line (point))
(goto-char (car lit-limits))
(if (looking-at prefix-regexp)
(goto-char (match-end 0))
(forward-char 2)
(skip-chars-forward " \t"))
(let (str col)
(if (eq (c-point 'boi) (car lit-limits))
(setq str (buffer-substring-no-properties
(c-point 'bol) (point))
col (current-column))
(let ((prefix-len (- (point) (car lit-limits)))
tmp)
(unwind-protect
(progn
(goto-char (car lit-limits))
(indent-to (prog1 (current-column)
(insert ?\n)))
(setq tmp (point))
(forward-char prefix-len)
(setq str (buffer-substring-no-properties
(c-point 'bol) (point))
col (current-column)))
(delete-region (car lit-limits) tmp))))
(setq res
(if (or (string-match "\\s \\'" str) (not (eolp)))
(cons str col)
(cons (concat str " ") (1+ col))))
)))))
(t
(setq comment-text-end
(save-excursion
(goto-char (- (cdr lit-limits) 2))
(if (looking-at "\\*/") (point) (cdr lit-limits))))
(save-excursion
(beginning-of-line)
(if (and (> (point) (car lit-limits))
(not (and (looking-at "[ \t]*\\*/")
(eq (cdr lit-limits) (match-end 0)))))
(setq prefix-line (point))
(goto-char (car lit-limits))
(cond ((or (/= (forward-line 1) 0)
(>= (point) (cdr lit-limits))
(and (looking-at "[ \t]*\\*/")
(eq (cdr lit-limits) (match-end 0)))
(and (looking-at prefix-regexp)
(<= (1- (cdr lit-limits)) (match-end 0))))
(setq comment-prefix (or c-block-comment-prefix "")))
((< here (point))
(if (and (match-beginning 1)
(/= (match-beginning 1) (match-end 1)))
(if (= (match-end 0) (c-point 'eol))
(setq comment-prefix (match-string 1))
(setq prefix-line (point)))
(if (<= (save-excursion (back-to-indentation)
(current-column))
(save-excursion (goto-char (car lit-limits))
(current-column)))
(setq comment-prefix (or c-block-comment-prefix ""))
(setq prefix-line (point)))))
(t
(setq prefix-line (point))))
(when comment-prefix
(setq res
(let (tmp-pre tmp-post)
(unwind-protect
(progn
(goto-char (car lit-limits))
(if (looking-at comment-start-regexp)
(goto-char (min (match-end 0)
comment-text-end))
(forward-char 2)
(skip-chars-forward " \t"))
(when (eq (char-syntax (char-before)) ?\ )
(setq comment-prefix
(concat (substring comment-prefix
0 (string-match
"\\s *\\'"
comment-prefix))
(buffer-substring-no-properties
(save-excursion
(skip-chars-backward " \t")
(point))
(point)))))
(setq tmp-pre (point-marker))
(insert-and-inherit "x\n" comment-prefix "x")
(setq tmp-post (point-marker))
(indent-according-to-mode)
(goto-char (1- tmp-post))
(cons (buffer-substring-no-properties
(c-point 'bol) (point))
(current-column)))
(when tmp-post
(delete-region tmp-pre tmp-post)
(set-marker tmp-pre nil)
(set-marker tmp-post nil))))))))))
(or res
(save-excursion
(let* (fb-string fb-endpos (test-line
(lambda ()
(when (and (looking-at prefix-regexp)
(<= (match-end 0) comment-text-end))
(unless (eq (match-end 0) (c-point 'eol))
(throw 'found (cons (buffer-substring-no-properties
(match-beginning 0) (match-end 0))
(progn (goto-char (match-end 0))
(current-column)))))
(unless fb-string
(setq fb-string (buffer-substring-no-properties
(match-beginning 0) (match-end 0))
fb-endpos (match-end 0)))
t))))
(or (catch 'found
(goto-char prefix-line)
(when (and (funcall test-line)
(or (/= (match-end 1) (match-end 0))
(and (= (match-beginning 1) (match-end 1))
(/= (match-beginning 0) (match-end 0)))))
(throw 'found (cons fb-string
(progn (goto-char fb-endpos)
(current-column)))))
(if (eq lit-type 'c++)
(while (and (zerop (forward-line -1))
(>= (point) (car lit-limits)))
(funcall test-line))
(while (and (zerop (forward-line -1))
(> (point) (car lit-limits)))
(funcall test-line)))
(goto-char prefix-line)
(while (and (zerop (forward-line 1))
(< (point) (cdr lit-limits)))
(funcall test-line))
(goto-char prefix-line)
nil)
(when fb-string
(cond ((or (string-match "\\s \\'" fb-string)
(progn
(goto-char fb-endpos)
(not (eolp))))
(cons fb-string (current-column)))
((progn
(goto-char (car lit-limits))
(if (looking-at comment-start-regexp)
(goto-char (match-end 0))
(forward-char 2)
(skip-chars-forward " \t"))
(or (not (eolp))
(eq (char-syntax (char-before)) ?\ )))
(setq fb-string (buffer-substring-no-properties
(save-excursion
(skip-chars-backward " \t")
(point))
(point)))
(goto-char fb-endpos)
(skip-chars-backward " \t")
(let ((tmp (point)))
(unwind-protect
(progn
(insert-and-inherit fb-string)
(cons (buffer-substring-no-properties
(c-point 'bol)
(point))
(current-column)))
(delete-region tmp (point)))))
(t
(cons (concat fb-string " ")
(progn (goto-char fb-endpos)
(1+ (current-column)))))))
(if comment-prefix
(cons (concat (buffer-substring-no-properties
prefix-line (c-point 'boi))
comment-prefix)
(progn (back-to-indentation)
(+ (current-column) (length comment-prefix))))
'("" . 0))))))
))
(defun c-mask-paragraph (fill-paragraph apply-outside-literal fun &rest args)
(let (fill
beg end
tmp-pre tmp-post
hang-ender-stuck
auto-fill-spaces
(here (point))
(c-lit-limits c-lit-limits)
(c-lit-type c-lit-type))
(if (and buffer-undo-list (not (eq buffer-undo-list t)))
(setq buffer-undo-list (cons (point) buffer-undo-list)))
(c-save-buffer-state ()
(save-restriction
(widen)
(unless c-lit-limits
(setq c-lit-limits (c-literal-limits nil fill-paragraph)))
(setq c-lit-limits (c-collect-line-comments c-lit-limits))
(unless c-lit-type
(setq c-lit-type (c-literal-type c-lit-limits))))
(save-excursion
(unless (c-safe (backward-char)
(forward-paragraph)
(>= (point) here))
(goto-char here)
(forward-paragraph))
(setq end (point-marker)))
(save-excursion
(unless (c-safe (forward-char)
(backward-paragraph)
(<= (point) here))
(goto-char here)
(backward-paragraph))
(setq beg (point))))
(unwind-protect
(progn
(cond
((eq c-lit-type 'c++) (save-excursion
(set-marker end (min end (cdr c-lit-limits)))
(when (<= beg (car c-lit-limits))
(goto-char (car c-lit-limits))
(back-to-indentation)
(if (eq (point) (car c-lit-limits))
(setq beg (c-point 'bol))
(setq tmp-pre t))))
(setq apply-outside-literal t))
((eq c-lit-type 'c) (when
(or (> end (cdr c-lit-limits))
(and (= end (cdr c-lit-limits))
(eq (char-before end) ?/)
(eq (char-before (1- end)) ?*)
(> (- (cdr c-lit-limits) (car c-lit-limits)) 3)))
(unless
(save-excursion
(goto-char (cdr c-lit-limits))
(beginning-of-line)
(and (search-forward-regexp
(concat "\\=[ \t]*\\(" c-current-comment-prefix "\\)")
(- (cdr c-lit-limits) 2) t)
(not (search-forward-regexp
"\\(\\s \\|\\sw\\)"
(- (cdr c-lit-limits) 2) 'limit))
(set-marker end (c-point 'bol))))
(let* ((ender-start (save-excursion
(goto-char (cdr c-lit-limits))
(skip-syntax-backward "^w ")
(point)))
(ender-column (save-excursion
(goto-char ender-start)
(current-column)))
(point-rel (- ender-start here))
spaces)
(save-excursion
(goto-char (cdr c-lit-limits))
(setq tmp-post (point-marker))
(insert ?\n)
(set-marker end (point))
(forward-line -1) (if (and (looking-at (concat "[ \t]*\\(\\("
c-current-comment-prefix
"\\)[ \t]*\\)"))
(eq ender-start (match-end 0)))
(setq spaces (- (match-end 1) (match-end 2)))
(goto-char ender-start))
(skip-chars-backward " \t\r\n")
(if (/= (point) ender-start)
(progn
(if (<= here (point))
(setq point-rel -1))
(unless spaces
(setq spaces (- ender-column (current-column))))
(setq auto-fill-spaces (c-delete-and-extract-region
(point) ender-start))
(if fill-paragraph
(setq spaces
(max
(min spaces
(if sentence-end-double-space 2 1))
1)))
(insert-char ?x spaces t)
(setq hang-ender-stuck spaces)
(setq point-rel
(and (>= point-rel 0)
(- (point) (min point-rel spaces)))))
(setq point-rel nil)))
(if point-rel
(goto-char point-rel)))
))
(when (<= beg (car c-lit-limits))
(save-excursion
(goto-char (car c-lit-limits))
(if (looking-at (concat "\\(" comment-start-skip "\\)$"))
(setq beg (c-point 'bonl))
(setq tmp-pre t))))
(setq apply-outside-literal t))
((eq c-lit-type 'string) (save-excursion
(when (>= end (cdr c-lit-limits))
(goto-char (1- (cdr c-lit-limits)))
(setq tmp-post (point-marker))
(insert ?\n)
(set-marker end (point)))
(when (<= beg (car c-lit-limits))
(goto-char (1+ (car c-lit-limits)))
(setq beg (if (looking-at "\\\\$")
(1+ (match-end 0))
(point)))))
(setq apply-outside-literal t))
((eq c-lit-type 'pound) (save-excursion
(c-save-buffer-state ()
(c-beginning-of-macro)
(beginning-of-line)
(if (> (point) beg)
(setq beg (point)))
(c-end-of-macro)
(forward-line)
(if (< (point) end)
(set-marker end (point))))))
(t (c-save-buffer-state nil
(save-excursion
(goto-char beg)
(c-forward-syntactic-ws end)
(beginning-of-line)
(setq beg (point))
(goto-char end)
(c-backward-syntactic-ws beg)
(forward-line)
(set-marker end (point))))))
(when tmp-pre
(setq fill (c-save-buffer-state nil
(c-guess-fill-prefix c-lit-limits c-lit-type)))
(unless (string-match (concat "\\`[ \t]*\\("
c-current-comment-prefix
"\\)[ \t]*\\'")
(car fill))
(message "\
Warning: Regexp from `c-comment-prefix-regexp' doesn't match the comment prefix %S"
(car fill)))
(save-excursion
(goto-char (car c-lit-limits))
(if (looking-at (if (eq c-lit-type 'c++)
c-current-comment-prefix
comment-start-skip))
(goto-char (match-end 0))
(forward-char 2)
(skip-chars-forward " \t"))
(while (and (< (current-column) (cdr fill))
(not (eolp)))
(forward-char 1))
(let ((col (current-column)))
(setq beg (1+ (point))
tmp-pre (list (point)))
(unwind-protect
(progn
(insert-and-inherit "\n" (car fill))
(insert-char ?x (- col (current-column)) t))
(setcdr tmp-pre (point))))))
(when apply-outside-literal
(let ((fill-prefix
(or fill-prefix
(when (and (eq c-lit-type 'c++)
(not (and (boundp 'filladapt-mode)
filladapt-mode))
(not (string-match
"\\`[ \t]*//"
(or (fill-context-prefix beg end)
""))))
(c-save-buffer-state nil
(car (or fill (c-guess-fill-prefix
c-lit-limits c-lit-type)))))))
(point-rel (cond ((< (point) beg) (- (point) beg))
((> (point) end) (- (point) end)))))
(prog1
(save-restriction
(narrow-to-region beg end)
(apply fun args))
(if point-rel
(if (< point-rel 0)
(goto-char (+ beg point-rel))
(goto-char (+ end point-rel))))))))
(when (consp tmp-pre)
(delete-region (car tmp-pre) (cdr tmp-pre)))
(when tmp-post
(save-excursion
(goto-char tmp-post)
(delete-char 1))
(when hang-ender-stuck
(setq here (point))
(goto-char tmp-post)
(skip-syntax-backward "^w ")
(forward-char (- hang-ender-stuck))
(if (or fill-paragraph (not auto-fill-spaces))
(insert-char ?\ hang-ender-stuck t)
(insert auto-fill-spaces)
(setq here (- here (- hang-ender-stuck (length auto-fill-spaces)))))
(delete-char hang-ender-stuck)
(goto-char here))
(set-marker tmp-post nil))
(set-marker end nil))))
(defun c-fill-paragraph (&optional arg)
"Like \\[fill-paragraph] but handles C and C++ style comments.
If any of the current line is a comment or within a comment, fill the
comment or the paragraph of it that point is in, preserving the
comment indentation or line-starting decorations (see the
`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
details).
If point is inside multiline string literal, fill it. This currently
does not respect escaped newlines, except for the special case when it
is the very first thing in the string. The intended use for this rule
is in situations like the following:
char description[] = \"\\
A very long description of something that you want to fill to make
nicely formatted output.\"\;
If point is in any other situation, i.e. in normal code, do nothing.
Optional prefix ARG means justify paragraph as well."
(interactive "*P")
(let ((fill-paragraph-function
(if (not (eq fill-paragraph-function 'c-fill-paragraph))
fill-paragraph-function)))
(c-mask-paragraph t nil 'fill-paragraph arg))
t)
(defun c-do-auto-fill ()
(let ((c-auto-fill-prefix
fill-prefix))
(c-mask-paragraph nil t 'do-auto-fill)))
(defun c-indent-new-comment-line (&optional soft allow-auto-fill)
"Break line at point and indent, continuing comment or macro if within one.
If inside a comment and `comment-multi-line' is non-nil, the
indentation and line prefix are preserved (see the
`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
details). If inside a single line comment and `comment-multi-line' is
nil, a new comment of the same type is started on the next line and
indented as appropriate for comments. If inside a macro, a line
continuation backslash is inserted and aligned as appropriate, and the
new line is indented according to `c-syntactic-indentation'.
If a fill prefix is specified, it overrides all the above."
(interactive)
(let ((fill-prefix fill-prefix)
(do-line-break
(lambda ()
(delete-horizontal-space)
(if soft
(insert-and-inherit ?\n)
(newline (if allow-auto-fill nil 1)))))
(c-lit-limits c-lit-limits)
(c-lit-type c-lit-type)
(c-macro-start c-macro-start))
(c-save-buffer-state ()
(when (not (eq c-auto-fill-prefix t))
(unless c-lit-limits
(setq c-lit-limits (c-literal-limits nil nil t)))
(unless c-lit-type
(setq c-lit-type (c-literal-type c-lit-limits)))
(if (memq (cond ((c-query-and-set-macro-start) 'cpp)
((null c-lit-type) 'code)
(t c-lit-type))
c-ignore-auto-fill)
(setq fill-prefix t) (if (and (null c-auto-fill-prefix)
(eq c-lit-type 'c)
(<= (c-point 'bol) (car c-lit-limits)))
(setq fill-prefix nil)
(when (and (eq c-lit-type 'c++)
(not (string-match (concat "\\`[ \t]*"
c-line-comment-starter)
(or fill-prefix ""))))
(setq fill-prefix nil)))
)))
(cond ((eq fill-prefix t)
)
(fill-prefix
(funcall do-line-break)
(insert-and-inherit fill-prefix))
((c-save-buffer-state ()
(unless c-lit-limits
(setq c-lit-limits (c-literal-limits)))
(unless c-lit-type
(setq c-lit-type (c-literal-type c-lit-limits)))
(memq c-lit-type '(c c++)))
(if (or comment-multi-line
(save-excursion
(goto-char (car c-lit-limits))
(end-of-line)
(< (point) (cdr c-lit-limits))))
(let ((fill (c-save-buffer-state nil
(c-guess-fill-prefix
(setq c-lit-limits
(c-collect-line-comments c-lit-limits))
c-lit-type)))
(pos (point))
(start-col (current-column))
(comment-text-end
(or (and (eq c-lit-type 'c)
(save-excursion
(goto-char (- (cdr c-lit-limits) 2))
(if (looking-at "\\*/") (point))))
(cdr c-lit-limits))))
(while (and (< (current-column) (cdr fill))
(not (eolp)))
(forward-char 1))
(if (and (> (point) comment-text-end)
(> (c-point 'bol) (car c-lit-limits)))
(progn
(setq pos (copy-marker pos t))
(beginning-of-line)
(insert-and-inherit (car fill))
(if soft (insert-and-inherit ?\n) (newline 1))
(goto-char pos)
(set-marker pos nil))
(cond ((> (point) comment-text-end)
(goto-char comment-text-end))
((< (point) (+ (car c-lit-limits) 2))
(goto-char (+ (car c-lit-limits) 2))))
(funcall do-line-break)
(insert-and-inherit (car fill))
(if (> (current-column) start-col)
(move-to-column start-col)))) (let ((comment-start comment-start)
(comment-end comment-end)
col)
(if (eq c-lit-type 'c)
(unless (string-match "[ \t]*/\\*" comment-start)
(setq comment-start "/* " comment-end " */"))
(unless (string-match "[ \t]*//" comment-start)
(setq comment-start "// " comment-end "")))
(setq col (save-excursion
(back-to-indentation)
(current-column)))
(funcall do-line-break)
(when (and comment-end (not (equal comment-end "")))
(forward-char -1)
(insert-and-inherit comment-end)
(forward-char 1))
(indent-to col)
(insert-and-inherit comment-start)
(indent-for-comment))))
((c-query-and-set-macro-start)
(unless (looking-at "[ \t]*\\\\$")
(delete-horizontal-space))
(c-newline-and-indent (if allow-auto-fill nil 1)))
(t
(let ((col (save-excursion
(beginning-of-line)
(while (and (looking-at "[ \t]*\\\\?$")
(= (forward-line -1) 0)))
(current-indentation))))
(funcall do-line-break)
(indent-to col))))))
(defalias 'c-comment-line-break-function 'c-indent-new-comment-line)
(make-obsolete 'c-comment-line-break-function 'c-indent-new-comment-line)
(unless (boundp 'comment-line-break-function)
(defvar c-inside-line-break-advice nil)
(defadvice indent-new-comment-line (around c-line-break-advice
activate preactivate)
"Call `c-indent-new-comment-line' if in CC Mode."
(if (or c-inside-line-break-advice
(not c-buffer-is-cc-mode))
ad-do-it
(let ((c-inside-line-break-advice t))
(c-indent-new-comment-line (ad-get-arg 0))))))
(defun c-context-line-break ()
"Do a line break suitable to the context.
When point is outside a comment or macro, insert a newline and indent
according to the syntactic context, unless `c-syntactic-indentation'
is nil, in which case the new line is indented as the previous
non-empty line instead.
When point is inside the content of a preprocessor directive, a line
continuation backslash is inserted before the line break and aligned
appropriately. The end of the cpp directive doesn't count as inside
it.
When point is inside a comment, continue it with the appropriate
comment prefix (see the `c-comment-prefix-regexp' and
`c-block-comment-prefix' variables for details). The end of a
C++-style line comment doesn't count as inside it.
When point is inside a string, only insert a backslash when it is also
inside a preprocessor directive."
(interactive "*")
(let* (c-lit-limits c-lit-type
(c-macro-start c-macro-start))
(c-save-buffer-state ()
(setq c-lit-limits (c-literal-limits nil nil t)
c-lit-type (c-literal-type c-lit-limits))
(when (eq c-lit-type 'c++)
(setq c-lit-limits (c-collect-line-comments c-lit-limits)))
(c-query-and-set-macro-start))
(cond
((or (eq c-lit-type 'c)
(and (eq c-lit-type 'c++) (< (save-excursion
(skip-chars-forward " \t")
(point))
(1- (cdr c-lit-limits))))
(and (numberp c-macro-start) (not (eq c-lit-type 'string))
(or (not (looking-at "\\s *$"))
(eq (char-before) ?\\))
(<= (save-excursion
(goto-char c-macro-start)
(if (looking-at c-opt-cpp-start)
(goto-char (match-end 0)))
(point))
(point))))
(let ((comment-multi-line t)
(fill-prefix nil))
(c-indent-new-comment-line nil t)))
((eq c-lit-type 'string)
(if (and (numberp c-macro-start)
(not (eq (char-before) ?\\)))
(insert ?\\))
(newline))
(t (delete-horizontal-space)
(newline)
(let ((col (save-excursion
(backward-char)
(forward-line 0)
(while (and (looking-at "[ \t]*\\\\?$")
(= (forward-line -1) 0)))
(current-indentation))))
(indent-to col))
(indent-according-to-mode)))))
(defun c-context-open-line ()
"Insert a line break suitable to the context and leave point before it.
This is the `c-context-line-break' equivalent to `open-line', which is
normally bound to C-o. See `c-context-line-break' for the details."
(interactive "*")
(let ((here (point)))
(unwind-protect
(progn
(insert ?x)
(c-context-line-break))
(goto-char here)
(delete-char 1))))
(cc-provide 'cc-cmds)