noctuid / things.el

Extensions to thingatpt.el
51 stars 0 forks source link

Multiple Selections/Composite Bounds #10

Open noctuid opened 5 years ago

noctuid commented 5 years ago

One thing that is not part of the current functionality/API is support for discontiguous things (i.e. things composed of multiple regions like the column text object). While I decided it was a good idea to build in direct support for composite things after not doing that with targets.el, I wasn't initially convinced the same would be true for composite bounds. Further consideration is necessary to determine whether the extra complexity would be actually be worth it.

Multiple Selections

If the multiple regions actually correspond to different things, it's not an issue to build this on top of the current library. One could just collect all bounds in a region, potentially with a predicate.

Column Thing

This is the first example that comes to mind of a single thing that is composed of multiple regions.

For a rectangular selection, it should be possible to do this without changes to the current API. One way to implement a column thing would be take another arbitrary thing as input used to delimit the column (e.g. a word). The implementation of end-op would get that thing (e.g. the bounds of a word thing) at the point, go to the next line at the same column number, check if there is that thing at the point and if it begins and/or ends at the same location, and then continue to the next line if the checks are met. begin-op would be the same in the opposite direction. Seeking would just use the delimiter thing's (again, a word in this case) seek operation.

The bounds could just be the start of the column to the end of the column. For the case of a rectangular selection, further processing of the bounds wouldn't actually be necessary. A non-rectangular column thing (e.g. a column in a csv) should still be possible to implement. It could be built on top of things.el by splitting the region afterwards. However, the downside is that this would require extra processing outside of things.el afterwards. The bounds provided by things.el would actually do almost no good in this case. Using a macro to edit a column in a csv, for example, would still be possible (the approach I personally would prefer), but it wouldn't be possible to easily create multiple selections for a csv column using the current things implemenation.

Other Discontiguous Things

I can't think of any other examples of discontiguous things off the top of my head. Semantic units in text and code are almost always contiguous. Columns seem to be the primary exception.

Columns seem like they could implemented using contiguous "cell" things (e.g. could be a word or could be a | separator for text tables). The first column in a table would be all the cells in the table (e.g. narrow to table using paragraph constraint) that meet the predicate of being the first on the line/row. Whitespace, alignment, etc. could be used as a predicate when collecting things.

The bounds function would set the predicate based on the point and then collect all bounds. Seeking would move the point based on how the cell is defined.

This does seem like a bad idea though since it would be reimplementing all the basic functionality again just for multi-region things (like how targets.el reimplemented functionality for composite things).

Use of Discontiguous Bounds Internally

Take a table where a row can span multiple lines as an example. If the user wanted to select a sentence within a cell, it would be necessary for multi-region bounds to be supported by constraints. The user could hypothetically narrow to the cell first, but this method would not support seeking between cells, for example. This example is somewhat unlikely.

Summary

There are some things the current system is not suited towards or can't handle, but I can't think of any really common use cases. The next step would be to look at how complicated it would be to change the current code to support handling a list of bounds. Some notes: