diff --git a/build.sbt b/build.sbt index 35e39cde..3b6d84f8 100644 --- a/build.sbt +++ b/build.sbt @@ -157,7 +157,7 @@ lazy val lsp = module("lsp") "org.http4s" %% "http4s-ember-client" % "0.23.27", "org.http4s" %% "http4s-ember-server" % "0.23.27" % Test, "io.get-coursier" %% "coursier" % "2.1.10", - "org.typelevel" %% "cats-tagless-core" % "0.16.1", + "org.typelevel" %% "cats-tagless-macros" % "0.16.1", ), buildInfoPackage := "playground.lsp.buildinfo", buildInfoKeys ++= Seq(version, scalaBinaryVersion), diff --git a/modules/lsp/src/main/scala/playground/lsp/LanguageClient.scala b/modules/lsp/src/main/scala/playground/lsp/LanguageClient.scala index 8d77a1bf..4c3a9625 100644 --- a/modules/lsp/src/main/scala/playground/lsp/LanguageClient.scala +++ b/modules/lsp/src/main/scala/playground/lsp/LanguageClient.scala @@ -1,8 +1,14 @@ package playground.lsp import cats.FlatMap +import cats.data.Kleisli import cats.effect.kernel.Async import cats.syntax.all.* +import cats.tagless.Derive +import cats.tagless.FunctorK +import cats.tagless.catsTaglessApplyKForIdK +import cats.tagless.implicits.* +import cats.~> import com.google.gson.JsonElement import org.eclipse.lsp4j.ConfigurationItem import org.eclipse.lsp4j.ConfigurationParams @@ -101,33 +107,19 @@ object LanguageClient { def refreshDiagnostics: F[Unit] = withClientF(_.refreshDiagnostics()).void } - // courtesy of github copilot - // workaround for https://github.com/typelevel/cats-tagless/pull/401 + implicit val functorK: FunctorK[LanguageClient] = Derive.functorK[LanguageClient] + def defer[F[_]: FlatMap]( fa: F[LanguageClient[F]] - ): LanguageClient[F] = - new LanguageClient[F] { + ): LanguageClient[F] = Derive + .readerT[LanguageClient, F] + .mapK(new (Kleisli[F, LanguageClient[F], *] ~> F) { - override def configuration[A]( - v: ConfigurationValue[A] - ): F[A] = fa.flatMap(_.configuration(v)) - - override def showMessage( - tpe: MessageType, - msg: String, - ): F[Unit] = fa.flatMap(_.showMessage(tpe, msg)) + def apply[A]( + k: Kleisli[F, LanguageClient[F], A] + ): F[A] = fa.flatMap(k.run) - override def refreshDiagnostics: F[Unit] = fa.flatMap(_.refreshDiagnostics) - - override def refreshCodeLenses: F[Unit] = fa.flatMap(_.refreshCodeLenses) - - override def showOutputPanel: F[Unit] = fa.flatMap(_.showOutputPanel) - - override def logOutput( - msg: String - ): F[Unit] = fa.flatMap(_.logOutput(msg)) - - } + }) val NoChangeDetected: String = "No change detected, not rebuilding server" } diff --git a/modules/lsp/src/main/scala/playground/lsp/LanguageServer.scala b/modules/lsp/src/main/scala/playground/lsp/LanguageServer.scala index 98931e6f..f6b4a010 100644 --- a/modules/lsp/src/main/scala/playground/lsp/LanguageServer.scala +++ b/modules/lsp/src/main/scala/playground/lsp/LanguageServer.scala @@ -3,9 +3,14 @@ package playground.lsp import cats.Applicative import cats.FlatMap import cats.MonadThrow +import cats.data.Kleisli import cats.effect.kernel.Async import cats.parse.LocationMap import cats.syntax.all.* +import cats.tagless.Derive +import cats.tagless.FunctorK +import cats.tagless.catsTaglessApplyKForIdK +import cats.tagless.implicits.* import cats.~> import com.google.gson.JsonElement import com.google.gson.JsonPrimitive @@ -351,72 +356,18 @@ object LanguageServer { def exit: F[Unit] = Applicative[F].unit } - // courtesy of github copilot - // workaround for https://github.com/typelevel/cats-tagless/pull/401 + implicit val functorK: FunctorK[LanguageServer] = Derive.functorK[LanguageServer] + def defer[F[_]: FlatMap]( fa: F[LanguageServer[F]] - ): LanguageServer[F] = - new LanguageServer[F] { - - override def initialize( - params: InitializeParams - ): F[InitializeResult] = fa.flatMap(_.initialize(params)); - - override def initialized( - params: InitializedParams - ): F[Unit] = fa.flatMap(_.initialized(params)); - - override def didChange( - params: DidChangeTextDocumentParams - ): F[Unit] = fa.flatMap(_.didChange(params)); - - override def didOpen( - params: DidOpenTextDocumentParams - ): F[Unit] = fa.flatMap(_.didOpen(params)); - - override def didSave( - params: DidSaveTextDocumentParams - ): F[Unit] = fa.flatMap(_.didSave(params)); - - override def didClose( - params: DidCloseTextDocumentParams - ): F[Unit] = fa.flatMap(_.didClose(params)); - - override def formatting( - params: DocumentFormattingParams - ): F[List[TextEdit]] = fa.flatMap(_.formatting(params)); - - override def completion( - position: CompletionParams - ): F[Either[List[CompletionItem], CompletionList]] = fa.flatMap(_.completion(position)); - - override def diagnostic( - params: DocumentDiagnosticParams - ): F[DocumentDiagnosticReport] = fa.flatMap(_.diagnostic(params)); - - override def codeLens( - params: CodeLensParams - ): F[List[CodeLens]] = fa.flatMap(_.codeLens(params)); - - override def documentSymbol( - params: DocumentSymbolParams - ): F[List[DocumentSymbol]] = fa.flatMap(_.documentSymbol(params)); - - override def didChangeWatchedFiles( - params: DidChangeWatchedFilesParams - ): F[Unit] = fa.flatMap(_.didChangeWatchedFiles(params)); - - override def executeCommand( - params: ExecuteCommandParams - ): F[Unit] = fa.flatMap(_.executeCommand(params)); - - override def runFile( - params: RunFileParams - ): F[Unit] = fa.flatMap(_.runFile(params)); + ): LanguageServer[F] = Derive + .readerT[LanguageServer, F] + .mapK(new (Kleisli[F, LanguageServer[F], *] ~> F) { - override def shutdown: F[Unit] = fa.flatMap(_.shutdown); + def apply[A]( + k: Kleisli[F, LanguageServer[F], A] + ): F[A] = fa.flatMap(k.run) - override def exit: F[Unit] = fa.flatMap(_.exit) - } + }) }