comparison lisp/newcomment.el @ 78909:545574ac320d

(comment-choose-indent): New function extracted from comment-indent. Improve the alignment algorithm. (comment-indent): Use it.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 28 Sep 2007 01:59:40 +0000
parents 9355f9b7bbff
children 73661ddc7ac7
comparison
equal deleted inserted replaced
78908:7543ecde159e 78909:545574ac320d
95 :group 'comment) 95 :group 'comment)
96 96
97 ;;;###autoload 97 ;;;###autoload
98 (defcustom comment-column 32 98 (defcustom comment-column 32
99 "Column to indent right-margin comments to. 99 "Column to indent right-margin comments to.
100 Each mode establishes a different default value for this variable; you 100 Each mode may establish a different default value for this variable; you
101 can set the value for a particular mode using that mode's hook. 101 can set the value for a particular mode using that mode's hook.
102 Comments might be indented to a value smaller than this in order 102 Comments might be indented to a different value in order not to go beyond
103 not to go beyond `comment-fill-column'." 103 `comment-fill-column' or in order to align them with surrounding comments."
104 :type 'integer 104 :type 'integer
105 :group 'comment) 105 :group 'comment)
106 (make-variable-buffer-local 'comment-column) 106 (make-variable-buffer-local 'comment-column)
107 ;;;###autoload(put 'comment-column 'safe-local-variable 'integerp) 107 ;;;###autoload(put 'comment-column 'safe-local-variable 'integerp)
108 108
192 (aligned . (nil t nil t)) 192 (aligned . (nil t nil t))
193 (multi-line . (t nil nil t)) 193 (multi-line . (t nil nil t))
194 (extra-line . (t nil t t)) 194 (extra-line . (t nil t t))
195 (box . (nil t t t)) 195 (box . (nil t t t))
196 (box-multi . (t t t t))) 196 (box-multi . (t t t t)))
197 "Possible comment styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)). 197 "Comment region styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)).
198 STYLE should be a mnemonic symbol. 198 STYLE should be a mnemonic symbol.
199 MULTI specifies that comments are allowed to span multiple lines. 199 MULTI specifies that comments are allowed to span multiple lines.
200 ALIGN specifies that the `comment-end' markers should be aligned. 200 ALIGN specifies that the `comment-end' markers should be aligned.
201 EXTRA specifies that an extra line should be used before and after the 201 EXTRA specifies that an extra line should be used before and after the
202 region to comment (to put the `comment-end' and `comment-start'). 202 region to comment (to put the `comment-end' and `comment-start').
206 ;;;###autoload 206 ;;;###autoload
207 (defcustom comment-style 'plain 207 (defcustom comment-style 'plain
208 "Style to be used for `comment-region'. 208 "Style to be used for `comment-region'.
209 See `comment-styles' for a list of available styles." 209 See `comment-styles' for a list of available styles."
210 :type (if (boundp 'comment-styles) 210 :type (if (boundp 'comment-styles)
211 `(choice ,@(mapcar (lambda (s) `(const ,(car s))) comment-styles)) 211 `(choice ,@(mapcar (lambda (s) `(const ,(car s)))
212 comment-styles))
212 'symbol) 213 'symbol)
213 :group 'comment) 214 :group 'comment)
214 215
215 ;;;###autoload 216 ;;;###autoload
216 (defcustom comment-padding " " 217 (defcustom comment-padding " "
514 0 515 0
515 (when (or (/= (current-column) (current-indentation)) 516 (when (or (/= (current-column) (current-indentation))
516 (and (> comment-add 0) (looking-at "\\s<\\(\\S<\\|\\'\\)"))) 517 (and (> comment-add 0) (looking-at "\\s<\\(\\S<\\|\\'\\)")))
517 comment-column))) 518 comment-column)))
518 519
520 (defun comment-choose-indent (&optional indent)
521 "Choose the indentation to use for a right-hand-side comment.
522 The criteria are (in this order):
523 - try to keep the comment's text within `comment-fill-column'.
524 - try to align with surrounding comments.
525 - prefer INDENT (or `comment-column' if nil).
526 Point is expected to be at the start of the comment."
527 (unless indent (setq indent comment-column))
528 ;; Avoid moving comments past the fill-column.
529 (let ((max (+ (current-column)
530 (- (or comment-fill-column fill-column)
531 (save-excursion (end-of-line) (current-column)))))
532 (other nil)
533 (min (save-excursion (skip-chars-backward " \t")
534 (1+ (current-column)))))
535 ;; Fix up the range.
536 (if (< max min) (setq max min))
537 ;; Don't move past the fill column.
538 (if (<= max indent) (setq indent max))
539 ;; We can choose anywhere between min..max.
540 ;; Let's try to align to a comment on the previous line.
541 (save-excursion
542 (when (and (zerop (forward-line -1))
543 (setq other (comment-search-forward
544 (line-end-position) t)))
545 (goto-char other) (setq other (current-column))))
546 (if (and other (<= other max) (>= other min))
547 ;; There is a comment and it's in the range: bingo!
548 other
549 ;; Can't align to a previous comment: let's try to align to comments
550 ;; on the following lines, then. These have not been re-indented yet,
551 ;; so we can't directly align ourselves with them. All we do is to try
552 ;; and choose an indentation point with which they will be able to
553 ;; align themselves.
554 (save-excursion
555 (while (and (zerop (forward-line 1))
556 (setq other (comment-search-forward
557 (line-end-position) t)))
558 (goto-char other)
559 (let ((omax (+ (current-column)
560 (- (or comment-fill-column fill-column)
561 (save-excursion (end-of-line) (current-column)))))
562 (omin (save-excursion (skip-chars-backward " \t")
563 (1+ (current-column)))))
564 (if (and (>= omax min) (<= omin max))
565 (progn (setq min (max omin min))
566 (setq max (min omax max)))
567 ;; Can't align with this anyway, so exit the loop.
568 (goto-char (point-max))))))
569 ;; Return the closest point to indent within min..max.
570 (max min (min max indent)))))
571
519 ;;;###autoload 572 ;;;###autoload
520 (defun comment-indent (&optional continue) 573 (defun comment-indent (&optional continue)
521 "Indent this line's comment to `comment-column', or insert an empty comment. 574 "Indent this line's comment to `comment-column', or insert an empty comment.
522 If CONTINUE is non-nil, use the `comment-continue' markers if any." 575 If CONTINUE is non-nil, use the `comment-continue' markers if any."
523 (interactive "*") 576 (interactive "*")
567 (unless (or indent (save-excursion (skip-chars-backward " \t") (bolp))) 620 (unless (or indent (save-excursion (skip-chars-backward " \t") (bolp)))
568 (setq indent comment-column)) 621 (setq indent comment-column))
569 (if (not indent) 622 (if (not indent)
570 ;; comment-indent-function refuses: delegate to line-indent. 623 ;; comment-indent-function refuses: delegate to line-indent.
571 (indent-according-to-mode) 624 (indent-according-to-mode)
572 ;; If the comment is at the left of code, adjust the indentation. 625 ;; If the comment is at the right of code, adjust the indentation.
573 (unless (save-excursion (skip-chars-backward " \t") (bolp)) 626 (unless (save-excursion (skip-chars-backward " \t") (bolp))
574 ;; Avoid moving comments past the fill-column. 627 (setq indent (comment-choose-indent indent)))
575 (let ((max (+ (current-column)
576 (- (or comment-fill-column fill-column)
577 (save-excursion (end-of-line) (current-column))))))
578 (if (<= max indent)
579 (setq indent max) ;Don't move past the fill column.
580 ;; We can choose anywhere between indent..max.
581 ;; Let's try to align to a comment on the previous line.
582 (let ((other nil)
583 (min (max indent
584 (save-excursion (skip-chars-backward " \t")
585 (1+ (current-column))))))
586 (save-excursion
587 (when (and (zerop (forward-line -1))
588 (setq other (comment-search-forward
589 (line-end-position) t)))
590 (goto-char other) (setq other (current-column))))
591 (if (and other (<= other max) (>= other min))
592 ;; There is a comment and it's in the range: bingo.
593 (setq indent other)
594 ;; Let's try to align to a comment on the next line, then.
595 (let ((other nil))
596 (save-excursion
597 (when (and (zerop (forward-line 1))
598 (setq other (comment-search-forward
599 (line-end-position) t)))
600 (goto-char other) (setq other (current-column))))
601 (if (and other (<= other max) (> other min))
602 ;; There is a comment and it's in the range: bingo.
603 (setq indent other))))))))
604 ;; Update INDENT to leave at least one space 628 ;; Update INDENT to leave at least one space
605 ;; after other nonwhite text on the line. 629 ;; after other nonwhite text on the line.
606 (save-excursion 630 (save-excursion
607 (skip-chars-backward " \t") 631 (skip-chars-backward " \t")
608 (unless (bolp) 632 (unless (bolp)
1018 (let* ((numarg (prefix-numeric-value arg)) 1042 (let* ((numarg (prefix-numeric-value arg))
1019 (style (cdr (assoc comment-style comment-styles))) 1043 (style (cdr (assoc comment-style comment-styles)))
1020 (lines (nth 2 style)) 1044 (lines (nth 2 style))
1021 (block (nth 1 style)) 1045 (block (nth 1 style))
1022 (multi (nth 0 style))) 1046 (multi (nth 0 style)))
1023 ;; we use `chars' instead of `syntax' because `\n' might be 1047
1048 ;; We use `chars' instead of `syntax' because `\n' might be
1024 ;; of end-comment syntax rather than of whitespace syntax. 1049 ;; of end-comment syntax rather than of whitespace syntax.
1025 ;; sanitize BEG and END 1050 ;; sanitize BEG and END
1026 (goto-char beg) (skip-chars-forward " \t\n\r") (beginning-of-line) 1051 (goto-char beg) (skip-chars-forward " \t\n\r") (beginning-of-line)
1027 (setq beg (max beg (point))) 1052 (setq beg (max beg (point)))
1028 (goto-char end) (skip-chars-backward " \t\n\r") (end-of-line) 1053 (goto-char end) (skip-chars-backward " \t\n\r") (end-of-line)