-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support multi-root for 'Add Configuration' #8066
Conversation
let model: DebugConfigurationModel | undefined; | ||
if (this.models.size > 1) { | ||
model = await this.quickPick.show(Array.from(this.models.entries()).map(entry => { | ||
const [rootFolder, modelValue] = entry; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if the list of roots would be ordered like what the user sees in the explorer: I guess if we iterate over the root folders array and 'get' from the map that would be the case. Iteration order over a map is not defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the feedback !
With my most recent update, I am using workspaceService.roots
to ensure the order of the workspace folders.
value: modelValue | ||
}; | ||
}), { | ||
placeholder: 'Select for which root folder to add the configuration to' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "workspace folder" would be the VS Code terminology here: I suggest:
Select the workspace folder to add the configuration to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
bb20598
to
7aacc6f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elaihau I had issues with adding configurations when I had multiple roots and my roots were simple folders without .theia
or .vscode
present. In these cases, when selecting a root with the quick-pick, the launch.json
was not created in their respective root and instead the workspace file was opened instead, is this the expected behavior?
{
"folders": [
{
"path": "file:///Users/vincentfugnitto/Desktop/a"
},
{
"path": "file:///Users/vincentfugnitto/workspace/theia"
}
],
"settings": {
"launch": {}
}
}
model = await this.quickPick.show(rootUris.map(rootUri => { | ||
const modelValue = this.models.get(rootUri); | ||
return { | ||
label: this.labelProvider.getName(new URI(rootUri)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can align with the 'new terminal' and also display the path to the workspace (helps when there are multiple roots with the same name):
theia/packages/terminal/src/browser/terminal-frontend-contribution.ts
Lines 568 to 571 in c7182b5
return this.quickPick.show(roots.map( | |
({ uri }) => ({ label: this.labelProvider.getName(new URI(uri)), description: this.labelProvider.getLongName(new URI(uri)), value: uri }) | |
), { placeholder: 'Select current working directory for new terminal' }); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your feedback should have been resolved in the lastest patch.
I tested the multi root workspace
- that has more than one folders
- that has only one folder, and
- with & without the
.theia
or.vscode
folders
Thank you !
I found a problem with the following scenario:
Where launch.json contains:
|
const { model } = this; | ||
let model: DebugConfigurationModel | undefined; | ||
if (this.models.size > 1) { | ||
const rootUris = (await this.workspaceService.roots).map(r => r.uri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't this first map
is needed: why not just use r.uri
inside the quick pick?
@@ -254,21 +274,28 @@ export class DebugConfigurationManager { | |||
|
|||
protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> { | |||
let uri = model.uri; | |||
if (!uri) { | |||
const configFileUri = this.getFolderConfigurationUri(model); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this sequence is ignoring the case where there is a launch.json but it's in the .vscode folder instead of .theia
@@ -254,21 +274,28 @@ export class DebugConfigurationManager { | |||
|
|||
protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> { | |||
let uri = model.uri; | |||
if (!uri) { | |||
const configFileUri = this.getFolderConfigurationUri(model); | |||
const fileStat = await this.filesystem.getFileStat(configFileUri.toString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line throws an error when the the parent folder of the file does not exist. Maybe exists
does the trick? But the documentation is really not very precise on this.
- If a user is using a multi-root workspace, the command "Debug: Add Configuration" adds a configuration directly in the first workspace root instead of prompting users to select the correct root. With this change the command prompts users with a quick-pick which allows them to select their desired workspace root. - resolves #5166 Signed-off-by: Liang Huang <[email protected]>
Thank you for your time @tsmaeder ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very good at finding subtle problems, I guess 🤷 Otherwise, looks good.
console.log(thismodel); | ||
} | ||
let model: DebugConfigurationModel | undefined; | ||
if (this.models.size > 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this check is not reliable: I was able to construct a case where I'm not asked which folder I would like to configure:
- Open an unrelated folder
- Select "Open Workspace" and open a folder looking like this:
Third
.vscode
launch.json
- Add a second folder to the workspace looking like this (don't save to a file)
Second
untitled.txt
- Hit F1->Debug: Add Configuration
- Observe: I'm not asked which workspace folder to use: the config goes to
Third
I've been able to trace the problem to the fact that the listener for preference changes is never called when a new workspace root is added: theia/packages/debug/src/browser/debug-configuration-manager.ts#88
I am not really sure what the right fix is, though: should we listen to workspace folder changes or should the preferences system send a change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akosyakov I'd like your opinion on that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds fine to listen to workspace root changes, since they are input to updateModels
function and seems to be easy fix.
But that we don't fire preference events when roots are changed bother me too. We should check what VS Code extensions will expect. Could you file an issue to investigate?
const paths = this.preferenceConfigurations.getPaths(); | ||
for (const configPath of paths) { | ||
const configUri = new URI(model.workspaceFolderUri).resolve(`${configPath}/launch.json`); | ||
if (await this.filesystem.exists(configUri.toString())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need it? if something exist already we should not override it at all, previous fallback was fine to me
doCreate
method should assume that it is called when nothing exists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous version of the PR did not work in the cases where a launch.json existed, but was under .vscode instead of .theia
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that sounds like a bug in the preference service, DebugConfigurationModel.uri
used to point to a config from which data was loaded or nothing
@@ -254,21 +277,27 @@ export class DebugConfigurationManager { | |||
|
|||
protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> { | |||
let uri = model.uri; | |||
if (!uri) { | |||
const configFileUri = await this.getFolderConfigurationUri(model); | |||
if (!await this.filesystem.exists(configFileUri.toString())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why previous check was not good? if uri
is missing, that already means that model does not exist.
uri = await this.doCreate(model); | ||
} | ||
return this.editorManager.open(uri, { | ||
return this.editorManager.open(uri!, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!
why is it needed?, if
branch should ensure that uri exists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i agree with you while the linter doesn't.
without !
it gives me this error
Argument of type 'URI | undefined' is not assignable to parameter of type 'URI'.
Type 'undefined' is not assignable to type 'URI'.ts(2345)
and
'Exit with failure status (1): concurrently -n compile,lint -c blue,green "theiaext compile" "theiaext lint"\nerror Command failed with exit code 1.\n',
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should sort out other comments, I don't think that so many changes to doCreate
function are required. It seems there are regressions with PreferenceService.
Liang's contract is over and he has moved-on from Theia. @tsmaeder I have not followed closely this PR - how close DYT it is to be merged? Is there someone on your side who could take-over and address remaining comments? |
@marcdumais there is a corner case when adding a workspace folder that needs to be addressed, should be pretty straight-forward, though. |
If a user is using a multi-root workspace, the command "Debug: Add Configuration" adds a configuration directly in the first workspace root instead of prompting users to select the correct root. With this change the command prompts users with a quick-pick which allows them to select their desired workspace root.
resolves [debug] support multi-root for 'Add Configuration' #5166
Signed-off-by: Liang Huang [email protected]
How to test
in a workspace that has only one root folder, the command "Debug: Add Configuration" should work the way it used ot
in a multi root workspace, we should see a prompt that asks users to select which root folder the configuration should be added to.
Review checklist
Reminder for reviewers