Subject: bug#21072: Brave new mark-defun (and a testing tool)

From: Noam Postavsky <[email-masked]>
Date: Tue, 25 Apr 2017 16:49:08 -0400

On Tue, Apr 25, 2017 at 7:43 AM, Marcin Borkowski <[email-masked]> wrote:
>>
>> Hmm, I was testing before now just by evaluating the changed functions
>> after startup, I must have messed something up.  I think this one might
>> be okay.
>
> Quick tests show that you are right.  I'd like to understand the code,
> too - that will take me a while.

I started commenting the code a bit which made me think of some more
strange corner cases, like

/* foo */ foo;
function () {
    return 0;
}

and I ended up with this

(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)
  (let (bobp)
    (while (let ((ppss (progn (setq bobp (= (forward-line -1) -1))
                              (syntax-ppss (line-end-position)))))
             (while (and (nth 4 ppss) ; If eol is in a line-spanning comment,
                         (< (nth 8 ppss) (line-beginning-position)))
               (goto-char (nth 8 ppss)) ; skip to comment start.
               (setq ppss (syntax-ppss (line-end-position))))
             (and (not bobp)
                  (progn (skip-syntax-backward
                          "-" (line-beginning-position))
                         (not (bolp))) ; Check for blank line.
                  (progn (parse-partial-sexp
                          (line-beginning-position) (line-end-position)
                          nil t (syntax-ppss (line-beginning-position)))
                         (eolp))))) ; Check for non-comment text.
    (forward-line (if bobp 0 1))))