@@ -13,8 +13,6 @@ import * as vscode from 'vscode';
1313import { LanguageClient , LanguageClientOptions , RevealOutputChannelOn ,
1414 ServerOptions } from 'vscode-languageclient' ;
1515import { enableOldServerWorkaround } from './compat'
16- import { WorksheetPublishOutputNotification } from './protocol'
17- import * as worksheet from './worksheet'
1816import * as features from './features'
1917
2018export let client : LanguageClient
@@ -68,29 +66,62 @@ export function activate(context: ExtensionContext) {
6866 } )
6967
7068 } else if ( ! fs . existsSync ( disableDottyIDEFile ) ) {
71- let configuredProject : Thenable < void > = Promise . resolve ( )
72- if ( ! isConfiguredProject ( ) ) {
73- configuredProject = vscode . window . showInformationMessage (
74- "This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?" ,
75- "Yes" , "No"
76- ) . then ( choice => {
77- if ( choice === "Yes" ) {
78- bootstrapSbtProject ( buildSbtFileSource , dottyPluginSbtFileSource )
79- return Promise . resolve ( )
80- } else if ( choice === "No" ) {
81- fs . appendFile ( disableDottyIDEFile , "" , _ => { } )
82- return Promise . reject ( )
83- }
84- } )
85- . then ( _ => connectToSbt ( coursierPath ) )
86- . then ( sbt => {
87- return withProgress ( "Configuring Dotty IDE..." , configureIDE ( sbt ) )
88- . then ( _ => { sbtserver . tellSbt ( outputChannel , sbt , "exit" ) } )
69+
70+ if ( ! vscode . workspace . workspaceFolders ) {
71+ if ( vscode . window . activeTextEditor ) {
72+ setWorkspaceAndReload ( vscode . window . activeTextEditor . document )
73+ }
74+ } else {
75+ let configuredProject : Thenable < void > = Promise . resolve ( )
76+ if ( ! isConfiguredProject ( ) ) {
77+ configuredProject = vscode . window . showInformationMessage (
78+ "This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?" ,
79+ "Yes" , "No"
80+ ) . then ( choice => {
81+ if ( choice === "Yes" ) {
82+ bootstrapSbtProject ( buildSbtFileSource , dottyPluginSbtFileSource )
83+ return Promise . resolve ( )
84+ } else if ( choice === "No" ) {
85+ fs . appendFile ( disableDottyIDEFile , "" , _ => { } )
86+ return Promise . reject ( )
87+ }
8988 } )
89+ . then ( _ => connectToSbt ( coursierPath ) )
90+ . then ( sbt => {
91+ return withProgress ( "Configuring Dotty IDE..." , configureIDE ( sbt ) )
92+ . then ( _ => { sbtserver . tellSbt ( outputChannel , sbt , "exit" ) } )
93+ } )
94+ }
95+
96+ configuredProject
97+ . then ( _ => runLanguageServer ( coursierPath , languageServerArtifactFile ) )
9098 }
99+ }
100+ }
91101
92- configuredProject
93- . then ( _ => runLanguageServer ( coursierPath , languageServerArtifactFile ) )
102+ /**
103+ * Find and set a workspace root if no folders are open in the workspace. If there are already
104+ * folders open in the workspace, do nothing.
105+ *
106+ * Adding a first folder to the workspace completely reloads the extension.
107+ */
108+ function setWorkspaceAndReload ( document : vscode . TextDocument ) {
109+ const documentPath = path . parse ( document . uri . fsPath ) . dir
110+ const workspaceRoot = findWorkspaceRoot ( documentPath ) || documentPath
111+ vscode . workspace . updateWorkspaceFolders ( 0 , null , { uri : vscode . Uri . file ( workspaceRoot ) } )
112+ }
113+
114+ /**
115+ * Find the closest parent of `current` that contains a `build.sbt`.
116+ */
117+ function findWorkspaceRoot ( current : string ) : string | undefined {
118+ const build = path . join ( current , "build.sbt" )
119+ if ( fs . existsSync ( build ) ) return current
120+ else {
121+ const parent = path . resolve ( current , ".." )
122+ if ( parent != current ) {
123+ return findWorkspaceRoot ( parent )
124+ }
94125 }
95126}
96127
0 commit comments