Skip to content

Commit

Permalink
Merge pull request #131 from gabro/workspace-execute-command
Browse files Browse the repository at this point in the history
Add workspace/executeCommand and clearIndexCache command
  • Loading branch information
gabro committed Dec 15, 2017
2 parents 3e35435 + 867e5b2 commit 892e5f1
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 8 deletions.
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ lazy val V = new {
val scala212 = "2.12.4"
val scalameta = "2.1.5"
val scalafix = "0.5.7"
val enumeratum = "1.5.12"
}

lazy val noPublish = List(
Expand All @@ -81,7 +82,7 @@ lazy val languageserver = project
resolvers += Resolver.bintrayRepo("dhpcs", "maven"),
libraryDependencies ++= Seq(
"com.dhpcs" %% "scala-json-rpc" % "2.0.1",
"com.beachape" %% "enumeratum" % "1.5.12",
"com.beachape" %% "enumeratum" % V.enumeratum,
"com.beachape" %% "enumeratum-play-json" % "1.5.12-2.6.0-M7",
"com.typesafe.scala-logging" %% "scala-logging" % "3.7.2",
"io.monix" %% "monix" % "2.3.0",
Expand Down Expand Up @@ -116,6 +117,7 @@ lazy val metaserver = project
"io.get-coursier" %% "coursier-cache" % coursier.util.Properties.version,
"ch.epfl.scala" % "scalafix-cli" % V.scalafix cross CrossVersion.full,
"org.scalameta" %% "semanticdb-scalac" % V.scalameta cross CrossVersion.full,
"com.beachape" %% "enumeratum" % V.enumeratum,
"com.lihaoyi" %% "utest" % "0.6.0" % Test,
"org.scalameta" %% "testkit" % V.scalameta % Test,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream)(implicit s:
case ("textDocument/hover", request: TextDocumentHoverRequest) => hover(request)
case ("textDocument/references", request: TextDocumentReferencesRequest) => references(request)
case ("textDocument/signatureHelp", request: TextDocumentSignatureHelpRequest) => signatureHelp(request)
case ("workspace/executeCommand", request: WorkspaceExecuteCommandRequest) => executeCommand(request).map(_ => ExecuteCommandResult)
case ("shutdown", _: Shutdown) => shutdown()
case c => Task.raiseError(new IllegalArgumentException(s"Unknown command $c"))
}
Expand Down Expand Up @@ -68,6 +69,8 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream)(implicit s:
def references(request: TextDocumentReferencesRequest): Task[ReferencesResult] = Task.now(ReferencesResult(Nil))
def signatureHelp(request: TextDocumentSignatureHelpRequest): Task[SignatureHelpResult] = Task.now(SignatureHelpResult(Nil, None, None))

// workspace
def executeCommand(request: WorkspaceExecuteCommandRequest): Task[Unit] = Task.now(())

def onOpenTextDocument(td: TextDocumentItem): Unit = {
logger.debug(s"openTextDocument $td")
Expand All @@ -88,5 +91,4 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream)(implicit s:
def onChangeWatchedFiles(changes: Seq[FileEvent]): Unit =
logger.debug(s"changeWatchedFiles $changes")


}
18 changes: 15 additions & 3 deletions languageserver/src/main/scala/langserver/messages/Commands.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ case class ServerCapabilities(
/**
* The server provides rename support.
*/
renameProvider: Boolean = false
renameProvider: Boolean = false,
/**
* The server provides execute command support.
*/
executeCommandProvider: ExecuteCommandOptions = ExecuteCommandOptions(Nil)
)

object ServerCapabilities {
Expand All @@ -133,6 +137,11 @@ object DocumentOnTypeFormattingOptions {
implicit val format: Format[DocumentOnTypeFormattingOptions] = Json.format[DocumentOnTypeFormattingOptions]
}

case class ExecuteCommandOptions(commands: Seq[String])
object ExecuteCommandOptions {
implicit val format: Format[ExecuteCommandOptions] = Json.format[ExecuteCommandOptions]
}

case class CompletionList(isIncomplete: Boolean, items: Seq[CompletionItem]) extends ResultResponse
object CompletionList {
implicit val format = Json.format[CompletionList]
Expand Down Expand Up @@ -183,14 +192,14 @@ case class ReferenceParams(
)

case class DocumentSymbolParams(textDocument: TextDocumentIdentifier) extends ServerCommand

case class TextDocumentSignatureHelpRequest(params: TextDocumentPositionParams) extends ServerCommand
case class TextDocumentCompletionRequest(params: TextDocumentPositionParams) extends ServerCommand
case class TextDocumentDefinitionRequest(params: TextDocumentPositionParams) extends ServerCommand
case class TextDocumentReferencesRequest(params: ReferenceParams) extends ServerCommand
case class TextDocumentDocumentHighlightRequest(params: TextDocumentPositionParams) extends ServerCommand
case class TextDocumentHoverRequest(params: TextDocumentPositionParams) extends ServerCommand
case class TextDocumentFormattingRequest(params: DocumentFormattingParams) extends ServerCommand
case class WorkspaceExecuteCommandRequest(params: WorkspaceExecuteCommandParams) extends ServerCommand

case class Hover(contents: Seq[MarkedString], range: Option[Range]) extends ResultResponse
object Hover {
Expand All @@ -212,7 +221,8 @@ object ServerCommand extends CommandCompanion[ServerCommand] {
"textDocument/documentHighlight" -> valueFormat(TextDocumentDocumentHighlightRequest)(_.params),
"textDocument/hover" -> valueFormat(TextDocumentHoverRequest)(_.params),
"textDocument/documentSymbol" -> Json.format[DocumentSymbolParams],
"textDocument/formatting" -> valueFormat(TextDocumentFormattingRequest)(_.params)
"textDocument/formatting" -> valueFormat(TextDocumentFormattingRequest)(_.params),
"workspace/executeCommand" -> valueFormat(WorkspaceExecuteCommandRequest)(_.params)
)

// NOTE: this is a workaround to read `shutdown` request which doesn't have parameters (scala-json-rpc requires parameters for all requests)
Expand Down Expand Up @@ -294,6 +304,7 @@ case class DocumentFormattingResult(params: Seq[TextEdit]) extends ResultRespons
case class SignatureHelpResult(signatures: Seq[SignatureInformation],
activeSignature: Option[Int],
activeParameter: Option[Int]) extends ResultResponse
case object ExecuteCommandResult extends ResultResponse
object SignatureHelpResult {
implicit val format = Json.format[SignatureHelpResult]
}
Expand All @@ -311,6 +322,7 @@ object ResultResponse extends ResponseCompanion[Any] {
"textDocument/hover" -> Json.format[Hover],
"textDocument/documentSymbol" -> valueFormat(DocumentSymbolResult)(_.params),
"textDocument/formatting" -> valueFormat(DocumentFormattingResult)(_.params),
"workspace/executeCommand" -> emptyFormat[ExecuteCommandResult.type],
"shutdown" -> ShutdownResult.format
)
}
6 changes: 6 additions & 0 deletions languageserver/src/main/scala/langserver/types/types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ object DocumentFormattingParams {
implicit val format = Json.format[DocumentFormattingParams]
}

case class WorkspaceExecuteCommandParams(command: String, arguments: Option[Seq[JsValue]])
object WorkspaceExecuteCommandParams {
implicit val format = Json.format[WorkspaceExecuteCommandParams]
}


/**
* An event describing a file change.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,14 @@ object JsonRpcUtils {
* )
* }}}
*/
def valueFormat[A, B: Format](apply: B => A)(unapply: A => B): Format[A] = new Format[A] {
def valueFormat[A, B: Format](apply: B => A)(unapply: A => B): Format[A] = new Format[A] {
override def reads(json: JsValue) = Reads.of[B].reads(json).map(apply(_))
override def writes(o: A) = Writes.of[B].writes(unapply(o))
}

def emptyFormat[A]: Format[A] = new Format[A] {
override def reads(json: JsValue) = ???
override def writes(u: A) = JsObject.empty
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ package scala.meta.languageserver
import java.io.InputStream
import java.io.OutputStream
import java.io.PrintStream
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.SimpleFileVisitor
import java.nio.file.FileVisitResult
import java.nio.file.attribute.BasicFileAttributes
import scala.concurrent.duration.FiniteDuration
import scala.meta.languageserver.compiler.CompilerConfig
import scala.meta.languageserver.compiler.Cursor
Expand Down Expand Up @@ -36,6 +42,8 @@ import langserver.messages.TextDocumentFormattingRequest
import langserver.messages.TextDocumentHoverRequest
import langserver.messages.TextDocumentReferencesRequest
import langserver.messages.TextDocumentSignatureHelpRequest
import langserver.messages.WorkspaceExecuteCommandRequest
import langserver.messages.ExecuteCommandOptions
import langserver.types._
import monix.eval.Task
import monix.execution.Cancelable
Expand Down Expand Up @@ -135,6 +143,8 @@ class ScalametaLanguageServer(
}
}

private val clearIndexCacheCommand = "clearIndexCache"

override def initialize(
request: InitializeParams
): Task[InitializeResult] = Task {
Expand All @@ -158,7 +168,9 @@ class ScalametaLanguageServer(
documentHighlightProvider = true,
documentSymbolProvider = true,
documentFormattingProvider = true,
hoverProvider = true
hoverProvider = true,
executeCommandProvider =
ExecuteCommandOptions(WorkspaceCommand.values.map(_.entryName))
)
InitializeResult(capabilities)
}
Expand Down Expand Up @@ -289,6 +301,18 @@ class ScalametaLanguageServer(
sourceChangeSubscriber.onNext(input)
}

override def executeCommand(request: WorkspaceExecuteCommandRequest) = Task {
import WorkspaceCommand._
WorkspaceCommand
.withNameOption(request.params.command)
.map {
case ClearIndexCache =>
logger.info("Clearing the index cache")
ScalametaLanguageServer.clearCacheDirectory()
}
.getOrElse(logger.error(s"Unknown command ${request.params.command}"))
}

override def onChangeTextDocument(
td: VersionedTextDocumentIdentifier,
changes: Seq[TextDocumentContentChangeEvent]
Expand Down Expand Up @@ -323,6 +347,27 @@ object ScalametaLanguageServer extends LazyLogging {
path
}

def clearCacheDirectory(): Unit =
Files.walkFileTree(
cacheDirectory.toNIO,
new SimpleFileVisitor[Path] {
override def visitFile(
file: Path,
attr: BasicFileAttributes
): FileVisitResult = {
Files.delete(file)
FileVisitResult.CONTINUE
}
override def postVisitDirectory(
dir: Path,
exc: IOException
): FileVisitResult = {
Files.delete(dir)
FileVisitResult.CONTINUE
}
}
)

def compilerConfigStream(cwd: AbsolutePath)(
implicit scheduler: Scheduler
): (Observer.Sync[AbsolutePath], Observable[CompilerConfig]) = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package scala.meta.languageserver

import enumeratum.Enum
import enumeratum.EnumEntry
import enumeratum.EnumEntry.Uncapitalised

sealed trait WorkspaceCommand extends EnumEntry with Uncapitalised

case object WorkspaceCommand extends Enum[WorkspaceCommand] {

case object ClearIndexCache extends WorkspaceCommand

val values = findValues

}
4 changes: 4 additions & 0 deletions vscode-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"command": "scalameta.restartServer",
"category": "Scalameta Language Server",
"title": "Restart server"
}, {
"command": "scalameta.clearIndexCache",
"category": "Scalameta Language Server",
"title": "Clear index cache"
}]
},
"main": "./out/extension",
Expand Down
10 changes: 9 additions & 1 deletion vscode-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
LanguageClientOptions,
ServerOptions,
TransportKind,
RevealOutputChannelOn
RevealOutputChannelOn,
ExecuteCommandRequest
} from 'vscode-languageclient';
import { Requirements } from './requirements';
import { exec } from 'child_process';
Expand Down Expand Up @@ -91,5 +92,12 @@ export async function activate(context: ExtensionContext) {
}
});

client.onReady().then(() => {
const clearIndexCacheCommand = commands.registerCommand("scalameta.clearIndexCache", async () => {
return client.sendRequest(ExecuteCommandRequest.type, { command: "clearIndexCache" });
});
context.subscriptions.push(clearIndexCacheCommand);
});

context.subscriptions.push(client.start(), restartServerCommand);
}

0 comments on commit 892e5f1

Please sign in to comment.