1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-14 16:50:58 +00:00

(comment-string-strip): Strip terminating newlines.

(comment-search-forward): Make LIMIT compulsory.
  If an unterminated string (rather than a comment) is found, try again,
  assuming that the region starts inside a string.
(comment-beginning): Make sure we don't move if we find a comment but
  it's not the one we're in.
(comment-enter-backward): Handle the case where comment-end-skip fails.
(comment-indent): Normalize variables and use line-end-position.
(comment-kill): Use line-end-position.
(comment-spill): Remove.
(comment-indent-new-line): Renamed from indent-new-comment-line.
  Cleaned up old commented-out code.
  Reset comment-continue and comment-end before calling comment-indent.
This commit is contained in:
Stefan Monnier 2000-05-16 22:02:37 +00:00
parent dd6b8ea7a8
commit ad679e458a

View File

@ -6,7 +6,7 @@
;; Maintainer: Stefan Monnier <monnier@cs.yale.edu> ;; Maintainer: Stefan Monnier <monnier@cs.yale.edu>
;; Keywords: comment uncomment ;; Keywords: comment uncomment
;; Version: $Name: $ ;; Version: $Name: $
;; Revision: $Id: newcomment.el,v 1.7 2000/05/13 19:41:08 monnier Exp $ ;; Revision: $Id: newcomment.el,v 1.8 2000/05/14 00:56:10 monnier Exp $
;; This program is free software; you can redistribute it and/or modify ;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by ;; it under the terms of the GNU General Public License as published by
@ -31,7 +31,6 @@
;; - single-char nestable comment-start can only do the "\\s<+" stuff ;; - single-char nestable comment-start can only do the "\\s<+" stuff
;; if the corresponding closing marker happens to be right. ;; if the corresponding closing marker happens to be right.
;; - comment-box in TeXinfo generate bogus comments @ccccc@ ;; - comment-box in TeXinfo generate bogus comments @ccccc@
;; - the code assumes that bol is outside of any comment/string.
;; - uncomment-region with a numeric argument can render multichar ;; - uncomment-region with a numeric argument can render multichar
;; comment markers invalid. ;; comment markers invalid.
@ -47,6 +46,9 @@
;; - support gnu-style "multi-line with space in continue" ;; - support gnu-style "multi-line with space in continue"
;; - somehow allow comment-dwim to use the region even if transient-mark-mode ;; - somehow allow comment-dwim to use the region even if transient-mark-mode
;; is not turned on. ;; is not turned on.
;; - (from c-comment-line-break-function): c-ignore-auto-fill so that you can
;; auto-fill comments but not code. This should probably be moved directly
;; inside do-auto-fill.
;;; Code: ;;; Code:
@ -167,7 +169,7 @@ This is obsolete because you might as well use \\[newline-and-indent]."
(defun comment-string-strip (str beforep afterp) (defun comment-string-strip (str beforep afterp)
"Strip STR of any leading (if BEFOREP) and/or trailing (if AFTERP) space." "Strip STR of any leading (if BEFOREP) and/or trailing (if AFTERP) space."
(string-match (concat "\\`" (if beforep "\\s-*") (string-match (concat "\\`" (if beforep "\\s-*")
"\\(.*?\\)" (if afterp "\\s-*") "\\(.*?\\)" (if afterp "\\s-*\n?")
"\\'") str) "\\'") str)
(match-string 1 str)) (match-string 1 str))
@ -253,7 +255,7 @@ If UNP is non-nil, unquote nested comment markers."
;;;; Navigation ;;;; Navigation
;;;; ;;;;
(defun comment-search-forward (&optional limit noerror) (defun comment-search-forward (limit &optional noerror)
"Find a comment start between point and LIMIT. "Find a comment start between point and LIMIT.
Moves point to inside the comment and returns the position of the Moves point to inside the comment and returns the position of the
comment-starter. If no comment is found, moves point to LIMIT comment-starter. If no comment is found, moves point to LIMIT
@ -261,25 +263,40 @@ and raises an error or returns nil of NOERROR is non-nil."
(if (not comment-use-syntax) (if (not comment-use-syntax)
(when (re-search-forward comment-start-skip limit noerror) (when (re-search-forward comment-start-skip limit noerror)
(or (match-end 1) (match-beginning 0))) (or (match-end 1) (match-beginning 0)))
(let ((s (parse-partial-sexp (point) (or limit (point-max)) nil nil nil t))) (let* ((pt (point))
(if (and (nth 8 s) (not (nth 3 s))) ;; Assume (at first) that pt is outside of any string.
(let ((pt (point)) (s (parse-partial-sexp pt (or limit (point-max)) nil nil nil t)))
(start (nth 8 s)) (when (and (nth 8 s) (nth 3 s))
(bol (save-excursion (beginning-of-line) (point))) ;; The search ended inside a string. Try to see if it
(end nil)) ;; works better when we assume that pt is inside a string.
(while (and (null end) (>= (point) bol)) (setq s (parse-partial-sexp
(if (looking-at comment-start-skip) pt (or limit (point-max)) nil nil
(setq end (min (or limit (point-max)) (match-end 0))) (list nil nil nil (nth 3 s) nil nil nil nil)
(backward-char))) t)))
(goto-char end) (if (not (and (nth 8 s) (not (nth 3 s))))
start) (unless noerror (error "No comment"))
(unless noerror (error "No comment")))))) ;; We found the comment.
(let ((pt (point))
(start (nth 8 s))
(bol (save-excursion (beginning-of-line) (point)))
(end nil))
(while (and (null end) (>= (point) bol))
(if (looking-at comment-start-skip)
(setq end (min (or limit (point-max)) (match-end 0)))
(backward-char)))
(goto-char end)
start)))))
(defun comment-search-backward (&optional limit noerror) (defun comment-search-backward (&optional limit noerror)
"Find a comment start between LIMIT and point. "Find a comment start between LIMIT and point.
Moves point to inside the comment and returns the position of the Moves point to inside the comment and returns the position of the
comment-starter. If no comment is found, moves point to LIMIT comment-starter. If no comment is found, moves point to LIMIT
and raises an error or returns nil of NOERROR is non-nil." and raises an error or returns nil of NOERROR is non-nil."
;; FIXME: If a comment-start appears inside a comment, we may erroneously
;; stop there. This can be rather bad in general, but since
;; comment-search-backward is only used to find the comment-column (in
;; comment-set-column) and to find the comment-start string (via
;; comment-beginning) in indent-new-comment-line, it should be harmless.
(if (not (re-search-backward comment-start-skip limit t)) (if (not (re-search-backward comment-start-skip limit t))
(unless noerror (error "No comment")) (unless noerror (error "No comment"))
(beginning-of-line) (beginning-of-line)
@ -303,10 +320,11 @@ Returns nil if not inside a comment, else moves point and returns
the same as `comment-search-forward'." the same as `comment-search-forward'."
(let ((pt (point)) (let ((pt (point))
(cs (comment-search-backward nil t))) (cs (comment-search-backward nil t)))
(save-excursion (when cs
(and cs (if (save-excursion (goto-char cs) (comment-forward 1) (> (point) pt))
(progn (goto-char cs) (forward-comment 1) (> (point) pt)) cs
cs)))) (goto-char pt)
nil))))
(defun comment-forward (&optional n) (defun comment-forward (&optional n)
"Skip forward over N comments. "Skip forward over N comments.
@ -333,8 +351,15 @@ Point is assumed to be just at the end of a comment."
(beginning-of-line) (beginning-of-line)
(save-restriction (save-restriction
(narrow-to-region (point) end) (narrow-to-region (point) end)
(re-search-forward (concat comment-end-skip "\\'")) (if (re-search-forward (concat comment-end-skip "\\'") nil t)
(goto-char (match-beginning 0)))))) (goto-char (match-beginning 0))
;; comment-end-skip not found probably because it was not set right.
;; Since \\s> should catch the single-char case, we'll blindly
;; assume we're at the end of a two-char comment-end.
(goto-char (point-max))
(backward-char 2)
(skip-chars-backward (string (char-after)))
(skip-syntax-backward " "))))))
;;;; ;;;;
;;;; Commands ;;;; Commands
@ -345,6 +370,7 @@ Point is assumed to be just at the end of a comment."
"Indent this line's comment to comment column, or insert an empty comment. "Indent this line's comment to comment column, or insert an empty comment.
If CONTINUE is non-nil, use the `comment-continuation' markers if any." If CONTINUE is non-nil, use the `comment-continuation' markers if any."
(interactive "*") (interactive "*")
(comment-normalize-vars)
(let* ((empty (save-excursion (beginning-of-line) (let* ((empty (save-excursion (beginning-of-line)
(looking-at "[ \t]*$"))) (looking-at "[ \t]*$")))
(starter (or (and continue comment-continue) (starter (or (and continue comment-continue)
@ -354,7 +380,7 @@ If CONTINUE is non-nil, use the `comment-continuation' markers if any."
(cond (cond
((null starter) ((null starter)
(error "No comment syntax defined")) (error "No comment syntax defined"))
(t (let* ((eolpos (save-excursion (end-of-line) (point))) (t (let* ((eolpos (line-end-position))
cpos indent begpos) cpos indent begpos)
(beginning-of-line) (beginning-of-line)
(when (setq begpos (comment-search-forward eolpos t)) (when (setq begpos (comment-search-forward eolpos t))
@ -389,16 +415,16 @@ With any other arg, set comment column to indentation of the previous comment
and then align or create a comment on this line at that column." and then align or create a comment on this line at that column."
(interactive "P") (interactive "P")
(cond (cond
((eq arg '-) (kill-comment nil)) ((eq arg '-) (comment-kill nil))
(arg (arg
(save-excursion (save-excursion
(beginning-of-line) (beginning-of-line)
(comment-search-backward) (comment-search-backward)
(beginning-of-line) (beginning-of-line)
(goto-char (comment-search-forward)) (goto-char (comment-search-forward (line-end-position)))
(setq comment-column (current-column)) (setq comment-column (current-column))
(message "Comment column set to %d" comment-column)) (message "Comment column set to %d" comment-column))
(indent-for-comment)) (comment-indent))
(t (setq comment-column (current-column)) (t (setq comment-column (current-column))
(message "Comment column set to %d" comment-column)))) (message "Comment column set to %d" comment-column))))
@ -407,21 +433,18 @@ With any other arg, set comment column to indentation of the previous comment
"Kill the comment on this line, if any. "Kill the comment on this line, if any.
With prefix ARG, kill comments on that many lines starting with this one." With prefix ARG, kill comments on that many lines starting with this one."
(interactive "P") (interactive "P")
(let (endc) (dotimes (_ (prefix-numeric-value arg))
(dotimes (_ (prefix-numeric-value arg)) (save-excursion
(save-excursion (beginning-of-line)
(end-of-line) (let ((cs (comment-search-forward (line-end-position) t)))
(setq endc (point)) (when cs
(beginning-of-line) (goto-char cs)
(let ((cs (comment-search-forward endc t))) (skip-syntax-backward " ")
(when cs (setq cs (point))
(goto-char cs) (comment-forward)
(skip-syntax-backward " ") (kill-region cs (if (bolp) (1- (point)) (point)))
(setq cs (point)) (indent-according-to-mode))))
(comment-forward) (if arg (forward-line 1))))
(kill-region cs (if (bolp) (1- (point)) (point)))
(indent-according-to-mode))))
(if arg (forward-line 1)))))
(defun comment-padright (str &optional n) (defun comment-padright (str &optional n)
"Construct a string composed of STR plus `comment-padding'. "Construct a string composed of STR plus `comment-padding'.
@ -561,6 +584,8 @@ comment markers."
(set-marker end nil)))) (set-marker end nil))))
(defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block) (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block)
"Make the leading and trailing extra lines.
This is used for `extra-line' style (or `box' style if BLOCK is specified)."
(if block (if block
(let* ((s (concat cs "a=m" cce "\n" (let* ((s (concat cs "a=m" cce "\n"
(make-string min-indent ? ) ccs)) (make-string min-indent ? ) ccs))
@ -767,12 +792,13 @@ end- comment markers additionally to what `comment-add' already specifies."
(comment-region beg end (+ comment-add arg)))) (comment-region beg end (+ comment-add arg))))
(defun comment-dwim (arg) (defun comment-dwim (arg)
"Call the comment command you want. "Call the comment command you want (Do What I Mean).
If the region is active and `transient-mark-mode' is on, If the region is active and `transient-mark-mode' is on, call
calls `comment-region' (unless it only consists `comment-region' (unless it only consists in comments, in which
in comments, in which case it calls `uncomment-region'). case it calls `uncomment-region').
Else, if the current line is empty, insert a comment and indent it. Else, if the current line is empty, insert a comment and indent it.
Else call `indent-for-comment' or `kill-comment' if a prefix ARG is specified." Else if a prefix ARG is specified, call `comment-kill'.
Else, call `comment-indent'."
(interactive "*P") (interactive "*P")
(comment-normalize-vars) (comment-normalize-vars)
(if (and mark-active transient-mark-mode) (if (and mark-active transient-mark-mode)
@ -785,7 +811,9 @@ Else call `indent-for-comment' or `kill-comment' if a prefix ARG is specified."
(uncomment-region beg end arg) (uncomment-region beg end arg)
(comment-region beg end arg))) (comment-region beg end arg)))
(if (save-excursion (beginning-of-line) (not (looking-at "\\s-*$"))) (if (save-excursion (beginning-of-line) (not (looking-at "\\s-*$")))
(if arg (kill-comment (and (integerp arg) arg)) (indent-for-comment)) ;; FIXME: If there's no comment to kill on this line and ARG is
;; specified, calling comment-kill is not very clever.
(if arg (comment-kill (and (integerp arg) arg)) (comment-indent))
(let ((add (if arg (prefix-numeric-value arg) (let ((add (if arg (prefix-numeric-value arg)
(if (= (length comment-start) 1) comment-add 0)))) (if (= (length comment-start) 1) comment-add 0))))
(insert (comment-padright comment-start add)) (insert (comment-padright comment-start add))
@ -794,10 +822,8 @@ Else call `indent-for-comment' or `kill-comment' if a prefix ARG is specified."
(insert (comment-padleft comment-end add))) (insert (comment-padleft comment-end add)))
(indent-according-to-mode)))))) (indent-according-to-mode))))))
(defcustom comment-spill t (defalias 'indent-new-comment-line 'comment-indent-new-line)
"") (defun comment-indent-new-line (&optional soft)
(defun indent-new-comment-line (&optional soft)
"Break line at point and indent, continuing comment if within one. "Break line at point and indent, continuing comment if within one.
This indents the body of the continued comment This indents the body of the continued comment
under the previous comment line. under the previous comment line.
@ -813,11 +839,9 @@ The inserted newline is marked hard if variable `use-hard-newlines' is true,
unless optional argument SOFT is non-nil." unless optional argument SOFT is non-nil."
(interactive) (interactive)
(comment-normalize-vars t) (comment-normalize-vars t)
(let (comcol comstart) (let (comcol comstart compt)
(skip-chars-backward " \t") (delete-region (progn (skip-chars-backward " \t") (point))
(delete-region (point) (progn (skip-chars-forward " \t") (point)))
(progn (skip-chars-forward " \t")
(point)))
(if soft (insert-and-inherit ?\n) (newline 1)) (if soft (insert-and-inherit ?\n) (newline 1))
(if fill-prefix (if fill-prefix
(progn (progn
@ -826,36 +850,38 @@ unless optional argument SOFT is non-nil."
(unless comment-multi-line (unless comment-multi-line
(save-excursion (save-excursion
(backward-char) (backward-char)
(if (and comment-start (when (and comment-start
(setq comcol (comment-beginning))) (setq compt (comment-beginning)))
;; The old line has a comment and point was inside the comment. ;; The old line has a comment and point was inside the comment.
;; Set WIN to the pos of the comment-start. ;; Indent this line like what we found.
(setq comstart (buffer-substring compt (point)))
;; If comment-start-skip contains a \(...\) pair, (goto-char compt)
;; the real comment delimiter starts at the end of that pair. (setq comcol (current-column)))))
(let ((win comcol)) (if compt
;; But if the comment is empty, look at preceding lines (let* ((comment-column comcol)
;; to find one that has a nonempty comment. (normal-comment
;; (while (and (eolp) (not (bobp)) (string-match (regexp-quote (comment-string-strip
;; (let (opoint) comment-start t t))
;; (beginning-of-line) comstart))
;; (setq opoint (point)) ;; Force comment-continue to be recreated from comment-start.
;; (forward-line -1) (comment-continue nil) ;(if normal-comment comment-continue)
;; (setq win (comment-search-forward opoint t))))) (comment-end
;; Why do we do that ? -sm (if normal-comment comment-end
;; The comment starter is not the normal comment-start
;; Indent this line like what we found. ;; so we can't just use comment-end.
(setq comstart (buffer-substring win (point))) (save-excursion
(goto-char win) (goto-char compt)
(setq comcol (current-column)) (if (not (comment-forward)) comment-end
)))) (comment-string-strip
(if comcol (buffer-substring
(let ((comment-column comcol) (save-excursion (comment-enter-backward) (point))
(comment-start comstart)) (point))
nil t)))))
(comment-start comstart))
;;(if (not (eolp)) (setq comment-end "")) ;;(if (not (eolp)) (setq comment-end ""))
(insert-and-inherit ?\n) (insert-and-inherit ?\n)
(forward-char -1) (forward-char -1)
(indent-for-comment (cadr (assoc comment-style comment-styles))) (comment-indent (cadr (assoc comment-style comment-styles)))
(save-excursion (save-excursion
(let ((pt (point))) (let ((pt (point)))
(end-of-line) (end-of-line)
@ -872,12 +898,28 @@ unless optional argument SOFT is non-nil."
;;; Change Log: ;;; Change Log:
;; $Log: newcomment.el,v $ ;; $Log: newcomment.el,v $
;; Revision 1.8 2000/05/14 00:56:10 monnier
;; (comment-start, comment-start-skip, comment-end): Made `defvar'.
;; (comment-style): Extract the choice out of comment-styles.
;; (comment-continue): Just a simple string now.
;; (comment-normalize-vars): Update for the new comment-continue.
;; (until, comment-end-quote-re): Removed.
;; (comment-quote-re, comment-quote-nested): New functions for quoting.
;; These quote both the end and the start and also work for single-chars.
;; (comment-padright): Added lots of comments.
;; (comment-padleft): Added more comments. Check comment-end rather than
;; STR to determine whether N can be applied or not.
;; (uncomment-region): Rename BLOCK to BOX.
;; Use the new comment-quote-nested.
;; Use only one marker and properly set it back to nil.
;; Be more picky when eliminating continuation markers.
;;
;; Revision 1.7 2000/05/13 19:41:08 monnier ;; Revision 1.7 2000/05/13 19:41:08 monnier
;; (comment-use-syntax): Change `maybe' to `undecided'. ;; (comment-use-syntax): Change `maybe' to `undecided'.
;; (comment-quote-nested): New. Replaces comment-nested. ;; (comment-quote-nested): New. Replaces comment-nested.
;; (comment-add): Turn into a mere defvar or a integer. ;; (comment-add): Turn into a mere defvar or a integer.
;; (comment-style): Change default to `plain'. ;; (comment-style): Change default to `plain'.
;; (comment-styles): Rename `plain' to `indent' and create a new plainer `plain'. ;; (comment-styles): Rename `plain' to `indent' and create a new plainer `plain'
;; (comment-string-reverse): Use nreverse. ;; (comment-string-reverse): Use nreverse.
;; (comment-normalize-vars): Change `maybe' to `undecided', add comments. ;; (comment-normalize-vars): Change `maybe' to `undecided', add comments.
;; Don't infer the setting of comment-nested anymore (the default for ;; Don't infer the setting of comment-nested anymore (the default for