Fanael / edit-indirect

Edit regions in separate buffers
99 stars 23 forks source link

edit-indirect-region should support rectangular regions #17

Open MyriaCore opened 3 years ago

MyriaCore commented 3 years ago

Currently, if the user selects a rectangular region, it's treated as any other region - the top-left and bottom-right corners are used as the boundaries of the edit-indirect buffer, and everything in between is used as editable content.

This behavior makes sense for most regions, but for rectangular regions, it's actually unexpected. For example, let's consider the following rectangular region, and see how these intuitions play out:

image

If you're like me, you'd probably expect the text in the edit indirect buffer to look like the following, because that's what we actually highlighted:

porro eius quaerat ipsum. N
 Eius amet adipisci tempora
quia magnam. Tempora est al
a labore voluptatem consect

Unfortunately, the text that ends up being put into the edit-indirect buffer includes text that wasn't even in the original rectangular selection:

image

This is likely because the rectangular region is converted to a normal region (with the top-left and bottom-right corners as the endpoints) to avoid having to implement separate logic for rectangular regions.

Implementation Details

Unfortunately, supporting rectangular regions isn't so trivial. The biggest difficulty here is deciding what to do if the user tries to commit an edit-indirect buffer that would write text past the boundaries of the original rectangular selection. I have a few ideas for how we could approach this problem:

  1. We could just disallow comitting a buffer that runs past the bounds of the rectangular region. This might involve a bounds check in edit-indirect-save and edit-indirect-commit, and an error if the bounds check isn't satisfied. We could also do something fancy with font-lock machinery, and highlight text in the edit-indirect buffer that goes past the bounds of the rectangular region. If we wanna add a cherry on top, I'm sure there's a way to make the buffer not even accept input past the bounds of the original rectangle[^1].
  2. We could allow the region to grow to horizontally, but not vertically. This means that we don't allow the region to grow downwards, but we do allow the region to grow to the right.

[^1]: we could, for example, rebind the newline function only work if the buffer has less lines than is contained within the rectangular region.

The way I see it, the best case scenario is if we do 2 by default, but then expose customizable variables that allow the user to enable (or disable) vertical or horizontal bounds checks entirely. This way, the user (or mode-authors who depend on this library) could decide for themselves whether they're OK with their rectangular edit-indirect region expanding past its boundaries.

Fanael commented 3 years ago

Thanks for the report. Alas, as you correctly identified, rectangular regions are a mess to deal with, and will require significant effort. Currently, I'm unfortunately not in the proper state of mind to deal with both the design and implementation issues that will arise, so I'm sorry: I know how much it sucks to have your issue report answered with "PRs are welcome", but at least for the moment that's what I'll have to leave it at.


If we have to redesign half of the library regardless, we could go the extra mile and allow arbitrary jagged line regions, characterized by begin point, end point, and a list of begin and end offsets from the start of the line, one for each line. Rectangular regions then become a trivial case of that. As far as I can see, this is not any harder to support than rectangular regions: there are still the same complications caused by the region growing in either direction, and the same amount of effort is needed to track what edit-indirect buffer positions correspond to what parent buffer positions.

MyriaCore commented 3 years ago

we might not have to do a full redesign. I'm sure there are ways of detecting if a region is rectangular or not. I'm simply proposing we keep all the current behavior for normal regions, and just add some special behavior (described in proposal) for rectangular regions.

I will say, the big motivation for filling this out was jrblevin/markdown-mode#375, but I do like your suggestion there. I might try and make some changes, and if I come up with anything functional, I'll let you know.