bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#21072: 24.5; inconsistent behaviour of `C-M-h (mark-defun)' in Emacs


From: Marcin Borkowski
Subject: bug#21072: 24.5; inconsistent behaviour of `C-M-h (mark-defun)' in Emacs Lisp
Date: Tue, 11 Oct 2016 19:07:47 +0200
User-agent: mu4e 0.9.17; emacs 26.0.50.1

On 2016-10-11, at 17:30, Drew Adams <drew.adams@oracle.com> wrote:

>> Basically, I took into consideration all the points Drew mentioned.  I'd
>> like to submit my work for review.
>
> Thanks for working on this, Marcin.

You're welcome.

BTW, as I probably already mentioned, while working on this, I found
a bug in end-of-defun, and until it's fixed, I have to use a silly
workaround.

>> I have one technical problem,
>> though: I have it as a series of commits on a separate branch in my
>> repo, and I'm not Git-literate enough to make one patch from them.
>
> Hopefully someone else can help with that.

I'd hope so!

> (For my part, if the code needed is small and you just include it here
> then I will give it a try and let you know what I think (FWIW).)

Here's the code (sans tests):

--8<---------------cut here---------------start------------->8---
(defun in-comment-line-p ()
  "Return non-nil if the point is in a comment line.
See http://lists.gnu.org/archive/html/help-gnu-emacs/2016-08/msg00141.html";
  (save-excursion
    (forward-line 0)
    (unless (looking-at "^\\s-*$")
      (< (line-end-position)
         (let ((ppss (syntax-ppss)))
           (when (nth 4 ppss)
             (goto-char (nth 8 ppss)))
           (forward-comment (point-max))
           (point))))))

(defun beginning-of-defun-comments (&optional arg)
  "Move to the beginning of ARGth defun, including comments."
  (interactive "^p")
  (unless arg (setq arg 1))
  (beginning-of-defun arg)
  (unless (bobp)
    (while (progn
             (forward-line -1)
             (in-comment-line-p)))
    (forward-line 1)))

(defun mark-defun (&optional arg)
  "Put mark at end of this defun, point at beginning.
The defun marked is the one that contains point or follows point.
With positive ARG, mark this and that many next defuns.

If (in Transient Mark mode) the mark is active, it marks the next
defun after the one(s) already marked.  With positive ARG, mark
that many more defuns.  With negative ARG, mark that many more
previous defuns."
  (interactive "p")
  (setq arg (or arg 1))
  (cond ((use-region-p)
         (if (>= arg 0)
             (set-mark
              (save-excursion
                (goto-char (mark))
                ;; change the dotimes below to (end-of-defun arg) once bug 
#24427 is fixed
                (dotimes (_ignore arg)
                  (end-of-defun))
                (point)))
           (beginning-of-defun-comments (- arg))))
        (t
         (let ((opoint (point))
               beg end)
           (push-mark opoint)
           ;; Try first in this order for the sake of languages with nested
           ;; functions where several can end at the same place as with the
           ;; offside rule, e.g. Python.
           (beginning-of-defun-comments)
           (setq beg (point))
           (end-of-defun)
           (setq end (point))
           (when (and (<= (point) opoint)
                      (> arg 0))
             ;; beginning-of-defun moved back one defun so we got the wrong
             ;; one.  If ARG < 0, however, we actually want to go back.
             (goto-char opoint)
             (end-of-defun)
             (setq end (point))
             (beginning-of-defun-comments)
             (setq beg (point)))
           (goto-char beg)
           (cond ((> arg 0)
                  ;; change the dotimes below to (end-of-defun arg) once bug 
#24427 is fixed
                  (dotimes (_ignore arg)
                    (end-of-defun))
                  (setq end (point))
                  (push-mark end nil t)
                  (goto-char beg))
                 (t
                  (goto-char beg)
                  (beginning-of-defun (1- (- arg)))
                  (push-mark end nil t))))))
  (while (progn
           (forward-line -1)
           (looking-at "^\\s-*$")))
  (forward-line 1))
--8<---------------cut here---------------end--------------->8---

Best,

-- 
Marcin Borkowski





reply via email to

[Prev in Thread] Current Thread [Next in Thread]