Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
devcarbon-com opened this issue May 11, 2023 · 5 comments
Open

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

devcarbon-com opened this issue May 11, 2023 · 5 comments

Comments

@devcarbon-com
Copy link
Collaborator

devcarbon-com commented May 11, 2023

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:

  • Structural navigation is great, but sometimes takes a little extra cognitive load to jump to something that is visually apparent. (Apparent because of the emphasis of indentation to particular portions of the structure)
  • this code is to make it easy to jump close to your already-eyed target, at which point the remaining AST navigation is intuitive.
  • indentation provides structure that currently is not utilized in symex. Let's use it to our advantage

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
Copy link
Collaborator

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
Copy link
Collaborator Author

devcarbon-com commented May 11, 2023

@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
Copy link
Collaborator

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

@devcarbon-com
Copy link
Collaborator Author

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
Copy link
Collaborator Author

@countvajhula Do you have a preference for default keybinds?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants