changeset 26645:39f87d842e57

(comment-make-extra-lines): Moved out of comment-region-internal. (comment-with-narrowing): New macro. Provides a way to preserve indentation inside narrowing. (comment-region-internal): Add "\n" to close the comment if necessary. Correctly handle commenting-out when BEG is not bolp.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 28 Nov 1999 21:33:55 +0000
parents 14334ad07b74
children 0d447856a2f7
files lisp/newcomment.el
diffstat 1 files changed, 84 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/newcomment.el	Sun Nov 28 20:14:03 1999 +0000
+++ b/lisp/newcomment.el	Sun Nov 28 21:33:55 1999 +0000
@@ -5,7 +5,7 @@
 ;; Author: Stefan Monnier <monnier@cs.yale.edu>
 ;; Keywords: comment uncomment
 ;; Version: $Name:  $
-;; Revision: $Id: diff-mode.el,v 1.11 1999/10/09 23:38:29 monnier Exp $
+;; Revision: $Id: newcomment.el,v 1.1 1999/11/28 18:51:06 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
@@ -29,6 +29,10 @@
 
 ;; - most of the code is not written (just copied from simple.el)
 ;; - too many other bugs to mention
+;; - if the region does not start at the beginning of a line,
+;;   comment-region will not align the comment markers properly
+;; - comment-multi-line already exists with a different meaning
+;;   and is not orthogonal to comment-extra-lines
 
 ;;; Todo:
 
@@ -245,6 +249,7 @@
     `(let (,retsym)
        (while (not (setq ,retsym (progn ,@body))))
        ,retsym)))
+(def-edebug-spec until t)
 
 (defun string-reverse (s) (concat (reverse (string-to-list s))))
 
@@ -324,6 +329,64 @@
 				  (delete-char (length ce)))))))))
 		(forward-line 1)))))))))
 
+(defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block)
+  (if block
+      (let* ((s (concat cs "a=m" cce "\n"
+			(make-string min-indent ? ) ccs))
+	     (e (concat cce "\n" (make-string min-indent ? )
+			ccs "a=m" ce))
+	     (_ (assert (string-match "\\s-*\\(a=m\\)\\s-*" s)))
+	     (fill (make-string (+ (- max-indent
+				      min-indent
+				      (match-beginning 0))
+				   (- (match-end 0)
+				      (match-end 1)))
+				(aref s (match-end 0)))))
+	(setq cs (replace-match fill t t s))
+	(assert (string-match "\\s-*\\(a=m\\)\\s-*" e))
+	(setq ce (replace-match fill t t e)))
+    (when (and ce (string-match "\\`\\s-*\\(.*\\S-\\)\\s-*\\'" ce))
+      (setq ce (match-string 1 ce)))
+    (let* ((c (concat ce "a=m" cs))
+	   (indent (if (string-match "\\(.+\\).*a=m\\(.*\\)\\1" c)
+		       (max (+ min-indent
+			       (- (match-end 2) (match-beginning 2))
+			       (- (match-beginning 0)))
+			    0)
+		     min-indent)))
+      (setq ce (concat cce "\n" (make-string indent ? ) (or ce cs)))
+      (setq cs (concat cs "\n" (make-string min-indent ? ) ccs))))
+  (values cs ce))
+
+(def-edebug-spec comment-with-narrowing t)
+(put 'comment-with-narrowing 'lisp-indent-function 2)
+(defmacro comment-with-narrowing (beg end &rest body)
+  "Execute BODY with BEG..END narrowing.
+Space is added (and then removed) at the beginning for the text's
+indentation to be kept as it was before narrowing."
+  `(let ((-bindent (save-excursion (goto-char beg) (current-column))))
+     (save-restriction
+       (narrow-to-region beg end)
+       (goto-char (point-min))
+       (insert (make-string -bindent ? ))
+       (prog1
+	   (progn ,@body)
+	 ;; remove the -bindent
+	 (save-excursion
+	   (goto-char (point-min))
+	   (when (looking-at " *")
+	     (let ((n (min (- (match-end 0) (match-beginning 0)) -bindent)))
+	       (delete-char n)
+	       (decf -bindent n)))
+	   (end-of-line)
+	   (let ((e (point)))
+	     (beginning-of-line)
+	     (while (and (> -bindent 0) (re-search-forward "  +" e t))
+	       (let ((n (min -bindent (- (match-end 0) (match-beginning 0) 1))))
+		 (goto-char (match-beginning 0))
+		 (delete-char n)
+		 (decf -bindent n)))))))))
+
 (defun comment-region-internal (beg end cs ce &optional ccs cce block lines)
   (assert (< beg end))
   (let ((no-empty t))
@@ -341,8 +404,9 @@
       (if (null cce) (setq cce (string-reverse ccs))))
 
     (save-excursion
-      (save-restriction
-	(narrow-to-region beg end)
+      (goto-char end)
+      (unless (or ce (eolp)) (insert "\n") (indent-according-to-mode))
+      (comment-with-narrowing beg end
 	(let ((ce-quote-re
 	       (when (and (not comment-nested) (> (length comment-end) 1))
 		 (concat (regexp-quote (substring comment-end 0 1))
@@ -367,33 +431,11 @@
 	  ;; inserting ccs can change max-indent by (1- tab-width)
 	  (incf max-indent (+ (max (length cs) (length ccs)) -1 tab-width))
 
+	  ;; make the leading and trailing lines if requested
 	  (when lines
-	    (if block
-		(let* ((s (concat cs "a=m" cce "\n"
-				  (make-string min-indent ? ) ccs))
-		       (e (concat cce "\n" (make-string min-indent ? )
-				  ccs "a=m" ce))
-		       (_ (assert (string-match "\\s-*\\(a=m\\)\\s-*" s)))
-		       (fill (make-string (+ (- max-indent
-						min-indent
-						(match-beginning 0))
-					     (- (match-end 0)
-						(match-end 1)))
-					  (aref s (match-end 0)))))
-		  (setq cs (replace-match fill t t s))
-		  (assert (string-match "\\s-*\\(a=m\\)\\s-*" e))
-		  (setq ce (replace-match fill t t e)))
-	      (when (and ce (string-match "\\`\\s-*\\(.*\\S-\\)\\s-*\\'" ce))
-		(setq ce (match-string 1 ce)))
-	      (let* ((c (concat ce "a=m" cs))
-		     (indent (if (string-match "\\(.+\\).*a=m\\(.*\\)\\1" c)
-				 (max (+ min-indent
-					 (- (match-end 2) (match-beginning 2))
-					 (- (match-beginning 0)))
-				      0)
-			       min-indent)))
-		(setq ce (concat cce "\n" (make-string indent ? ) (or ce cs)))
-		(setq cs (concat cs "\n" (make-string min-indent ? ) ccs)))))
+	    (multiple-value-setq (cs ce)
+	      (comment-make-extra-lines
+	       cs ce ccs cce min-indent max-indent block)))
 	  
 	  (goto-char (point-min))
 	  ;; Loop over all lines from BEG to END.
@@ -489,6 +531,18 @@
 (provide 'newcomment)
 
 ;;; Change Log:
-;; $Log$
+;; $Log: newcomment.el,v $
+;; Revision 1.1  1999/11/28 18:51:06  monnier
+;; First "working" version:
+;; - uncomment-region doesn't work for some unknown reason
+;; - comment-multi-line allows the use of multi line comments
+;; - comment-extra-lines allows yet another style choice
+;; - comment-add allows to default to `;;'
+;; - comment-region on a comment calls uncomment-region
+;; - C-u C-u comment-region aligns comment end markers
+;; - C-u C-u C-u comment-region puts the comment inside a rectangle
+;; - comment-region will try to quote coment-end markers inside the region
+;; - comment-start markers are placed at the indentation level
+;;
 
 ;;; newcomment.el ends here