drym-org / symex.el

An intuitive way to edit Lisp symbolic expressions ("symexes") structurally in Emacs
Other
271 stars 22 forks source link

A Discussion - semi-structural (ie. indentation) navigation #122

Open devcarbon-com opened 1 year ago

devcarbon-com commented 1 year ago

The goal of this code is to simplify the process of navigating quickly to a specific, or approximate target, by leveraging the structure provided by indentation.

Some quick thoughts:

Here are a few examples: ( *|* is cursor)

Admittedly not the best showcase, try it out in your swiss-army-knife-emacs-defun-that-takes-on-the-whole-world of choice! :P

;;before
*|*(defun baz ()
      (say :bar)
      (say :bar
            :hello
            :goodbye)
      (say :bar))

;; after 1  climb up  (Using Symex vernacular of "climbing up" 
;; as in going up the AST).

(defun baz ()
      *|*(say :bar)
      (say :bar
            :hello
            :goodbye)
      (say :bar))

;; after 2 climb up

(defun baz ()
      (say :bar)
      (say :bar
            *|*:hello
            :goodbye)
      (say :bar))

What do you think? Close enough a fit to be within the scope of Symex, or would it be better suited as a separate package?

  (defun dc/first-line-p ()
    "Return true if point is on the first line of the buffer."
    (save-excursion (beginning-of-line) (bobp)))

  (defun dc/last-line-p ()
    "Return true if point is on the last line of the buffer."
    (save-excursion (end-of-line) (eobp)))

  (defun dc/at-buffer-line-boundary-p ()
    "Return true if point is on the last line of the buffer."
    (or (dc/first-line-p) (dc/last-line-p)))

  (defun dc/traverse-over-empty (mover)
    (while (and (not (symex--current-line-empty-p))
                (zerop (current-indentation))
                (not (dc/at-buffer-line-boundary-p)))
      (funcall mover))
    (while (and (symex--current-line-empty-p)
                (not (dc/at-buffer-line-boundary-p)))
      (funcall mover)))

  (defun dc/traverse-indentation (mover &optional starting-indentation)
    "Move by MOVER until different indentation."
    (let ((starting-indentation (or starting-indentation (current-indentation))))
      (if (or (zerop starting-indentation)
              (symex--current-line-empty-p))
          ;; already at zero, don't want to shoot to the file boundary,
          ;; just right past next blank line
          (dc/traverse-over-empty mover)

        (while (and (not (dc/at-buffer-line-boundary-p))
                    (not (symex--point-at-root-symex-p))

                    (or (when (zerop (current-indentation))
                          (dc/traverse-indentation mover 0))
                        (= (current-indentation) starting-indentation)
                        (hs-inside-comment-p)))
          (funcall mover)
          (dc/traverse-indentation mover starting-indentation)))))

(defun dc/climb-up-to-greater-indentation ()
    "Move down a line until the level of indentation is greater than when it started."
    (interactive)
    (dc/traverse-indentation (lambda () (forward-line) (back-to-indentation))))

  (defun dc/climb-down-to-lesser-indentation ()
    "Move up a line until the level of indentation is less than when it started."
    (interactive)
    (dc/traverse-indentation (lambda () (previous-line) (back-to-indentation))))
tommy-mor commented 1 year ago

I would love to try this. Visual ast jumping would help especially for tree-sitter languages, where the nodes are less obvious.

do I just paste these forms into a scratch buffer to try it? which branch do I need to be on to try your snippets

devcarbon-com commented 1 year ago

@tommy-mor Yep, should just be able to paste them in a scratch buffer. I just copy/pasted them out of my personal config. (Thus the dc/ prefix on everything.)

I'm using the 2.0 integration branch, but any branch with symex--point-at-root-symex-p and symex--current-line-empty-p should work in theory.

countvajhula commented 1 year ago

Sounds like a useful feature! Feel free to start a PR @devcarbon-com

devcarbon-com commented 1 year ago

Sounds good!

It might be a little while before I can.. it needs a little tweaking still. Currently gets "stuck" at the beginning or end of a file.

devcarbon-com commented 1 year ago

@countvajhula Do you have a preference for default keybinds?