Skip to content

Filter / forgiving adverbs #1015

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 of 5 tasks
pokey opened this issue Oct 6, 2022 · 6 comments
Open
1 of 5 tasks

Filter / forgiving adverbs #1015

pokey opened this issue Oct 6, 2022 · 6 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@pokey
Copy link
Member

pokey commented Oct 6, 2022

  • Error when can't expand ("funk") (default behaviour)
  • Keep only inputs which don't error when applying modifier, but return the input unchanged ("can funk")
    • eg is it weakly contained by visible characters? ("can char")
  • Drop target when can't expand; expand those that can ("only funk")
  • Passthrough unmodified those that can't expand; expand those that can ("soft funk")
  • Look into using this for https://github.com/cursorless-dev/cursorless/pull/1094/files#r1016693441

Implementation

We can implement this with a new compositional modifier:

interface ErrorSuppressorModifier {
   type: "errorSuppressor";
   modifier: Modifier;
   onSuccess: "useOriginal" | "useModified";
   onError: "useOriginal" | "drop";
}

The modifier stage would just apply modifier, surrounded by a try block. On success it would either use the original or modified depending on onSuccess. On error it would either use original or return [] depending on onError

Then Talon-side we could map spoken forms as follows:

{
    "can": {"onSuccess": "useOriginal", "onError": "drop"},
    "only": {"onSuccess": "useModified", "onError": "drop"},
    "soft": {"onSuccess": "useModified", "onError": "useOriginal"},
}

Note that these spoken forms can't be used on their own; they are of the form {user.cursorlessErrorSuppressor} <user.cursorlessModifier>, and construct a composed modifier

See also #1006

Might be helpful to have a look at extension and talon side of head and tail:

Update

@AndreasArvidsson had the idea to have the modifier function more like an "error boundary". It wouldn't be an adverb that tries to run modifiers itself. Instead, it would just indicate error behaviour:

interface ErrorBoundaryModifier {
   type: "errorBoundary";
   onSuccess: "useOriginal" | "useModified";
   onError: "useOriginal" | "drop";
}

Then the pipeline, when a modifier throws an error, will scan onwards in the pipeline looking for an error boundary, and use that to determine what to do

@pokey pokey added enhancement New feature or request good first issue Good for newcomers blocked Blocked on something; eg another PR being completed. Look in comments of issue / PR for reason labels Oct 6, 2022
@pokey pokey removed the blocked Blocked on something; eg another PR being completed. Look in comments of issue / PR for reason label Feb 24, 2023
@josharian
Copy link
Collaborator

Cross-linking: This came up as useful in combination with #1631.

@pokey pokey changed the title Filter / forgiving modifiers Filter / forgiving adverbs Dec 5, 2023
@pokey
Copy link
Member Author

pokey commented Dec 6, 2023

I do wonder if the error boundary approach is too fancy. Having modifiers which have long-range impacts on other modifiers feels slightly strange. Also, how does the data flow work? Does it flow out of the original modifier or the error boundary? And how would it interact with #756? and #2000?

The advantage of the original proposal is that the semantics are very clear, and no special sauce needs to appear in the pipeline. In addition, for keyboard, the pipeline is not used at all, so they wouldn't be able to use these error boundaries

cc/ @AndreasArvidsson @josharian

@AndreasArvidsson
Copy link
Member

I was just thinking that if one stage of the pipeline throws an error we check if the next stage can handle that. Nothing fancy. How this interact with future features and specifically the keyboard I have no idea.

@pokey
Copy link
Member Author

pokey commented Dec 6, 2023

I thought you were planning to walk multiple stages, as you suggested it was an alternative to having to think bout whether we swallow multiple modifiers

@AndreasArvidsson
Copy link
Member

That is a possibility, but not necessary.

@pokey
Copy link
Member Author

pokey commented Dec 6, 2023

I'm leaning back towards the original, more explicit approach, but maybe @josharian has some thoughts here. Fwiw jq does something more like the original approach, and the original approach feels more traditional: surrounding something explicitly in a try-catch block.

If the only benefit is simplifying Talon grammar, then I don't think it's worth it. But if there are other tangible benefits then I could see it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants