changeset 28904:8d91ded5215c

(comment-start, comment-start-skip, comment-end): Made `defvar'. (comment-style): Extract the choice out of comment-styles. (comment-continue): Just a simple string now. (comment-normalize-vars): Update for the new comment-continue. (until, comment-end-quote-re): Removed. (comment-quote-re, comment-quote-nested): New functions for quoting. These quote both the end and the start and also work for single-chars. (comment-padright): Added lots of comments. (comment-padleft): Added more comments. Check comment-end rather than STR to determine whether N can be applied or not. (uncomment-region): Rename BLOCK to BOX. Use the new comment-quote-nested. Use only one marker and properly set it back to nil. Be more picky when eliminating continuation markers.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 14 May 2000 00:56:10 +0000
parents b4c050c78f75
children e96880caf4e5
files lisp/newcomment.el
diffstat 1 files changed, 234 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/newcomment.el	Sat May 13 23:24:25 2000 +0000
+++ b/lisp/newcomment.el	Sun May 14 00:56:10 2000 +0000
@@ -6,7 +6,7 @@
 ;; Maintainer: Stefan Monnier <monnier@cs.yale.edu>
 ;; Keywords: comment uncomment
 ;; Version: $Name:  $
-;; Revision: $Id: newcomment.el,v 1.6 1999/12/08 00:19:51 monnier Exp $
+;; Revision: $Id: newcomment.el,v 1.7 2000/05/13 19:41:08 monnier Exp $
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -34,8 +34,6 @@
 ;; - the code assumes that bol is outside of any comment/string.
 ;; - uncomment-region with a numeric argument can render multichar
 ;;   comment markers invalid.
-;; - comment-box in C with a numeric argument generates wrong end-of-line
-;;   continuation markers.
 
 ;;; Todo:
 
@@ -45,20 +43,10 @@
 ;; - uncomment-region with a consp (for blocks) or somehow make the
 ;;   deletion of continuation markers less dangerous
 ;; - drop block-comment-<foo> unless it's really used
-;; - uncomment-region on a part of a comment
-;; - obey the numarg of uncomment-region for continuation markers
+;; - uncomment-region on a subpart of a comment
 ;; - support gnu-style "multi-line with space in continue"
-;; - document string-strip
-;; - better document comment-continue (and probably turn it into a
-;;   simple string).
-;; - don't overwrite comment-padding.
-;; - better document comment-end-quote.  Probably make it better
-;;   self-sufficient so that other quoting can be used.
-;; - comment the padright/padleft.
 ;; - somehow allow comment-dwim to use the region even if transient-mark-mode
 ;;   is not turned on.
-;; - document comment-region-internal
-;; - comment-quote-nested should quote both the start and end of comment.
 
 ;;; Code:
 
@@ -73,7 +61,8 @@
   "Non-nil if syntax-tables can be used instead of regexps.
 Can also be `undecided' which means that a somewhat expensive test will
 be used to try to determine whether syntax-tables should be trusted
-to understand comments or not.")
+to understand comments or not in the given buffer.
+Major modes should set this variable.")
 
 (defcustom comment-column 32
   "*Column to indent right-margin comments to.
@@ -84,28 +73,20 @@
   :group 'comment)
 (make-variable-buffer-local 'comment-column)
 
-(defcustom comment-start nil
-  "*String to insert to start a new comment, or nil if no comment syntax."
-  :type '(choice (const :tag "None" nil)
-		 string)
-  :group 'comment)
+(defvar comment-start nil
+  "*String to insert to start a new comment, or nil if no comment syntax.")
 
-(defcustom comment-start-skip nil
+(defvar comment-start-skip nil
   "*Regexp to match the start of a comment plus everything up to its body.
 If there are any \\(...\\) pairs, the comment delimiter text is held to begin
-at the place matched by the close of the first pair."
-  :type '(choice (const :tag "None" nil)
-		 regexp)
-  :group 'comment)
+at the place matched by the close of the first pair.")
 
 (defvar comment-end-skip nil
   "Regexp to match the end of a comment plus everything up to its body.")
 
-(defcustom comment-end ""
+(defvar comment-end ""
   "*String to insert to end a new comment.
-Should be an empty string if comments are terminated by end-of-line."
-  :type 'string
-  :group 'comment)
+Should be an empty string if comments are terminated by end-of-line.")
 
 (defvar comment-indent-hook nil
   "Obsolete variable for function to compute desired indentation for a comment.
@@ -126,19 +107,22 @@
 This should be locally set by each major mode if needed.")
 
 (defvar comment-continue nil
-  "Pair of strings to insert for multiline comments.")
-(defvar comment-add 0
-  "How many more chars should be inserted by default.")
+  "Continuation string to insert for multiline comments.
+This string will be added at the beginning of each line except the very
+first one when commenting a region with a commenting style that allows
+comments to span several lines.
+It should generally have the same length as `comment-start' in order to
+preserve indentation.
+If it is nil a value will be automatically derived from `comment-start'
+by replacing its first character with a space.")
 
-(defcustom comment-style 'plain
-  "*Style to be used for inserting comments."
-  :group 'comment
-  :type '(choice (const plain)
-		 (const indent)
-		 (const aligned)
-		 (const multi-line)
-		 (const extra-line)
-		 (const box)))
+(defvar comment-add 0
+  "How many more comment chars should be inserted by `comment-region'.
+This determines the default value of the numeric argument of `comment-region'.
+This should generally stay 0, except for a few modes like Lisp where
+it can be convenient to set it to 1 so that regions are commented with
+two semi-colons.")
+
 (defconst comment-styles
   '((plain	. (nil nil nil nil))
     (indent	. (nil nil nil t))
@@ -146,12 +130,25 @@
     (multi-line	. (t nil nil t))
     (extra-line	. (t nil t t))
     (box	. (t t t t)))
-  "Possible styles.
-(STYLE . (MULTI ALIGN EXTRA INDENT).")
+  "Possible comment styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)).
+STYLE should be a mnemonic symbol.
+MULTI specifies that comments are allowed to span multiple lines.
+ALIGN specifies that the `comment-end' markers should be aligned.
+EXTRA specifies that an extra line should be used before and after the
+  region to comment (to put the `comment-end' and `comment-start').
+INDENT specifies that the `comment-start' markers should not be put at the
+  left margin but at the current indentation of the region to comment.")
+
+(defcustom comment-style 'plain
+  "*Style to be used for `comment-region'.
+See `comment-styles' for a list of available styles."
+  :group 'comment
+  :type `(choice ,@(mapcar (lambda (s) `(const ,(car s))) comment-styles)))
 
 (defcustom comment-padding 1
-  "Number of spaces `comment-region' puts between comment chars and text.
-Can also be a string instead.
+  "Padding string that `comment-region' puts between comment chars and text.
+Can also be an integer which will be automatically turned into a string
+of the corresponding number of spaces.
 
 Extra spacing between the comment characters and the comment text
 makes the comment easier to read.  Default is 1.  nil means 0.")
@@ -167,13 +164,15 @@
 ;;;; Helpers
 ;;;;
 
-(defun comment-string-strip (str before after)
-  (string-match (concat "\\`" (if before "\\s-*")
-			"\\(.*?\\)" (if after "\\s-*")
+(defun comment-string-strip (str beforep afterp)
+  "Strip STR of any leading (if BEFOREP) and/or trailing (if AFTERP) space."
+  (string-match (concat "\\`" (if beforep "\\s-*")
+			"\\(.*?\\)" (if afterp "\\s-*")
 			"\\'") str)
   (match-string 1 str))
 
 (defun comment-string-reverse (s)
+  "Return the mirror image of string S, without any trailing space."
   (comment-string-strip (concat (nreverse (string-to-list s))) nil t))
 
 (defun comment-normalize-vars (&optional noerror)
@@ -198,12 +197,9 @@
     ;;(setq comment-start (comment-string-strip comment-start t nil))
     ;;(setq comment-end (comment-string-strip comment-end nil t))
     ;; comment-continue
-    (unless (or (car comment-continue) (string= comment-end ""))
+    (unless (or comment-continue (string= comment-end ""))
       (set (make-local-variable 'comment-continue)
-	   (cons (concat " " (substring comment-start 1))
-		 nil)))
-    (when (and (car comment-continue) (null (cdr comment-continue)))
-      (setcdr comment-continue (comment-string-reverse (car comment-continue))))
+	   (concat " " (substring comment-start 1))))
     ;; comment-skip regexps
     (unless comment-start-skip
       (set (make-local-variable 'comment-start-skip)
@@ -220,22 +216,38 @@
 		     (regexp-quote (substring ce 1))
 		     "\\)"))))))
  
-(defmacro until (&rest body)
-  (let ((retsym (make-symbol "ret")))
-    `(let (,retsym)
-       (while (not (setq ,retsym (progn ,@body))))
-       ,retsym)))
-(def-edebug-spec until t)
+(defun comment-quote-re (str unp)
+  (concat (regexp-quote (substring str 0 1))
+	  "\\\\" (if unp "+" "*")
+	  (regexp-quote (substring str 1))))
 
-(defun comment-end-quote-re (str &optional re)
-  "Make a regexp that matches the (potentially quoted) STR comment-end.
-The regexp has one group in it which matches RE right after the
-potential quoting."
-  (setq str (comment-string-strip str t t))
-  (when (and comment-quote-nested (> (length str) 1))
-    (concat (regexp-quote (substring str 0 1))
-	    "\\\\*\\(" re "\\)"
-	    (regexp-quote (substring str 1)))))
+(defun comment-quote-nested (cs ce unp)
+  "Quote or unquote nested comments.
+If UNP is non-nil, unquote nested comment markers."
+  (setq cs (comment-string-strip cs t t))
+  (setq ce (comment-string-strip ce t t))
+  (when (and comment-quote-nested (> (length ce) 0))
+    (let ((re (concat (comment-quote-re ce unp)
+		      "\\|" (comment-quote-re cs unp))))
+      (goto-char (point-min))
+      (while (re-search-forward re nil t)
+	(goto-char (match-beginning 0))
+	(forward-char 1)
+	(if unp (delete-char 1) (insert "\\"))
+	(when (= (length ce) 1)
+	  ;; If the comment-end is a single char, adding a \ after that
+	  ;; "first" char won't deactivate it, so we turn such a CE
+	  ;; into !CS.  I.e. for pascal, we turn } into !{
+	  (if (not unp)
+	      (when (string= (match-string 0) ce)
+		(replace-match (concat "!" cs) t t))
+	    (when (and (< (point-min) (match-beginning 0))
+		       (string= (buffer-substring (1- (match-beginning 0))
+						  (1- (match-end 0)))
+				(concat "!" cs)))
+	      (backward-char 2)
+	      (delete-char (- (match-end 0) (match-beginning 0)))
+	      (insert ce))))))))
 
 ;;;;
 ;;;; Navigation
@@ -335,9 +347,9 @@
   (interactive "*")
   (let* ((empty (save-excursion (beginning-of-line)
 				(looking-at "[ \t]*$")))
-	 (starter (or (and continue (car comment-continue))
+	 (starter (or (and continue comment-continue)
 		      (and empty block-comment-start) comment-start))
-	 (ender (or (and continue (car comment-continue) "")
+	 (ender (or (and continue comment-continue "")
 		    (and empty block-comment-end) comment-end)))
     (cond
      ((null starter)
@@ -413,86 +425,102 @@
 
 (defun comment-padright (str &optional n)
   "Construct a string composed of STR plus `comment-padding'.
-It contains N copies of the last non-whitespace chars of STR.
+It also adds N copies of the last non-whitespace chars of STR.
 If STR already contains padding, the corresponding amount is
-  ignored from `comment-padding'.
-N defaults to 1.
+ignored from `comment-padding'.
+N defaults to 0.
+If N is `re', a regexp is returned instead, that would match
+the string for any N."
+  (setq n (or n 0))
+  (when (and (stringp str) (not (string= "" str)))
+    ;; Separate the actual string from any leading/trailing padding
+    (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str)
+    (let ((s (match-string 1 str))	;actual string
+	  (lpad (substring str 0 (match-beginning 1))) ;left padding
+	  (rpad (concat (substring str (match-end 1)) ;original right padding
+			(substring comment-padding ;additional right padding
+				   (min (- (match-end 0) (match-end 1))
+					(length comment-padding))))))
+      (if (not (symbolp n))
+	  (concat lpad s (make-string n (aref str (1- (match-end 1)))) rpad)
+	;; construct a regexp that would match anything from just S
+	;; to any possible output of this function for any N.
+	(concat (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
+			   lpad "")	;padding is not required
+		(regexp-quote s) "+"	;the last char of S might be repeated
+		(mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
+			   rpad "")))))) ;padding is not required
+
+(defun comment-padleft (str &optional n)
+  "Construct a string composed of `comment-padding' plus STR.
+It also adds N copies of the first non-whitespace chars of STR.
+If STR already contains padding, the corresponding amount is
+ignored from `comment-padding'.
+N defaults to 0.
 If N is `re', a regexp is returned instead, that would match
   the string for any N."
   (setq n (or n 0))
   (when (and (stringp str) (not (string= "" str)))
-    (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str)
-    (let ((s (match-string 1 str))
-	  (lpad (substring str 0 (match-beginning 1)))
-	  (rpad (concat (substring str (match-end 1))
-			(substring comment-padding
-				   (min (- (match-end 0) (match-end 1))
-					(length comment-padding))))))
-      (if (symbolp n)
-	  (concat (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
-			     lpad "")
-		  (regexp-quote s) "+"
-		  (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
-			     rpad ""))
-	(concat lpad s (make-string n (aref str (1- (match-end 1)))) rpad)))))
-
-(defun comment-padleft (str &optional n)
-  "Construct a string composed of `comment-padding' plus STR.
-It contains N copies of the last non-whitespace chars of STR.
-If STR already contains padding, the corresponding amount is
-  ignored from `comment-padding'.
-N defaults to 1.
-If N is `re', a regexp is returned instead, that would match
-  the string for any N."
-  (setq n (or n 0))
-  (when (and (stringp str) (not (string= "" str)))
+    ;; Only separate the left pad because we assume there is no right pad.
     (string-match "\\`\\s-*" str)
     (let ((s (substring str (match-end 0)))
 	  (pad (concat (substring comment-padding
 				  (min (- (match-end 0) (match-beginning 0))
 				       (length comment-padding)))
 		       (match-string 0 str)))
-	  (c (aref str (match-end 0)))
-	  (multi (or (not comment-quote-nested) (string= comment-end "")
-		     (> (length str) (1+ (match-end 0))))))
-      (if (symbolp n)
-	  (concat "\\s-*"
-		  (if multi (concat (regexp-quote (string c)) "*"))
-		  (regexp-quote s))
-	(concat pad (when multi (make-string n c)) s)))))
+	  (c (aref str (match-end 0)))	;the first non-space char of STR
+	  ;; We can only duplicate C if the comment-end has multiple chars
+	  ;; or if comments can be nested, else the comment-end `}' would
+	  ;; be turned into `}}}' where only the first ends the comment
+	  ;; and the rest becomes bogus junk.
+	  (multi (not (and comment-quote-nested
+			   ;; comment-end is a single char
+			   (string-match "\\`\\s-*\\S-\\s-*\\'" comment-end)))))
+      (if (not (symbolp n))
+	  (concat pad (when multi (make-string n c)) s)
+	;; Construct a regexp that would match anything from just S
+	;; to any possible output of this function for any N.
+	;; We match any number of leading spaces because this regexp will
+	;; be used for uncommenting where we might want to remove
+	;; uncomment markers with arbitrary leading space (because
+	;; they were aligned).
+	(concat "\\s-*"
+		(if multi (concat (regexp-quote (string c)) "*"))
+		(regexp-quote s))))))
 
 (defun uncomment-region (beg end &optional arg)
   "Uncomment each line in the BEG..END region.
-ARG is currently ignored."
+The numeric prefix ARG can specify a number of chars to remove from the
+comment markers."
   (interactive "*r\nP")
   (comment-normalize-vars)
   (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
   (save-excursion
     (goto-char beg)
-    (unless (markerp end) (setq end (copy-marker end)))
+    (setq end (copy-marker end))
     (let ((numarg (prefix-numeric-value arg))
 	  spt)
       (while (and (< (point) end)
 		  (setq spt (comment-search-forward end t)))
 	(let* ((ipt (point))
-	       ;; find the end of the comment
+	       ;; Find the end of the comment.
 	       (ept (progn
 		      (goto-char spt)
 		      (unless (comment-forward)
 			(error "Can't find the comment end"))
-		      (point-marker)))
-	       (block nil)
-	       (end-quote-re (comment-end-quote-re comment-end "\\\\"))
-	       (ccs (car comment-continue))
+		      (point)))
+	       (box nil)
+	       (ccs comment-continue)
 	       (srei (comment-padright ccs 're))
 	       (sre (and srei (concat "^\\s-*?\\(" srei "\\)"))))
 	  (save-restriction
 	    (narrow-to-region spt ept)
-	    ;; remove the comment-start
+	    ;; Remove the comment-start.
 	    (goto-char ipt)
 	    (skip-syntax-backward " ")
+	    ;; A box-comment starts with a looong comment-start marker.
 	    (when (> (- (point) (point-min) (length comment-start)) 7)
-	      (setq block t))
+	      (setq box t))
 	    (when (looking-at (regexp-quote comment-padding))
 	      (goto-char (match-end 0)))
 	    (when (and sre (looking-at (concat "\\s-*\n\\s-*" srei)))
@@ -501,35 +529,36 @@
 	      (skip-syntax-backward " ")
 	      (delete-char (- numarg)))
 
-	    ;; remove the end-comment (and leading padding and such)
+	    ;; Remove the end-comment (and leading padding and such).
 	    (goto-char (point-max)) (comment-enter-backward)
 	    (unless (string-match "\\`\\(\n\\|\\s-\\)*\\'"
-				  (buffer-substring (point) ept))
+				  (buffer-substring (point) (point-max)))
 	      (when (and (bolp) (not (bobp))) (backward-char))
-	      (if (null arg) (delete-region (point) ept)
+	      (if (null arg) (delete-region (point) (point-max))
 		(skip-syntax-forward " ")
 		(delete-char numarg)))
 
-	    ;; unquote any nested end-comment
-	    (when end-quote-re
-	      (goto-char (point-min))
-	      (while (re-search-forward end-quote-re nil t)
-		(delete-region (match-beginning 1) (match-end 1))))
+	    ;; Unquote any nested end-comment.
+	    (comment-quote-nested comment-start comment-end t)
 
-	    ;; eliminate continuation markers as well
-	    (let* ((cce (or (cdr comment-continue)
-			(comment-string-reverse comment-start)))
-		   (erei (and block (comment-padleft cce 're)))
-		   (ere (and erei (concat "\\(" erei "\\)\\s-*$")))
-		   (re (if (and sre ere) (concat sre "\\|" ere) (or sre ere))))
-	      (when re
+	    ;; Eliminate continuation markers as well.
+	    (when sre
+	      (let* ((cce (comment-string-reverse (or comment-continue
+						      comment-start)))
+		     (erei (and box (comment-padleft cce 're)))
+		     (ere (and erei (concat "\\(" erei "\\)\\s-*$"))))
 		(goto-char (point-min))
-		;; there can't be a real SRE on the first line.
-		(when (and sre (looking-at sre)) (goto-char (match-end 0)))
-		(while (re-search-forward re nil t)
+		(while (progn
+			 (if (and ere (re-search-forward
+				       ere (line-end-position) t))
+			     (replace-match "" t t nil (if (match-end 2) 2 1))
+			   (setq ere nil))
+			 (forward-line 1)
+			 (re-search-forward sre (line-end-position) t))
 		  (replace-match "" t t nil (if (match-end 2) 2 1)))))
-	      ;; go the the end for the next comment
-	    (goto-char (point-max))))))))
+	    ;; Go the the end for the next comment.
+	    (goto-char (point-max)))))
+      (set-marker end nil))))
 
 (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block)
   (if block
@@ -591,41 +620,54 @@
 
 (defun comment-region-internal (beg end cs ce
 				    &optional ccs cce block lines indent)
+  "Comment region BEG..END.
+CS and CE are the comment start resp. end string.
+CCS and CCE are the comment continuation strings for the start resp. end
+of lines (default to CS and CE).
+BLOCK indicates that end of lines should be marked with either CCE, CE or CS
+\(if CE is empty) and that those markers should be aligned.
+LINES indicates that an extra lines will be used at the beginning and end
+of the region for CE and CS.
+INDENT indicates to put CS and CCS at the current indentation of the region
+rather than at left margin."
   (assert (< beg end))
   (let ((no-empty t))
-    ;; sanitize ce and cce
+    ;; Sanitize CE and CCE.
     (if (and (stringp ce) (string= "" ce)) (setq ce nil))
     (if (and (stringp cce) (string= "" cce)) (setq cce nil))
-    ;; should we mark empty lines as well ?
+    ;; If CE is empty, multiline cannot be used.
+    (unless ce (setq ccs nil cce nil))
+    ;; Should we mark empty lines as well ?
     (if (or ccs block lines) (setq no-empty nil))
-    ;; make sure we have end-markers for BLOCK mode
+    ;; Make sure we have end-markers for BLOCK mode.
     (when block (unless ce (setq ce (comment-string-reverse cs))))
-    ;; continuation defaults to the same
-    (if ccs (unless block (setq cce nil))
-      (setq ccs cs cce ce))
+    ;; If BLOCK is not requested, we don't need CCE.
+    (unless block (setq cce nil))
+    ;; Continuation defaults to the same as CS and CE.
+    (unless ccs (setq ccs cs cce ce))
     
     (save-excursion
       (goto-char end)
+      ;; If the end is not at the end of a line and the comment-end
+      ;; is implicit (i.e. a newline), explicitly insert a newline.
       (unless (or ce (eolp)) (insert "\n") (indent-according-to-mode))
       (comment-with-narrowing beg end
-	(let ((ce-quote-re (comment-end-quote-re comment-end))
-	      (min-indent (point-max))
+	(let ((min-indent (point-max))
 	      (max-indent 0))
 	  (goto-char (point-min))
-	  ;; loop over all lines to find the needed indentations
-	  (until
-	   (unless (looking-at "[ \t]*$")
-	     (setq min-indent (min min-indent (current-indentation))))
-	   (when ce-quote-re
-	     (let ((eol (line-end-position)))
-	       (while (re-search-forward ce-quote-re eol 'move)
-		 (incf eol)
-		 (replace-match "\\" t t nil 1))))
-	   (end-of-line)
-	   (setq max-indent (max max-indent (current-column)))
-	   (or (eobp) (progn (forward-line) nil)))
+	  ;; Quote any nested comment marker
+	  (comment-quote-nested comment-start comment-end nil)
 
-	  ;; inserting ccs can change max-indent by (1- tab-width)
+	  ;; Loop over all lines to find the needed indentations.
+	  (while
+	      (progn
+		(unless (looking-at "[ \t]*$")
+		  (setq min-indent (min min-indent (current-indentation))))
+		(end-of-line)
+		(setq max-indent (max max-indent (current-column)))
+		(not (or (eobp) (progn (forward-line) nil)))))
+	  
+	  ;; Inserting ccs can change max-indent by (1- tab-width).
 	  (incf max-indent (+ (max (length cs) (length ccs)) -1 tab-width))
 	  (unless indent (setq min-indent 0))
 
@@ -639,17 +681,18 @@
 	  
 	  (goto-char (point-min))
 	  ;; Loop over all lines from BEG to END.
-	  (until
-	   (unless (and no-empty (looking-at "[ \t]*$"))
-	     (move-to-column min-indent t)
-	     (insert cs) (setq cs ccs)
-	     (end-of-line)
-	     (if (eobp) (setq cce ce))
-	     (when cce
-	       (when block (move-to-column max-indent t))
-	       (insert cce)))
-	   (end-of-line)
-	   (or (eobp) (progn (forward-line) nil))))))))
+	  (while
+	      (progn
+		(unless (and no-empty (looking-at "[ \t]*$"))
+		  (move-to-column min-indent t)
+		  (insert cs) (setq cs ccs) ;switch to CCS after the first line
+		  (end-of-line)
+		  (if (eobp) (setq cce ce))
+		  (when cce
+		    (when block (move-to-column max-indent t))
+		    (insert cce)))
+		(end-of-line)
+		(not (or (eobp) (progn (forward-line) nil))))))))))
 
 (defun comment-region (beg end &optional arg)
   "Comment or uncomment each line in the region.
@@ -709,8 +752,8 @@
        (let ((s (comment-padleft comment-end numarg)))
 	 (and s (if (string-match comment-end-skip s) s
 		  (comment-padright comment-end))))
-       (if multi (comment-padright (car comment-continue) numarg))
-       (if multi (comment-padleft (cdr comment-continue) numarg))
+       (if multi (comment-padright comment-continue numarg))
+       (if multi (comment-padleft (comment-string-reverse comment-continue) numarg))
        block
        lines
        (nth 3 style))))))
@@ -829,6 +872,28 @@
 
 ;;; Change Log:
 ;; $Log: newcomment.el,v $
+;; Revision 1.7  2000/05/13 19:41:08  monnier
+;; (comment-use-syntax): Change `maybe' to `undecided'.
+;; (comment-quote-nested): New.  Replaces comment-nested.
+;; (comment-add): Turn into a mere defvar or a integer.
+;; (comment-style): Change default to `plain'.
+;; (comment-styles): Rename `plain' to `indent' and create a new plainer `plain'.
+;; (comment-string-reverse): Use nreverse.
+;; (comment-normalize-vars): Change `maybe' to `undecided', add comments.
+;;   Don't infer the setting of comment-nested anymore (the default for
+;;   comment-quote-nested is safe).  Use comment-quote-nested.
+;; (comment-end-quote-re): Use comment-quote-nested.
+;; (comment-search-forward): Obey LIMIT.
+;; (comment-indent): Don't skip forward further past comment-search-forward.
+;; (comment-padleft): Use comment-quote-nested.
+;; (comment-make-extra-lines): Use `cons' rather than `values'.
+;; (comment-region-internal): New arg INDENT.  Use line-end-position.
+;;   Avoid multiple-value-setq.
+;; (comment-region): Follow the new comment-add semantics.
+;;   Don't do box comments any more.
+;; (comment-box): New function.
+;; (comment-dwim): Only do the region stuff is transient-mark-active.
+;;
 ;; Revision 1.6  1999/12/08 00:19:51  monnier
 ;; various fixes and gratuitous movements.
 ;;