From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Theodor Thornhill via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#60128: 30.0.50; [PATCH]: Add treesit-transpose-sexps Date: Sat, 17 Dec 2022 13:52:30 +0100 Message-ID: <87edsytcoh.fsf@thornhill.no> References: <87a63nru7n.fsf@thornhill.no> Reply-To: Theodor Thornhill Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="25248"; mail-complaints-to="usenet@ciao.gmane.io" Cc: casouri@gmail.com, Stefan Monnier To: 60128@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Dec 17 13:53:12 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p6Wgi-0006Lj-Bg for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 17 Dec 2022 13:53:12 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6Wgb-00086r-2F; Sat, 17 Dec 2022 07:53:05 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6WgY-00086i-AL for bug-gnu-emacs@gnu.org; Sat, 17 Dec 2022 07:53:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p6WgX-0003ty-U0 for bug-gnu-emacs@gnu.org; Sat, 17 Dec 2022 07:53:01 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1p6WgX-0000YF-PQ for bug-gnu-emacs@gnu.org; Sat, 17 Dec 2022 07:53:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Theodor Thornhill Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 17 Dec 2022 12:53:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 60128 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 60128-submit@debbugs.gnu.org id=B60128.16712815562106 (code B ref 60128); Sat, 17 Dec 2022 12:53:01 +0000 Original-Received: (at 60128) by debbugs.gnu.org; 17 Dec 2022 12:52:36 +0000 Original-Received: from localhost ([127.0.0.1]:55783 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p6Wg8-0000Xu-2c for submit@debbugs.gnu.org; Sat, 17 Dec 2022 07:52:36 -0500 Original-Received: from out-193.mta0.migadu.com ([91.218.175.193]:57525) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p6Wg5-0000Xd-4t for 60128@debbugs.gnu.org; Sat, 17 Dec 2022 07:52:34 -0500 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thornhill.no; s=key1; t=1671281551; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Trvgd0nvj7ZQO0bO7jYjGO1cB41Mdw9080M3qyXstTs=; b=H4PwfK+BrpEg6UXA2eaaC8H/hG6PF23gp6uc7zPcQdgecRDFal3TPPGbFvkyNhelpLAIdb /BzM+bKV3QERMhsQzUVgPAK5GBJoba1CNXRKQSr1ENgag5wSvM9aphllmT8aMvmFXQ9bl8 92Bqw52TaoQIJSWJ86vpVjcoEFrIu62vupB9hQb3m87EkM0masob/hqLKy0Idc1y9HQdlf TfTr8acDcmHjIO15IlGI076TKf9VUdFZatK61u78NXyVDXDJ/NwoGkjDCCbujrlBuinGJW aAhWUTIDwxSqIVv8Is99DkWyg2gj22B6cszsHIdeL8hbroduNZsleSpyzhMv6g== In-Reply-To: <87a63nru7n.fsf@thornhill.no> (Theodor Thornhill's message of "Fri, 16 Dec 2022 21:04:28 +0100") X-Migadu-Flow: FLOW_OUT X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:251278 Archived-At: --=-=-= Content-Type: text/plain Theodor Thornhill writes: > Hi there! > > Attached is a patch that enables transpose-sexps for tree-sitter enabled > modes. > > This function will swap the node _before_ node-at-point with the node > _after_, so it would do something like: > > foo a|nd bar => bar and foo| > > or > foo(a + 4,| y + c * b, b, d); => foo(y + c * b, a + 4|, b, d); > > It will _not_ try to swap things that are not siblings. I think that > makes sense in the case of non-lisp languages, since _most_ places you > can transpose-sexps you will end up with broken code. > from 'transpose-subr-1': (if (> (cdr pos1) (car pos2)) (error "Don't have two things to transpose")) I added this hack into the function in the patch, but I think that triggering an error is too much. ;; Hack to trigger the error message in `transpose-subr-1' when we ;; don't have siblings to swap. (list (cons 0 1) (cons 0 1)))) I guess I could just follow suit in my function and do like in the following patch: Theo --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Add-treesit-transpose-sexps.patch >From e26dc6ab62ddf7b60fcbe2532acdf9f8500c904f Mon Sep 17 00:00:00 2001 From: Theodor Thornhill Date: Thu, 15 Dec 2022 21:22:13 +0100 Subject: [PATCH] Add treesit-transpose-sexps We don't really need to rely on forward-sexp to define what to transpose. In tree-sitter we can consider siblings as "balanced expressions", and swap them without doing any movement to calculate where the siblings in question are. * lisp/simple.el: Add requires for treesit. * lisp/simple.el (transpose-sexps): If tree-sitter is available, use treesit-transpose-sexps as the 'special' function. (transpose-subr): Just use tree-sitter when available. * lisp/treesit.el (treesit-transpose-sexps): New function. --- lisp/simple.el | 67 ++++++++++++++++++++++++++----------------------- lisp/treesit.el | 14 +++++++++++ 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/lisp/simple.el b/lisp/simple.el index dcc2242e49..15f7381f06 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -28,10 +28,12 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(eval-when-compile (require 'cl-lib) + (require 'treesit)) (declare-function widget-convert "wid-edit" (type &rest args)) (declare-function shell-mode "shell" ()) +(declare-function treesit-parser-list "treesit.c") ;;; From compile.el (defvar compilation-current-error) @@ -8453,36 +8455,37 @@ transpose-sexps (transpose-sexps arg nil) (scan-error (user-error "Not between two complete sexps"))) (transpose-subr - (lambda (arg) - ;; Here we should try to simulate the behavior of - ;; (cons (progn (forward-sexp x) (point)) - ;; (progn (forward-sexp (- x)) (point))) - ;; Except that we don't want to rely on the second forward-sexp - ;; putting us back to where we want to be, since forward-sexp-function - ;; might do funny things like infix-precedence. - (if (if (> arg 0) - (looking-at "\\sw\\|\\s_") - (and (not (bobp)) - (save-excursion - (forward-char -1) - (looking-at "\\sw\\|\\s_")))) - ;; Jumping over a symbol. We might be inside it, mind you. - (progn (funcall (if (> arg 0) - 'skip-syntax-backward 'skip-syntax-forward) - "w_") - (cons (save-excursion (forward-sexp arg) (point)) (point))) - ;; Otherwise, we're between sexps. Take a step back before jumping - ;; to make sure we'll obey the same precedence no matter which - ;; direction we're going. - (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) - " .") - (cons (save-excursion (forward-sexp arg) (point)) - (progn (while (or (forward-comment (if (> arg 0) 1 -1)) - (not (zerop (funcall (if (> arg 0) - 'skip-syntax-forward - 'skip-syntax-backward) - "."))))) - (point))))) + (if (treesit-parser-list) #'treesit-transpose-sexps + (lambda (arg) + ;; Here we should try to simulate the behavior of + ;; (cons (progn (forward-sexp x) (point)) + ;; (progn (forward-sexp (- x)) (point))) + ;; Except that we don't want to rely on the second forward-sexp + ;; putting us back to where we want to be, since forward-sexp-function + ;; might do funny things like infix-precedence. + (if (if (> arg 0) + (looking-at "\\sw\\|\\s_") + (and (not (bobp)) + (save-excursion + (forward-char -1) + (looking-at "\\sw\\|\\s_")))) + ;; Jumping over a symbol. We might be inside it, mind you. + (progn (funcall (if (> arg 0) + 'skip-syntax-backward 'skip-syntax-forward) + "w_") + (cons (save-excursion (forward-sexp arg) (point)) (point))) + ;; Otherwise, we're between sexps. Take a step back before jumping + ;; to make sure we'll obey the same precedence no matter which + ;; direction we're going. + (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) + " .") + (cons (save-excursion (forward-sexp arg) (point)) + (progn (while (or (forward-comment (if (> arg 0) 1 -1)) + (not (zerop (funcall (if (> arg 0) + 'skip-syntax-forward + 'skip-syntax-backward) + "."))))) + (point)))))) arg 'special))) (defun transpose-lines (arg) @@ -8521,6 +8524,8 @@ transpose-subr (progn (funcall mover (- x)) (point)))))) pos1 pos2) (cond + ((treesit-parser-list) + (apply #'transpose-subr-1 (funcall aux arg))) ((= arg 0) (save-excursion (setq pos1 (funcall aux 1)) diff --git a/lisp/treesit.el b/lisp/treesit.el index 0df71d12ed..1504ad3482 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1623,6 +1623,20 @@ treesit--defun-maybe-top-level node) finally return node)))) +(defun treesit-transpose-sexps (&optional arg) + "Tree-sitter `transpose-sexps' function. +Arg is the same as in `transpose-sexps'." + (if-let* ((node (treesit-node-at (point))) + (parent (treesit-node-parent node)) + (index (treesit-node-index node)) + (prev (treesit-node-child parent (1- index))) + (next (treesit-node-child parent (+ arg index)))) + (list (cons (treesit-node-start prev) + (treesit-node-end prev)) + (cons (treesit-node-start next) + (treesit-node-end next))) + (user-error "Don't have two things to transpose"))) + (defun treesit-beginning-of-defun (&optional arg) "Move backward to the beginning of a defun. -- 2.34.1 --=-=-=--