Skip to content

Commit 688c149

Browse files
committed
IDE: Find and add workspace root if there are none
When the IDE is opened without a workspace (no folder is open), and then a Scala source is opened, we will now search for the closest possible workspace root (the closest parent directory that contains a `build.sbt`). If no such directory can be found, the parent directory of the file that has been opened is chosen. This folder is then added as a workspace folder. Adding a new workspace folder triggers a reloading of the extension. The code of the extension will be executed in an environment where a workspace root is set, and Dotty IDE will be able to start correctly. Fixes #5281
1 parent ba81b0e commit 688c149

File tree

1 file changed

+53
-20
lines changed

1 file changed

+53
-20
lines changed

vscode-dotty/src/extension.ts

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,29 +66,62 @@ export function activate(context: ExtensionContext) {
6666
})
6767

6868
} else if (!fs.existsSync(disableDottyIDEFile)) {
69-
let configuredProject: Thenable<void> = Promise.resolve()
70-
if (!isConfiguredProject()) {
71-
configuredProject = vscode.window.showInformationMessage(
72-
"This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?",
73-
"Yes", "No"
74-
).then(choice => {
75-
if (choice === "Yes") {
76-
bootstrapSbtProject(buildSbtFileSource, dottyPluginSbtFileSource)
77-
return Promise.resolve()
78-
} else if (choice === "No") {
79-
fs.appendFile(disableDottyIDEFile, "", _ => {})
80-
return Promise.reject()
81-
}
82-
})
83-
.then(_ => connectToSbt(coursierPath))
84-
.then(sbt => {
85-
return withProgress("Configuring Dotty IDE...", configureIDE(sbt))
86-
.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+
}
8788
})
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))
8898
}
99+
}
100+
}
89101

90-
configuredProject
91-
.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.path).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+
}
92125
}
93126
}
94127

0 commit comments

Comments
 (0)