Mercurial > emacs
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 |