unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Yoni Rabkin Katzenell <yoni-r@actcom.com>
Subject: comment-indent and tail comments
Date: Wed, 09 Aug 2006 11:35:53 +0300	[thread overview]
Message-ID: <874pwm5ms6.fsf@actcom.com> (raw)


I'm using GNU Emacs 22.0.50.1 (i686-pc-linux-gnu, X toolkit, Xaw3d
scroll bars) of 2006-07-23 on ardbeg.

I've noticed that sometimes indenting a region of Lisp code will modify
the buffer (as seen by the ** in the mode line) without actually
changing the contents of the buffer.

After looking at it I got to Line 604 in the function `comment-indent'
which is defined in the file "newcomment.el". Line 604 runs
`delete-region', which modifies the buffer and then runs `indent-to'
which intents to the exact same place as the comment was before.

This only happens with tail comments positioned after a certain column.

I arrived at this conclusion by changing `comment-indent' so that it
would modify the buffer only if the indentation would actually modify
the line in question.

Here is the "instrumented" version of `comment-indent', which I used to
find the problem, the seemingly problematic part starts at "(unless (=
(current-column) indent)", most of the way down the function:

(defun comment-indent (&optional continue)
  "Indent this line's comment to `comment-column', or insert an empty comment.
If CONTINUE is non-nil, use the `comment-continue' markers if any."
  (interactive "*")
  (comment-normalize-vars)
  (let* ((empty (save-excursion (beginning-of-line)
				(looking-at "[ \t]*$")))
	 (before 0)
	 (after 0)
	 (isolate "")
	 (starter (or (and continue comment-continue)
		      (and empty block-comment-start) comment-start))
	 (ender (or (and continue comment-continue "")
		    (and empty block-comment-end) comment-end)))
    (unless starter (error "No comment syntax defined"))
    (beginning-of-line)
    (let* ((eolpos (line-end-position))
	   (begpos (comment-search-forward eolpos t))
	   cpos indent)
      ;; An existing comment?
      (if begpos
	  (progn
	    (if (and (not (looking-at "[\t\n ]"))
		     (looking-at comment-end-skip))
		;; The comment is empty and we have skipped all its space
		;; and landed right before the comment-ender:
		;; Go back to the middle of the space.
		(forward-char (/ (skip-chars-backward " \t") -2)))
	    (setq cpos (point-marker)))
	;; If none, insert one.
	(if comment-insert-comment-function
	    (funcall comment-insert-comment-function)
	  (save-excursion
	    ;; Some `comment-indent-function's insist on not moving
	    ;; comments that are in column 0, so we first go to the
	    ;; likely target column.
	    (indent-to comment-column)
	    ;; Ensure there's a space before the comment for things
	    ;; like sh where it matters (as well as being neater).
	    (unless (memq (char-before) '(nil ?\n ?\t ?\ ))
	      (insert ?\ ))
	    (setq begpos (point))
	    (insert starter)
	    (setq cpos (point-marker))
	    (insert ender))))
      (goto-char begpos)
      ;; Compute desired indent.
      (setq indent (save-excursion (funcall comment-indent-function)))
      ;; If `indent' is nil and there's code before the comment, we can't
      ;; use `indent-according-to-mode', so we default to comment-column.
      (unless (or indent (save-excursion (skip-chars-backward " \t") (bolp)))
	(setq indent comment-column))
      (if (not indent)
	  ;; comment-indent-function refuses: delegate to line-indent.
	  (indent-according-to-mode)
	;; If the comment is at the left of code, adjust the indentation.
	(unless (save-excursion (skip-chars-backward " \t") (bolp))
	  ;; Avoid moving comments past the fill-column.
	  (let ((max (+ (current-column)
			(- (or comment-fill-column fill-column)
			   (save-excursion (end-of-line) (current-column))))))
	    (if (<= max indent)
		(setq indent max)    ;Don't move past the fill column.
	      ;; We can choose anywhere between indent..max.
	      ;; Let's try to align to a comment on the previous line.
	      (let ((other nil)
		    (min (max indent
			      (save-excursion (skip-chars-backward " \t")
					      (1+ (current-column))))))
		(save-excursion
		  (when (and (zerop (forward-line -1))
			     (setq other (comment-search-forward
					  (line-end-position) t)))
		    (goto-char other) (setq other (current-column))))
		(if (and other (<= other max) (>= other min))
		    ;; There is a comment and it's in the range: bingo.
		    (setq indent other)
		  ;; Let's try to align to a comment on the next line, then.
		  (let ((other nil))
		    (save-excursion
		      (when (and (zerop (forward-line 1))
				 (setq other (comment-search-forward
					      (line-end-position) t)))
			(goto-char other) (setq other (current-column))))
		    (if (and other (<= other max) (> other min))
			;; There is a comment and it's in the range: bingo.
			(setq indent other))))))))
	(unless (= (current-column) indent)
	  ;; If that's different from current, change it.
	  ;;
	  ;; since this line is not like the one before or after it,
	  ;; we can deal with it in isolation.
	  (setq before (current-column))
	  (save-excursion
	    (setq isolate 
		  (buffer-substring (point-at-bol) (point-at-eol))))
	  (with-temp-buffer
	    (insert isolate)
	    (goto-char before)
	    (delete-region (point) (progn (skip-chars-backward " \t") (point)))
	    (indent-to (if (bolp) indent
			 (max indent (1+ (current-column)))))
	    (setq after (current-column))
	    (setq isolate
		  (buffer-substring (point-at-bol) (point-at-eol))))
	  (when (not (= before after))
	    (delete-region (point) (progn (skip-chars-backward " \t") (point)))
	    (indent-to (if (bolp) indent
			 (max indent (1+ (current-column))))))))
      (goto-char cpos)
      (set-marker cpos nil))))

-- 
   "Cut your own wood and it will warm you twice"

             reply	other threads:[~2006-08-09  8:35 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-09  8:35 Yoni Rabkin Katzenell [this message]
2006-08-10  1:14 ` comment-indent and tail comments Richard Stallman
2006-08-10 10:21   ` Yoni Rabkin Katzenell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874pwm5ms6.fsf@actcom.com \
    --to=yoni-r@actcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).