comparison lisp/newcomment.el @ 28901:0e7bbb764f47

(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.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sat, 13 May 2000 19:41:08 +0000
parents 5a4671b4895c
children 8d91ded5215c
comparison
equal deleted inserted replaced
28900:ac620ff5fd5d 28901:0e7bbb764f47
1 ;;; newcomment.el --- (un)comment regions of buffers 1 ;;; newcomment.el --- (un)comment regions of buffers
2 2
3 ;; Copyright (C) 1999 Stefan Monnier <monnier@cs.yale.edu> 3 ;; Copyright (C) 1999-2000 Free Software Foundation Inc.
4 4
5 ;; Author: Stefan Monnier <monnier@cs.yale.edu> 5 ;; Author: FSF??
6 ;; Maintainer: Stefan Monnier <monnier@cs.yale.edu>
6 ;; Keywords: comment uncomment 7 ;; Keywords: comment uncomment
7 ;; Version: $Name: $ 8 ;; Version: $Name: $
8 ;; Revision: $Id: newcomment.el,v 1.5 1999/11/30 16:20:55 monnier Exp $ 9 ;; Revision: $Id: newcomment.el,v 1.6 1999/12/08 00:19:51 monnier Exp $
9 10
10 ;; This program is free software; you can redistribute it and/or modify 11 ;; 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 12 ;; 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 13 ;; the Free Software Foundation; either version 2 of the License, or
13 ;; (at your option) any later version. 14 ;; (at your option) any later version.
21 ;; along with this program; if not, write to the Free Software 22 ;; along with this program; if not, write to the Free Software
22 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 24
24 ;;; Commentary: 25 ;;; Commentary:
25 26
26 ;;; History: 27 ;; A replacement for simple.el's comment-related functions.
27 28
28 ;;; Bugs: 29 ;;; Bugs:
29 30
30 ;; - single-char nestable comment-start can only do the "\\s<+" stuff 31 ;; - single-char nestable comment-start can only do the "\\s<+" stuff
31 ;; if the corresponding closing marker happens to be right. 32 ;; if the corresponding closing marker happens to be right.
32 ;; - C-u C-u comment-region in TeXinfo generates bogus comments @ccccc@ 33 ;; - comment-box in TeXinfo generate bogus comments @ccccc@
33 ;; - the code assumes that bol is outside of any comment/string. 34 ;; - the code assumes that bol is outside of any comment/string.
34 ;; - uncomment-region with a numeric argument can render multichar 35 ;; - uncomment-region with a numeric argument can render multichar
35 ;; comment markers invalid. 36 ;; comment markers invalid.
37 ;; - comment-box in C with a numeric argument generates wrong end-of-line
38 ;; continuation markers.
36 39
37 ;;; Todo: 40 ;;; Todo:
38 41
39 ;; - extract comment data from the syntax-table 42 ;; - try to align tail comments
40 ;; - maybe do the opposite as well (set the syntax-table from other data) 43 ;; - check what c-comment-line-break-function has to say
41 ;; - spill auto-fill of comments onto the end of the next line 44 ;; - spill auto-fill of comments onto the end of the next line
42 ;; - uncomment-region with a consp (for blocks) or somehow make the 45 ;; - uncomment-region with a consp (for blocks) or somehow make the
43 ;; deletion of continuation markers less dangerous 46 ;; deletion of continuation markers less dangerous
44 ;; - drop block-comment-<foo> unless it's really used 47 ;; - drop block-comment-<foo> unless it's really used
45 ;; - uncomment-region on a part of a comment 48 ;; - uncomment-region on a part of a comment
46 ;; - obey the numarg of uncomment-region for continuation markers 49 ;; - obey the numarg of uncomment-region for continuation markers
50 ;; - support gnu-style "multi-line with space in continue"
51 ;; - document string-strip
52 ;; - better document comment-continue (and probably turn it into a
53 ;; simple string).
54 ;; - don't overwrite comment-padding.
55 ;; - better document comment-end-quote. Probably make it better
56 ;; self-sufficient so that other quoting can be used.
57 ;; - comment the padright/padleft.
58 ;; - somehow allow comment-dwim to use the region even if transient-mark-mode
59 ;; is not turned on.
60 ;; - document comment-region-internal
61 ;; - comment-quote-nested should quote both the start and end of comment.
47 62
48 ;;; Code: 63 ;;; Code:
49 64
50 (eval-when-compile (require 'cl)) 65 (eval-when-compile (require 'cl))
51 66
52 (defgroup comment nil 67 (defgroup comment nil
53 "Indenting and filling of comments." 68 "Indenting and filling of comments."
54 :prefix "comment-" 69 :prefix "comment-"
55 :group 'fill) 70 :group 'fill)
56 71
57 (defvar comment-use-syntax 'maybe 72 (defvar comment-use-syntax 'undecided
58 "Non-nil if syntax-tables can be used instead of regexps.") 73 "Non-nil if syntax-tables can be used instead of regexps.
74 Can also be `undecided' which means that a somewhat expensive test will
75 be used to try to determine whether syntax-tables should be trusted
76 to understand comments or not.")
59 77
60 (defcustom comment-column 32 78 (defcustom comment-column 32
61 "*Column to indent right-margin comments to. 79 "*Column to indent right-margin comments to.
62 Setting this variable automatically makes it local to the current buffer. 80 Setting this variable automatically makes it local to the current buffer.
63 Each mode establishes a different default value for this variable; you 81 Each mode establishes a different default value for this variable; you
77 If there are any \\(...\\) pairs, the comment delimiter text is held to begin 95 If there are any \\(...\\) pairs, the comment delimiter text is held to begin
78 at the place matched by the close of the first pair." 96 at the place matched by the close of the first pair."
79 :type '(choice (const :tag "None" nil) 97 :type '(choice (const :tag "None" nil)
80 regexp) 98 regexp)
81 :group 'comment) 99 :group 'comment)
100
82 (defvar comment-end-skip nil 101 (defvar comment-end-skip nil
83 "Regexp to match the end of a comment plus everything up to its body.") 102 "Regexp to match the end of a comment plus everything up to its body.")
84 103
85 (defcustom comment-end "" 104 (defcustom comment-end ""
86 "*String to insert to end a new comment. 105 "*String to insert to end a new comment.
92 "Obsolete variable for function to compute desired indentation for a comment. 111 "Obsolete variable for function to compute desired indentation for a comment.
93 This function is called with no args with point at the beginning of 112 This function is called with no args with point at the beginning of
94 the comment's starting delimiter.") 113 the comment's starting delimiter.")
95 114
96 (defvar comment-indent-function 115 (defvar comment-indent-function
97 '(lambda () comment-column) 116 (lambda () comment-column)
98 "Function to compute desired indentation for a comment. 117 "Function to compute desired indentation for a comment.
99 This function is called with no args with point at the beginning of 118 This function is called with no args with point at the beginning of
100 the comment's starting delimiter.") 119 the comment's starting delimiter.")
101 120
102 (defvar block-comment-start nil) 121 (defvar block-comment-start nil)
103 (defvar block-comment-end nil) 122 (defvar block-comment-end nil)
104 123
105 (defcustom comment-nested 'maybe 124 (defvar comment-quote-nested t
106 "Whether the comments can be nested.") 125 "Non-nil if nested comments should be quoted.
107 (defcustom comment-continue nil 126 This should be locally set by each major mode if needed.")
127
128 (defvar comment-continue nil
108 "Pair of strings to insert for multiline comments.") 129 "Pair of strings to insert for multiline comments.")
109 (defcustom comment-add '(0 . 2) 130 (defvar comment-add 0
110 "How many more chars should be inserted by default.") 131 "How many more chars should be inserted by default.")
111 132
112 (defcustom comment-style 'multi-line 133 (defcustom comment-style 'plain
113 "*Style to be used for inserting comments." 134 "*Style to be used for inserting comments."
114 :group 'comment 135 :group 'comment
115 :type '(choice (const plain) 136 :type '(choice (const plain)
137 (const indent)
116 (const aligned) 138 (const aligned)
117 (const multi-line) 139 (const multi-line)
118 (const extra-line))) 140 (const extra-line)
141 (const box)))
119 (defconst comment-styles 142 (defconst comment-styles
120 '((plain . (nil nil nil)) 143 '((plain . (nil nil nil nil))
121 (aligned . (nil t nil)) 144 (indent . (nil nil nil t))
122 (multi-line . (t nil nil)) 145 (aligned . (nil t nil t))
123 (extra-line . (t nil t))) 146 (multi-line . (t nil nil t))
124 "Possible styles.") 147 (extra-line . (t nil t t))
148 (box . (t t t t)))
149 "Possible styles.
150 (STYLE . (MULTI ALIGN EXTRA INDENT).")
125 151
126 (defcustom comment-padding 1 152 (defcustom comment-padding 1
127 "Number of spaces `comment-region' puts between comment chars and text. 153 "Number of spaces `comment-region' puts between comment chars and text.
128 Can also be a string instead. 154 Can also be a string instead.
129 155
130 Extra spacing between the comment characters and the comment text 156 Extra spacing between the comment characters and the comment text
131 makes the comment easier to read. Default is 1. Nil means 0.") 157 makes the comment easier to read. Default is 1. nil means 0.")
132 158
133 (defcustom comment-multi-line nil 159 (defcustom comment-multi-line nil
134 "*Non-nil means \\[indent-new-comment-line] should continue same comment 160 "*Non-nil means \\[indent-new-comment-line] should continue same comment
135 on new line, with no new terminator or starter. 161 on new line, with no new terminator or starter.
136 This is obsolete because you might as well use \\[newline-and-indent]." 162 This is obsolete because you might as well use \\[newline-and-indent]."
146 "\\(.*?\\)" (if after "\\s-*") 172 "\\(.*?\\)" (if after "\\s-*")
147 "\\'") str) 173 "\\'") str)
148 (match-string 1 str)) 174 (match-string 1 str))
149 175
150 (defun comment-string-reverse (s) 176 (defun comment-string-reverse (s)
151 (comment-string-strip (concat (reverse (string-to-list s))) nil t)) 177 (comment-string-strip (concat (nreverse (string-to-list s))) nil t))
152 178
153 (defun comment-normalize-vars (&optional noerror) 179 (defun comment-normalize-vars (&optional noerror)
154 (if (not comment-start) (or noerror (error "No comment syntax is defined")) 180 (if (not comment-start) (or noerror (error "No comment syntax is defined"))
155 ;; comment-use-syntax 181 ;; comment-use-syntax
156 (when (eq comment-use-syntax 'maybe) 182 (when (eq comment-use-syntax 'undecided)
157 (set (make-local-variable 'comment-use-syntax) 183 (set (make-local-variable 'comment-use-syntax)
158 (let ((st (syntax-table)) 184 (let ((st (syntax-table))
159 (cs comment-start) 185 (cs comment-start)
160 (ce (if (string= "" comment-end) "\n" comment-end))) 186 (ce (if (string= "" comment-end) "\n" comment-end)))
187 ;; Try to skip over a comment using forward-comment
188 ;; to see if the syntax tables properly recognize it.
161 (with-temp-buffer 189 (with-temp-buffer
162 (set-syntax-table st) 190 (set-syntax-table st)
163 (insert cs " hello " ce) 191 (insert cs " hello " ce)
164 (goto-char (point-min))
165 (and (forward-comment 1) (eobp))))))
166 (when (eq comment-nested 'maybe)
167 (set (make-local-variable 'comment-nested)
168 (let ((st (syntax-table))
169 (cs comment-start)
170 (ce (if (string= "" comment-end) "\n" comment-end)))
171 (with-temp-buffer
172 (set-syntax-table st)
173 (insert cs " he " cs " hello " ce " ho " ce)
174 (goto-char (point-min)) 192 (goto-char (point-min))
175 (and (forward-comment 1) (eobp)))))) 193 (and (forward-comment 1) (eobp))))))
176 ;; comment-padding 194 ;; comment-padding
177 (when (integerp comment-padding) 195 (when (integerp comment-padding)
178 (setq comment-padding (make-string comment-padding ? ))) 196 (setq comment-padding (make-string comment-padding ? )))
194 "+\\)\\s-*"))) 212 "+\\)\\s-*")))
195 (unless comment-end-skip 213 (unless comment-end-skip
196 (let ((ce (if (string= "" comment-end) "\n" 214 (let ((ce (if (string= "" comment-end) "\n"
197 (comment-string-strip comment-end t t)))) 215 (comment-string-strip comment-end t t))))
198 (set (make-local-variable 'comment-end-skip) 216 (set (make-local-variable 'comment-end-skip)
199 (concat "\\s-*\\(\\s>" (if comment-nested "+" "") 217 (concat "\\s-*\\(\\s>" (if comment-quote-nested "" "+")
200 "\\|" (regexp-quote (substring ce 0 1)) 218 "\\|" (regexp-quote (substring ce 0 1))
201 (if (or comment-nested (> (length ce) 1)) "+" "") 219 (if (and comment-quote-nested (<= (length ce) 1)) "" "+")
202 (regexp-quote (substring ce 1)) 220 (regexp-quote (substring ce 1))
203 "\\)")))))) 221 "\\)"))))))
204 222
205 (defmacro until (&rest body) 223 (defmacro until (&rest body)
206 (let ((retsym (make-symbol "ret"))) 224 (let ((retsym (make-symbol "ret")))
212 (defun comment-end-quote-re (str &optional re) 230 (defun comment-end-quote-re (str &optional re)
213 "Make a regexp that matches the (potentially quoted) STR comment-end. 231 "Make a regexp that matches the (potentially quoted) STR comment-end.
214 The regexp has one group in it which matches RE right after the 232 The regexp has one group in it which matches RE right after the
215 potential quoting." 233 potential quoting."
216 (setq str (comment-string-strip str t t)) 234 (setq str (comment-string-strip str t t))
217 (when (and (not comment-nested) (> (length str) 1)) 235 (when (and comment-quote-nested (> (length str) 1))
218 (concat (regexp-quote (substring str 0 1)) 236 (concat (regexp-quote (substring str 0 1))
219 "\\\\*\\(" re "\\)" 237 "\\\\*\\(" re "\\)"
220 (regexp-quote (substring str 1))))) 238 (regexp-quote (substring str 1)))))
221 239
222 ;;;; 240 ;;;;
223 ;;;; Navigation 241 ;;;; Navigation
224 ;;;; 242 ;;;;
225 243
226 (defun comment-search-forward (&optional limit noerror) 244 (defun comment-search-forward (&optional limit noerror)
227 "Find a comment start between the point and LIMIT. 245 "Find a comment start between point and LIMIT.
228 Moves the point to inside the comment and returns the position of the 246 Moves point to inside the comment and returns the position of the
229 comment-starter. If no comment is found, moves the point to LIMIT 247 comment-starter. If no comment is found, moves point to LIMIT
230 and raises an error or returns nil of NOERROR is non-nil." 248 and raises an error or returns nil of NOERROR is non-nil."
231 (if (not comment-use-syntax) 249 (if (not comment-use-syntax)
232 (when (re-search-forward comment-start-skip limit noerror) 250 (when (re-search-forward comment-start-skip limit noerror)
233 (or (match-end 1) (match-beginning 0))) 251 (or (match-end 1) (match-beginning 0)))
234 (let ((s (parse-partial-sexp (point) (or limit (point-max)) nil nil nil t))) 252 (let ((s (parse-partial-sexp (point) (or limit (point-max)) nil nil nil t)))
237 (start (nth 8 s)) 255 (start (nth 8 s))
238 (bol (save-excursion (beginning-of-line) (point))) 256 (bol (save-excursion (beginning-of-line) (point)))
239 (end nil)) 257 (end nil))
240 (while (and (null end) (>= (point) bol)) 258 (while (and (null end) (>= (point) bol))
241 (if (looking-at comment-start-skip) 259 (if (looking-at comment-start-skip)
242 (setq end (match-end 0)) 260 (setq end (min (or limit (point-max)) (match-end 0)))
243 (backward-char))) 261 (backward-char)))
244 (goto-char end) 262 (goto-char end)
245 start) 263 start)
246 (unless noerror (error "No comment")))))) 264 (unless noerror (error "No comment"))))))
247 265
248 (defun comment-search-backward (&optional limit noerror) 266 (defun comment-search-backward (&optional limit noerror)
249 "Find a comment start between LIMIT and point. 267 "Find a comment start between LIMIT and point.
250 Moves the point to inside the comment and returns the position of the 268 Moves point to inside the comment and returns the position of the
251 comment-starter. If no comment is found, moves the point to LIMIT 269 comment-starter. If no comment is found, moves point to LIMIT
252 and raises an error or returns nil of NOERROR is non-nil." 270 and raises an error or returns nil of NOERROR is non-nil."
253 (if (not (re-search-backward comment-start-skip limit t)) 271 (if (not (re-search-backward comment-start-skip limit t))
254 (unless noerror (error "No comment")) 272 (unless noerror (error "No comment"))
255 (beginning-of-line) 273 (beginning-of-line)
256 (let* ((end (match-end 0)) 274 (let* ((end (match-end 0))
266 (setq pt (point))) 284 (setq pt (point)))
267 (goto-char pt) 285 (goto-char pt)
268 cs)))) 286 cs))))
269 287
270 (defun comment-beginning () 288 (defun comment-beginning ()
271 "Find the beginning of the inclosing comment. 289 "Find the beginning of the enclosing comment.
272 Returns nil if not inside a comment, else moves the point and returns 290 Returns nil if not inside a comment, else moves point and returns
273 the same as `comment-search-forward'." 291 the same as `comment-search-forward'."
274 (let ((pt (point)) 292 (let ((pt (point))
275 (cs (comment-search-backward nil t))) 293 (cs (comment-search-backward nil t)))
276 (save-excursion 294 (save-excursion
277 (and cs 295 (and cs
293 (setq n -1))) 311 (setq n -1)))
294 (= n 0)))) 312 (= n 0))))
295 313
296 (defun comment-enter-backward () 314 (defun comment-enter-backward ()
297 "Move from the end of a comment to the end of its content. 315 "Move from the end of a comment to the end of its content.
298 The point is assumed to be right at the end of a comment." 316 Point is assumed to be just at the end of a comment."
299 (if (bolp) 317 (if (bolp)
300 ;; comment-end = "" 318 ;; comment-end = ""
301 (progn (backward-char) (skip-syntax-backward " ")) 319 (progn (backward-char) (skip-syntax-backward " "))
302 (let ((end (point))) 320 (let ((end (point)))
303 (beginning-of-line) 321 (beginning-of-line)
326 (error "No comment syntax defined")) 344 (error "No comment syntax defined"))
327 (t (let* ((eolpos (save-excursion (end-of-line) (point))) 345 (t (let* ((eolpos (save-excursion (end-of-line) (point)))
328 cpos indent begpos) 346 cpos indent begpos)
329 (beginning-of-line) 347 (beginning-of-line)
330 (when (setq begpos (comment-search-forward eolpos t)) 348 (when (setq begpos (comment-search-forward eolpos t))
331 (skip-chars-forward
332 (concat (buffer-substring (1- (point)) (point)) " \t"))
333 (setq cpos (point-marker)) 349 (setq cpos (point-marker))
334 (goto-char begpos)) 350 (goto-char begpos))
335 (setq begpos (point)) 351 (setq begpos (point))
336 ;; Compute desired indent. 352 ;; Compute desired indent.
337 (if (= (current-column) 353 (if (= (current-column)
399 "Construct a string composed of STR plus `comment-padding'. 415 "Construct a string composed of STR plus `comment-padding'.
400 It contains N copies of the last non-whitespace chars of STR. 416 It contains N copies of the last non-whitespace chars of STR.
401 If STR already contains padding, the corresponding amount is 417 If STR already contains padding, the corresponding amount is
402 ignored from `comment-padding'. 418 ignored from `comment-padding'.
403 N defaults to 1. 419 N defaults to 1.
404 It N is 're, a regexp is returned instead, that would match 420 If N is `re', a regexp is returned instead, that would match
405 the string for any N." 421 the string for any N."
406 (setq n (or n 0)) 422 (setq n (or n 0))
407 (when (and (stringp str) (not (string= "" str))) 423 (when (and (stringp str) (not (string= "" str)))
408 (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str) 424 (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str)
409 (let ((s (match-string 1 str)) 425 (let ((s (match-string 1 str))
424 "Construct a string composed of `comment-padding' plus STR. 440 "Construct a string composed of `comment-padding' plus STR.
425 It contains N copies of the last non-whitespace chars of STR. 441 It contains N copies of the last non-whitespace chars of STR.
426 If STR already contains padding, the corresponding amount is 442 If STR already contains padding, the corresponding amount is
427 ignored from `comment-padding'. 443 ignored from `comment-padding'.
428 N defaults to 1. 444 N defaults to 1.
429 It N is 're, a regexp is returned instead, that would match 445 If N is `re', a regexp is returned instead, that would match
430 the string for any N." 446 the string for any N."
431 (setq n (or n 0)) 447 (setq n (or n 0))
432 (when (and (stringp str) (not (string= "" str))) 448 (when (and (stringp str) (not (string= "" str)))
433 (string-match "\\`\\s-*" str) 449 (string-match "\\`\\s-*" str)
434 (let ((s (substring str (match-end 0))) 450 (let ((s (substring str (match-end 0)))
435 (pad (concat (substring comment-padding 451 (pad (concat (substring comment-padding
436 (min (- (match-end 0) (match-beginning 0)) 452 (min (- (match-end 0) (match-beginning 0))
437 (length comment-padding))) 453 (length comment-padding)))
438 (match-string 0 str))) 454 (match-string 0 str)))
439 (c (aref str (match-end 0))) 455 (c (aref str (match-end 0)))
440 (multi (or comment-nested (string= comment-end "") 456 (multi (or (not comment-quote-nested) (string= comment-end "")
441 (> (length str) (1+ (match-end 0)))))) 457 (> (length str) (1+ (match-end 0))))))
442 (if (symbolp n) 458 (if (symbolp n)
443 (concat "\\s-*" 459 (concat "\\s-*"
444 (if multi (concat (regexp-quote (string c)) "*")) 460 (if multi (concat (regexp-quote (string c)) "*"))
445 (regexp-quote s)) 461 (regexp-quote s))
540 (- (match-beginning 0))) 556 (- (match-beginning 0)))
541 0) 557 0)
542 min-indent))) 558 min-indent)))
543 (setq ce (concat cce "\n" (make-string indent ? ) (or ce cs))) 559 (setq ce (concat cce "\n" (make-string indent ? ) (or ce cs)))
544 (setq cs (concat cs "\n" (make-string min-indent ? ) ccs)))) 560 (setq cs (concat cs "\n" (make-string min-indent ? ) ccs))))
545 (values cs ce)) 561 (cons cs ce))
546 562
547 (def-edebug-spec comment-with-narrowing t) 563 (def-edebug-spec comment-with-narrowing t)
548 (put 'comment-with-narrowing 'lisp-indent-function 2) 564 (put 'comment-with-narrowing 'lisp-indent-function 2)
549 (defmacro comment-with-narrowing (beg end &rest body) 565 (defmacro comment-with-narrowing (beg end &rest body)
550 "Execute BODY with BEG..END narrowing. 566 "Execute BODY with BEG..END narrowing.
571 (let ((n (min -bindent (- (match-end 0) (match-beginning 0) 1)))) 587 (let ((n (min -bindent (- (match-end 0) (match-beginning 0) 1))))
572 (goto-char (match-beginning 0)) 588 (goto-char (match-beginning 0))
573 (delete-char n) 589 (delete-char n)
574 (decf -bindent n))))))))) 590 (decf -bindent n)))))))))
575 591
576 (defun comment-region-internal (beg end cs ce &optional ccs cce block lines) 592 (defun comment-region-internal (beg end cs ce
593 &optional ccs cce block lines indent)
577 (assert (< beg end)) 594 (assert (< beg end))
578 (let ((no-empty t)) 595 (let ((no-empty t))
579 ;; sanitize ce and cce 596 ;; sanitize ce and cce
580 (if (and (stringp ce) (string= "" ce)) (setq ce nil)) 597 (if (and (stringp ce) (string= "" ce)) (setq ce nil))
581 (if (and (stringp cce) (string= "" cce)) (setq cce nil)) 598 (if (and (stringp cce) (string= "" cce)) (setq cce nil))
598 ;; loop over all lines to find the needed indentations 615 ;; loop over all lines to find the needed indentations
599 (until 616 (until
600 (unless (looking-at "[ \t]*$") 617 (unless (looking-at "[ \t]*$")
601 (setq min-indent (min min-indent (current-indentation)))) 618 (setq min-indent (min min-indent (current-indentation))))
602 (when ce-quote-re 619 (when ce-quote-re
603 (let ((eol (save-excursion (end-of-line) (point)))) 620 (let ((eol (line-end-position)))
604 (while (re-search-forward ce-quote-re eol 'move) 621 (while (re-search-forward ce-quote-re eol 'move)
605 (incf eol) 622 (incf eol)
606 (replace-match "\\" t t nil 1)))) 623 (replace-match "\\" t t nil 1))))
607 (end-of-line) 624 (end-of-line)
608 (setq max-indent (max max-indent (current-column))) 625 (setq max-indent (max max-indent (current-column)))
609 (or (eobp) (progn (forward-line) nil))) 626 (or (eobp) (progn (forward-line) nil)))
610 627
611 ;; inserting ccs can change max-indent by (1- tab-width) 628 ;; inserting ccs can change max-indent by (1- tab-width)
612 (incf max-indent (+ (max (length cs) (length ccs)) -1 tab-width)) 629 (incf max-indent (+ (max (length cs) (length ccs)) -1 tab-width))
630 (unless indent (setq min-indent 0))
613 631
614 ;; make the leading and trailing lines if requested 632 ;; make the leading and trailing lines if requested
615 (when lines 633 (when lines
616 (multiple-value-setq (cs ce) 634 (let ((csce
617 (comment-make-extra-lines 635 (comment-make-extra-lines
618 cs ce ccs cce min-indent max-indent block))) 636 cs ce ccs cce min-indent max-indent block)))
637 (setq cs (car csce))
638 (setq ce (cdr csce))))
619 639
620 (goto-char (point-min)) 640 (goto-char (point-min))
621 ;; Loop over all lines from BEG to END. 641 ;; Loop over all lines from BEG to END.
622 (until 642 (until
623 (unless (and no-empty (looking-at "[ \t]*$")) 643 (unless (and no-empty (looking-at "[ \t]*$"))
643 `comment-start' without trailing spaces and `comment-padding'." 663 `comment-start' without trailing spaces and `comment-padding'."
644 (interactive "*r\nP") 664 (interactive "*r\nP")
645 (comment-normalize-vars) 665 (comment-normalize-vars)
646 (if (> beg end) (let (mid) (setq mid beg beg end end mid))) 666 (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
647 (let* ((numarg (prefix-numeric-value arg)) 667 (let* ((numarg (prefix-numeric-value arg))
648 (add (car comment-add)) 668 (add comment-add)
649 (style (cdr (assoc comment-style comment-styles))) 669 (style (cdr (assoc comment-style comment-styles)))
650 (lines (nth 2 style)) 670 (lines (nth 2 style))
651 (block (nth 1 style)) 671 (block (nth 1 style))
652 (multi (nth 0 style))) 672 (multi (nth 0 style)))
653 (save-excursion 673 (save-excursion
667 (progn (goto-char beg) (beginning-of-line) 687 (progn (goto-char beg) (beginning-of-line)
668 (skip-syntax-forward " ") 688 (skip-syntax-forward " ")
669 (>= (point) beg)) 689 (>= (point) beg))
670 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ") 690 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ")
671 (<= (point) end)) 691 (<= (point) end))
672 (not (string= "" comment-end)) 692 (or (not (string= "" comment-end)) block)
673 (progn (goto-char beg) (search-forward "\n" end t))))) 693 (progn (goto-char beg) (search-forward "\n" end t)))))
674
675 ;; C-u C-u makes a full block
676 (when (and (consp arg) (>= numarg 16))
677 (setq lines t block t add (or (cdr comment-add) 2))
678 (setq arg nil numarg 1))
679 694
680 ;; don't add end-markers just because the user asked for `block' 695 ;; don't add end-markers just because the user asked for `block'
681 (unless (or lines (string= "" comment-end)) (setq block nil)) 696 (unless (or lines (string= "" comment-end)) (setq block nil))
682 697
683 (cond 698 (cond
695 (and s (if (string-match comment-end-skip s) s 710 (and s (if (string-match comment-end-skip s) s
696 (comment-padright comment-end)))) 711 (comment-padright comment-end))))
697 (if multi (comment-padright (car comment-continue) numarg)) 712 (if multi (comment-padright (car comment-continue) numarg))
698 (if multi (comment-padleft (cdr comment-continue) numarg)) 713 (if multi (comment-padleft (cdr comment-continue) numarg))
699 block 714 block
700 lines))))) 715 lines
716 (nth 3 style))))))
717
718 (defun comment-box (beg end &optional arg)
719 "Comment out the BEG..END region, putting it inside a box.
720 The numeric prefix ARG specifies how many characters to add to begin- and
721 end- comment markers additionally to what `comment-add' already specifies."
722 (interactive "*r\np")
723 (let ((comment-style 'box))
724 (comment-region beg end (+ comment-add arg))))
701 725
702 (defun comment-dwim (arg) 726 (defun comment-dwim (arg)
703 "Call the comment command you want. 727 "Call the comment command you want.
704 If the region is active, calls `comment-region' (unless it only consists 728 If the region is active and `transient-mark-mode' is on,
729 calls `comment-region' (unless it only consists
705 in comments, in which case it calls `uncomment-region'). 730 in comments, in which case it calls `uncomment-region').
706 Else, if the current line is empty, insert a comment and indent it. 731 Else, if the current line is empty, insert a comment and indent it.
707 Else call `indent-for-comment' or `kill-comment' if a prefix ARG is specified." 732 Else call `indent-for-comment' or `kill-comment' if a prefix ARG is specified."
708 (interactive "*P") 733 (interactive "*P")
709 (comment-normalize-vars) 734 (comment-normalize-vars)
710 (if mark-active 735 (if (and mark-active transient-mark-mode)
711 (let ((beg (min (point) (mark))) 736 (let ((beg (min (point) (mark)))
712 (end (max (point) (mark)))) 737 (end (max (point) (mark))))
713 (if (save-excursion ;; check for already commented region 738 (if (save-excursion ;; check for already commented region
714 (goto-char beg) 739 (goto-char beg)
715 (comment-forward (point-max)) 740 (comment-forward (point-max))
717 (uncomment-region beg end arg) 742 (uncomment-region beg end arg)
718 (comment-region beg end arg))) 743 (comment-region beg end arg)))
719 (if (save-excursion (beginning-of-line) (not (looking-at "\\s-*$"))) 744 (if (save-excursion (beginning-of-line) (not (looking-at "\\s-*$")))
720 (if arg (kill-comment (and (integerp arg) arg)) (indent-for-comment)) 745 (if arg (kill-comment (and (integerp arg) arg)) (indent-for-comment))
721 (let ((add (if arg (prefix-numeric-value arg) 746 (let ((add (if arg (prefix-numeric-value arg)
722 (if (= (length comment-start) 1) (car comment-add) 0)))) 747 (if (= (length comment-start) 1) comment-add 0))))
723 (insert (comment-padright comment-start add)) 748 (insert (comment-padright comment-start add))
724 (save-excursion 749 (save-excursion
725 (unless (string= "" comment-end) 750 (unless (string= "" comment-end)
726 (insert (comment-padleft comment-end add))) 751 (insert (comment-padleft comment-end add)))
727 (indent-according-to-mode)))))) 752 (indent-according-to-mode))))))
802 827
803 (provide 'newcomment) 828 (provide 'newcomment)
804 829
805 ;;; Change Log: 830 ;;; Change Log:
806 ;; $Log: newcomment.el,v $ 831 ;; $Log: newcomment.el,v $
832 ;; Revision 1.6 1999/12/08 00:19:51 monnier
833 ;; various fixes and gratuitous movements.
834 ;;
807 ;; Revision 1.5 1999/11/30 16:20:55 monnier 835 ;; Revision 1.5 1999/11/30 16:20:55 monnier
808 ;; (comment-style(s)): Replaces comment-extra-lines (and comment-multi-line). 836 ;; (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. 837 ;; (comment-use-syntax): Whether to use the syntax-table or just the regexps.
810 ;; (comment-end-skip): To find the end of the text. 838 ;; (comment-end-skip): To find the end of the text.
811 ;; ... 839 ;; ...