Function: c-indent-new-comment-line

c-indent-new-comment-line is an interactive and byte-compiled function defined in cc-cmds.el.gz.

Signature

(c-indent-new-comment-line &optional SOFT ALLOW-AUTO-FILL)

Documentation

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.

Key Bindings

Aliases

c-comment-line-break-function (obsolete since 21.1)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-cmds.el.gz
(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."
  ;; allow-auto-fill is used from c-context-line-break to allow auto
  ;; filling to break the line more than once.  Since this function is
  ;; used from auto-fill itself, that's normally disabled to avoid
  ;; unnecessary recursion.
  (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)))))
	;; Already know the literal type and limits when called from
	;; c-context-line-break.
	(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))
	;; Called from do-auto-fill.
	(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)	; Used as flag in the cond.
	  (if (and (null c-auto-fill-prefix)
		   (eq c-lit-type 'c)
		   (<= (c-point 'bol) (car c-lit-limits)))
	      ;; The adaptive fill function has generated a prefix, but
	      ;; we're on the first line in a block comment so it'll be
	      ;; wrong.  Ignore it to guess a better one below.
	      (setq fill-prefix nil)
	    (when (and (eq c-lit-type 'c++)
		       (not (string-match (concat "\\`[ \t]*"
						  c-line-comment-starter)
					  (or fill-prefix ""))))
	      ;; Kludge: If the function that adapted the fill prefix
	      ;; doesn't produce the required comment starter for line
	      ;; comments, then we ignore it.
	      (setq fill-prefix nil)))
	  )))

    (cond ((eq fill-prefix t)
	   ;; A call from do-auto-fill which should be ignored.
	   )
	  (fill-prefix
	   ;; A fill-prefix overrides anything.
	   (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++)))
	   ;; Some sort of comment.
	   (if (or comment-multi-line
		   (save-excursion
		     (goto-char (car c-lit-limits))
		     (end-of-line)
		     (< (point) (cdr c-lit-limits))))
	       ;; Inside a comment that should be continued.
	       (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))
		     (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))))
		 ;; Skip forward past the fill prefix in case
		 ;; we're standing in it.
		 ;;
		 ;; FIXME: This doesn't work well in cases like
		 ;;
		 ;; /* Bla bla bla bla bla
		 ;;         bla bla
		 ;;
		 ;; If point is on the 'B' then the line will be
		 ;; broken after "Bla b".
		 ;;
		 ;; If we have an empty comment, /*   */, the next
		 ;; lot of code pushes point to the */.  We fix
		 ;; this by never allowing point to end up to the
		 ;; right of where it started.
		 (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
		       ;; The skip takes us out of the (block)
		       ;; comment; insert the fill prefix at bol
		       ;; instead and keep the position.
		       (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))
		   ;; Don't break in the middle of a comment starter
		   ;; or ender.
		   (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 (and (looking-at c-block-comment-ender-regexp)
			    (memq (char-before) '(?\  ?\t)))
		       (backward-char)))) ; can this hit the
					  ; middle of a TAB?
	     ;; Inside a comment that should be broken.
	     (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))
	       ;; c-comment-indent may look at the current
	       ;; indentation, so let's start out with the same
	       ;; indentation as the previous one.
	       (indent-to col)
	       (insert-and-inherit comment-start)
	       (indent-for-comment))))
	  ((c-query-and-set-macro-start)
	   ;; In a macro.
	   (unless (looking-at "[ \t]*\\\\$")
	     ;; Do not clobber the alignment of the line continuation
	     ;; slash; c-backslash-region might look at it.
	     (delete-horizontal-space))
	   ;; Got an asymmetry here: In normal code this command
	   ;; doesn't indent the next line syntactically, and otoh a
	   ;; normal syntactically indenting newline doesn't continue
	   ;; the macro.
	   (c-newline-and-indent (if allow-auto-fill nil 1)))
	  (t
	   ;; Somewhere else in the code.
	   (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))))))