Description
The problem
Today's cursorless targets are flat, allowing only a single modifier. This limitation dramatically restricts the power of cursorless commands. See What's next for the big picture; here we focus on the details of the solution.
The solution
Instead of being a flat object with optional attributes, each of which represent a stage in a makeshift pipeline, PrimitiveTarget
will simply have a list of pipeline stages. During execution, cursorless will apply each pipeline stage to the output of the one before it. Each pipeline stage output will be a rich target, giving the next stage enough information to process the previous output. The mark
will just become a pipeline stage with zero inputs.
The approach is inspired by jq. Each pipeline stage in a cursorless target description takes a single input and emits zero or more outputs. The outputs of a modifier stage are passed in one by one to the next stage in the modifier pipeline, and then all outputs from that stage are passed onward, etc. See the jq language spec for a better idea of the paradigm.
Some of our modifiers will be parametrized. For example "every" is a modifier that takes a scope type such as "line", "funk", etc as a parameter, and generates a pipeline stage that yields every instance of the given scope type occurring in each of its inputs. So for example "every line in funk" will create a pipeline that first expands its input to the nearest containing function, and then yields every line in that function