emacs-devel
[Top][All Lists]
Advanced

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

Re: Plug treesit.el into other emacs constructs


From: Stefan Monnier
Subject: Re: Plug treesit.el into other emacs constructs
Date: Mon, 26 Dec 2022 17:46:18 -0500
User-agent: Gnus/5.13 (Gnus v5.13)

> +(defvar-local transpose-sexps-function nil
> +  "If non-nil, `transpose-sexps' delegates to this function.
> +
> +The return value of this function is expected to be a cons of two
> +conses, denoting the positions in the current buffer to be
> +transposed.  If no such pair of positions is available, signal
> +USER-ERROR.")

This docstring needs to tell what args are passed to the function.

I see you make it return a pair of pairs, so it has to handle all the
semantics of `transpose-sexps`.  My intuition told me to go with
a function that returns a pair of positions (i.e. it takes an ARG and
returns the BEG..END of the ARGth sibling).  I suspect it would fit
within `transpose-subr` a bit better.

> +     (if transpose-sexps-function transpose-sexps-function
> +       (lambda (arg)

Aka (or transpose-sexps-function (lambda (arg) ...))
But even better is to put the `lambda` in the default value of the
variable, so you just use `transpose-sexps-function` unconditionally.

> +  (let* ((aux (if special mover
> +             (lambda (x)
> +               (cons (progn (funcall mover x) (point))
> +                     (progn (funcall mover (- x)) (point))))))

If `mover` is changed to return a pair of positions, than the above can
just be:

> +  (let* ((aux (if special mover
> +             (lambda (x)
> +               (cons (progn (funcall mover x) (point))
> +                     (progn (funcall mover (- x)) (point))))))


> +      (pos1 (save-excursion (funcall aux arg)))
> +         pos2)
>      (cond
> +     ((and (consp (car pos1)) (consp (cdr pos1)))
> +      (transpose-subr-1 (car pos1) (cdr pos1)))
>       ((= arg 0)
>        (save-excursion
>       (setq pos1 (funcall aux 1))
> diff --git a/lisp/treesit.el b/lisp/treesit.el
> index cefbed1a16..9f0965ac68 100644
> --- a/lisp/treesit.el
> +++ b/lisp/treesit.el
> @@ -1582,6 +1582,27 @@ treesit-search-forward-goto
>        (goto-char current-pos)))
>      node))
>  
> +(defun treesit-transpose-sexps (&optional arg)
> +  "Tree-sitter `transpose-sexps' function.
> +Arg is the same as in `transpose-sexps'.
> +
> +Return a pair of positions describing the regions to transpose
> +for use in `transpose-subr' and friends."
> +  (let* ((parent (treesit-node-parent (treesit-node-at (point))))
> +         (child (treesit-node-child parent 0 t)))
> +    (named-let loop ((prev child)
> +                     (next (treesit-node-child
> +                            parent (+ arg (treesit-node-index child t))
> +                            t)))
> +      (if (< (point) (or (treesit-node-end next)
> +                         (user-error "Don't have two things to transpose")))
> +          (cons (cons (treesit-node-start prev)
> +                      (treesit-node-end prev))
> +                (cons (treesit-node-start next)
> +                      (treesit-node-end next)))
> +        (loop (treesit-node-next-sibling prev t)
> +              (treesit-node-next-sibling next t))))))
> +
>  ;;; Navigation, defun, things
>  ;;
>  ;; Emacs lets you define "things" by a regexp that matches the type of
> @@ -2111,7 +2132,8 @@ treesit-major-mode-setup
>    ;; Defun name.
>    (when treesit-defun-name-function
>      (setq-local add-log-current-defun-function
> -                #'treesit-add-log-current-defun)))
> +                #'treesit-add-log-current-defun))
> +  (setq-local transpose-sexps-function #'treesit-transpose-sexps))
>  
>  ;;; Debugging




reply via email to

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