diff options
| author | Stefan Monnier | 1999-11-29 00:49:18 +0000 |
|---|---|---|
| committer | Stefan Monnier | 1999-11-29 00:49:18 +0000 |
| commit | 7a0a180a0a512424ed47360bfc9237e70b3ebab4 (patch) | |
| tree | 7d629559d11cc5bcb4077a05f77d837d95a0b4fd | |
| parent | aac88001d4ded0af679bf29b4b36d1141122dc5c (diff) | |
| download | emacs-7a0a180a0a512424ed47360bfc9237e70b3ebab4.tar.gz emacs-7a0a180a0a512424ed47360bfc9237e70b3ebab4.zip | |
(kill-comment): Fixed by rewriting it with syntax-tables rather than regexps
(comment-normalize-vars): Set default (cdr comment-continue)
(comment-end-quote-re): new function taken out of `comment-region-internal'
(uncomment-region): Rewritten using syntax-tables. Also unquotes
nested comment-ends and eliminates continuation markers.
(comment-region-internal): Don't create a default for cce.
Use `comment-end-quote-re'.
| -rw-r--r-- | lisp/newcomment.el | 261 |
1 files changed, 136 insertions, 125 deletions
diff --git a/lisp/newcomment.el b/lisp/newcomment.el index 2cce9386fd7..748330a599c 100644 --- a/lisp/newcomment.el +++ b/lisp/newcomment.el | |||
| @@ -5,7 +5,7 @@ | |||
| 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.1 1999/11/28 18:51:06 monnier Exp $ | 8 | ;; Revision: $Id: newcomment.el,v 1.2 1999/11/28 21:33: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 |
| @@ -39,6 +39,9 @@ | |||
| 39 | ;; - extract comment data from the syntax-table | 39 | ;; - extract comment data from the syntax-table |
| 40 | ;; - 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) |
| 41 | ;; - customizable auto-fill of comments | 41 | ;; - customizable auto-fill of comments |
| 42 | ;; - uncomment-region with a numeric argument | ||
| 43 | ;; - uncomment-region with a consp (for blocks) or somehow make the | ||
| 44 | ;; deletion of continuation markers less dangerous | ||
| 42 | 45 | ||
| 43 | ;;; Code: | 46 | ;;; Code: |
| 44 | 47 | ||
| @@ -173,45 +176,6 @@ With any other arg, set comment column to indentation of the previous comment | |||
| 173 | (setq comment-column (current-column)) | 176 | (setq comment-column (current-column)) |
| 174 | (message "Comment column set to %d" comment-column)))) | 177 | (message "Comment column set to %d" comment-column)))) |
| 175 | 178 | ||
| 176 | (defun kill-comment (arg) | ||
| 177 | "Kill the comment on this line, if any. | ||
| 178 | With argument, kill comments on that many lines starting with this one." | ||
| 179 | ;; this function loses in a lot of situations. it incorrectly recognises | ||
| 180 | ;; comment delimiters sometimes (ergo, inside a string), doesn't work | ||
| 181 | ;; with multi-line comments, can kill extra whitespace if comment wasn't | ||
| 182 | ;; through end-of-line, et cetera. | ||
| 183 | (interactive "P") | ||
| 184 | (or comment-start-skip (error "No comment syntax defined")) | ||
| 185 | (let ((count (prefix-numeric-value arg)) endc) | ||
| 186 | (while (> count 0) | ||
| 187 | (save-excursion | ||
| 188 | (end-of-line) | ||
| 189 | (setq endc (point)) | ||
| 190 | (beginning-of-line) | ||
| 191 | (and (string< "" comment-end) | ||
| 192 | (setq endc | ||
| 193 | (progn | ||
| 194 | (re-search-forward (regexp-quote comment-end) endc 'move) | ||
| 195 | (skip-chars-forward " \t") | ||
| 196 | (point)))) | ||
| 197 | (beginning-of-line) | ||
| 198 | (if (re-search-forward comment-start-skip endc t) | ||
| 199 | (progn | ||
| 200 | (goto-char (match-beginning 0)) | ||
| 201 | (skip-chars-backward " \t") | ||
| 202 | (kill-region (point) endc) | ||
| 203 | ;; to catch comments a line beginnings | ||
| 204 | (indent-according-to-mode)))) | ||
| 205 | (if arg (forward-line 1)) | ||
| 206 | (setq count (1- count))))) | ||
| 207 | |||
| 208 | (defvar comment-padding 1 | ||
| 209 | "Number of spaces `comment-region' puts between comment chars and text. | ||
| 210 | Can also be a string instead. | ||
| 211 | |||
| 212 | Extra spacing between the comment characters and the comment text | ||
| 213 | makes the comment easier to read. Default is 1. Nil means 0.") | ||
| 214 | |||
| 215 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 179 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 216 | 180 | ||
| 217 | (defcustom comment-nested nil | 181 | (defcustom comment-nested nil |
| @@ -228,6 +192,34 @@ If 'multiline, only add them for truly multiline comments.") | |||
| 228 | ;; (defcustom comment-multiline t | 192 | ;; (defcustom comment-multiline t |
| 229 | ;; "non-nil if `comment-region' should use multi-line comments.") | 193 | ;; "non-nil if `comment-region' should use multi-line comments.") |
| 230 | 194 | ||
| 195 | (defvar comment-padding 1 | ||
| 196 | "Number of spaces `comment-region' puts between comment chars and text. | ||
| 197 | Can also be a string instead. | ||
| 198 | |||
| 199 | Extra spacing between the comment characters and the comment text | ||
| 200 | makes the comment easier to read. Default is 1. Nil means 0.") | ||
| 201 | |||
| 202 | (defun kill-comment (arg) | ||
| 203 | "Kill the comment on this line, if any. | ||
| 204 | With prefix ARG, kill comments on that many lines starting with this one." | ||
| 205 | (interactive "P") | ||
| 206 | (let (endc) | ||
| 207 | (dotimes (_ (prefix-numeric-value arg)) | ||
| 208 | (save-excursion | ||
| 209 | (end-of-line) | ||
| 210 | (setq endc (point)) | ||
| 211 | (beginning-of-line) | ||
| 212 | (let ((cs (nth 8 (parse-partial-sexp (point) endc nil nil nil t)))) | ||
| 213 | (when cs | ||
| 214 | (goto-char cs) | ||
| 215 | (skip-syntax-backward " ") | ||
| 216 | (setq cs (point)) | ||
| 217 | (forward-comment 1) | ||
| 218 | (skip-syntax-backward " ") | ||
| 219 | (kill-region cs (if (bolp) (1- (point)) (point))) | ||
| 220 | (indent-according-to-mode)))) | ||
| 221 | (if arg (forward-line 1))))) | ||
| 222 | |||
| 231 | (defun comment-normalize-vars () | 223 | (defun comment-normalize-vars () |
| 232 | (or comment-start (error "No comment syntax is defined")) | 224 | (or comment-start (error "No comment syntax is defined")) |
| 233 | (when (integerp comment-padding) | 225 | (when (integerp comment-padding) |
| @@ -238,11 +230,12 @@ If 'multiline, only add them for truly multiline comments.") | |||
| 238 | (when (string-match "\\`\\s-*\\(.*\\S-\\)\\s-*\\'" comment-end) | 230 | (when (string-match "\\`\\s-*\\(.*\\S-\\)\\s-*\\'" comment-end) |
| 239 | (setq comment-end (match-string 1 comment-end))) | 231 | (setq comment-end (match-string 1 comment-end))) |
| 240 | ;; | 232 | ;; |
| 241 | (let ((csl (length comment-start))) | 233 | (unless (or (car comment-continue) (string= comment-end "")) |
| 242 | (if (not (or comment-continue (string= comment-end ""))) | 234 | (set (make-local-variable 'comment-continue) |
| 243 | (set (make-local-variable 'comment-continue) | 235 | (cons (concat " " (substring comment-start 1)) |
| 244 | (cons (concat " " (substring comment-start 1)) | 236 | nil))) |
| 245 | ""))))) | 237 | (when (and (car comment-continue) (null (cdr comment-continue))) |
| 238 | (setf (cdr comment-continue) (string-reverse (car comment-continue))))) | ||
| 246 | 239 | ||
| 247 | (defmacro until (&rest body) | 240 | (defmacro until (&rest body) |
| 248 | (let ((retsym (make-symbol "ret"))) | 241 | (let ((retsym (make-symbol "ret"))) |
| @@ -253,81 +246,98 @@ If 'multiline, only add them for truly multiline comments.") | |||
| 253 | 246 | ||
| 254 | (defun string-reverse (s) (concat (reverse (string-to-list s)))) | 247 | (defun string-reverse (s) (concat (reverse (string-to-list s)))) |
| 255 | 248 | ||
| 256 | (defun uncomment-region (beg end &optional arg) | 249 | (defun comment-end-quote-re (str &optional re) |
| 257 | "Comment or uncomment each line in the region. | 250 | "Make a regexp that matches the (potentially quoted) STR comment-end. |
| 258 | With just C-u prefix arg, uncomment each line in region. | 251 | The regexp has one group in it which matches RE right after the |
| 259 | Numeric prefix arg ARG means use ARG comment characters. | 252 | potential quoting." |
| 260 | If ARG is negative, delete that many comment characters instead. | 253 | (when (and (not comment-nested) (> (length str) 1)) |
| 261 | Comments are terminated on each line, even for syntax in which newline does | 254 | (concat (regexp-quote (substring str 0 1)) |
| 262 | not end the comment. Blank lines do not get comments. | 255 | "\\\\*\\(" re "\\)" |
| 256 | (regexp-quote (substring str 1))))) | ||
| 263 | 257 | ||
| 264 | The strings used as comment starts are build from | 258 | (defun uncomment-region (beg end &optional arg) |
| 265 | `comment-start' without trailing spaces and `comment-padding'." | 259 | "Uncomment each line in the BEG..END region. |
| 260 | ARG is currently ignored." | ||
| 266 | (interactive "*r\nP") | 261 | (interactive "*r\nP") |
| 267 | (comment-normalize-vars) | 262 | (comment-normalize-vars) |
| 268 | (if (> beg end) (let (mid) (setq mid beg beg end end mid))) | 263 | (if (> beg end) (let (mid) (setq mid beg beg end end mid))) |
| 269 | (save-excursion | 264 | (save-excursion |
| 270 | (save-restriction | 265 | (goto-char beg) |
| 271 | (let* ((cs comment-start) (ce comment-end) | 266 | (unless (markerp end) (setq end (copy-marker end))) |
| 272 | numarg) | 267 | (let ((numarg (prefix-numeric-value arg)) |
| 273 | (if (consp arg) (setq numarg t) | 268 | state spt) |
| 274 | (setq numarg (prefix-numeric-value arg)) | 269 | (while (and (< (point) end) |
| 275 | ;; For positive arg > 1, replicate the comment delims now, | 270 | (setq state (parse-partial-sexp |
| 276 | ;; then insert the replicated strings just once. | 271 | (point) end |
| 277 | (while (> numarg 1) | 272 | nil nil nil t)) |
| 278 | (setq cs (concat cs comment-start) | 273 | (setq spt (nth 8 state))) |
| 279 | ce (concat ce comment-end)) | 274 | (unless (nth 3 state) |
| 280 | (setq numarg (1- numarg)))) | 275 | (let* ((stxt (buffer-substring spt (point))) |
| 281 | ;; Loop over all lines from BEG to END. | 276 | ;; find the end of the comment |
| 282 | (narrow-to-region beg end) | 277 | (ept (progn |
| 283 | (goto-char beg) | 278 | (when (nth 8 (parse-partial-sexp |
| 284 | (cond | 279 | (point) (point-max) |
| 285 | ((consp arg) (comment-region beg end)) | 280 | nil nil state 'syntax-table)) |
| 286 | ((< numarg 0) (comment-region beg end (- numarg))) | 281 | (error "Can't find the comment end")) |
| 287 | (t | 282 | (point-marker))) |
| 288 | (while (not (eobp)) | 283 | ;; find the start of the end-comment |
| 289 | (let (found-comment) | 284 | (_ (while (save-excursion |
| 290 | ;; Delete comment start from beginning of line. | 285 | (nth 8 |
| 291 | (if (eq numarg t) | 286 | (save-restriction |
| 292 | (while (looking-at (regexp-quote cs)) | 287 | (narrow-to-region (point) ept) |
| 293 | (setq found-comment t) | 288 | (parse-partial-sexp (point) ept |
| 294 | (delete-char (length cs))) | 289 | nil nil state)))) |
| 295 | (let ((count numarg)) | 290 | (backward-char))) |
| 296 | (while (and (> 1 (setq count (1+ count))) | 291 | (etxt (buffer-substring (point) ept)) |
| 297 | (looking-at (regexp-quote cs))) | 292 | (end-quote-re (comment-end-quote-re etxt "\\\\"))) |
| 298 | (setq found-comment t) | 293 | (save-restriction |
| 299 | (delete-char (length cs))))) | 294 | (narrow-to-region spt ept) |
| 300 | ;; Delete comment padding from beginning of line | 295 | ;; remove the end-comment (and leading padding and such) |
| 301 | (when (and found-comment comment-padding | 296 | (unless (string= "\n" etxt) |
| 302 | (looking-at (regexp-quote comment-padding))) | 297 | (beginning-of-line) |
| 303 | (delete-char (length comment-padding))) | 298 | (re-search-forward (concat "\\(^\\s-*\\|\\(" |
| 304 | ;; Delete comment end from end of line. | 299 | (regexp-quote comment-padding) |
| 305 | (if (string= "" ce) | 300 | "\\)?\\)" |
| 306 | nil | 301 | (regexp-quote (substring etxt 0 1)) |
| 307 | (if (eq numarg t) | 302 | "+" |
| 308 | (progn | 303 | (regexp-quote (substring etxt 1)) |
| 309 | (end-of-line) | 304 | "\\'")) |
| 310 | ;; This is questionable if comment-end ends in | 305 | (delete-region (match-beginning 0) (match-end 0))) |
| 311 | ;; whitespace. That is pretty brain-damaged, | 306 | |
| 312 | ;; though. | 307 | ;; remove the comment-start |
| 313 | (while (progn (skip-chars-backward " \t") | 308 | (goto-char (point-min)) |
| 314 | (and (>= (- (point) (point-min)) (length ce)) | 309 | (looking-at (concat (regexp-quote stxt) |
| 315 | (save-excursion | 310 | "+\\(\\s-*$\\|" |
| 316 | (backward-char (length ce)) | 311 | (regexp-quote comment-padding) |
| 317 | (looking-at (regexp-quote ce))))) | 312 | "\\)")) |
| 318 | (delete-char (- (length ce))))) | 313 | (delete-region (match-beginning 0) (match-end 0)) |
| 319 | (let ((count numarg)) | 314 | |
| 320 | (while (> 1 (setq count (1+ count))) | 315 | ;; unquote any nested end-comment |
| 321 | (end-of-line) | 316 | (when end-quote-re |
| 322 | ;; this is questionable if comment-end ends in whitespace | 317 | (goto-char (point-min)) |
| 323 | ;; that is pretty brain-damaged though | 318 | (while (re-search-forward end-quote-re nil t) |
| 324 | (skip-chars-backward " \t") | 319 | (delete-region (match-beginning 1) (match-end 1)))) |
| 325 | (if (>= (- (point) (point-min)) (length ce)) | 320 | |
| 326 | (save-excursion | 321 | ;; eliminate continuation markers as well |
| 327 | (backward-char (length ce)) | 322 | (let* ((ccs (car comment-continue)) |
| 328 | (if (looking-at (regexp-quote ce)) | 323 | (cce (cdr comment-continue)) |
| 329 | (delete-char (length ce))))))))) | 324 | (sre (when (and (stringp ccs) (not (string= "" ccs))) |
| 330 | (forward-line 1))))))))) | 325 | (concat |
| 326 | "^\\s-*\\(" (regexp-quote ccs) | ||
| 327 | "+\\(" (regexp-quote comment-padding) | ||
| 328 | "\\)?\\)"))) | ||
| 329 | (ere (when (and (stringp cce) (not (string= "" cce))) | ||
| 330 | (concat | ||
| 331 | "\\(\\(" (regexp-quote comment-padding) | ||
| 332 | "\\)?" (regexp-quote cce) "\\)\\s-*$"))) | ||
| 333 | (re (if (and sre ere) (concat sre "\\|" ere) | ||
| 334 | (or sre ere)))) | ||
| 335 | (when re | ||
| 336 | (goto-char (point-min)) | ||
| 337 | (while (re-search-forward re nil t) | ||
| 338 | (replace-match "" t t nil (if (match-end 1) 1 3))))) | ||
| 339 | ;; go the the end for the next comment | ||
| 340 | (goto-char (point-max))))))))) | ||
| 331 | 341 | ||
| 332 | (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block) | 342 | (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block) |
| 333 | (if block | 343 | (if block |
| @@ -395,23 +405,17 @@ indentation to be kept as it was before narrowing." | |||
| 395 | (if (and (stringp cce) (string= "" cce)) (setq cce nil)) | 405 | (if (and (stringp cce) (string= "" cce)) (setq cce nil)) |
| 396 | ;; should we mark empty lines as well ? | 406 | ;; should we mark empty lines as well ? |
| 397 | (if (or ccs block lines) (setq no-empty nil)) | 407 | (if (or ccs block lines) (setq no-empty nil)) |
| 408 | ;; make sure we have end-markers for BLOCK mode | ||
| 409 | (when block (unless ce (setq ce (string-reverse cs)))) | ||
| 398 | ;; continuation defaults to the same | 410 | ;; continuation defaults to the same |
| 399 | (if ccs (unless block (setq cce nil)) | 411 | (if ccs (unless block (setq cce nil)) |
| 400 | (setq ccs cs cce ce)) | 412 | (setq ccs cs cce ce)) |
| 401 | ;; make sure we have end-markers for BLOCK mode | 413 | |
| 402 | (when block | ||
| 403 | (if (null ce) (setq ce (string-reverse cs))) | ||
| 404 | (if (null cce) (setq cce (string-reverse ccs)))) | ||
| 405 | |||
| 406 | (save-excursion | 414 | (save-excursion |
| 407 | (goto-char end) | 415 | (goto-char end) |
| 408 | (unless (or ce (eolp)) (insert "\n") (indent-according-to-mode)) | 416 | (unless (or ce (eolp)) (insert "\n") (indent-according-to-mode)) |
| 409 | (comment-with-narrowing beg end | 417 | (comment-with-narrowing beg end |
| 410 | (let ((ce-quote-re | 418 | (let ((ce-quote-re (comment-end-quote-re comment-end)) |
| 411 | (when (and (not comment-nested) (> (length comment-end) 1)) | ||
| 412 | (concat (regexp-quote (substring comment-end 0 1)) | ||
| 413 | "\\\\*\\(\\)" | ||
| 414 | (regexp-quote (substring comment-end 1))))) | ||
| 415 | (min-indent (point-max)) | 419 | (min-indent (point-max)) |
| 416 | (max-indent 0)) | 420 | (max-indent 0)) |
| 417 | (goto-char (point-min)) | 421 | (goto-char (point-min)) |
| @@ -532,6 +536,13 @@ The strings used as comment starts are built from | |||
| 532 | 536 | ||
| 533 | ;;; Change Log: | 537 | ;;; Change Log: |
| 534 | ;; $Log: newcomment.el,v $ | 538 | ;; $Log: newcomment.el,v $ |
| 539 | ;; Revision 1.2 1999/11/28 21:33:55 monnier | ||
| 540 | ;; (comment-make-extra-lines): Moved out of comment-region-internal. | ||
| 541 | ;; (comment-with-narrowing): New macro. Provides a way to preserve | ||
| 542 | ;; indentation inside narrowing. | ||
| 543 | ;; (comment-region-internal): Add "\n" to close the comment if necessary. | ||
| 544 | ;; Correctly handle commenting-out when BEG is not bolp. | ||
| 545 | ;; | ||
| 535 | ;; Revision 1.1 1999/11/28 18:51:06 monnier | 546 | ;; Revision 1.1 1999/11/28 18:51:06 monnier |
| 536 | ;; First "working" version: | 547 | ;; First "working" version: |
| 537 | ;; - uncomment-region doesn't work for some unknown reason | 548 | ;; - uncomment-region doesn't work for some unknown reason |