From 52f885bf9e57488581b51e03b3ab12ed69409cd9 Mon Sep 17 00:00:00 2001 From: Siddhartha Date: Tue, 17 Sep 2024 19:54:05 -0700 Subject: [PATCH] Revert to using lisp-specific (paredit) emit and capture for now It would be nice to have a common (Symex) implementation of these features for Lisp and tree-sitter, but it may be that doing these operations purely in a structural way ends up having behavior (like indenting according to the new structure) that we don't necessarily want, as it often isn't invertible/idempotent. Handling trailing whitespace also seems problematic and prone to special cases. Understanding the right approach will take more careful analysis of each case. For now, we will revert to the earlier implementation as it works well for Lisp (but doesn't for tree-sitter, of course), and leave the tree-sitter features unimplemented. We can return to this in the future to see what the best thing to do would be. --- symex-transformations-lisp.el | 74 +++++++++++++++++++++++++++++++++++ symex-transformations-ts.el | 16 ++++++++ symex-transformations.el | 40 +++++++------------ symex-traversals.el | 30 -------------- 4 files changed, 104 insertions(+), 56 deletions(-) diff --git a/symex-transformations-lisp.el b/symex-transformations-lisp.el index 199def15..17cd6d48 100644 --- a/symex-transformations-lisp.el +++ b/symex-transformations-lisp.el @@ -262,5 +262,79 @@ selected expression. Otherwise, paste in place." (end (symex--get-end-point count))) (copy-region-as-kill start end)))) +(defun symex-lisp--emit-backward () + "Emit backward." + (when (and (symex-left-p) + (not (symex-empty-list-p))) + (save-excursion + (symex--go-up) ; need to be inside the symex to emit and capture + (paredit-backward-barf-sexp 1)) + (symex--go-forward) + (when (symex-empty-list-p) + (fixup-whitespace) + (re-search-forward symex--re-left) + (symex--go-down)))) + +(defun symex-lisp-emit-backward (count) + "Emit backward COUNT times." + (dotimes (_ count) + (symex-lisp--emit-backward))) + +(defun symex-lisp--emit-forward () + "Emit forward." + (when (and (symex-left-p) + (not (symex-empty-list-p))) + (save-excursion + (symex--go-up) ; need to be inside the symex to emit and capture + (paredit-forward-barf-sexp 1)) + (when (symex-empty-list-p) + (symex--go-forward) + (fixup-whitespace) + (re-search-backward symex--re-left)))) + +(defun symex-lisp-emit-forward (count) + "Emit forward COUNT times." + (dotimes (_ count) + (symex-lisp--emit-forward))) + +(defun symex-lisp--capture-backward () + "Capture from behind." + (when (and (symex-left-p) + ;; paredit captures 1 ((|2 3)) -> (1 (2 3)) but we don't + ;; want to in this case since point indicates the inner + ;; symex, which cannot capture, rather than the outer + ;; one. We avoid this by employing a guard condition here. + (not (symex--point-at-first-symex-p))) + (if (symex-empty-list-p) + (forward-char) + (symex--go-up)) ; need to be inside the symex to emit and capture + (paredit-backward-slurp-sexp 1) + (fixup-whitespace) + (symex--go-down))) + +(defun symex-lisp-capture-backward (count) + "Capture from behind, COUNT times." + (dotimes (_ count) + (symex-lisp--capture-backward))) + +(defun symex-lisp--capture-forward () + "Capture from the front." + (when (and (symex-left-p) + (not (save-excursion + (symex-other) + (forward-char) + (symex-lisp--point-at-end-p)))) + (save-excursion + (if (symex-empty-list-p) + (forward-char) + (symex--go-up)) ; need to be inside the symex to emit and capture + (paredit-forward-slurp-sexp 1)))) + +(defun symex-lisp-capture-forward (count) + "Capture from the front, COUNT times." + (dotimes (_ count) + (symex-lisp--capture-forward))) + + (provide 'symex-transformations-lisp) ;;; symex-transformations-lisp.el ends here diff --git a/symex-transformations-ts.el b/symex-transformations-ts.el index e19b172b..56c2c7f7 100644 --- a/symex-transformations-ts.el +++ b/symex-transformations-ts.el @@ -243,6 +243,22 @@ DIRECTION should be either the symbol `before' or `after'." ;; Update current node from point and reindent if necessary (indent-according-to-mode)) +(defun symex-ts-emit-backward (count) + "Emit backward." + nil) + +(defun symex-ts-emit-forward (count) + "Emit forward." + nil) + +(defun symex-ts-capture-backward (count) + "Capture from behind, COUNT times." + nil) + +(defun symex-ts-capture-forward (count) + "Capture forward." + nil) + ;; TODO: TS: capture node ;; TODO: TS: delete remaining nodes diff --git a/symex-transformations.el b/symex-transformations.el index 4ad0c55f..23c1037d 100644 --- a/symex-transformations.el +++ b/symex-transformations.el @@ -165,45 +165,33 @@ (symex-ts-clear) (symex-lisp-clear))) -(defun symex--emit-backward (count) - "Emit backward." - (dotimes (_ count) - (symex-execute-traversal symex--traversal-emit-backward))) - (symex-define-command symex-emit-backward (count) "Emit backward, COUNT times." (interactive "p") - (symex--emit-backward count)) - -(defun symex--emit-forward (count) - "Emit forward." - (dotimes (_ count) - (symex-execute-traversal symex--traversal-emit-forward))) + (if tree-sitter-mode + (symex-ts-emit-backward count) + (symex-lisp-emit-backward count))) (symex-define-command symex-emit-forward (count) "Emit forward, COUNT times." (interactive "p") - (symex--emit-forward count)) - -(defun symex--capture-backward (count) - "Capture from behind." - (dotimes (_ count) - (symex-execute-traversal symex--traversal-capture-backward))) + (if tree-sitter-mode + (symex-ts-emit-forward count) + (symex-lisp-emit-forward count))) (symex-define-command symex-capture-backward (count) - "Capture from behind, COUNT times." + "Capture backward, COUNT times." (interactive "p") - (symex--capture-backward count)) - -(defun symex--capture-forward (count) - "Capture from the front." - (dotimes (_ count) - (symex-execute-traversal symex--traversal-capture-forward))) + (if tree-sitter-mode + (symex-ts-capture-backward count) + (symex-lisp-capture-backward count))) (symex-define-command symex-capture-forward (count) - "Capture from the front, COUNT times." + "Capture forward, COUNT times." (interactive "p") - (symex--capture-forward count)) + (if tree-sitter-mode + (symex-ts-capture-forward count) + (symex-lisp-capture-forward count))) (symex-define-command symex-split () "Split symex into two." diff --git a/symex-traversals.el b/symex-traversals.el index 86e9b364..cab70173 100644 --- a/symex-traversals.el +++ b/symex-traversals.el @@ -202,36 +202,6 @@ when the way is blocked.") (precaution symex--traversal-goto-first (beforehand (not (at root))))))) -(symex-deftraversal symex--traversal-emit-backward - (maneuver (move up) - (delete) - (move down) - (paste before)) - "Emit backward.") - -(symex-deftraversal symex--traversal-emit-forward - (maneuver (move up) - (circuit (move forward)) - (delete) - (move down) - (paste after)) - "Emit forward.") - -(symex-deftraversal symex--traversal-capture-backward - (maneuver (delete previous) - (move up) - (paste before) - (move down)) - "Capture backward.") - -(symex-deftraversal symex--traversal-capture-forward - (maneuver (delete next) - (move up) - (circuit (move forward)) - (paste after) - (move down)) - "Capture forward.") - (symex-define-motion symex-traverse-forward (count) "Traverse symex as a tree, using pre-order traversal.