From d60c695ff27aa7a05456e89b60e544e9fd6c097f Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Thu, 5 Dec 2024 18:09:34 +0100 Subject: [PATCH] refactor: Remove decoration protocol --- architecture.md | 7 +- docs/editors/overview.md | 11 +- docs/integrations/decoration-protocol.md | 130 ------------- docs/integrations/new-editor.md | 21 --- .../main/scala/docs/WorksheetModifier.scala | 4 +- .../decorations/DecorationClient.scala | 41 ---- ...bleDecorationAttachmentRenderOptions.scala | 21 --- ...mableDecorationInstanceRenderOptions.scala | 10 - .../internal/metals/ClientConfiguration.scala | 10 - .../ClientExperimentalCapabilities.scala | 1 + .../metals/InitializationOptions.scala | 2 + .../internal/metals/MetalsLspService.scala | 52 ++---- .../language/ConfiguredLanguageClient.scala | 9 - .../language/DelegatingLanguageClient.scala | 7 - .../clients/language/MetalsHttpClient.scala | 9 - .../language/MetalsLanguageClient.scala | 6 +- .../clients/language/NoopLanguageClient.scala | 4 - .../DecorationWorksheetPublisher.scala | 78 -------- .../worksheets/WorksheetProvider.scala | 30 --- .../worksheets/WorksheetPublisher.scala | 20 -- .../WorkspaceEditWorksheetPublisher.scala | 176 ------------------ .../scala/tests/sbt/SbtBloopLspSuite.scala | 9 - .../scala/tests/scalacli/ScalaCliSuite.scala | 2 - .../scala/tests/BaseWorksheetLspSuite.scala | 8 +- .../src/main/scala/tests/TestingClient.scala | 103 ---------- .../WorksheetInfiniteLoopSuite.scala | 7 +- .../WorksheetNoDecorationsLspSuite.scala | 114 ------------ website/i18n/en.json | 4 - website/sidebars.json | 1 - 29 files changed, 33 insertions(+), 864 deletions(-) delete mode 100644 docs/integrations/decoration-protocol.md delete mode 100644 metals/src/main/scala/scala/meta/internal/decorations/DecorationClient.scala delete mode 100644 metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationAttachmentRenderOptions.scala delete mode 100644 metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationInstanceRenderOptions.scala delete mode 100644 metals/src/main/scala/scala/meta/internal/worksheets/DecorationWorksheetPublisher.scala delete mode 100644 metals/src/main/scala/scala/meta/internal/worksheets/WorksheetPublisher.scala delete mode 100644 metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala delete mode 100644 tests/unit/src/test/scala/tests/worksheets/WorksheetNoDecorationsLspSuite.scala diff --git a/architecture.md b/architecture.md index 0aacdf277ef..a9a3a5d6a24 100644 --- a/architecture.md +++ b/architecture.md @@ -70,14 +70,11 @@ Metals communicates with build server such as `bloop` and `sbt` using [Build Ser For more details about sbt's BSP support in Metals, see [the blog post](https://scalameta.org/metals/blog/2020/11/06/sbt-BSP-support/). -## Worksheet +## Worksheets Worksheet support is provided by [mdoc](https://github.com/scalameta/mdoc), which is able to typecheck and evaluate each line of the input. The main class responsible for worksheets is [WorksheetProvider.scala](https://github.com/scalameta/metals/blob/main/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetProvider.scala). It is responsible for downloading mdoc instance for each Scala version that is supported and running the evaluation in the file input. -Later the evaluations are published using [decoration extension](https://scalameta.org/metals/docs/integrations/decoration-protocol) or via additional Text Edits for editors that do not support decorations. This is done in the two classes implementing [WorksheetPublisher.scala](https://github.com/scalameta/metals/blob/main/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetPublisher.scala): - -- [DecorationWorksheetPublisher.scala](https://github.com/scalameta/metals/blob/main/metals/src/main/scala/scala/meta/internal/worksheets/DecorationWorksheetPublisher.scala) for decoration publishing -- [WorkspaceEditWorksheetPublisher.scala](https://github.com/scalameta/metals/blob/main/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala) for publishing decorations as comments in the code +Later the evaluations are published using [inlay hints](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHint). ## Formatting diff --git a/docs/editors/overview.md b/docs/editors/overview.md index 6acb35cf5d8..3b5410b5267 100644 --- a/docs/editors/overview.md +++ b/docs/editors/overview.md @@ -357,13 +357,7 @@ projects. ## Worksheets -**✅**: Worksheets work via the Decoration protocol and are added as a -non-editable side decoration. - -**Comments**: Worksheets work via `workspace/applyEdit` by adding comments to -the source code and support hover to show larger output. You can find more -information about worksheets under the editor specific worksheet section. For -example, [here for VS Code](vscode.md#worksheets). +**✅**: Worksheets work via inlay hints. By default there is a 30 second timeout on worksheet evaluation, this setting can be overridden by `-Dmetals.worksheet-timeout=` server property. @@ -448,9 +442,6 @@ website. **Status bar**: Editor client implements the `metals/status` notification. -**Decoration protocol**: Editor client implements the -[Decoration Protocol](../integrations/decoration-protocol.md). - **Tree view**: Editor client implements the [Tree View Protocol](../integrations/tree-view-protocol.md). diff --git a/docs/integrations/decoration-protocol.md b/docs/integrations/decoration-protocol.md deleted file mode 100644 index 6dd3f219b3c..00000000000 --- a/docs/integrations/decoration-protocol.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -id: decoration-protocol -sidebar_label: Decoration Protocol -title: Decoration Protocol v0.2.0 ---- - -Metals implements a Language Server Protocol extension called the "Decoration -Protocol" to display non-editable text in the text editor. - -## Base data structures - -The Decoration Protocol has several base data structures that are mostly derived -from the [VS Code API](https://code.visualstudio.com/api/references/vscode-api). - -### Decoration - -A "decoration" represents non-editable code that is displayed in the text editor -alongside editable code. The GIF below demonstrates an example of green -decorations that are formatted as comments, which contain the evaluated code. - -![Example decoration](https://user-images.githubusercontent.com/1408093/68091453-bacbea00-fe77-11e9-80b9-52a9bbd6d98a.gif) - -Although decorations appear as text inside the editor, they can't be edited by -the user. In the GIF above, observe that the decoration can optionally include a -message that's displayed on mouse hover. - -## DecorationOptions - -```ts -export interface DecorationOptions { - /** - * The range position to place the decoration. - * The Range data structure is defined in the Language Server Protocol. - */ - range: Range; - /** - * The text to display when the mouse hovers over the decoration. - * The MarkupContent data structure is defined in the LanguageServerProtocol - */ - hoverMessage?: MarkupContent; - /** The URI of the text document to place text decorations */ - renderOptions: ThemableDecorationInstanceRenderOption; -} -``` - -## ThemableDecorationInstanceRenderOption - -```ts -export interface ThemableDecorationInstanceRenderOption { - /** The decoration to display next to the given range. */ - after?: ThemableDecorationAttachmentRenderOptions; -} -``` - -## ThemableDecorationAttachmentRenderOptions - -```ts -export interface ThemableDecorationAttachmentRenderOptions { - /** The text to display in the decoration */ - contentText?: string; - /** The color of `contentText`. More colors may be added in the future. */ - color?: "green"; - /** The font style to use for displaying `contentText. More styles may be added in the future. */ - fontStyle?: "italic"; -} -``` - -## Endpoints - -The Decoration Protocol is embedded inside the Language Server Protocol and -consists of a single JSON-RPC notification. - -### `initialize` - -The Decoration Protocol is only enabled when client declares support for the -protocol by adding an `decorationProvider: true` field to the -`initializationOptions` during the `initialize` request. - -Depending on your editor, it may also allow for inline decorations. This is used -for features like showing implicit arguments and inferred types, both which are -user configuration settings that a user can toggle. However, in order for those -features to use decorations rather than just extra information in your hover, -your client also needs to declare that it's an `inlineDecorationsProvider`. - -```json -"initializationOptions": { - "decorationProvider": true, - "inlineDecorationProvider": true -} -``` - -### `metals/publishDecorations` - -The decoration ranges did change notification is sent from the server to the -client to notify that decorations have changes for a given text document. - -_Notification_: - -- method: `metals/publishDecorations` -- params: `PublishDecorationsParams` as defined below: - -```ts -export interface PublishDecorationsParams { - /** The URI of the text document to place text decorations */ - uri: string; - - /** - * The ranges to publish for this given document. - * Use empty list to clear all decorations. - */ - options: DecorationOptions[]; - - /** - * Used to distinguish if inline decorations from the - * line ones as otherwise they will get replaced. This - * parameter along with specific inline decorations will - * not be sent if the client doesn't support inline - * decorations. - */ - inline: boolean; -} -``` - -## Changelog - -- v0.1.0: First release with basic support for worksheets. -- v0.2.0: `MarkedString` in `DecorationOptions` changed to `MarkupContent` to - align with LSP 3.15 -- v0.2.1: added `isInline` to `PublishDecorationsParams` to be able to - distinguish between worksheet evaluation and inline decorations. diff --git a/docs/integrations/new-editor.md b/docs/integrations/new-editor.md index 317d404ff11..ae5e2b49ce5 100644 --- a/docs/integrations/new-editor.md +++ b/docs/integrations/new-editor.md @@ -101,8 +101,6 @@ The currently available settings for `InitializationOptions` are listed below. snippetAutoIndent?: boolean; } debuggingProvider?: boolean; - decorationProvider?: boolean; - inlineDecorationProvider?: boolean; didFocusProvider?: boolean; doctorProvider?: "json" | "html"; executeClientCommandProvider?: boolean; @@ -230,13 +228,6 @@ Boolean value to signify that the client supports the Default value: `false` -##### `decorationProvider` - -Boolean value to signify that the client supports the -[Decoration Protocol](../integrations/decoration-protocol.md). - -Default value: `false` - ##### `didFocusProvider` Boolean value to signify that the client supports the @@ -289,13 +280,6 @@ Possible values: For example, `C:\Users\IEUser\workspace\project/*.{scala,sbt,properties}`. This mode is used by the VS Code client. -##### `inlineDecorationProvider` - -If the client implements the Metals Decoration Protocol **and** supports -decorations to be shown inline and not only at the end of a line. - -Default: `false` - ##### `icons` Possible values: @@ -696,11 +680,6 @@ Metals implements several custom JSON-RPC endpoints related to rendering tree views in the editor client, the [Tree View Protocol](../integrations/tree-view-protocol.md). -### Decoration Protocol - -Metals implements an LSP extension to display non-editable text in the editor, -see the [Decoration Protocol](../integrations/decoration-protocol.md). - ### `metals/status` The Metals status notification is sent from the server to the client to notify diff --git a/metals-docs/src/main/scala/docs/WorksheetModifier.scala b/metals-docs/src/main/scala/docs/WorksheetModifier.scala index f1f452df516..62651257787 100644 --- a/metals-docs/src/main/scala/docs/WorksheetModifier.scala +++ b/metals-docs/src/main/scala/docs/WorksheetModifier.scala @@ -16,8 +16,8 @@ class WorksheetModifier extends StringModifier { val (howYouSeeEvaluations, howToHover) = info match { case "vscode" => - "as a decoration at the end of the line." -> - "hover on the decoration to expand the decoration." + "as a inlay hint at the end of the line." -> + "hover on the inlay hint to expand it." case _ => "as a comment as the end of the line." -> "hover on the comment to expand." } diff --git a/metals/src/main/scala/scala/meta/internal/decorations/DecorationClient.scala b/metals/src/main/scala/scala/meta/internal/decorations/DecorationClient.scala deleted file mode 100644 index 47441ae3c04..00000000000 --- a/metals/src/main/scala/scala/meta/internal/decorations/DecorationClient.scala +++ /dev/null @@ -1,41 +0,0 @@ -package scala.meta.internal.decorations - -import javax.annotation.Nullable - -import org.eclipse.lsp4j.MarkupContent -import org.eclipse.lsp4j.Range -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification - -trait DecorationClient { - @JsonNotification("metals/publishDecorations") - def metalsPublishDecorations( - params: PublishDecorationsParams - ): Unit -} - -case class DecorationOptions( - range: Range, - @Nullable hoverMessage: MarkupContent = null, - @Nullable renderOptions: ThemableDecorationInstanceRenderOptions = null, -) - -object DecorationOptions { - def apply(text: String, range: Range) = - new DecorationOptions( - range, - renderOptions = ThemableDecorationInstanceRenderOptions( - after = ThemableDecorationAttachmentRenderOptions( - text, - color = "grey", - fontStyle = "italic", - opacity = 0.7, - ) - ), - ) -} - -case class PublishDecorationsParams( - uri: String, - options: Array[DecorationOptions], - @Nullable isInline: java.lang.Boolean, -) diff --git a/metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationAttachmentRenderOptions.scala b/metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationAttachmentRenderOptions.scala deleted file mode 100644 index 73ed233f371..00000000000 --- a/metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationAttachmentRenderOptions.scala +++ /dev/null @@ -1,21 +0,0 @@ -package scala.meta.internal.decorations - -import javax.annotation.Nullable - -case class ThemableDecorationAttachmentRenderOptions( - @Nullable contentText: String = null, - @Nullable contentIconPath: String = null, - @Nullable border: String = null, - @Nullable borderColor: String = null, - @Nullable fontStyle: String = null, - @Nullable fontWeight: String = null, - @Nullable textDecoration: String = null, - @Nullable color: String = null, - @Nullable backgroundColor: String = null, - @Nullable margin: String = null, - @Nullable width: String = null, - @Nullable height: String = null, - @Nullable opacity: java.lang.Double = null, - @Nullable light: ThemableDecorationAttachmentRenderOptions = null, - @Nullable dark: ThemableDecorationAttachmentRenderOptions = null, -) diff --git a/metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationInstanceRenderOptions.scala b/metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationInstanceRenderOptions.scala deleted file mode 100644 index 6b80ccf1350..00000000000 --- a/metals/src/main/scala/scala/meta/internal/decorations/ThemableDecorationInstanceRenderOptions.scala +++ /dev/null @@ -1,10 +0,0 @@ -package scala.meta.internal.decorations - -import javax.annotation.Nullable - -case class ThemableDecorationInstanceRenderOptions( - @Nullable before: ThemableDecorationAttachmentRenderOptions = null, - @Nullable after: ThemableDecorationAttachmentRenderOptions = null, - @Nullable light: ThemableDecorationInstanceRenderOptions = null, - @Nullable dark: ThemableDecorationInstanceRenderOptions = null, -) diff --git a/metals/src/main/scala/scala/meta/internal/metals/ClientConfiguration.scala b/metals/src/main/scala/scala/meta/internal/metals/ClientConfiguration.scala index 6dff22f89a4..79c1d1128a8 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ClientConfiguration.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ClientConfiguration.scala @@ -144,16 +144,6 @@ final class ClientConfiguration( def isRunProvider(): Boolean = initializationOptions.runProvider.getOrElse(false) - def isDecorationProvider(): Boolean = - extract( - initializationOptions.decorationProvider, - experimentalCapabilities.decorationProvider, - false, - ) - - def isInlineDecorationProvider(): Boolean = - initializationOptions.inlineDecorationProvider.getOrElse(false) - def isInlayHintsEnabled(): Boolean = { for { capabilities <- clientCapabilities diff --git a/metals/src/main/scala/scala/meta/internal/metals/ClientExperimentalCapabilities.scala b/metals/src/main/scala/scala/meta/internal/metals/ClientExperimentalCapabilities.scala index d7533bb9cc0..d90b33a3d04 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ClientExperimentalCapabilities.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ClientExperimentalCapabilities.scala @@ -15,6 +15,7 @@ import org.eclipse.{lsp4j => l} */ final case class ClientExperimentalCapabilities( debuggingProvider: Option[Boolean], + @deprecated("Decoration protocol is no longer used.") decorationProvider: Option[Boolean], didFocusProvider: Option[Boolean], doctorProvider: Option[String], diff --git a/metals/src/main/scala/scala/meta/internal/metals/InitializationOptions.scala b/metals/src/main/scala/scala/meta/internal/metals/InitializationOptions.scala index 3b6cea590d5..5a7a73cc4f9 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/InitializationOptions.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/InitializationOptions.scala @@ -54,7 +54,9 @@ final case class InitializationOptions( compilerOptions: CompilerInitializationOptions, debuggingProvider: Option[Boolean], runProvider: Option[Boolean], + @deprecated("Decoration protocol is no longer used.") decorationProvider: Option[Boolean], + @deprecated("Decoration protocol is no longer used.") inlineDecorationProvider: Option[Boolean], didFocusProvider: Option[Boolean], doctorProvider: Option[String], diff --git a/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala b/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala index 56f0b77a864..9b3f85bcc64 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala @@ -59,9 +59,7 @@ import scala.meta.internal.parsing.FoldingRangeProvider import scala.meta.internal.parsing.Trees import scala.meta.internal.rename.RenameProvider import scala.meta.internal.search.SymbolHierarchyOps -import scala.meta.internal.worksheets.DecorationWorksheetPublisher import scala.meta.internal.worksheets.WorksheetProvider -import scala.meta.internal.worksheets.WorkspaceEditWorksheetPublisher import scala.meta.io.AbsolutePath import scala.meta.metals.lsp.TextDocumentService import scala.meta.parsers.ParseException @@ -409,33 +407,22 @@ abstract class MetalsLspService( definitionProvider, ) - val worksheetProvider: WorksheetProvider = { - val worksheetPublisher = - if (clientConfig.isDecorationProvider()) - new DecorationWorksheetPublisher( - clientConfig.isInlineDecorationProvider() - ) - else - new WorkspaceEditWorksheetPublisher(buffers, trees) - - register( - new WorksheetProvider( - folder, - buffers, - trees, - buildTargets, - languageClient, - () => userConfig, - workDoneProgress, - diagnostics, - embedded, - worksheetPublisher, - compilations, - scalaVersionSelector, - clientConfig, - ) + val worksheetProvider: WorksheetProvider = register( + new WorksheetProvider( + folder, + buffers, + trees, + buildTargets, + languageClient, + () => userConfig, + workDoneProgress, + diagnostics, + embedded, + compilations, + scalaVersionSelector, + clientConfig, ) - } + ) protected val compilers: Compilers = register( new Compilers( @@ -821,7 +808,6 @@ abstract class MetalsLspService( } else if (recentlyOpenedFiles.isRecentlyActive(path)) { CompletableFuture.completedFuture(DidFocusResult.RecentlyActive) } else { - worksheetProvider.onDidFocus(path) maybeCompileOnDidFocus(path, prevBuildTarget).asJava } } @@ -996,13 +982,7 @@ abstract class MetalsLspService( .hover(params, token) .map(_.map(_.toLsp())) .map( - _.orElse { - val path = params.textDocument.getUri.toAbsolutePath - if (path.isWorksheet) - worksheetProvider.hover(path, params.getPosition) - else - None - }.orNull + _.orNull ) } } diff --git a/metals/src/main/scala/scala/meta/internal/metals/clients/language/ConfiguredLanguageClient.scala b/metals/src/main/scala/scala/meta/internal/metals/clients/language/ConfiguredLanguageClient.scala index 3f13e88d13c..d599378788b 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/clients/language/ConfiguredLanguageClient.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/clients/language/ConfiguredLanguageClient.scala @@ -5,7 +5,6 @@ import java.util.concurrent.atomic.AtomicBoolean import scala.concurrent.ExecutionContext -import scala.meta.internal.decorations.PublishDecorationsParams import scala.meta.internal.metals.ClientCommands import scala.meta.internal.metals.ClientConfiguration import scala.meta.internal.metals.MetalsEnrichments._ @@ -188,14 +187,6 @@ final class ConfiguredLanguageClient( } } - override def metalsPublishDecorations( - params: PublishDecorationsParams - ): Unit = { - if (clientConfig.isDecorationProvider()) { - underlying.metalsPublishDecorations(params) - } - } - private def toShowMessageRequestParams( params: MetalsQuickPickParams ): ShowMessageRequestParams = { diff --git a/metals/src/main/scala/scala/meta/internal/metals/clients/language/DelegatingLanguageClient.scala b/metals/src/main/scala/scala/meta/internal/metals/clients/language/DelegatingLanguageClient.scala index 98ccc6b19bd..1e5409c8e21 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/clients/language/DelegatingLanguageClient.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/clients/language/DelegatingLanguageClient.scala @@ -3,7 +3,6 @@ package scala.meta.internal.metals.clients.language import java.util.concurrent.CompletableFuture import java.{util => ju} -import scala.meta.internal.decorations.PublishDecorationsParams import scala.meta.internal.tvp._ import org.eclipse.lsp4j.ApplyWorkspaceEditParams @@ -96,12 +95,6 @@ class DelegatingLanguageClient(var underlying: MetalsLanguageClient) underlying.metalsTreeViewDidChange(params) } - override def metalsPublishDecorations( - params: PublishDecorationsParams - ): Unit = { - underlying.metalsPublishDecorations(params) - } - override def refreshModel(): CompletableFuture[Unit] = underlying.refreshModel() diff --git a/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsHttpClient.scala b/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsHttpClient.scala index 4d06f3ab2a9..b71f2b2b9ef 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsHttpClient.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsHttpClient.scala @@ -8,7 +8,6 @@ import java.util.concurrent.atomic.AtomicReference import scala.concurrent.ExecutionContext import scala.util.Try -import scala.meta.internal.decorations.PublishDecorationsParams import scala.meta.internal.io.PathIO import scala.meta.internal.metals.MetalsEnrichments._ import scala.meta.internal.metals.clients.language.DelegatingLanguageClient @@ -135,14 +134,6 @@ final class MetalsHttpClient( underlying.logMessage(message) } - override def metalsPublishDecorations( - params: PublishDecorationsParams - ): Unit = { - if (clientConfig.isDecorationProvider()) { - underlying.metalsPublishDecorations(params) - } - } - // ======= // Helpers // ======= diff --git a/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsLanguageClient.scala b/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsLanguageClient.scala index 6d7483b9bd8..1e045afd2f0 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsLanguageClient.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/clients/language/MetalsLanguageClient.scala @@ -5,7 +5,6 @@ import javax.annotation.Nullable import scala.util.Try -import scala.meta.internal.decorations.DecorationClient import scala.meta.internal.metals.Icons import scala.meta.internal.tvp._ @@ -18,10 +17,7 @@ import org.eclipse.lsp4j.jsonrpc.services.JsonNotification import org.eclipse.lsp4j.jsonrpc.services.JsonRequest import org.eclipse.lsp4j.services.LanguageClient -trait MetalsLanguageClient - extends LanguageClient - with TreeViewClient - with DecorationClient { +trait MetalsLanguageClient extends LanguageClient with TreeViewClient { /** * Display message in the editor "status bar", which should be displayed somewhere alongside the buffer. diff --git a/metals/src/main/scala/scala/meta/internal/metals/clients/language/NoopLanguageClient.scala b/metals/src/main/scala/scala/meta/internal/metals/clients/language/NoopLanguageClient.scala index f48a7bba409..8d616587824 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/clients/language/NoopLanguageClient.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/clients/language/NoopLanguageClient.scala @@ -2,7 +2,6 @@ package scala.meta.internal.metals.clients.language import java.util.concurrent.CompletableFuture -import scala.meta.internal.decorations.PublishDecorationsParams import scala.meta.internal.tvp._ import org.eclipse.lsp4j.ExecuteCommandParams @@ -47,9 +46,6 @@ abstract class NoopLanguageClient extends MetalsLanguageClient { override def metalsTreeViewDidChange( params: TreeViewDidChangeParams ): Unit = () - override def metalsPublishDecorations( - params: PublishDecorationsParams - ): Unit = () override def refreshModel(): CompletableFuture[Unit] = CompletableFuture.completedFuture(()) diff --git a/metals/src/main/scala/scala/meta/internal/worksheets/DecorationWorksheetPublisher.scala b/metals/src/main/scala/scala/meta/internal/worksheets/DecorationWorksheetPublisher.scala deleted file mode 100644 index 1445c8f0693..00000000000 --- a/metals/src/main/scala/scala/meta/internal/worksheets/DecorationWorksheetPublisher.scala +++ /dev/null @@ -1,78 +0,0 @@ -package scala.meta.internal.worksheets - -import scala.meta.internal.decorations.DecorationOptions -import scala.meta.internal.decorations.PublishDecorationsParams -import scala.meta.internal.decorations.ThemableDecorationAttachmentRenderOptions -import scala.meta.internal.decorations.ThemableDecorationInstanceRenderOptions -import scala.meta.internal.metals.MetalsEnrichments._ -import scala.meta.internal.metals.clients.language.MetalsLanguageClient -import scala.meta.internal.pc.HoverMarkup -import scala.meta.internal.worksheets.MdocEnrichments._ -import scala.meta.io.AbsolutePath - -import mdoc.interfaces.EvaluatedWorksheet -import org.eclipse.lsp4j.Hover -import org.eclipse.lsp4j.MarkupContent -import org.eclipse.lsp4j.MarkupKind -import org.eclipse.lsp4j.Position - -class DecorationWorksheetPublisher(isInlineDecorationProvider: Boolean) - extends WorksheetPublisher { - - private val commentHeader = " // " - - override def publish( - languageClient: MetalsLanguageClient, - path: AbsolutePath, - worksheet: EvaluatedWorksheet, - ): Unit = { - val rendered = render(worksheet) - publish(languageClient, path, rendered) - } - - override def hover(path: AbsolutePath, position: Position): Option[Hover] = - // publish'ed Decorations handle hover, so nothing to return here - None - - private def render( - worksheet: EvaluatedWorksheet - ): Array[DecorationOptions] = { - worksheet - .statements() - .iterator() - .asScala - .map { s => - new DecorationOptions( - s.position().toLsp, - new MarkupContent( - MarkupKind.MARKDOWN, - HoverMarkup(s.prettyDetails()), - ), - ThemableDecorationInstanceRenderOptions( - after = ThemableDecorationAttachmentRenderOptions( - commentHeader + truncatify(s), - color = "green", - fontStyle = "italic", - ) - ), - ) - } - .toArray - } - - private def publish( - languageClient: MetalsLanguageClient, - path: AbsolutePath, - decorations: Array[DecorationOptions], - ): Unit = { - val params = - new PublishDecorationsParams( - path.toURI.toString(), - decorations, - // do not send additional param if it's not inline provider - isInline = if (isInlineDecorationProvider) false else null, - ) - languageClient.metalsPublishDecorations(params) - } - -} diff --git a/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetProvider.scala b/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetProvider.scala index 62382975010..f9b8cced0fc 100644 --- a/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetProvider.scala @@ -52,7 +52,6 @@ import coursierapi.Fetch import coursierapi.error.SimpleResolutionError import mdoc.interfaces.EvaluatedWorksheet import mdoc.interfaces.Mdoc -import org.eclipse.lsp4j.Hover import org.eclipse.lsp4j.InlayHint import org.eclipse.lsp4j.MessageType import org.eclipse.lsp4j.Position @@ -73,7 +72,6 @@ class WorksheetProvider( workDoneProgress: WorkDoneProgress, diagnostics: Diagnostics, embedded: Embedded, - publisher: WorksheetPublisher, compilations: Compilations, scalaVersionSelector: ScalaVersionSelector, clientConfig: ClientConfiguration, @@ -143,22 +141,6 @@ class WorksheetProvider( reset() } - def onDidFocus(path: AbsolutePath): Future[Unit] = { - if (!clientConfig.isInlayHintsEnabled()) { - exportableEvaluations.get(path) match { - case Some(worksheetF) => - worksheetF.future.map { worksheet => - publisher.publish( - languageClient, - path, - worksheet.evaluatedWorksheet, - ) - } - case None => Future.successful(()) - } - } else Future.successful(()) - } - private def evaluateAndPublish[T]( path: AbsolutePath, token: CancelToken, @@ -188,8 +170,6 @@ class WorksheetProvider( _.foreach { toPublish => if (clientConfig.isInlayHintsRefreshEnabled()) languageClient.refreshInlayHints() - else - publisher.publish(languageClient, path, toPublish.evaluatedWorksheet) }, ) } @@ -219,7 +199,6 @@ class WorksheetProvider( } } else Future.successful(Nil) - // TODO switch to only inlay hints private def toInlayHints( path: AbsolutePath, worksheet: Option[EvaluatedWorksheetSnapshot], @@ -251,15 +230,6 @@ class WorksheetProvider( } } - /** - * Fallback hover for results. - * While for the actual code hover's provided by Compilers, - * for evaluated results hover's provided here - */ - def hover(path: AbsolutePath, position: Position): Option[Hover] = { - publisher.hover(path, position) - } - /** * Check to see for a given path if there is an evaluated worksheet that * matches thie exact input. diff --git a/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetPublisher.scala b/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetPublisher.scala deleted file mode 100644 index 0b26a01f096..00000000000 --- a/metals/src/main/scala/scala/meta/internal/worksheets/WorksheetPublisher.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.meta.internal.worksheets - -import scala.meta.internal.metals.clients.language.MetalsLanguageClient -import scala.meta.io.AbsolutePath - -import mdoc.interfaces.EvaluatedWorksheet -import org.eclipse.lsp4j.Hover -import org.eclipse.lsp4j.Position - -trait WorksheetPublisher { - - def publish( - languageClient: MetalsLanguageClient, - path: AbsolutePath, - worksheet: EvaluatedWorksheet, - ): Unit - - def hover(path: AbsolutePath, position: Position): Option[Hover] - -} diff --git a/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala b/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala deleted file mode 100644 index 3bafadd3d7a..00000000000 --- a/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala +++ /dev/null @@ -1,176 +0,0 @@ -package scala.meta.internal.worksheets - -import scala.meta.inputs.Input -import scala.meta.internal.metals.Buffers -import scala.meta.internal.metals.MetalsEnrichments._ -import scala.meta.internal.metals.clients.language.MetalsLanguageClient -import scala.meta.internal.parsing.Trees -import scala.meta.internal.pc.HoverMarkup -import scala.meta.internal.worksheets.MdocEnrichments._ -import scala.meta.internal.worksheets.MdocEnrichments.truncatify -import scala.meta.internal.worksheets.WorkspaceEditWorksheetPublisher._ -import scala.meta.io.AbsolutePath - -import mdoc.interfaces.EvaluatedWorksheet -import mdoc.interfaces.EvaluatedWorksheetStatement -import org.eclipse.lsp4j.ApplyWorkspaceEditParams -import org.eclipse.lsp4j.Hover -import org.eclipse.lsp4j.MarkupContent -import org.eclipse.lsp4j.MarkupKind -import org.eclipse.lsp4j.Position -import org.eclipse.lsp4j.Range -import org.eclipse.lsp4j.TextEdit -import org.eclipse.lsp4j.WorkspaceEdit - -class WorkspaceEditWorksheetPublisher(buffers: Buffers, trees: Trees) - extends WorksheetPublisher { - - private var hoverMessages = Map.empty[AbsolutePath, HoverMap] - - override def publish( - languageClient: MetalsLanguageClient, - path: AbsolutePath, - worksheet: EvaluatedWorksheet, - ): Unit = { - val rendered = render(path, worksheet) - publish(languageClient, path, rendered) - } - - override def hover(path: AbsolutePath, position: Position): Option[Hover] = { - for { - messages <- hoverMessages.get(path) - distance = buffers.tokenEditDistance( - path, - messages.textSnapshot, - trees, - ) - snapshotPosition <- - distance - .toOriginal(position.getLine(), position.getCharacter()) - .toPosition(position) - message <- getHoverMessage(snapshotPosition, messages.hovers) - } yield new Hover( - new MarkupContent( - MarkupKind.MARKDOWN, - HoverMarkup(message), - ) - ) - } - - private def render( - path: AbsolutePath, - worksheet: EvaluatedWorksheet, - ): RenderResult = { - val source = path.toInputFromBuffers(buffers) - val editsWithDetails = - worksheet.statements.asScala - .map(statement => renderEdit(statement, source)) - - val edits = - editsWithDetails.map(ed => new TextEdit(ed.range, ed.text)).toList - val hovers = editsWithDetails.map(ed => - HoverMessage( - ed.range - .copy( - endCharacter = ed.range.getStart.getCharacter + ed.text.length - ), - ed.details, - ) - ) - val hoverMap = HoverMap(updateWithEdits(source.text, edits), hovers.toSeq) - - RenderResult(edits, hoverMap) - } - - private def publish( - languageClient: MetalsLanguageClient, - path: AbsolutePath, - rendered: RenderResult, - ): Unit = { - hoverMessages = hoverMessages.updated(path, rendered.hovers) - - val params = new ApplyWorkspaceEditParams( - new WorkspaceEdit( - Map(path.toURI.toString -> (rendered.edits.asJava)).asJava - ) - ) - languageClient.applyEdit(params) - } - - private def renderEdit( - statement: EvaluatedWorksheetStatement, - source: Input, - ): RenderEditResult = { - val startPosition = - new Position(statement.position.endLine, statement.position.endColumn) - val endPosition = - locatePreviousEdit(statement, source).getOrElse(startPosition) - - RenderEditResult( - new Range(startPosition, endPosition), - renderMessage(statement), - statement.prettyDetails(), - ) - } - - private def renderMessage(statement: EvaluatedWorksheetStatement): String = { - val out = new StringBuilder() - out.append(" /*> ") - out.append(truncatify(statement)) - out.append(" */") - out.result() - } - - private def locatePreviousEdit( - statement: EvaluatedWorksheetStatement, - source: Input, - ): Option[Position] = { - val editPattern = """\A\s*/\*>.*?\*/""".r - val offset = - source.lineToOffset( - statement.position.endLine - ) + statement.position.endColumn - val text = source.text.drop(offset) - editPattern - .findFirstMatchIn(text) - .map(m => { - val p = source.toOffsetPosition(offset + m.end) - new Position(p.endLine, p.endColumn) - }) - } - - private def getHoverMessage( - position: Position, - hovers: Seq[HoverMessage], - ): Option[String] = { - hovers.find(_.range.encloses(position)).map(_.message) - } - - private def updateWithEdits(text: String, edits: List[TextEdit]): String = { - val editsMap = edits.map(e => e.getRange().getStart().getLine() -> e).toMap - - text.linesIterator.zipWithIndex - .map { case (line, i) => - editsMap.get(i) match { - case Some(edit) => - val before = - line.substring(0, edit.getRange.getStart.getCharacter) - val after = line.substring(edit.getRange.getEnd.getCharacter) - before + edit.getNewText() + after - case None => line - } - } - .mkString("\n") - } - -} - -object WorkspaceEditWorksheetPublisher { - - case class HoverMessage(range: Range, message: String) - case class HoverMap(textSnapshot: String, hovers: Seq[HoverMessage]) - - case class RenderEditResult(range: Range, text: String, details: String) - case class RenderResult(edits: List[TextEdit], hovers: HoverMap) - -} diff --git a/tests/slow/src/test/scala/tests/sbt/SbtBloopLspSuite.scala b/tests/slow/src/test/scala/tests/sbt/SbtBloopLspSuite.scala index 516fc0bc51f..101838c80b7 100644 --- a/tests/slow/src/test/scala/tests/sbt/SbtBloopLspSuite.scala +++ b/tests/slow/src/test/scala/tests/sbt/SbtBloopLspSuite.scala @@ -8,7 +8,6 @@ import scala.meta.internal.builds.SbtBuildTool import scala.meta.internal.builds.SbtDigest import scala.meta.internal.io.FileIO import scala.meta.internal.metals.ClientCommands -import scala.meta.internal.metals.InitializationOptions import scala.meta.internal.metals.Messages import scala.meta.internal.metals.Messages._ import scala.meta.internal.metals.MetalsEnrichments._ @@ -37,14 +36,6 @@ class SbtBloopLspSuite workspace: AbsolutePath ): Option[String] = SbtDigest.current(workspace) - override protected def initializationOptions: Option[InitializationOptions] = - Some( - InitializationOptions.Default.copy( - decorationProvider = Some(true), - inlineDecorationProvider = Some(true), - ) - ) - test("basic") { cleanWorkspace() // directory should not be used as sbt script diff --git a/tests/slow/src/test/scala/tests/scalacli/ScalaCliSuite.scala b/tests/slow/src/test/scala/tests/scalacli/ScalaCliSuite.scala index ce477c7ec25..f053c4d665d 100644 --- a/tests/slow/src/test/scala/tests/scalacli/ScalaCliSuite.scala +++ b/tests/slow/src/test/scala/tests/scalacli/ScalaCliSuite.scala @@ -22,8 +22,6 @@ class ScalaCliSuite extends BaseScalaCliSuite("3.3.3") { override protected def initializationOptions: Option[InitializationOptions] = Some( InitializationOptions.Default.copy( - inlineDecorationProvider = Some(true), - decorationProvider = Some(true), debuggingProvider = Option(true), runProvider = Option(true), ) diff --git a/tests/unit/src/main/scala/tests/BaseWorksheetLspSuite.scala b/tests/unit/src/main/scala/tests/BaseWorksheetLspSuite.scala index cc7cf00e6f5..40aeb98c73f 100644 --- a/tests/unit/src/main/scala/tests/BaseWorksheetLspSuite.scala +++ b/tests/unit/src/main/scala/tests/BaseWorksheetLspSuite.scala @@ -139,7 +139,7 @@ abstract class BaseWorksheetLspSuite( """|import java.nio.file.Files |val name = "Susan"/* // : String = "Susan"*/ |val greeting = s"Hello $name"/* // : String = "Hello Susan"*/ - |println(greeting + "\nHow are you?")/* // Hello Susan...*/ + |println(greeting + "\nHow are you?")/* // Hello Susan…*/ |1.to(10).toVector/* // : Vector[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)*/ |val List(a, b) = List(42, 10)/* // a: Int = 42, b: Int = 10*/ |""".stripMargin, @@ -148,7 +148,7 @@ abstract class BaseWorksheetLspSuite( """|import java.nio.file.Files |val name = "Susan"/* // : String = Susan*/ |val greeting = s"Hello $name"/* // : String = Hello Susan*/ - |println(greeting + "\nHow are you?")/* // Hello Susan...*/ + |println(greeting + "\nHow are you?")/* // Hello Susan…*/ |1.to(10).toVector/* // : Vector[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)*/ |val List(a, b) = List(42, 10)/* // a: Int = 42, b: Int = 10*/ |""".stripMargin @@ -183,7 +183,7 @@ abstract class BaseWorksheetLspSuite( """|import java.nio.file.Files |val name = "Susan"/* // : String = "Susan"| name: String = "Susan" |*/ |val greeting = s"Hello $name"/* // : String = "Hello Susan"| greeting: String = "Hello Susan" |*/ - |println(greeting + "\nHow are you?")/* // Hello Susan...| // Hello Susan\n// How are you? |*/ + |println(greeting + "\nHow are you?")/* // Hello Susan…| // Hello Susan\n// How are you? |*/ |1.to(10).toVector/* // : Vector[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)| res1: Vector[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |*/ |val List(a, b) = List(42, 10)/* // a: Int = 42, b: Int = 10| a: Int = 42\nb: Int = 10 |*/ |""".stripMargin, @@ -192,7 +192,7 @@ abstract class BaseWorksheetLspSuite( """|import java.nio.file.Files |val name = "Susan"/* // : String = Susan| name: String = Susan |*/ |val greeting = s"Hello $name"/* // : String = Hello Susan| greeting: String = Hello Susan |*/ - |println(greeting + "\nHow are you?")/* // Hello Susan...| // Hello Susan\n// How are you? |*/ + |println(greeting + "\nHow are you?")/* // Hello Susan…| // Hello Susan\n// How are you? |*/ |1.to(10).toVector/* // : Vector[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)| res1: Vector[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |*/ |val List(a, b) = List(42, 10)/* // a: Int = 42, b: Int = 10| a: Int = 42\nb: Int = 10 |*/ |""".stripMargin diff --git a/tests/unit/src/main/scala/tests/TestingClient.scala b/tests/unit/src/main/scala/tests/TestingClient.scala index 26f3990580f..a637dcea924 100644 --- a/tests/unit/src/main/scala/tests/TestingClient.scala +++ b/tests/unit/src/main/scala/tests/TestingClient.scala @@ -2,7 +2,6 @@ package tests import java.net.URI import java.util.concurrent.CompletableFuture -import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedDeque import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.atomic.AtomicInteger @@ -15,7 +14,6 @@ import scala.concurrent.Promise import scala.meta.inputs.Input import scala.meta.internal.bsp.ConnectionBspStatus import scala.meta.internal.builds.BuildTools -import scala.meta.internal.decorations.PublishDecorationsParams import scala.meta.internal.metals.Buffers import scala.meta.internal.metals.ClientCommands import scala.meta.internal.metals.Debug @@ -113,8 +111,6 @@ class TestingClient(workspace: AbsolutePath, val buffers: Buffers) /** Stores commands executed by the client */ val clientCommands = new ConcurrentLinkedDeque[ExecuteCommandParams]() - val decorations = - new ConcurrentHashMap[AbsolutePath, Set[PublishDecorationsParams]]() var showMessageHandler: MessageParams => Unit = { (_: MessageParams) => () } @@ -471,105 +467,6 @@ class TestingClient(workspace: AbsolutePath, val buffers: Buffers) treeViewChanges.add(params) } - override def metalsPublishDecorations( - params: PublishDecorationsParams - ): Unit = { - val path = params.uri.toAbsolutePath - decorations.compute( - path, - { - case (_, decorationTypes) => { - if (decorationTypes == null) { - Set(params) - } else { - decorationTypes.filter(p => p.isInline != params.isInline) + params - } - } - }, - ) - } - - def syntheticDecorations: String = { - syntheticDecorations(isHover = false) - } - - def workspaceDecorations(filename: String): String = { - syntheticDecorations(isHover = false, Some(filename)) - } - - def syntheticDecorationHoverMessage: String = - syntheticDecorations(isHover = true) - - def syntheticDecorationHoverMessage( - filename: String - ): String = { - syntheticDecorations(isHover = true, Some(filename)) - } - private def syntheticDecorations( - isHover: Boolean, - filename: Option[String] = None, - ): String = { - val out = new StringBuilder() - decorationsForPath(filename).foreach { case (path, synthetics) => - val input = path.toInputFromBuffers(buffers) - input.text.linesIterator.zipWithIndex.foreach { case (line, i) => - val lineDecorations = synthetics.toList - .flatMap(params => - params.options.map(o => - ( - o, - Option(params.isInline).getOrElse( - false.asInstanceOf[java.lang.Boolean] - ), - ) - ) - ) - .filter { case (deco, _) => deco.range.getEnd().getLine() == i } - /* Need to sort them by the type of decoration, inline needs to be first. - * This mirrors the VS Code behaviour, the first declared type is - * shown first if the end is the same */ - .sortBy { case (deco, isInline) => - (deco.range.getEnd().getCharacter(), !isInline) - } - .map(_._1) - if (isHover) { - out.append(line) - lineDecorations.collect { - case decoration if decoration.hoverMessage != null => - out.append("\n" + decoration.hoverMessage.getValue()) - } - out.append("\n") - } else { - val lineIndex = lineDecorations.foldLeft(0) { - case (index, decoration) => - if (decoration.renderOptions.after.contentText != null) { - val decoCharacter = decoration.range.getEnd().getCharacter() - out.append(line.substring(index, decoCharacter)) - out.append(decoration.renderOptions.after.contentText) - decoCharacter - } else { - index - } - } - out.append(line.substring(lineIndex)) - out.append("\n") - } - } - } - out.toString() - } - - private def decorationsForPath(filename: Option[String]) = { - filename match { - case None => - decorations.asScala.find(_._2.nonEmpty) - case Some(file) => - val path = workspace.resolve(file) - val synthetics = decorations.asScala.getOrElse(path, Set.empty) - Some(path, synthetics) - } - } - def workspaceTreeViewChanges: String = { val changes = treeViewChanges.asScala.toSeq .map { change => diff --git a/tests/unit/src/test/scala/tests/worksheets/WorksheetInfiniteLoopSuite.scala b/tests/unit/src/test/scala/tests/worksheets/WorksheetInfiniteLoopSuite.scala index b6f314473ca..e1c9a437ea6 100644 --- a/tests/unit/src/test/scala/tests/worksheets/WorksheetInfiniteLoopSuite.scala +++ b/tests/unit/src/test/scala/tests/worksheets/WorksheetInfiniteLoopSuite.scala @@ -59,9 +59,10 @@ class WorksheetInfiniteLoopSuite "val a = 1" ) _ <- server.didSave("a/src/main/scala/foo/Main.worksheet.sc")(identity) - _ = assertNoDiff( - client.syntheticDecorations, - "val a = 1 // : Int = 1", + _ <- server.assertInlayHints( + "a/src/main/scala/Main.worksheet.sc", + """|val a = 1/* // : Int = 1*/ + |""".stripMargin, ) } yield () } diff --git a/tests/unit/src/test/scala/tests/worksheets/WorksheetNoDecorationsLspSuite.scala b/tests/unit/src/test/scala/tests/worksheets/WorksheetNoDecorationsLspSuite.scala deleted file mode 100644 index e5af14318f5..00000000000 --- a/tests/unit/src/test/scala/tests/worksheets/WorksheetNoDecorationsLspSuite.scala +++ /dev/null @@ -1,114 +0,0 @@ -package tests.worksheets - -import scala.concurrent.Future - -import scala.meta.internal.metals.MetalsEnrichments._ - -import munit.Location -import tests.BaseLspSuite -import tests.TestHovers - -class WorksheetNoDecorationsLspSuite - extends BaseLspSuite("worksheet-no-decorations") - with TestHovers { - - test("edits-and-hovers") { - for { - _ <- initialize( - s""" - |/metals.json - |{ - | "a": { } - |} - |/a/src/main/scala/foo/Main.worksheet.sc - |val x = 1 - |val foo = "bar" - |println("metals") - |""".stripMargin - ) - _ <- server.didOpen("a/src/main/scala/foo/Main.worksheet.sc") - _ <- server.didSave("a/src/main/scala/foo/Main.worksheet.sc")(identity) - _ = assertNoDiff( - workspace.resolve("a/src/main/scala/foo/Main.worksheet.sc").readText, - """ - |val x = 1 /*> : Int = 1 */ - |val foo = "bar" /*> : String = "bar" */ - |println("metals") /*> metals */ - |""".stripMargin, - ) - _ <- assertHovers( - "a/src/main/scala/foo/Main.worksheet.sc", - """ - |val x = 1 /*> : Int@@ = 1 */ - |val foo = "bar" /*> : @@String = "bar" */ - |println("metals") /*> @@metals */ - |""".stripMargin, - """x: Int = 1""".hover, - """foo: String = "bar"""".hover, - """// metals""".hover, - ) - } yield () - } - - test("new-edits") { - for { - _ <- initialize( - s""" - |/metals.json - |{ - | "a": { } - |} - |/a/src/main/scala/foo/Main.worksheet.sc - |val x = 2 /*> 1 */ - |val foo = "baz" /*> "bar" */ - |println("meta ls") /*> metals */ - |""".stripMargin - ) - _ <- server.didOpen("a/src/main/scala/foo/Main.worksheet.sc") - _ <- server.didSave("a/src/main/scala/foo/Main.worksheet.sc")(identity) - _ = assertNoDiff( - workspace.resolve("a/src/main/scala/foo/Main.worksheet.sc").readText, - """ - |val x = 2 /*> : Int = 2 */ - |val foo = "baz" /*> : String = "baz" */ - |println("meta ls") /*> meta ls */ - |""".stripMargin, - ) - _ <- assertHovers( - "a/src/main/scala/foo/Main.worksheet.sc", - """ - |val x = 2 /*> : Int @@= 2 */ - |val foo = "baz" /*> : String = "baz"@@ */ - |println("meta ls") /*> meta@@ ls */ - |""".stripMargin, - """x: Int = 2""".hover, - """foo: String = "baz"""".hover, - """// meta ls""".hover, - ) - } yield () - } - - private def assertHovers( - filename: String, - query: String, - expected: String* - )(implicit loc: Location): Future[Unit] = { - val queriesAndExpected = - "@@".r - .findAllMatchIn(query) - .map { m => - val before = query.substring(0, m.start).replace("@@", "") - val after = query.substring(m.end).replace("@@", "") - before + "@@" + after - } - .toList - .zip(expected.toList) - - Future - .traverse(queriesAndExpected) { case (q, e) => - server.assertHover(filename, q, e) - } - .map(_ => ()) - } - -} diff --git a/website/i18n/en.json b/website/i18n/en.json index 8494a5001cd..d7f9e5ae787 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -69,10 +69,6 @@ "title": "Debug Adapter Protocol", "sidebar_label": "Debug Adapter Protocol" }, - "integrations/decoration-protocol": { - "title": "Decoration Protocol v0.2.0", - "sidebar_label": "Decoration Protocol" - }, "integrations/new-build-tool": { "title": "Integrating a new build tool" }, diff --git a/website/sidebars.json b/website/sidebars.json index 245e8c9f599..d7bcfac6eb0 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -34,7 +34,6 @@ "integrations/new-editor", "integrations/test-explorer", "integrations/tree-view-protocol", - "integrations/decoration-protocol", "integrations/debug-adapter-protocol" ], "Troubleshooting": [