comparison lisp/newcomment.el @ 29037:238233843fc1

(comment-styles): New `box-multi'. (comment-normalize-vars): Better default for comment-continue to avoid whitespace-only continuations. (comment-search-forward): Always move even in the no-syntax case. (comment-padright): Only obey N if it's only obeyed for padleft. (comment-make-extra-lines): Better handling of empty continuations. Use `=' for the filler if comment-start has only one character. (uncomment-region): Try handling the special `=' filler. (comment-region): Allow LINES even if MULTI is nil. (comment-box): Choose box style based on comment-style.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 21 May 2000 00:27:31 +0000
parents 80e6f0d6eac1
children 720287a2312f
comparison
equal deleted inserted replaced
29036:91115e6a0f53 29037:238233843fc1
4 4
5 ;; Author: code extracted from Emacs-20's simple.el 5 ;; Author: code extracted from Emacs-20's simple.el
6 ;; Maintainer: Stefan Monnier <monnier@cs.yale.edu> 6 ;; Maintainer: Stefan Monnier <monnier@cs.yale.edu>
7 ;; Keywords: comment uncomment 7 ;; Keywords: comment uncomment
8 ;; Version: $Name: $ 8 ;; Version: $Name: $
9 ;; Revision: $Id: newcomment.el,v 1.10 2000/05/17 19:32:32 monnier Exp $ 9 ;; Revision: $Id: newcomment.el,v 1.11 2000/05/19 15:37:41 monnier Exp $
10 10
11 ;; This file is part of GNU Emacs. 11 ;; This file is part of GNU Emacs.
12 12
13 ;; GNU Emacs is free software; you can redistribute it and/or modify 13 ;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by 14 ;; it under the terms of the GNU General Public License as published by
132 '((plain . (nil nil nil nil)) 132 '((plain . (nil nil nil nil))
133 (indent . (nil nil nil t)) 133 (indent . (nil nil nil t))
134 (aligned . (nil t nil t)) 134 (aligned . (nil t nil t))
135 (multi-line . (t nil nil t)) 135 (multi-line . (t nil nil t))
136 (extra-line . (t nil t t)) 136 (extra-line . (t nil t t))
137 (box . (t t t t))) 137 (box . (nil t t t))
138 (box-multi . (t t t t)))
138 "Possible comment styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)). 139 "Possible comment styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)).
139 STYLE should be a mnemonic symbol. 140 STYLE should be a mnemonic symbol.
140 MULTI specifies that comments are allowed to span multiple lines. 141 MULTI specifies that comments are allowed to span multiple lines.
141 ALIGN specifies that the `comment-end' markers should be aligned. 142 ALIGN specifies that the `comment-end' markers should be aligned.
142 EXTRA specifies that an extra line should be used before and after the 143 EXTRA specifies that an extra line should be used before and after the
202 ;;(setq comment-start (comment-string-strip comment-start t nil)) 203 ;;(setq comment-start (comment-string-strip comment-start t nil))
203 ;;(setq comment-end (comment-string-strip comment-end nil t)) 204 ;;(setq comment-end (comment-string-strip comment-end nil t))
204 ;; comment-continue 205 ;; comment-continue
205 (unless (or comment-continue (string= comment-end "")) 206 (unless (or comment-continue (string= comment-end ""))
206 (set (make-local-variable 'comment-continue) 207 (set (make-local-variable 'comment-continue)
207 (concat " " (substring comment-start 1)))) 208 (concat (if (string-match "\\S-\\S-" comment-start) " " "|")
209 (substring comment-start 1))))
208 ;; comment-skip regexps 210 ;; comment-skip regexps
209 (unless comment-start-skip 211 (unless comment-start-skip
210 (set (make-local-variable 'comment-start-skip) 212 (set (make-local-variable 'comment-start-skip)
211 (concat "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(\\s<+\\|" 213 (concat "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(\\s<+\\|"
212 (regexp-quote (comment-string-strip comment-start t t)) 214 (regexp-quote (comment-string-strip comment-start t t))
262 "Find a comment start between point and LIMIT. 264 "Find a comment start between point and LIMIT.
263 Moves point to inside the comment and returns the position of the 265 Moves point to inside the comment and returns the position of the
264 comment-starter. If no comment is found, moves point to LIMIT 266 comment-starter. If no comment is found, moves point to LIMIT
265 and raises an error or returns nil of NOERROR is non-nil." 267 and raises an error or returns nil of NOERROR is non-nil."
266 (if (not comment-use-syntax) 268 (if (not comment-use-syntax)
267 (when (re-search-forward comment-start-skip limit noerror) 269 (if (re-search-forward comment-start-skip limit noerror)
268 (or (match-end 1) (match-beginning 0))) 270 (or (match-end 1) (match-beginning 0))
271 (goto-char limit)
272 (unless noerror (error "No comment")))
269 (let* ((pt (point)) 273 (let* ((pt (point))
270 ;; Assume (at first) that pt is outside of any string. 274 ;; Assume (at first) that pt is outside of any string.
271 (s (parse-partial-sexp pt (or limit (point-max)) nil nil nil t))) 275 (s (parse-partial-sexp pt (or limit (point-max)) nil nil nil t)))
272 (when (and (nth 8 s) (nth 3 s)) 276 (when (and (nth 8 s) (nth 3 s))
273 ;; The search ended inside a string. Try to see if it 277 ;; The search ended inside a string. Try to see if it
277 (list nil nil nil (nth 3 s) nil nil nil nil) 281 (list nil nil nil (nth 3 s) nil nil nil nil)
278 t))) 282 t)))
279 (if (not (and (nth 8 s) (not (nth 3 s)))) 283 (if (not (and (nth 8 s) (not (nth 3 s))))
280 (unless noerror (error "No comment")) 284 (unless noerror (error "No comment"))
281 ;; We found the comment. 285 ;; We found the comment.
282 (let ((pt (point)) 286 (let ((pos (point))
283 (start (nth 8 s)) 287 (start (nth 8 s))
284 (bol (save-excursion (beginning-of-line) (point))) 288 (bol (line-beginning-position))
285 (end nil)) 289 (end nil))
286 (while (and (null end) (>= (point) bol)) 290 (while (and (null end) (>= (point) bol))
287 (if (looking-at comment-start-skip) 291 (if (looking-at comment-start-skip)
288 (setq end (min (or limit (point-max)) (match-end 0))) 292 (setq end (min (or limit (point-max)) (match-end 0)))
289 (backward-char))) 293 (backward-char)))
290 (goto-char end) 294 (goto-char (or end pos))
291 start))))) 295 start)))))
292 296
293 (defun comment-search-backward (&optional limit noerror) 297 (defun comment-search-backward (&optional limit noerror)
294 "Find a comment start between LIMIT and point. 298 "Find a comment start between LIMIT and point.
295 Moves point to inside the comment and returns the position of the 299 Moves point to inside the comment and returns the position of the
385 ((null starter) 389 ((null starter)
386 (error "No comment syntax defined")) 390 (error "No comment syntax defined"))
387 (t (let* ((eolpos (line-end-position)) 391 (t (let* ((eolpos (line-end-position))
388 cpos indent begpos) 392 cpos indent begpos)
389 (beginning-of-line) 393 (beginning-of-line)
390 (when (setq begpos (comment-search-forward eolpos t)) 394 (if (not (setq begpos (comment-search-forward eolpos t)))
395 (setq begpos (point))
391 (setq cpos (point-marker)) 396 (setq cpos (point-marker))
392 (goto-char begpos)) 397 (goto-char begpos))
393 (setq begpos (point))
394 ;; Compute desired indent. 398 ;; Compute desired indent.
395 (if (= (current-column) 399 (if (= (current-column)
396 (setq indent (if comment-indent-hook 400 (setq indent (if comment-indent-hook
397 (funcall comment-indent-hook) 401 (funcall comment-indent-hook)
398 (funcall comment-indent-function)))) 402 (funcall comment-indent-function))))
401 (skip-chars-backward " \t") 405 (skip-chars-backward " \t")
402 (delete-region (point) begpos) 406 (delete-region (point) begpos)
403 (indent-to indent)) 407 (indent-to indent))
404 ;; An existing comment? 408 ;; An existing comment?
405 (if cpos 409 (if cpos
406 (progn (goto-char cpos) 410 (progn (goto-char cpos) (set-marker cpos nil))
407 (set-marker cpos nil))
408 ;; No, insert one. 411 ;; No, insert one.
409 (insert starter) 412 (insert starter)
410 (save-excursion 413 (save-excursion
411 (insert ender)))))))) 414 (insert ender))))))))
412 415
463 (let ((s (match-string 1 str)) ;actual string 466 (let ((s (match-string 1 str)) ;actual string
464 (lpad (substring str 0 (match-beginning 1))) ;left padding 467 (lpad (substring str 0 (match-beginning 1))) ;left padding
465 (rpad (concat (substring str (match-end 1)) ;original right padding 468 (rpad (concat (substring str (match-end 1)) ;original right padding
466 (substring comment-padding ;additional right padding 469 (substring comment-padding ;additional right padding
467 (min (- (match-end 0) (match-end 1)) 470 (min (- (match-end 0) (match-end 1))
468 (length comment-padding)))))) 471 (length comment-padding)))))
472 ;; We can only duplicate C if the comment-end has multiple chars
473 ;; or if comments can be nested, else the comment-end `}' would
474 ;; be turned into `}}}' where only the first ends the comment
475 ;; and the rest becomes bogus junk.
476 (multi (not (and comment-quote-nested
477 ;; comment-end is a single char
478 (string-match "\\`\\s-*\\S-\\s-*\\'" comment-end)))))
469 (if (not (symbolp n)) 479 (if (not (symbolp n))
470 (concat lpad s (make-string n (aref str (1- (match-end 1)))) rpad) 480 (concat lpad s (when multi (make-string n (aref str (1- (match-end 1))))) rpad)
471 ;; construct a regexp that would match anything from just S 481 ;; construct a regexp that would match anything from just S
472 ;; to any possible output of this function for any N. 482 ;; to any possible output of this function for any N.
473 (concat (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?")) 483 (concat (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
474 lpad "") ;padding is not required 484 lpad "") ;padding is not required
475 (regexp-quote s) "+" ;the last char of S might be repeated 485 (regexp-quote s)
486 (when multi "+") ;the last char of S might be repeated
476 (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?")) 487 (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
477 rpad "")))))) ;padding is not required 488 rpad "")))))) ;padding is not required
478 489
479 (defun comment-padleft (str &optional n) 490 (defun comment-padleft (str &optional n)
480 "Construct a string composed of `comment-padding' plus STR. 491 "Construct a string composed of `comment-padding' plus STR.
541 (save-restriction 552 (save-restriction
542 (narrow-to-region spt ept) 553 (narrow-to-region spt ept)
543 ;; Remove the comment-start. 554 ;; Remove the comment-start.
544 (goto-char ipt) 555 (goto-char ipt)
545 (skip-syntax-backward " ") 556 (skip-syntax-backward " ")
557 ;; Check for special `=' used sometimes in comment-box.
558 (when (and (= (- (point) (point-min)) 1) (looking-at "=\\{7\\}"))
559 (skip-chars-forward "="))
546 ;; A box-comment starts with a looong comment-start marker. 560 ;; A box-comment starts with a looong comment-start marker.
547 (when (> (- (point) (point-min) (length comment-start)) 7) 561 (when (> (- (point) (point-min) (length comment-start)) 7)
548 (setq box t)) 562 (setq box t))
549 (when (looking-at (regexp-quote comment-padding)) 563 (when (looking-at (regexp-quote comment-padding))
550 (goto-char (match-end 0))) 564 (goto-char (match-end 0)))
554 (skip-syntax-backward " ") 568 (skip-syntax-backward " ")
555 (delete-char (- numarg))) 569 (delete-char (- numarg)))
556 570
557 ;; Remove the end-comment (and leading padding and such). 571 ;; Remove the end-comment (and leading padding and such).
558 (goto-char (point-max)) (comment-enter-backward) 572 (goto-char (point-max)) (comment-enter-backward)
559 (unless (string-match "\\`\\(\n\\|\\s-\\)*\\'" 573 ;; Check for special `=' used sometimes in comment-box.
560 (buffer-substring (point) (point-max))) 574 (when (and (= (- (point-max) (point)) 1) (> (point) 7)
575 (save-excursion (backward-char 7)
576 (looking-at "=\\{7\\}")))
577 (skip-chars-backward "="))
578 (unless (looking-at "\\(\n\\|\\s-\\)*\\'")
561 (when (and (bolp) (not (bobp))) (backward-char)) 579 (when (and (bolp) (not (bobp))) (backward-char))
562 (if (null arg) (delete-region (point) (point-max)) 580 (if (null arg) (delete-region (point) (point-max))
563 (skip-syntax-forward " ") 581 (skip-syntax-forward " ")
564 (delete-char numarg))) 582 (delete-char numarg)))
565 583
586 (set-marker end nil)))) 604 (set-marker end nil))))
587 605
588 (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block) 606 (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block)
589 "Make the leading and trailing extra lines. 607 "Make the leading and trailing extra lines.
590 This is used for `extra-line' style (or `box' style if BLOCK is specified)." 608 This is used for `extra-line' style (or `box' style if BLOCK is specified)."
591 (if block 609 (let ((eindent 0))
592 (let* ((s (concat cs "a=m" cce "\n" 610 (if (not block)
593 (make-string min-indent ? ) ccs)) 611 ;; Try to match CS and CE's content so they align aesthetically.
594 (e (concat cce "\n" (make-string min-indent ? ) 612 (progn
595 ccs "a=m" ce)) 613 (setq ce (comment-string-strip ce t t))
596 ;;(_ (assert (string-match "\\s-*\\(a=m\\)\\s-*" s))) 614 (when (string-match "\\(.+\\).*\n\\(.*?\\)\\1" (concat ce "\n" cs))
597 (fill (make-string (+ (- max-indent 615 (setq eindent
598 min-indent 616 (max (- (match-end 2) (match-beginning 2) (match-beginning 0))
599 (match-beginning 0)) 617 0))))
600 (- (match-end 0) 618 ;; box comment
601 (match-end 1))) 619 (let* ((width (- max-indent min-indent))
602 (aref s (match-end 0))))) 620 (s (concat cs "a=m" cce))
621 (e (concat ccs "a=m" ce))
622 (c (if (string-match ".*\\S-\\S-" cs)
623 (aref cs (1- (match-end 0))) ?=))
624 (_ (assert (string-match "\\s-*a=m\\s-*" s)))
625 (fill
626 (make-string (+ width (- (match-end 0)
627 (match-beginning 0) (length cs) 3)) c)))
603 (setq cs (replace-match fill t t s)) 628 (setq cs (replace-match fill t t s))
604 ;;(assert (string-match "\\s-*\\(a=m\\)\\s-*" e)) 629 (assert (string-match "\\s-*a=m\\s-*" e))
605 (setq ce (replace-match fill t t e))) 630 (setq ce (replace-match fill t t e))))
606 (when (and ce (string-match "\\`\\s-*\\(.*\\S-\\)\\s-*\\'" ce)) 631 (cons (concat cs "\n" (make-string min-indent ? ) ccs)
607 (setq ce (match-string 1 ce))) 632 (concat cce "\n" (make-string (+ min-indent eindent) ? ) ce))))
608 (let* ((c (concat ce "a=m" cs))
609 (indent (if (string-match "\\(.+\\).*a=m\\(.*\\)\\1" c)
610 (max (+ min-indent
611 (- (match-end 2) (match-beginning 2))
612 (- (match-beginning 0)))
613 0)
614 min-indent)))
615 (setq ce (concat cce "\n" (make-string indent ? ) (or ce cs)))
616 (setq cs (concat cs "\n" (make-string min-indent ? ) ccs))))
617 (cons cs ce))
618 633
619 (def-edebug-spec comment-with-narrowing t) 634 (def-edebug-spec comment-with-narrowing t)
620 (put 'comment-with-narrowing 'lisp-indent-function 2) 635 (put 'comment-with-narrowing 'lisp-indent-function 2)
621 (defmacro comment-with-narrowing (beg end &rest body) 636 (defmacro comment-with-narrowing (beg end &rest body)
622 "Execute BODY with BEG..END narrowing. 637 "Execute BODY with BEG..END narrowing.
753 (if (>= beg end) (error "Nothing to comment")) 768 (if (>= beg end) (error "Nothing to comment"))
754 769
755 ;; sanitize LINES 770 ;; sanitize LINES
756 (setq lines 771 (setq lines
757 (and 772 (and
758 lines multi 773 lines ;; multi
759 (progn (goto-char beg) (beginning-of-line) 774 (progn (goto-char beg) (beginning-of-line)
760 (skip-syntax-forward " ") 775 (skip-syntax-forward " ")
761 (>= (point) beg)) 776 (>= (point) beg))
762 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ") 777 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ")
763 (<= (point) end)) 778 (<= (point) end))
790 (defun comment-box (beg end &optional arg) 805 (defun comment-box (beg end &optional arg)
791 "Comment out the BEG..END region, putting it inside a box. 806 "Comment out the BEG..END region, putting it inside a box.
792 The numeric prefix ARG specifies how many characters to add to begin- and 807 The numeric prefix ARG specifies how many characters to add to begin- and
793 end- comment markers additionally to what `comment-add' already specifies." 808 end- comment markers additionally to what `comment-add' already specifies."
794 (interactive "*r\np") 809 (interactive "*r\np")
795 (let ((comment-style 'box)) 810 (let ((comment-style (if (cadr (assoc comment-style comment-styles))
811 'box-multi 'box)))
796 (comment-region beg end (+ comment-add arg)))) 812 (comment-region beg end (+ comment-add arg))))
797 813
798 (defun comment-dwim (arg) 814 (defun comment-dwim (arg)
799 "Call the comment command you want (Do What I Mean). 815 "Call the comment command you want (Do What I Mean).
800 If the region is active and `transient-mark-mode' is on, call 816 If the region is active and `transient-mark-mode' is on, call
920 936
921 (provide 'newcomment) 937 (provide 'newcomment)
922 938
923 ;;; Change Log: 939 ;;; Change Log:
924 ;; $Log: newcomment.el,v $ 940 ;; $Log: newcomment.el,v $
941 ;; Revision 1.11 2000/05/19 15:37:41 monnier
942 ;; Fix license text and author.
943 ;; Move aliases (indent-for-comment, set-comment-column, kill-comment
944 ;; and indent-new-comment-line) to the beginning of the file.
945 ;; Get rid of the last few CLisms.
946 ;; (comment-forward): Avoid decf.
947 ;; (comment-make-extra-lines): Comment-out asserts.
948 ;; (comment-with-narrowing): Properly create uninterned symbol.
949 ;; (comment-region-internal): Comment-out asserts. Avoid incf and decf.
950 ;; (comment-indent-new-line): Fix bug where compt could be set but
951 ;; not comstart. Set comment-column more carefully.
952 ;;
925 ;; Revision 1.10 2000/05/17 19:32:32 monnier 953 ;; Revision 1.10 2000/05/17 19:32:32 monnier
926 ;; (comment-beginning): Handle unclosed comment. 954 ;; (comment-beginning): Handle unclosed comment.
927 ;; (comment-auto-fill-only-comments): New var. 955 ;; (comment-auto-fill-only-comments): New var.
928 ;; (comment-indent-new-line): Obey comment-auto-fill-only-comments. 956 ;; (comment-indent-new-line): Obey comment-auto-fill-only-comments.
929 ;; Align with comment-column rather than previous comment if previous 957 ;; Align with comment-column rather than previous comment if previous