Skip to content

Commit

Permalink
Merge pull request #2776 from dotty-staging/ide-path
Browse files Browse the repository at this point in the history
Make the IDE work under Windows
  • Loading branch information
smarter committed Jun 19, 2017
2 parents 3242e86 + d74757f commit 6ade705
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 68 deletions.
4 changes: 3 additions & 1 deletion docs/docs/usage/ide-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ Usage
=====
1. Install [Visual Studio Code](https://code.visualstudio.com/).
2. Make sure `code`, the binary for Visual Studio Code, is on your `$PATH`, this
is the case if you can start the IDE by running `code` in a terminal.
is the case if you can start the IDE by running `code` in a terminal. This
is the default on all systems except Mac where you'll need to follow these
instructions: https://code.visualstudio.com/docs/setup/mac#_command-line
3. In your project, run:
```shell
sbt launchIDE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class DottyLanguageServer extends LanguageServer

myDrivers = new mutable.HashMap
for (config <- configs) {
val classpathFlags = List("-classpath", (config.classDirectory +: config.dependencyClasspath).mkString(":"))
val classpathFlags = List("-classpath", (config.classDirectory +: config.dependencyClasspath).mkString(File.pathSeparator))
val settings = defaultFlags ++ config.compilerArguments.toList ++ classpathFlags
myDrivers.put(config, new InteractiveDriver(settings))
}
Expand All @@ -76,7 +76,7 @@ class DottyLanguageServer extends LanguageServer
def driverFor(uri: URI): InteractiveDriver = {
val matchingConfig =
drivers.keys.find(config => config.sourceDirectories.exists(sourceDir =>
uri.getRawPath.startsWith(sourceDir.getAbsolutePath.toString)))
new File(uri.getPath).getCanonicalPath.startsWith(sourceDir.getCanonicalPath)))
matchingConfig match {
case Some(config) =>
drivers(config)
Expand Down
72 changes: 19 additions & 53 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import sbt.Package.ManifestAttributes
import com.typesafe.sbteclipse.plugin.EclipsePlugin._

import dotty.tools.sbtplugin.DottyPlugin.autoImport._
import dotty.tools.sbtplugin.DottyIDEPlugin.{ prepareCommand, runProcess }
import dotty.tools.sbtplugin.DottyIDEPlugin.autoImport._
import org.scalajs.sbtplugin.ScalaJSPlugin
import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._
Expand Down Expand Up @@ -766,8 +767,13 @@ object Build {
val mainClass = "dotty.tools.languageserver.Main"
val extensionPath = (baseDirectory in `vscode-dotty`).value.getAbsolutePath

val codeArgs = if (inputArgs.isEmpty) List((baseDirectory.value / "..").getAbsolutePath) else inputArgs
val allArgs = List("-client_command", "code", s"--extensionDevelopmentPath=$extensionPath") ++ codeArgs
val codeArgs =
s"--extensionDevelopmentPath=$extensionPath" +:
(if (inputArgs.isEmpty) List((baseDirectory.value / "..").getAbsolutePath) else inputArgs)

val clientCommand = prepareCommand(codeCommand.value ++ codeArgs)

val allArgs = "-client_command" +: clientCommand

runTask(Runtime, mainClass, allArgs: _*)
}.dependsOn(compile in (`vscode-dotty`, Compile)).evaluated
Expand Down Expand Up @@ -893,7 +899,7 @@ object Build {


sbtPlugin := true,
version := "0.1.2",
version := "0.1.3",
ScriptedPlugin.scriptedSettings,
ScriptedPlugin.sbtTestDirectory := baseDirectory.value / "sbt-test",
ScriptedPlugin.scriptedBufferLog := false,
Expand Down Expand Up @@ -924,76 +930,36 @@ object Build {
compile in Compile := {
val coursier = baseDirectory.value / "out/coursier"
val packageJson = baseDirectory.value / "package.json"
if (!coursier.exists || packageJson.lastModified > coursier.lastModified) {
val exitCode = new java.lang.ProcessBuilder("npm", "run", "update-all")
.directory(baseDirectory.value)
.inheritIO()
.start()
.waitFor()
if (exitCode != 0)
throw new MessageOnlyException("'npm run update-all' in vscode-dotty failed")
}
if (!coursier.exists || packageJson.lastModified > coursier.lastModified)
runProcess(Seq("npm", "run", "update-all"), wait = true, directory = baseDirectory.value)
val tsc = baseDirectory.value / "node_modules" / ".bin" / "tsc"
val exitCodeTsc = new java.lang.ProcessBuilder(tsc.getAbsolutePath, "--pretty", "--project", baseDirectory.value.getAbsolutePath)
.inheritIO()
.start()
.waitFor()
if (exitCodeTsc != 0)
throw new MessageOnlyException("tsc in vscode-dotty failed")
runProcess(Seq(tsc.getAbsolutePath, "--pretty", "--project", baseDirectory.value.getAbsolutePath), wait = true)

// Currently, vscode-dotty depends on daltonjorge.scala for syntax highlighting,
// this is not automatically installed when starting the extension in development mode
// (--extensionDevelopmentPath=...)
val exitCodeInstall = new java.lang.ProcessBuilder("code", "--install-extension", "daltonjorge.scala")
.inheritIO()
.start()
.waitFor()
if (exitCodeInstall != 0)
throw new MessageOnlyException("Installing dependency daltonjorge.scala failed")
runProcess(codeCommand.value ++ Seq("--install-extension", "daltonjorge.scala"), wait = true)

sbt.inc.Analysis.Empty
},
sbt.Keys.`package`:= {
val exitCode = new java.lang.ProcessBuilder("vsce", "package")
.directory(baseDirectory.value)
.inheritIO()
.start()
.waitFor()
if (exitCode != 0)
throw new MessageOnlyException("vsce package failed")
runProcess(Seq("vsce", "package"), wait = true, directory = baseDirectory.value)

baseDirectory.value / s"dotty-${version.value}.vsix"
},
unpublish := {
val exitCode = new java.lang.ProcessBuilder("vsce", "unpublish")
.directory(baseDirectory.value)
.inheritIO()
.start()
.waitFor()
if (exitCode != 0)
throw new MessageOnlyException("vsce unpublish failed")
runProcess(Seq("vsce", "unpublish"), wait = true, directory = baseDirectory.value)
},
publish := {
val exitCode = new java.lang.ProcessBuilder("vsce", "publish")
.directory(baseDirectory.value)
.inheritIO()
.start()
.waitFor()
if (exitCode != 0)
throw new MessageOnlyException("vsce publish failed")
runProcess(Seq("vsce", "publish"), wait = true, directory = baseDirectory.value)
},
run := Def.inputTask {
val inputArgs = spaceDelimited("<arg>").parsed
val codeArgs = if (inputArgs.isEmpty) List((baseDirectory.value / "..").getAbsolutePath) else inputArgs
val extensionPath = baseDirectory.value.getAbsolutePath
val processArgs = List("code", s"--extensionDevelopmentPath=${extensionPath}") ++ codeArgs

val exitCode = new java.lang.ProcessBuilder(processArgs: _*)
.inheritIO()
.start()
.waitFor()
if (exitCode != 0)
throw new MessageOnlyException("Running Visual Studio Code failed")
val processArgs = List(s"--extensionDevelopmentPath=${extensionPath}") ++ codeArgs

runProcess(codeCommand.value ++ processArgs, wait = true)
}.dependsOn(compile in Compile).evaluated
)

Expand Down
42 changes: 32 additions & 10 deletions sbt-dotty/src/dotty/tools/sbtplugin/DottyIDEPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import sbt.Keys._
import java.io._
import java.lang.ProcessBuilder
import scala.collection.mutable
import scala.util.Properties.{ isWin, isMac }

import dotty.tools.languageserver.config.ProjectConfig

Expand Down Expand Up @@ -123,9 +124,34 @@ object DottyIDEPlugin extends AutoPlugin {
runTask(joinedTask, state)
}

/** Prepare command to be passed to ProcessBuilder */
def prepareCommand(cmd: Seq[String]): Seq[String] =
if (isWin) Seq("cmd.exe", "/C") ++ cmd
else cmd

/** Run `cmd`.
* @param wait If true, wait for `cmd` to return and throw an exception if the exit code is non-zero.
* @param directory If not null, run `cmd` in this directory.
*/
def runProcess(cmd: Seq[String], wait: Boolean = false, directory: File = null): Unit = {
val pb0 = new ProcessBuilder(prepareCommand(cmd): _*).inheritIO()
val pb = if (directory != null) pb0.directory(directory) else pb0
if (wait) {
val exitCode = pb.start().waitFor()
if (exitCode != 0) {
val cmdString = cmd.mkString(" ")
val description = if (directory != null) s""" in directory "$directory"""" else ""
throw new MessageOnlyException(s"""Running command "${cmdString}"${description} failed.""")
}
}
else
pb.start()
}

private val projectConfig = taskKey[Option[ProjectConfig]]("")

object autoImport {
val codeCommand = taskKey[Seq[String]]("Command to start VSCode")
val runCode = taskKey[Unit]("Start VSCode, usually called from launchIDE")
val launchIDE = taskKey[Unit]("Configure and run VSCode on this project")
}
Expand Down Expand Up @@ -203,17 +229,13 @@ object DottyIDEPlugin extends AutoPlugin {
override def buildSettings: Seq[Setting[_]] = Seq(
commands ++= Seq(configureIDE, compileForIDE),

codeCommand := {
Seq("code", "-n")
},

runCode := {
val exitCode = new ProcessBuilder("code", "--install-extension", "lampepfl.dotty")
.inheritIO()
.start()
.waitFor()
if (exitCode != 0)
throw new MessageOnlyException("Installing the Dotty support for VSCode failed")

new ProcessBuilder("code", baseDirectory.value.getAbsolutePath)
.inheritIO()
.start()
runProcess(codeCommand.value ++ Seq("--install-extension", "lampepfl.dotty"), wait = true)
runProcess(codeCommand.value ++ Seq("."), directory = baseDirectory.value)
}

) ++ addCommandAlias("launchIDE", ";configureIDE;runCode")
Expand Down
1 change: 1 addition & 0 deletions vscode-dotty/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ target/**
.vscode/**
.vscode-test/**
out/test/**
out/.keep
test/**
src/**
**/*.map
Expand Down
5 changes: 4 additions & 1 deletion vscode-dotty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ Dotty, please follow the instructions at https://github.com/lampepfl/dotty-examp

## Starting Visual Studio Code from sbt
First, make sure `code`, the binary for Visual Studio Code, is on your `$PATH`,
this is the case if you can start the IDE by running `code` in a terminal.
this is the case if you can start the IDE by running `code` in a terminal. This
is the default on all systems except Mac where you'll need to follow these
instructions: https://code.visualstudio.com/docs/setup/mac#_command-line


If this is the case and your project succesfully compiles with dotty, you can
simply use the `launchIDE` command provided by the sbt-dotty plugin:
Expand Down
Empty file added vscode-dotty/out/.keep
Empty file.
2 changes: 1 addition & 1 deletion vscode-dotty/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"tsc": "./node_modules/.bin/tsc",
"vscode:prepublish": "npm run update-all && ./node_modules/.bin/tsc -p ./",
"compile": "./node_modules/.bin/tsc -p ./",
"update-all": "npm install && node ./node_modules/vscode/bin/install && mkdir -p out && curl -L -o out/coursier https://github.com/coursier/coursier/raw/v1.0.0-RC3/coursier",
"update-all": "npm install && node ./node_modules/vscode/bin/install && curl -L -o out/coursier https://github.com/coursier/coursier/raw/v1.0.0-RC3/coursier",
"test": "node ./node_modules/vscode/bin/test"
},
"extensionDependencies": [
Expand Down

0 comments on commit 6ade705

Please sign in to comment.