cursorless icon indicating copy to clipboard operation
cursorless copied to clipboard

support targeting children of unary/binary operators

Open josharian opened this issue 2 years ago • 5 comments

Cursorless has a state scope but no expr scope. Expressions are too dense and nested to be useful targets. In particular, it’s hard to target them precisely.

One exception is the children of unary/binary operators. We could support left/right scopes, where the domain is the operator and the content range is the subexpression. This would enable things like swapping the order of conjuncts.

josharian avatar Oct 24 '23 20:10 josharian

Maybe we could do the following:

     (a + b) + c
//!1  ^
//!1  xxxx
//!2      ^
//!2   xxxx
//!3  *****
//!4 ^^^^^^^
//!4 xxxxxxxxxx
//!5           ^
//!5        xxxx
//!6 ***********

Then you could say (assuming scope is called "operand", first + has gray hat, and second + has blue hat):

  • "first operand plus" to get a,
  • "last operand plus" to get b,
  • "first operand blue plus" to get (a + b), and
  • "last operand blue plus" to get c.
  • "chuck first operand blue plus" to leave just c

Then we don't need all the specialness around "left" / "right" / domain being contained by range, etc.

I don't feel strongly tho if you like your syntax better

We might also add insertion delimiters for operators that are associative

pokey avatar Nov 11 '23 17:11 pokey

We might want to think a bit more carefully bout associative operators. Should prob be able to say things like "fourth operand", etc, even if parse tree uses a car-cdr style hierarchy

pokey avatar Nov 11 '23 17:11 pokey

Note that in my proposal, "next operand plus" / "previous operand plus" should work as well

pokey avatar Nov 11 '23 17:11 pokey

My gut reaction is as follows. Happy to discuss more.

We might want to think a bit more carefully bout associative operators. Should prob be able to say things like "fourth operand", etc, even if parse tree uses a car-cdr style hierarchy

I think this gets complicated.

What should "third operand plus" be in each of these scenarios, assuming the default hat is always over the leftmost +?

a + b + c (a + b) + c a + (b + c) a + b - c a + b * c

I'm guessing it is only well-defined in (1), despite the semantic equivalence of (1) to (2) and (3) and the syntactic similarity of (1) and (4) and (5).

Also, how do you easily explain to users that the first plus in a + b + c has a third operator, but the first dash in a - b - c doesn't?

I see the appeal of it, but I think it ends up mixing up syntactic and semantic notions in a way that may end up confusing.

even if parse tree uses a car-cdr style hierarchy

I would be astonished to learn that parse trees for binary operators did anything but.

I think users will very quickly learn that a + b + c is implicitly a + (b + c), and from there everything else is pretty intuitive.

If you buy this, then there are only ever first operand and second/last operand, which are clean and clear from the grammatical perspective but also a lot of syllables vs left/right.

"chuck first operand blue plus" to leave just c

This is really nice. I can see using this a lot.

josharian avatar Nov 11 '23 23:11 josharian

Update from meet-up:

  1. Define private.operand and private.operation as follows:
     (a + b) + c
//!1  ^          <~ private.operand
//!1  xxxx
//!2      ^      <~ private.operand
//!2   xxxx
//!3  ^^^^^      <~ private.operation
//!4 ^^^^^^^     <~ private.operand
//!4 xxxxxxxxxx
//!5           ^ <~ private.operand
//!5        xxxx
//!6 ^^^^^^^^^^^ <~ private.operation
  1. Note that private.operation is likely to be a useful scope on its own, eg "operation plus" gives you a + b if first plus has gray hat. Alternate spoken form ideas: "nary", "opera"
  2. Define modifiers "left" and "right" as follows. Here's "right" ("left" is analogous):
iterationRange = containing(operationScopeHandler, input);
candidates = operandScopeHandler.generateScopes(editor, input.end, "forward", {
  // might be able to drop next line
  includeDescendantScopes: true,
  distalPosition: iterationRange.end,
});

return largest candidate

pokey avatar Nov 12 '23 19:11 pokey