comparison lisp/newcomment.el @ 26763:5a4671b4895c

various fixes and gratuitous movements.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 08 Dec 1999 00:19:51 +0000
parents 9979145a424e
children 0e7bbb764f47
comparison
equal deleted inserted replaced
26762:46f1294a19db 26763:5a4671b4895c
3 ;; Copyright (C) 1999 Stefan Monnier <monnier@cs.yale.edu> 3 ;; Copyright (C) 1999 Stefan Monnier <monnier@cs.yale.edu>
4 4
5 ;; Author: Stefan Monnier <monnier@cs.yale.edu> 5 ;; Author: Stefan Monnier <monnier@cs.yale.edu>
6 ;; Keywords: comment uncomment 6 ;; Keywords: comment uncomment
7 ;; Version: $Name: $ 7 ;; Version: $Name: $
8 ;; Revision: $Id: newcomment.el,v 1.4 1999/11/29 01:31:47 monnier Exp $ 8 ;; Revision: $Id: newcomment.el,v 1.5 1999/11/30 16:20:55 monnier Exp $
9 9
10 ;; This program is free software; you can redistribute it and/or modify 10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by 11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2 of the License, or 12 ;; the Free Software Foundation; either version 2 of the License, or
13 ;; (at your option) any later version. 13 ;; (at your option) any later version.
28 ;;; Bugs: 28 ;;; Bugs:
29 29
30 ;; - single-char nestable comment-start can only do the "\\s<+" stuff 30 ;; - single-char nestable comment-start can only do the "\\s<+" stuff
31 ;; if the corresponding closing marker happens to be right. 31 ;; if the corresponding closing marker happens to be right.
32 ;; - C-u C-u comment-region in TeXinfo generates bogus comments @ccccc@ 32 ;; - C-u C-u comment-region in TeXinfo generates bogus comments @ccccc@
33 ;; - removal of comment-continue does not necesarily work because the 33 ;; - the code assumes that bol is outside of any comment/string.
34 ;; continuation marker could have a leading space that turned into a tab 34 ;; - uncomment-region with a numeric argument can render multichar
35 ;; comment markers invalid.
35 36
36 ;;; Todo: 37 ;;; Todo:
37 38
38 ;; - extract comment data from the syntax-table 39 ;; - extract comment data from the syntax-table
39 ;; - maybe do the opposite as well (set the syntax-table from other data) 40 ;; - maybe do the opposite as well (set the syntax-table from other data)
40 ;; - customizable auto-fill of comments 41 ;; - spill auto-fill of comments onto the end of the next line
41 ;; - uncomment-region with a numeric argument
42 ;; - uncomment-region with a consp (for blocks) or somehow make the 42 ;; - uncomment-region with a consp (for blocks) or somehow make the
43 ;; deletion of continuation markers less dangerous 43 ;; deletion of continuation markers less dangerous
44 ;; - drop block-comment-<foo> unless it's really used 44 ;; - drop block-comment-<foo> unless it's really used
45 ;; - uncomment-region un a part of a comment 45 ;; - uncomment-region on a part of a comment
46 46 ;; - obey the numarg of uncomment-region for continuation markers
47 ;;; Problems:
48
49 ;; - comment padding: (= comment-start "[- ") can either mean that
50 ;; the syntax of a comment-start is "[-" plus " " of padding
51 ;; (as is the case for C) or that the space is strictly required
52 ;; as is the case for TeXinfo.
53 47
54 ;;; Code: 48 ;;; Code:
55 49
56 (eval-when-compile (require 'cl)) 50 (eval-when-compile (require 'cl))
57 51
58 (defcustom comment-use-syntax 'maybe 52 (defgroup comment nil
53 "Indenting and filling of comments."
54 :prefix "comment-"
55 :group 'fill)
56
57 (defvar comment-use-syntax 'maybe
59 "Non-nil if syntax-tables can be used instead of regexps.") 58 "Non-nil if syntax-tables can be used instead of regexps.")
60 59
61 (defcustom comment-column 32 60 (defcustom comment-column 32
62 "*Column to indent right-margin comments to. 61 "*Column to indent right-margin comments to.
63 Setting this variable automatically makes it local to the current buffer. 62 Setting this variable automatically makes it local to the current buffer.
64 Each mode establishes a different default value for this variable; you 63 Each mode establishes a different default value for this variable; you
65 can set the value for a particular mode using that mode's hook." 64 can set the value for a particular mode using that mode's hook."
66 :type 'integer 65 :type 'integer
67 :group 'fill-comments) 66 :group 'comment)
68 (make-variable-buffer-local 'comment-column) 67 (make-variable-buffer-local 'comment-column)
69 68
70 (defcustom comment-start nil 69 (defcustom comment-start nil
71 "*String to insert to start a new comment, or nil if no comment syntax." 70 "*String to insert to start a new comment, or nil if no comment syntax."
72 :type '(choice (const :tag "None" nil) 71 :type '(choice (const :tag "None" nil)
73 string) 72 string)
74 :group 'fill-comments) 73 :group 'comment)
75 74
76 (defcustom comment-start-skip nil 75 (defcustom comment-start-skip nil
77 "*Regexp to match the start of a comment plus everything up to its body. 76 "*Regexp to match the start of a comment plus everything up to its body.
78 If there are any \\(...\\) pairs, the comment delimiter text is held to begin 77 If there are any \\(...\\) pairs, the comment delimiter text is held to begin
79 at the place matched by the close of the first pair." 78 at the place matched by the close of the first pair."
80 :type '(choice (const :tag "None" nil) 79 :type '(choice (const :tag "None" nil)
81 regexp) 80 regexp)
82 :group 'fill-comments) 81 :group 'comment)
83 (defcustom comment-end-skip nil 82 (defvar comment-end-skip nil
84 "*Regexp to match the end of a comment plus everything up to its body." 83 "Regexp to match the end of a comment plus everything up to its body.")
85 :type '(choice (const :tag "None" nil)
86 regexp)
87 :group 'fill-comments)
88 84
89 (defcustom comment-end "" 85 (defcustom comment-end ""
90 "*String to insert to end a new comment. 86 "*String to insert to end a new comment.
91 Should be an empty string if comments are terminated by end-of-line." 87 Should be an empty string if comments are terminated by end-of-line."
92 :type 'string 88 :type 'string
93 :group 'fill-comments) 89 :group 'comment)
94 90
95 (defvar comment-indent-hook nil 91 (defvar comment-indent-hook nil
96 "Obsolete variable for function to compute desired indentation for a comment. 92 "Obsolete variable for function to compute desired indentation for a comment.
97 This function is called with no args with point at the beginning of 93 This function is called with no args with point at the beginning of
98 the comment's starting delimiter.") 94 the comment's starting delimiter.")
101 '(lambda () comment-column) 97 '(lambda () comment-column)
102 "Function to compute desired indentation for a comment. 98 "Function to compute desired indentation for a comment.
103 This function is called with no args with point at the beginning of 99 This function is called with no args with point at the beginning of
104 the comment's starting delimiter.") 100 the comment's starting delimiter.")
105 101
106 (defcustom block-comment-start nil 102 (defvar block-comment-start nil)
107 "*String to insert to start a new comment on a line by itself. 103 (defvar block-comment-end nil)
108 If nil, use `comment-start' instead.
109 Note that the regular expression `comment-start-skip' should skip this string
110 as well as the `comment-start' string."
111 :type '(choice (const :tag "Use comment-start" nil)
112 string)
113 :group 'fill-comments)
114
115 (defcustom block-comment-end nil
116 "*String to insert to end a new comment on a line by itself.
117 Should be an empty string if comments are terminated by end-of-line.
118 If nil, use `comment-end' instead."
119 :type '(choice (const :tag "Use comment-end" nil)
120 string)
121 :group 'fill-comments)
122 104
123 (defcustom comment-nested 'maybe 105 (defcustom comment-nested 'maybe
124 "Whether the comments can be nested.") 106 "Whether the comments can be nested.")
125 (defcustom comment-continue nil 107 (defcustom comment-continue nil
126 "Pair of strings to insert for multiline comments.") 108 "Pair of strings to insert for multiline comments.")
139 (aligned . (nil t nil)) 121 (aligned . (nil t nil))
140 (multi-line . (t nil nil)) 122 (multi-line . (t nil nil))
141 (extra-line . (t nil t))) 123 (extra-line . (t nil t)))
142 "Possible styles.") 124 "Possible styles.")
143 125
144 (defvar comment-padding 1 126 (defcustom comment-padding 1
145 "Number of spaces `comment-region' puts between comment chars and text. 127 "Number of spaces `comment-region' puts between comment chars and text.
146 Can also be a string instead. 128 Can also be a string instead.
147 129
148 Extra spacing between the comment characters and the comment text 130 Extra spacing between the comment characters and the comment text
149 makes the comment easier to read. Default is 1. Nil means 0.") 131 makes the comment easier to read. Default is 1. Nil means 0.")
132
133 (defcustom comment-multi-line nil
134 "*Non-nil means \\[indent-new-comment-line] should continue same comment
135 on new line, with no new terminator or starter.
136 This is obsolete because you might as well use \\[newline-and-indent]."
137 :type 'boolean
138 :group 'comment)
150 139
151 ;;;; 140 ;;;;
152 ;;;; Helpers 141 ;;;; Helpers
153 ;;;; 142 ;;;;
154 143
319 308
320 ;;;; 309 ;;;;
321 ;;;; Commands 310 ;;;; Commands
322 ;;;; 311 ;;;;
323 312
324 (defun indent-for-comment (&optional continue) 313 (defalias 'indent-for-comment 'comment-indent)
314 (defun comment-indent (&optional continue)
325 "Indent this line's comment to comment column, or insert an empty comment. 315 "Indent this line's comment to comment column, or insert an empty comment.
326 If CONTINUE is non-nil, use the `comment-continuation' markers if any." 316 If CONTINUE is non-nil, use the `comment-continuation' markers if any."
327 (interactive "*") 317 (interactive "*")
328 (let* ((empty (save-excursion (beginning-of-line) 318 (let* ((empty (save-excursion (beginning-of-line)
329 (looking-at "[ \t]*$"))) 319 (looking-at "[ \t]*$")))
360 ;; No, insert one. 350 ;; No, insert one.
361 (insert starter) 351 (insert starter)
362 (save-excursion 352 (save-excursion
363 (insert ender)))))))) 353 (insert ender))))))))
364 354
365 (defun set-comment-column (arg) 355 (defalias 'set-comment-column 'comment-set-column)
356 (defun comment-set-column (arg)
366 "Set the comment column based on point. 357 "Set the comment column based on point.
367 With no ARG, set the comment column to the current column. 358 With no ARG, set the comment column to the current column.
368 With just minus as arg, kill any comment on this line. 359 With just minus as arg, kill any comment on this line.
369 With any other arg, set comment column to indentation of the previous comment 360 With any other arg, set comment column to indentation of the previous comment
370 and then align or create a comment on this line at that column." 361 and then align or create a comment on this line at that column."
381 (message "Comment column set to %d" comment-column)) 372 (message "Comment column set to %d" comment-column))
382 (indent-for-comment)) 373 (indent-for-comment))
383 (t (setq comment-column (current-column)) 374 (t (setq comment-column (current-column))
384 (message "Comment column set to %d" comment-column)))) 375 (message "Comment column set to %d" comment-column))))
385 376
386 (defun kill-comment (arg) 377 (defalias 'kill-comment 'comment-kill)
378 (defun comment-kill (arg)
387 "Kill the comment on this line, if any. 379 "Kill the comment on this line, if any.
388 With prefix ARG, kill comments on that many lines starting with this one." 380 With prefix ARG, kill comments on that many lines starting with this one."
389 (interactive "P") 381 (interactive "P")
390 (let (endc) 382 (let (endc)
391 (dotimes (_ (prefix-numeric-value arg)) 383 (dotimes (_ (prefix-numeric-value arg))
411 N defaults to 1. 403 N defaults to 1.
412 It N is 're, a regexp is returned instead, that would match 404 It N is 're, a regexp is returned instead, that would match
413 the string for any N." 405 the string for any N."
414 (setq n (or n 0)) 406 (setq n (or n 0))
415 (when (and (stringp str) (not (string= "" str))) 407 (when (and (stringp str) (not (string= "" str)))
416 (string-match "\\s-*\\'" str) 408 (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str)
417 (let ((s (substring str 0 (match-beginning 0))) 409 (let ((s (match-string 1 str))
418 (pad (concat (match-string 0 str) 410 (lpad (substring str 0 (match-beginning 1)))
419 (substring comment-padding 411 (rpad (concat (substring str (match-end 1))
420 (min (- (match-end 0) (match-beginning 0)) 412 (substring comment-padding
421 (length comment-padding)))))) 413 (min (- (match-end 0) (match-end 1))
414 (length comment-padding))))))
422 (if (symbolp n) 415 (if (symbolp n)
423 (concat (regexp-quote s) "+" 416 (concat (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
417 lpad "")
418 (regexp-quote s) "+"
424 (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?")) 419 (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?"))
425 pad "")) 420 rpad ""))
426 (concat s (make-string n (aref str (1- (match-beginning 0)))) pad))))) 421 (concat lpad s (make-string n (aref str (1- (match-end 1)))) rpad)))))
427 422
428 (defun comment-padleft (str &optional n) 423 (defun comment-padleft (str &optional n)
429 "Construct a string composed of `comment-padding' plus STR. 424 "Construct a string composed of `comment-padding' plus STR.
430 It contains N copies of the last non-whitespace chars of STR. 425 It contains N copies of the last non-whitespace chars of STR.
431 If STR already contains padding, the corresponding amount is 426 If STR already contains padding, the corresponding amount is
472 (point-marker))) 467 (point-marker)))
473 (block nil) 468 (block nil)
474 (end-quote-re (comment-end-quote-re comment-end "\\\\")) 469 (end-quote-re (comment-end-quote-re comment-end "\\\\"))
475 (ccs (car comment-continue)) 470 (ccs (car comment-continue))
476 (srei (comment-padright ccs 're)) 471 (srei (comment-padright ccs 're))
477 (sre (and srei (concat "^\\s-*\\(" srei "\\)")))) 472 (sre (and srei (concat "^\\s-*?\\(" srei "\\)"))))
478 (save-restriction 473 (save-restriction
479 (narrow-to-region spt ept) 474 (narrow-to-region spt ept)
480 ;; remove the comment-start 475 ;; remove the comment-start
481 (goto-char ipt) 476 (goto-char ipt)
482 (skip-syntax-backward " ") 477 (skip-syntax-backward " ")
484 (setq block t)) 479 (setq block t))
485 (when (looking-at (regexp-quote comment-padding)) 480 (when (looking-at (regexp-quote comment-padding))
486 (goto-char (match-end 0))) 481 (goto-char (match-end 0)))
487 (when (and sre (looking-at (concat "\\s-*\n\\s-*" srei))) 482 (when (and sre (looking-at (concat "\\s-*\n\\s-*" srei)))
488 (goto-char (match-end 0))) 483 (goto-char (match-end 0)))
489 (delete-region (point-min) (point)) 484 (if (null arg) (delete-region (point-min) (point))
485 (skip-syntax-backward " ")
486 (delete-char (- numarg)))
490 487
491 ;; remove the end-comment (and leading padding and such) 488 ;; remove the end-comment (and leading padding and such)
492 (goto-char (point-max)) (comment-enter-backward) 489 (goto-char (point-max)) (comment-enter-backward)
493 (unless (string-match "\\`\\(\n\\|\\s-\\)*\\'" 490 (unless (string-match "\\`\\(\n\\|\\s-\\)*\\'"
494 (buffer-substring (point) ept)) 491 (buffer-substring (point) ept))
495 (when (and (bolp) (not (bobp))) (backward-char)) 492 (when (and (bolp) (not (bobp))) (backward-char))
496 (delete-region (point) ept)) 493 (if (null arg) (delete-region (point) ept)
494 (skip-syntax-forward " ")
495 (delete-char numarg)))
497 496
498 ;; unquote any nested end-comment 497 ;; unquote any nested end-comment
499 (when end-quote-re 498 (when end-quote-re
500 (goto-char (point-min)) 499 (goto-char (point-min))
501 (while (re-search-forward end-quote-re nil t) 500 (while (re-search-forward end-quote-re nil t)
687 (t 686 (t
688 (if (and (null arg) (= (length comment-start) 1)) 687 (if (and (null arg) (= (length comment-start) 1))
689 (setq numarg add) (decf numarg)) 688 (setq numarg add) (decf numarg))
690 (comment-region-internal 689 (comment-region-internal
691 beg end 690 beg end
692 (comment-padright comment-start numarg) 691 (let ((s (comment-padright comment-start numarg)))
693 (comment-padleft comment-end numarg) 692 (if (string-match comment-start-skip s) s
693 (comment-padright comment-start)))
694 (let ((s (comment-padleft comment-end numarg)))
695 (and s (if (string-match comment-end-skip s) s
696 (comment-padright comment-end))))
694 (if multi (comment-padright (car comment-continue) numarg)) 697 (if multi (comment-padright (car comment-continue) numarg))
695 (if multi (comment-padleft (cdr comment-continue) numarg)) 698 (if multi (comment-padleft (cdr comment-continue) numarg))
696 block 699 block
697 lines))))) 700 lines)))))
698 701
721 (save-excursion 724 (save-excursion
722 (unless (string= "" comment-end) 725 (unless (string= "" comment-end)
723 (insert (comment-padleft comment-end add))) 726 (insert (comment-padleft comment-end add)))
724 (indent-according-to-mode)))))) 727 (indent-according-to-mode))))))
725 728
726 (defcustom comment-multi-line nil 729 (defcustom comment-spill t
727 "*Non-nil means \\[indent-new-comment-line] should continue same comment 730 "")
728 on new line, with no new terminator or starter.
729 This is obsolete because you might as well use \\[newline-and-indent]."
730 :type 'boolean
731 :group 'fill-comments)
732 731
733 (defun indent-new-comment-line (&optional soft) 732 (defun indent-new-comment-line (&optional soft)
734 "Break line at point and indent, continuing comment if within one. 733 "Break line at point and indent, continuing comment if within one.
735 This indents the body of the continued comment 734 This indents the body of the continued comment
736 under the previous comment line. 735 under the previous comment line.
803 802
804 (provide 'newcomment) 803 (provide 'newcomment)
805 804
806 ;;; Change Log: 805 ;;; Change Log:
807 ;; $Log: newcomment.el,v $ 806 ;; $Log: newcomment.el,v $
807 ;; Revision 1.5 1999/11/30 16:20:55 monnier
808 ;; (comment-style(s)): Replaces comment-extra-lines (and comment-multi-line).
809 ;; (comment-use-syntax): Whether to use the syntax-table or just the regexps.
810 ;; (comment-end-skip): To find the end of the text.
811 ;; ...
812 ;;
808 ;; Revision 1.4 1999/11/29 01:31:47 monnier 813 ;; Revision 1.4 1999/11/29 01:31:47 monnier
809 ;; (comment-find): New function. 814 ;; (comment-find): New function.
810 ;; (indent-for-comment, set-comment-column, kill-comment): use it. 815 ;; (indent-for-comment, set-comment-column, kill-comment): use it.
811 ;; 816 ;;
812 ;; Revision 1.3 1999/11/29 00:49:18 monnier 817 ;; Revision 1.3 1999/11/29 00:49:18 monnier
832 ;; - comment-extra-lines allows yet another style choice 837 ;; - comment-extra-lines allows yet another style choice
833 ;; - comment-add allows to default to `;;' 838 ;; - comment-add allows to default to `;;'
834 ;; - comment-region on a comment calls uncomment-region 839 ;; - comment-region on a comment calls uncomment-region
835 ;; - C-u C-u comment-region aligns comment end markers 840 ;; - C-u C-u comment-region aligns comment end markers
836 ;; - C-u C-u C-u comment-region puts the comment inside a rectangle 841 ;; - C-u C-u C-u comment-region puts the comment inside a rectangle
837 ;; - comment-region will try to quote coment-end markers inside the region 842 ;; - comment-region will try to quote comment-end markers inside the region
838 ;; - comment-start markers are placed at the indentation level 843 ;; - comment-start markers are placed at the indentation level
839 ;; 844 ;;
840 845
841 ;;; newcomment.el ends here 846 ;;; newcomment.el ends here