ethan-leba / tree-edit

🌲 Structural editing in Emacs for anyβ„’ language!
GNU General Public License v3.0
390 stars 16 forks source link

adds minor tree-edit-mode #53

Closed fgeller closed 1 year ago

fgeller commented 2 years ago

πŸ‘‹

thought i'd add a PR to check if you want to pull this into tree-edit or a separate package. if you do, there's probably still some more tweaks i could do, but as time is scarce/valuable, here's a discussion starter 😁

i use it for motion/movement 90% and then usually work on the selection/marked region, rather than use the structural editing commands. but that's mostly out of habit i believe, and motion works really well.

some changes since the last update on #40:

some open tasks:

fgeller commented 2 years ago

:wave:

thought i'd add a PR to check if you want to pull this into tree-edit or a separate package. if you do, there's probably still some more tweaks i could do, but as time is scarce/valuable, here's a discussion starter grin

  • if you'd integrate it into tree-edit, we could factor out the common functionality from evil-tree-edit

I'd definitely like to factor out the commonalities between the two.

do you want me to give this a go? haven't used evil in a while, but could start the process?

Things that should probably be common:

* Movement and editing functions

* Hooks

* Some of the overlay stuff? The hide current node overlay stuff wouldn't make sense in evil-tree-edit

agreed, would add the current node as a commonality

I'd really like the mode to have keybindings setup so those who are curious about tree-edit and don't use evil can have something running without any config, do you think you could add that in?

gave it a shot, let me know what you think

  • added a notion of desired node types to more quickly travel upwards in the tree (i.e., i often want to jump up to the start of a for loop or func declaration)

An issue with an approach like that is that the lack of fine-grain control will limit what structural editing actions you can take. Maybe you can provide a separate set of functions for large scale vs small scale movement? evil-tree-edit deals with the sometimes cumbersome node structure by allowing you to avy jump to any node with a certain type within the block, another approach to consider.

need to try / explore the avy-jump alternative, sounds good :) my use case is often somewhat different: some functions span multiple pages and jumping to the beginning or end wouldn't be feasible with avy. haven't used the editing functionality much, but i see your point. but, yes - it's additional behavior, just an analogue to the regular go to parent. or do you think skipping the nodes that share the same range is an issue? could add a bool flag to make it customizable?

  • i didn't add all edit / refactoring commands, but doing so is simple as they're just wrappers to add (interactive). i simply added a suffix (-cmd) to the lib version, unsure if there's a downside to adding (interactive) to the lib version?

The downside isn't the (interactive) part, but that we would need to hardcode the NODE parameter as tree-edit--current-node.

that makes perfect sense :) what do you think of the -cmd suffix?

  • raise and other edit commands are fairly slow on my macbook, haven't used the profiler to figure out what's slow

Unfortunately the way tree-edit performs structural editing on nodes is not very optimized, so it starts slowing down once you hit ~20 nodes in a single block. This is something I'd like to work on addressing, but as a stopgap measure you can override how the editing works for certain nodes with large amounts of children: https://github.com/ethan-leba/tree-edit/blob/main/tree-edit-python.el#L120

still need to test this more, will add feedback if it remains an issue

Do you have any ideas about how you'll use commands that take a type? wrap/insert/ec.

not yet :)

ethan-leba commented 2 years ago

do you want me to give this a go? haven't used evil in a while, but could start the process?

If you'd be willing to work on that, it'd be a great help! But if that's more than you'd like to bite off right now I can work on that after we get this PR mostly done :)

I'd really like the mode to have keybindings setup so those who are curious about tree-edit and don't use evil can have something running without any config, do you think you could add that in?

gave it a shot, let me know what you think

LGTM!

need to try / explore the avy-jump alternative, sounds good :) my use case is often somewhat different: some functions span multiple pages and jumping to the beginning or end wouldn't be feasible with avy.

fair point! i'll think on if there's a way to address this.

do you think skipping the nodes that share the same range is an issue?

unfortunately yes, for example in Python a one node block:

if foo:
   TREE

If you have the block type selected inserting a new node would go onto the next line, while if you have the identifier node selected it would insert a new node on the same line with a comma: TREE,TREE.

Maybe we could special case this for certain nodes, but it seems to me that all the nodes with a shared boundary have it for a reason in regards to what structural editing operations can be performed.

It does feel like quite bad UX to have the user determine which node in an identical range performs the edit they want, but I'm not sure how to address this right now :(

could add a bool flag to make it customizable?

Maybe some sort of toggle as part of the keybindings? Or as part of macro/micro movement keybindings?

that makes perfect sense :) what do you think of the -cmd suffix?

Works for me, but I reserve the right to change my mind later on ;)

Do you have any ideas about how you'll use commands that take a type? wrap/insert/ec.

not yet :)

Maybe something like C-c C-t w <keytype> (example for wrap)? That's basically how evil-tree-edit works, programmatically generating the keymaps for these type-taking cmds.

ethan-leba commented 1 year ago

Closing due to staleness, thanks for your interest :)