Skip to content
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

LSP code actions for pattern-matching #472

Open
jiribenes opened this issue May 27, 2024 · 0 comments
Open

LSP code actions for pattern-matching #472

jiribenes opened this issue May 27, 2024 · 0 comments
Labels

Comments

@jiribenes
Copy link
Contributor

Follow-up to #463 & #470
It would be nice to offer code actions for pattern-matching, specifically:

1. a quick-fix for a missing case in a pattern match

After #470, the compiler suggests: Non-exhaustive pattern matching, missing case Fork(Fork(_, _, Fork(_, _, _)), _, _)), which really means that the user might want to add <indent>case Fork(Fork(_, _, Fork(_, _, _)), _, _)) => <>.

What we'd really want here is a quick-fix like in Scala 3: https://github.com/scala/scala3/blob/e0c030ccd44089e70629b59d76962c1dfc8dbb16/compiler/src/dotty/tools/dotc/reporting/messages.scala#L871-L891 which automatically inserts the missing case(s).

In order to do that, we need to pair a Message (a LSP Diagnostic) with a corresponding TreeAction (a LSP CodeAction). As far as I can tell, we would need to dynamically register CodeActions based on the Diagnostics we currently have, as it's the job of the "CodeActionContext" to store the relevant diagnostics. This would probably require some changes in Kiama.

I don't know whether we should also name the patterns (we definitely can, since we force the user to name the fields) or whether we should just leave ignore patterns (_) everywhere. 🤷‍♂️

2. exhaustive autocompletion

Building up on 1., if we know the type of a variable, then we should also be able to get all of the constructors for that type.
It would be nice to somehow -- either autocomplete on x.match like in IntelliJ, or perhaps by just right-clicking on an identifier -- be able to generate the whole exhaustive match.

x.match // [Autocomplete: Exhaustive pattern-matching]

// would get transformed to
x match {
  case Cons(head, tail) => <>
  case Nil() => <>
}

3. case-of-case split on a pattern

Building up on 2., it would be absolutely amazing to be able to split by right-clicking on a variable pattern, similarly to Agda/Idris, creating a nested pattern match. This might be quite difficult to get right as it's a little bit more complicated to perform the editor changes (replace identifier, make a hole, copy whole line k-times, fill all holes with all k possible constructors).

x match {
  case Cons(head, tail) => head
  //              ^^^^ right click here and select "case split"
  case Nil() => 42
}

// would get transformed to
x match {
  case Cons(head, Cons(head2, tail2)) => head // !
  case Cons(head, Nil()) => head              // !
  case Nil() => 42
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant