This repository has been archived by the owner on Jun 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added ensime-based implementation of LangServer
Managed to start ensime and get some events flowing.
- Loading branch information
Showing
12 changed files
with
299 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,5 @@ target/ | |
.settings/ | ||
node_modules/ | ||
out/ | ||
.DS_Store | ||
.DS_Store | ||
.ensime_cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
appender("FILE", FileAppender) { | ||
file = "ensime-langserver.log" | ||
append = false | ||
encoder(PatternLayoutEncoder) { | ||
pattern = "%level %logger - %msg%n" | ||
} | ||
} | ||
|
||
root(DEBUG, ["FILE"]) | ||
logger("slick", ERROR, ["FILE"]) | ||
logger("langserver.core", ERROR, ["FILE"]) | ||
logger("scala.tools.nsc", ERROR, ["FILE"]) |
96 changes: 96 additions & 0 deletions
96
ensime-server/src/main/scala/org/github/dragos/vscode/EnsimeLanguageServer.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package org.github.dragos.vscode | ||
|
||
import java.io.File | ||
import java.io.InputStream | ||
import java.io.OutputStream | ||
|
||
import org.ensime.api._ | ||
import org.ensime.config.EnsimeConfigProtocol | ||
|
||
import com.google.common.base.Charsets | ||
import com.google.common.io.Files | ||
|
||
import akka.actor.ActorSystem | ||
import langserver.core.LanguageServer | ||
import langserver.messages._ | ||
import langserver.types.TextDocumentIdentifier | ||
import langserver.types.TextDocumentContentChangeEvent | ||
import langserver.types.VersionedTextDocumentIdentifier | ||
import langserver.types.TextDocumentItem | ||
import akka.actor.ActorRef | ||
import akka.actor.Props | ||
import org.ensime.api.TypecheckFileReq | ||
import java.net.URI | ||
import scalariform.formatter.preferences.FormattingPreferences | ||
|
||
class EnsimeLanguageServer(in: InputStream, out: OutputStream) extends LanguageServer(in, out) { | ||
private val system = ActorSystem("ENSIME") | ||
|
||
private var ensimeProject: ActorRef = _ | ||
|
||
override def initialize(pid: Long, rootPath: String, capabilities: ClientCapabilities): ServerCapabilities = { | ||
logger.info(s"Initialized with $pid, $rootPath, $capabilities") | ||
val rootFile = new File(rootPath) | ||
val cacheDir = new File(rootFile, ".ensime-vscode-cache") | ||
cacheDir.mkdir() | ||
val noConfig = EnsimeConfig( | ||
rootFile, | ||
cacheDir, | ||
javaHome = new File(scala.util.Properties.javaHome), | ||
name = "scala", | ||
scalaVersion = "2.11.8", | ||
compilerArgs = Nil, | ||
referenceSourceRoots = Nil, | ||
subprojects = Nil, | ||
formattingPrefs = FormattingPreferences(), | ||
sourceMode = false, | ||
javaLibs = Nil) | ||
|
||
val ensimeFile = new File(s"$rootPath/.ensime") | ||
val config: EnsimeConfig = try { | ||
EnsimeConfigProtocol.parse(Files.toString(ensimeFile, Charsets.UTF_8)) | ||
} catch { | ||
case e: Throwable => | ||
showMessage(MessageType.Error, s"There was a problem parsing $ensimeFile ${e.getMessage}") | ||
noConfig | ||
} | ||
showMessage(MessageType.Info, s"Using configuration: $ensimeFile") | ||
logger.info(s"Using configuration: $config") | ||
|
||
ensimeProject = system.actorOf(Props(classOf[EnsimeProjectServer], config)) | ||
|
||
// we don't give a damn about them, but Ensime expects it | ||
ensimeProject ! ConnectionInfoReq | ||
ServerCapabilities(completionProvider = Some(CompletionOptions(false, Seq(".")))) | ||
} | ||
|
||
override def onOpenTextDocument(td: TextDocumentItem) = { | ||
logger.debug(s"openTextDocuemnt $td") | ||
|
||
val f = new File(new URI(td.uri)) | ||
ensimeProject ! TypecheckFileReq(SourceFileInfo(f, Some(td.text))) | ||
} | ||
|
||
override def onChangeTextDocument(td: VersionedTextDocumentIdentifier, changes: Seq[TextDocumentContentChangeEvent]) = { | ||
logger.debug(s"changeTextDocuemnt $td") | ||
|
||
val f = new File(new URI(td.uri)) | ||
|
||
// we assume full text sync | ||
assert(changes.size == 1) | ||
val change = changes.head | ||
assert(change.range.isEmpty) | ||
assert(change.rangeLength.isEmpty) | ||
|
||
ensimeProject ! TypecheckFileReq(SourceFileInfo(f, Some(change.text))) | ||
} | ||
|
||
override def onSaveTextDocument(td: TextDocumentIdentifier) = { | ||
logger.debug(s"saveTextDocuemnt $td") | ||
showMessage(MessageType.Info, s"Saved text document ${td.uri}") | ||
} | ||
|
||
override def onCloseTextDocument(td: TextDocumentIdentifier) = { | ||
logger.debug(s"closeTextDocuemnt $td") | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
ensime-server/src/main/scala/org/github/dragos/vscode/EnsimeProjectServer.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package org.github.dragos.vscode | ||
|
||
import scala.collection.mutable.ListBuffer | ||
import scala.concurrent.duration._ | ||
|
||
import org.ensime.api._ | ||
import org.ensime.api.EnsimeConfig | ||
import org.ensime.core.Broadcaster | ||
import org.ensime.core.Project | ||
|
||
import com.typesafe.scalalogging.LazyLogging | ||
|
||
import akka.actor.Actor | ||
import akka.util.Timeout | ||
|
||
class EnsimeProjectServer(implicit val config: EnsimeConfig) extends Actor with LazyLogging { | ||
implicit val timeout: Timeout = Timeout(10 seconds) | ||
|
||
val broadcaster = context.actorOf(Broadcaster(), "broadcaster") | ||
val project = context.actorOf(Project(broadcaster), "project") | ||
|
||
override def preStart() { | ||
broadcaster ! Broadcaster.Register | ||
} | ||
|
||
val compilerDiagnostics: ListBuffer[Note] = ListBuffer.empty | ||
|
||
override def receive = { | ||
case ClearAllScalaNotesEvent => | ||
compilerDiagnostics.clear() | ||
|
||
case NewScalaNotesEvent(isFull, notes) => | ||
compilerDiagnostics ++= notes | ||
publishDiagnostics() | ||
|
||
case AnalyzerReadyEvent => | ||
logger.info("Analyzer is ready!") | ||
|
||
case FullTypeCheckCompleteEvent => | ||
logger.info("Full typecheck complete event") | ||
|
||
case message => | ||
project forward message | ||
} | ||
|
||
private def publishDiagnostics(): Unit = { | ||
logger.debug(s"Scala notes: ${compilerDiagnostics}") | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
ensime-server/src/main/scala/org/github/dragos/vscode/Main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.github.dragos.vscode | ||
|
||
import com.typesafe.scalalogging.LazyLogging | ||
import scala.util.Properties | ||
|
||
object Main extends LazyLogging { | ||
def main(args: Array[String]): Unit = { | ||
logger.info(s"Starting server in ${System.getenv("PWD")}") | ||
logger.info(s"Classpath: ${Properties.javaClassPath}") | ||
|
||
val server = new EnsimeLanguageServer(System.in, System.out) | ||
server.start() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
appender("FILE", FileAppender) { | ||
file = "scala-langserver.log" | ||
append = false | ||
encoder(PatternLayoutEncoder) { | ||
pattern = "%level %logger - %msg%n" | ||
} | ||
} | ||
|
||
root(DEBUG, ["FILE"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.