diff --git a/metals/src/main/scala/scala/meta/internal/builds/BloopInstall.scala b/metals/src/main/scala/scala/meta/internal/builds/BloopInstall.scala index dc0f92c42f0..7061fe8d752 100644 --- a/metals/src/main/scala/scala/meta/internal/builds/BloopInstall.scala +++ b/metals/src/main/scala/scala/meta/internal/builds/BloopInstall.scala @@ -7,7 +7,6 @@ import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.meta.internal.builds.Digest.Status -import scala.meta.internal.metals.AutoImportBuildKind import scala.meta.internal.metals.BuildInfo import scala.meta.internal.metals.Confirmation import scala.meta.internal.metals.Messages._ @@ -133,9 +132,7 @@ final class BloopInstall( scribe.info(s"skipping build import with status '${result.name}'") Future.successful(result) case _ => - if ( - userConfig().automaticImportBuild == AutoImportBuildKind.Initial || userConfig().automaticImportBuild == AutoImportBuildKind.All - ) { + if (userConfig().shouldAutoImportNewProject) { runUnconditionally(buildTool, isImportInProcess) } else { scribe.debug("Awaiting user response...") diff --git a/metals/src/main/scala/scala/meta/internal/metals/Messages.scala b/metals/src/main/scala/scala/meta/internal/metals/Messages.scala index 6dca10da430..074641ccd64 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/Messages.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/Messages.scala @@ -189,6 +189,31 @@ object Messages { } } + object GenerateBspAndConnect { + def yes = new MessageActionItem("Connect") + + def notNow: MessageActionItem = Messages.notNow + + def params( + buildToolName: String, + buildServerName: String, + ): ShowMessageRequestParams = { + val params = new ShowMessageRequestParams() + params.setMessage( + s"New $buildToolName workspace detected, would you like connect to $buildServerName build server?" + ) + params.setType(MessageType.Info) + params.setActions( + List( + yes, + notNow, + dontShowAgain, + ).asJava + ) + params + } + } + object MainClass { val message = "Multiple main classes found. Which would you like to run?" } 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 d7abe8e0011..ae90dd60092 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala @@ -2126,14 +2126,28 @@ class MetalsLspService( .flatMap(_ => quickConnectToBuildServer()) case Some(BuildTool.Found(buildTool: BuildServerProvider, _)) if !buildTool.isBspGenerated(folder) => - tables.buildServers.chooseServer(buildTool.buildServerName) - buildTool - .generateBspConfig( - folder, - args => bspConfigGenerator.runUnconditionally(buildTool, args), - statusBar, - ) - .flatMap(_ => quickConnectToBuildServer()) + val notification = tables.dismissedNotifications.ImportChanges + if (userConfig.shouldAutoImportNewProject) { + generateBspAndConnect(buildTool) + } else if (notification.isDismissed) { + Future.successful(BuildChange.None) + } else { + scribe.debug("Awaiting user response...") + languageClient + .showMessageRequest( + Messages.GenerateBspAndConnect + .params(buildTool.executableName, buildTool.buildServerName) + ) + .asScala + .flatMap { item => + if (item == Messages.dontShowAgain) { + notification.dismissForever() + Future.successful(BuildChange.None) + } else if (item == Messages.GenerateBspAndConnect.yes) { + generateBspAndConnect(buildTool) + } else Future.successful(BuildChange.None) + } + } case Some(BuildTool.Found(buildTool, _)) if !chosenBuildServer.exists( _ == buildTool.buildServerName @@ -2157,6 +2171,19 @@ class MetalsLspService( } } + def generateBspAndConnect( + buildTool: BuildServerProvider + ): Future[BuildChange] = { + tables.buildServers.chooseServer(buildTool.buildServerName) + buildTool + .generateBspConfig( + folder, + args => bspConfigGenerator.runUnconditionally(buildTool, args), + statusBar, + ) + .flatMap(_ => quickConnectToBuildServer()) + } + /** * If there is no auto-connectable build server and no supported build tool is found * we assume it's a scala-cli project. diff --git a/metals/src/main/scala/scala/meta/internal/metals/UserConfiguration.scala b/metals/src/main/scala/scala/meta/internal/metals/UserConfiguration.scala index 7d34bf5d818..b4686eecbc9 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/UserConfiguration.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/UserConfiguration.scala @@ -59,6 +59,9 @@ case class UserConfiguration( preferredBuildServes: List[String] = Nil, ) { + def shouldAutoImportNewProject: Boolean = + automaticImportBuild != AutoImportBuildKind.Off + def currentBloopVersion: String = bloopVersion.getOrElse(BuildInfo.bloopVersion) diff --git a/tests/slow/src/test/scala/tests/PreferredBuildServer.scala b/tests/slow/src/test/scala/tests/PreferredBuildServer.scala index 453a11e8799..d96e4b25ef2 100644 --- a/tests/slow/src/test/scala/tests/PreferredBuildServer.scala +++ b/tests/slow/src/test/scala/tests/PreferredBuildServer.scala @@ -1,5 +1,6 @@ package tests +import scala.meta.internal.metals.Messages import scala.meta.internal.metals.UserConfiguration import scala.meta.internal.metals.{BuildInfo => V} @@ -10,6 +11,15 @@ class PreferredBuildServer extends BaseLspSuite("preferred-build-server") { test("start-sbt-when-preferred-no-bsp") { cleanWorkspace() + val importMessage = + Messages.GenerateBspAndConnect.params("sbt", "sbt").getMessage() + + client.showMessageRequestHandler = msg => { + if (msg.getMessage() == importMessage) + Some(Messages.GenerateBspAndConnect.notNow) + else None + } + val fileLayout = s"""|/project/build.properties |sbt.version=${V.sbtVersion} @@ -28,12 +38,11 @@ class PreferredBuildServer extends BaseLspSuite("preferred-build-server") { for { _ <- server.initialize() _ <- server.initialized() - _ <- server.server.buildServerPromise.future _ = assertNoDiff( - server.server.tables.buildServers.selectedServer().get, - "sbt", + client.workspaceMessageRequests, + importMessage, ) - _ = assert(server.server.bspSession.exists(_.main.isSbt)) + _ = assert(server.server.bspSession.isEmpty) } yield () }