@@ -13,28 +13,42 @@ import { LanguageClient, LanguageClientOptions, RevealOutputChannelOn,
13
13
let extensionContext : ExtensionContext
14
14
let outputChannel : vscode . OutputChannel
15
15
16
+ const sbtVersion = "1.2.3"
17
+ const sbtArtifact = `org.scala-sbt:sbt-launch:${ sbtVersion } `
18
+ const workspaceRoot = `${ vscode . workspace . rootPath } `
19
+ const disableDottyIDEFile = path . join ( workspaceRoot , ".dotty-ide-disabled" )
20
+ const sbtProjectDir = path . join ( workspaceRoot , "project" )
21
+ const sbtPluginFile = path . join ( sbtProjectDir , "dotty-plugin.sbt" )
22
+ const sbtBuildPropertiesFile = path . join ( sbtProjectDir , "build.properties" )
23
+ const sbtBuildSbtFile = path . join ( workspaceRoot , "build.sbt" )
24
+ const languageServerArtifactFile = path . join ( workspaceRoot , ".dotty-ide-artifact" )
25
+
26
+ function isUnconfiguredProject ( ) {
27
+ return ! ( fs . existsSync ( disableDottyIDEFile )
28
+ || fs . existsSync ( sbtPluginFile )
29
+ || fs . existsSync ( sbtBuildPropertiesFile )
30
+ || fs . existsSync ( sbtBuildSbtFile )
31
+ )
32
+ }
33
+
16
34
export function activate ( context : ExtensionContext ) {
17
35
extensionContext = context
18
36
outputChannel = vscode . window . createOutputChannel ( 'Dotty Language Client' ) ;
19
37
20
- const sbtArtifact = "org.scala-sbt:sbt-launch:1.2.3"
21
- const buildSbtFile = `${ vscode . workspace . rootPath } /build.sbt`
22
- const dottyPluginSbtFile = path . join ( extensionContext . extensionPath , './out/dotty-plugin.sbt' )
23
- const disableDottyIDEFile = `${ vscode . workspace . rootPath } /.dotty-ide-disabled`
24
- const languageServerArtifactFile = `${ vscode . workspace . rootPath } /.dotty-ide-artifact`
25
- const languageServerDefaultConfigFile = path . join ( extensionContext . extensionPath , './out/default-dotty-ide-config' )
26
- const coursierPath = path . join ( extensionContext . extensionPath , './out/coursier' ) ;
38
+ const coursierPath = path . join ( extensionContext . extensionPath , "out" , "coursier" ) ;
39
+ const dottyPluginSbtFileSource = path . join ( extensionContext . extensionPath , "out" , "dotty-plugin.sbt" )
40
+ const buildSbtFileSource = path . join ( extensionContext . extensionPath , "out" , "build.sbt" )
27
41
28
42
if ( process . env [ 'DLS_DEV_MODE' ] ) {
29
- const portFile = ` ${ vscode . workspace . rootPath } /. dotty-ide-dev-port`
43
+ const portFile = path . join ( workspaceRoot , ". dotty-ide-dev-port" )
30
44
fs . readFile ( portFile , ( err , port ) => {
31
45
if ( err ) {
32
46
outputChannel . append ( `Unable to parse ${ portFile } ` )
33
47
throw err
34
48
}
35
49
36
50
run ( {
37
- module : context . asAbsolutePath ( ' out/ src/ passthrough-server.js' ) ,
51
+ module : context . asAbsolutePath ( path . join ( " out" , " src" , " passthrough-server.js" ) ) ,
38
52
args : [ port . toString ( ) ]
39
53
} )
40
54
} )
@@ -44,20 +58,14 @@ export function activate(context: ExtensionContext) {
44
58
// otherwise, try propose to start it if there's no build.sbt
45
59
if ( fs . existsSync ( languageServerArtifactFile ) ) {
46
60
runLanguageServer ( coursierPath , languageServerArtifactFile )
47
- } else if ( ! fs . existsSync ( disableDottyIDEFile ) && ! fs . existsSync ( buildSbtFile ) ) {
61
+ } else if ( isUnconfiguredProject ( ) ) {
48
62
vscode . window . showInformationMessage (
49
63
"This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?" ,
50
64
"Yes" , "No"
51
65
) . then ( choice => {
52
66
if ( choice == "Yes" ) {
53
- fs . readFile ( languageServerDefaultConfigFile , ( err , data ) => {
54
- if ( err ) throw err
55
- else {
56
- const languageServerScalaVersion = data . toString ( ) . trim ( )
57
- fetchAndConfigure ( coursierPath , sbtArtifact , languageServerScalaVersion , dottyPluginSbtFile ) . then ( ( ) => {
58
- runLanguageServer ( coursierPath , languageServerArtifactFile )
59
- } )
60
- }
67
+ fetchAndConfigure ( coursierPath , sbtArtifact , buildSbtFileSource , dottyPluginSbtFileSource ) . then ( ( ) => {
68
+ runLanguageServer ( coursierPath , languageServerArtifactFile )
61
69
} )
62
70
} else {
63
71
fs . appendFile ( disableDottyIDEFile , "" , _ => { } )
@@ -82,17 +90,17 @@ function runLanguageServer(coursierPath: string, languageServerArtifactFile: str
82
90
} )
83
91
}
84
92
85
- function fetchAndConfigure ( coursierPath : string , sbtArtifact : string , languageServerScalaVersion : string , dottyPluginSbtFile : string ) {
93
+ function fetchAndConfigure ( coursierPath : string , sbtArtifact : string , buildSbtFileSource : string , dottyPluginSbtFileSource : string ) {
86
94
return fetchWithCoursier ( coursierPath , sbtArtifact ) . then ( ( sbtClasspath ) => {
87
- return configureIDE ( sbtClasspath , languageServerScalaVersion , dottyPluginSbtFile )
95
+ return configureIDE ( sbtClasspath , buildSbtFileSource , dottyPluginSbtFileSource )
88
96
} )
89
97
}
90
98
91
99
function fetchWithCoursier ( coursierPath : string , artifact : string , extra : string [ ] = [ ] ) {
92
100
return vscode . window . withProgress ( {
93
101
location : vscode . ProgressLocation . Window ,
94
102
title : `Fetching ${ artifact } `
95
- } , ( progress ) => {
103
+ } , _ => {
96
104
const args = [
97
105
"-jar" , coursierPath ,
98
106
"fetch" ,
@@ -119,20 +127,26 @@ function fetchWithCoursier(coursierPath: string, artifact: string, extra: string
119
127
} )
120
128
}
121
129
122
- function configureIDE ( sbtClasspath : string , languageServerScalaVersion : string , dottyPluginSbtFile : string ) {
130
+ function configureIDE ( sbtClasspath : string ,
131
+ buildSbtFileSource : string ,
132
+ dottyPluginSbtFileSource : string ) {
133
+
123
134
return vscode . window . withProgress ( {
124
135
location : vscode . ProgressLocation . Window ,
125
136
title : 'Configuring the IDE for Dotty...'
126
- } , ( progress ) => {
137
+ } , _ => {
138
+
139
+ // Bootstrap an sbt build
140
+ fs . mkdirSync ( sbtProjectDir )
141
+ fs . appendFileSync ( sbtBuildPropertiesFile , `sbt.version=${ sbtVersion } ` )
142
+ fs . copyFileSync ( buildSbtFileSource , sbtBuildSbtFile )
143
+ fs . copyFileSync ( dottyPluginSbtFileSource , path . join ( sbtProjectDir , "plugins.sbt" ) )
127
144
128
- // Run sbt to configure the IDE. If the `DottyPlugin` is not present, dynamically load it and
129
- // eventually run `configureIDE`.
145
+ // Run sbt to configure the IDE.
130
146
const sbtPromise =
131
147
cpp . spawn ( "java" , [
132
148
"-classpath" , sbtClasspath ,
133
149
"xsbt.boot.Boot" ,
134
- `--addPluginSbtFile=${ dottyPluginSbtFile } ` ,
135
- `set every scalaVersion := "${ languageServerScalaVersion } "` ,
136
150
"configureIDE"
137
151
] )
138
152
@@ -145,7 +159,7 @@ function configureIDE(sbtClasspath: string, languageServerScalaVersion: string,
145
159
}
146
160
} )
147
161
148
- return sbtPromise
162
+ return sbtPromise
149
163
} )
150
164
}
151
165
0 commit comments