Skip to content

Commit

Permalink
IDE: Find and add workspace root if there are none
Browse files Browse the repository at this point in the history
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 scala#5281
  • Loading branch information
Duhemm committed Oct 18, 2018
1 parent ba81b0e commit 688c149
Showing 1 changed file with 53 additions and 20 deletions.
73 changes: 53 additions & 20 deletions vscode-dotty/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,62 @@ export function activate(context: ExtensionContext) {
})

} else if (!fs.existsSync(disableDottyIDEFile)) {
let configuredProject: Thenable<void> = Promise.resolve()
if (!isConfiguredProject()) {
configuredProject = vscode.window.showInformationMessage(
"This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?",
"Yes", "No"
).then(choice => {
if (choice === "Yes") {
bootstrapSbtProject(buildSbtFileSource, dottyPluginSbtFileSource)
return Promise.resolve()
} else if (choice === "No") {
fs.appendFile(disableDottyIDEFile, "", _ => {})
return Promise.reject()
}
})
.then(_ => connectToSbt(coursierPath))
.then(sbt => {
return withProgress("Configuring Dotty IDE...", configureIDE(sbt))
.then(_ => { sbtserver.tellSbt(outputChannel, sbt, "exit") })

if (!vscode.workspace.workspaceFolders) {
if (vscode.window.activeTextEditor) {
setWorkspaceAndReload(vscode.window.activeTextEditor.document)
}
} else {
let configuredProject: Thenable<void> = Promise.resolve()
if (!isConfiguredProject()) {
configuredProject = vscode.window.showInformationMessage(
"This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?",
"Yes", "No"
).then(choice => {
if (choice === "Yes") {
bootstrapSbtProject(buildSbtFileSource, dottyPluginSbtFileSource)
return Promise.resolve()
} else if (choice === "No") {
fs.appendFile(disableDottyIDEFile, "", _ => {})
return Promise.reject()
}
})
.then(_ => connectToSbt(coursierPath))
.then(sbt => {
return withProgress("Configuring Dotty IDE...", configureIDE(sbt))
.then(_ => { sbtserver.tellSbt(outputChannel, sbt, "exit") })
})
}

configuredProject
.then(_ => runLanguageServer(coursierPath, languageServerArtifactFile))
}
}
}

configuredProject
.then(_ => runLanguageServer(coursierPath, languageServerArtifactFile))
/**
* Find and set a workspace root if no folders are open in the workspace. If there are already
* folders open in the workspace, do nothing.
*
* Adding a first folder to the workspace completely reloads the extension.
*/
function setWorkspaceAndReload(document: vscode.TextDocument) {
const documentPath = path.parse(document.uri.path).dir
const workspaceRoot = findWorkspaceRoot(documentPath) || documentPath
vscode.workspace.updateWorkspaceFolders(0, null, { uri: vscode.Uri.file(workspaceRoot) })
}

/**
* Find the closest parent of `current` that contains a `build.sbt`.
*/
function findWorkspaceRoot(current: string): string | undefined {
const build = path.join(current, "build.sbt")
if (fs.existsSync(build)) return current
else {
const parent = path.resolve(current, "..")
if (parent != current) {
return findWorkspaceRoot(parent)
}
}
}

Expand Down

0 comments on commit 688c149

Please sign in to comment.