;; Author: code extracted from Emacs-20's simple.el
;; Maintainer: Stefan Monnier <monnier@cs.yale.edu>
;; Keywords: comment uncomment
-;; Revision: $Id: newcomment.el,v 1.30 2001/02/22 01:47:40 monnier Exp $
+;; Revision: $Id: newcomment.el,v 1.36 2001/10/11 01:44:48 monnier Exp $
;; This file is part of GNU Emacs.
;;; Todo:
+;; - quantized steps in comment-alignment
;; - try to align tail comments
;; - check what c-comment-line-break-function has to say
;; - spill auto-fill of comments onto the end of the next line
"Return the mirror image of string S, without any trailing space."
(comment-string-strip (concat (nreverse (string-to-list s))) nil t))
+;;;###autoload
(defun comment-normalize-vars (&optional noerror)
(if (not comment-start) (or noerror (error "No comment syntax is defined"))
;; comment-use-syntax
(unless (or comment-continue (string= comment-end ""))
(set (make-local-variable 'comment-continue)
(concat (if (string-match "\\S-\\S-" comment-start) " " "|")
- (substring comment-start 1))))
+ (substring comment-start 1)))
+ ;; Hasn't been necessary yet.
+ ;; (unless (string-match comment-start-skip comment-continue)
+ ;; (kill-local-variable 'comment-continue))
+ )
;; comment-skip regexps
(unless comment-start-skip
(set (make-local-variable 'comment-start-skip)
(let ((ce (if (string= "" comment-end) "\n"
(comment-string-strip comment-end t t))))
(set (make-local-variable 'comment-end-skip)
- (concat "\\s-*\\(\\s>" (if comment-quote-nested "" "+")
+ ;; We use [ \t] rather than \s- because we don't want to
+ ;; remove ^L in C mode when uncommenting.
+ (concat "[ \t]*\\(\\s>" (if comment-quote-nested "" "+")
"\\|" (regexp-quote (substring ce 0 1))
(if (and comment-quote-nested (<= (length ce) 1)) "" "+")
(regexp-quote (substring ce 1))
(when cs
(if (save-excursion
(goto-char cs)
- (if (comment-forward 1) (> (point) pt) (eobp)))
+ (and
+ ;; For modes where comment-start and comment-end are the same,
+ ;; the search above may have found a `ce' rather than a `cs'.
+ (or (not (looking-at comment-end-skip))
+ ;; Maybe font-lock knows that it's a `cs'?
+ (eq (get-text-property (match-end 0) 'face)
+ 'font-lock-comment-face)
+ (unless (eq (get-text-property (point) 'face)
+ 'font-lock-comment-face)
+ ;; Let's assume it's a `cs' if we're on the same line.
+ (>= (line-end-position) pt)))
+ ;; Make sure that PT is not past the end of the comment.
+ (if (comment-forward 1) (> (point) pt) (eobp))))
cs
(goto-char pt)
nil)))))
;;;###autoload
(defun comment-indent (&optional continue)
"Indent this line's comment to comment column, or insert an empty comment.
-If CONTINUE is non-nil, use the `comment-continuation' markers if any."
+If CONTINUE is non-nil, use the `comment-continue' markers if any."
(interactive "*")
(comment-normalize-vars)
(let* ((empty (save-excursion (beginning-of-line)
;; If none, insert one.
(save-excursion
;; Some comment-indent-function insist on not moving comments that
- ;; are in column 0, so we insert a space to avoid this special case
- (insert " ")
+ ;; are in column 0, so we first go to the likely target column.
+ (indent-to comment-column)
(setq begpos (point))
(insert starter)
(setq cpos (point-marker))
(+ (current-column)
(- fill-column
(save-excursion (end-of-line) (current-column))))))
- (if (= (current-column) indent)
- (goto-char begpos)
+ (unless (= (current-column) indent)
;; If that's different from current, change it.
- (skip-chars-backward " \t")
- (delete-region (point) begpos)
+ (delete-region (point) (progn (skip-chars-backward " \t") (point)))
(indent-to (if (bolp) indent
(max indent (1+ (current-column)))))))
(goto-char cpos)
:type 'boolean
:group 'comment)
+(defun comment-valid-prefix (prefix compos)
+ (or
+ ;; Accept any prefix if the current comment is not EOL-terminated.
+ (save-excursion (goto-char compos) (comment-forward) (not (bolp)))
+ ;; Accept any prefix that starts with a comment-start marker.
+ (string-match (concat "\\`[ \t]*\\(?:" comment-start-skip "\\)")
+ fill-prefix)))
+
;;;###autoload
(defun comment-indent-new-line (&optional soft)
"Break line at point and indent, continuing comment if within one.
;; Now we know we should auto-fill.
(delete-horizontal-space)
(if soft (insert-and-inherit ?\n) (newline 1))
- (if fill-prefix
+ (if (and fill-prefix (not adaptive-fill-mode))
+ ;; Blindly trust a non-adaptive fill-prefix.
(progn
(indent-to-left-margin)
(insert-and-inherit fill-prefix))
(setq compos (comment-beginning))
(setq comin (point))))
- ;; If we're not inside a comment, just try to indent.
- (if (not compos) (indent-according-to-mode)
+ (cond
+ ;; If there's an adaptive prefix, use it unless we're inside
+ ;; a comment and the prefix is not a comment starter.
+ ((and fill-prefix
+ (or (not compos)
+ (comment-valid-prefix fill-prefix compos)))
+ (indent-to-left-margin)
+ (insert-and-inherit fill-prefix))
+ ;; If we're not inside a comment, just try to indent.
+ ((not compos) (indent-according-to-mode))
+ (t
(let* ((comment-column
;; The continuation indentation should be somewhere between
;; the current line's indentation (plus 2 for good measure)
nil t)))))
(comment-start comstart)
;; Force comment-continue to be recreated from comment-start.
+ ;; FIXME: wrong if comment-continue was set explicitly!
(comment-continue nil))
(insert-and-inherit ?\n)
(forward-char -1)
(beginning-of-line)
(backward-char)
(insert comend)
- (forward-char))))))))))
+ (forward-char)))))))))))
(provide 'newcomment)