Subject: Re: bug#78703: beginning-of-defun and friends still wrong in typescript-ts-mode

From: Troy Brown <[email-masked]>
Date: Thu, 12 Jun 2025 08:04:55 -0400

On Tue, Jun 10, 2025 at 2:02 AM Yuan Fu <[email-masked]> wrote:
>
> > After that, I'm less concerned about its behavior, but think the
> > current `nested` behavior of visiting the previous sibling defun until
> > there are no more, then visiting the parent defun makes sense.  The
> > key difference is that you only visit the previous sibling if point is
> > at a defun boundary...otherwise visit the defun containing point.
>
> Hmmm, it doesn’t feel very convenient, you’d need to first adjust your point to be precisely at the boundary, then press C-M-a/e? IMO that adds too much overhead.

You shouldn't need to adjust point at all.  By boundary, I'm referring
to the place that `beginning-of-defun` (or
`beginning-of-defun-comments`) would place you after running.  I think
something like the following demonstrates what I mean by this.  When
you're within a defun, it takes you to the beginning of the enclosing
defun.  After that, it moves according to the tactic.  To me, this is
much more intuitive than the current behavior, and I believe would
have fixed the issues I described with the prog-fill-reindent-defun
behavior.

```elisp
(defun defun-boundary-p ()
  (or
   ;; Just before a defun
   (save-excursion
     (forward-comment (point-max))
     (when-let* ((treesit-defun-tactic 'nested)
                 (node (treesit-defun-at-point)))
       (eq (point) (treesit-node-start node))))
   ;; Just after a defun
   (save-excursion
     (skip-chars-backward " \t\n")
     (when (not (bobp))
       (goto-char (1- (point)))
       (when-let* ((treesit-defun-tactic 'nested)
                   (node (treesit-defun-at-point)))
         (eq (1+ (point)) (treesit-node-end node)))))
   ;; No enclosing defun
   (null (treesit-defun-at-point))))

(defun my/beginning-of-defun ()
  (interactive)
  (if (defun-boundary-p)
      ;; adhere to tactic
      (beginning-of-defun)
    (let* ((treesit-defun-tactic 'nested)
           (node (treesit-defun-at-point)))
      (goto-char (treesit-node-start node))
      (beginning-of-line))))
```