microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.41k stars 29.33k forks source link

Profiles feature request: Ability to apply user settings across all profiles #176813

Closed aaronsteers closed 1 year ago

aaronsteers commented 1 year ago

As mentioned also in: https://github.com/microsoft/vscode/issues/15909#issuecomment-1464172862

The release of Profiles feature is exciting but I can't figure out how/if I can use this for "mode switching" in my own dev experience.

I am having a hard time making these work for the named application here (from the docs):

Since profiles are remembered per workspace, they are a great way to customize VS Code for a specific programming language.

I'm starting to hoping to use Profiles to keep my IDE more lean and focused - for instance one profile for Python development, one for Terraform development, and one for Data Analysis. But what I'm finding is that the isolation between profiles is a bit too strong in cases. Perfect example is my use of Code Spell Checker - I have built a usage pattern of always adding exceptions/additions to the default spell check dictionary to my user settings - these follow me everywhere. But now, if I correctly understand the behavior of Profiles feature, these settings won't follow me to other profiles.

Now with profiles, I think I'm going to end up repeating the same changes, and having to deal with drift across these profiles when there are some settings I just want to have permanent.

I don't know if we're going to get updates to Profiles feature that will allow some settings to follow us across profiles. The example above for the spell check dictionary, but also applies for extension settings like, ChatGPT, Live Share, etc. I think the common theme here is that certain settings and extensions are personal and some are modal.

Proposal

Application of two profiles

I think this basically requires two layers of profiles to be active at the same time:

Handling global settings

Basically, there are certain plugins I'd like to treat as "global" or "personal" and those would ideally have these behaviors:

Handling extension-managed writes when 2 profiles exist

I believe this algorithm is sensible:

  1. Whenever setting a value {my-ext}.{my-setting}, first check if a same-named setting exists in the personal profile. If yes, update it there.
  2. Else, if the same-named setting exists in the applied modal profile, then update it there.
  3. Else, if the {my-ext} extension has any existing config in the modal profile, set the new setting there, adjacent to existing settings. (We presume the setting is modal until the user has moved it to their global profile.)
  4. Else, if the {my-ext} extension has any existing config in the personal profile, set the new setting there, adjacent to existing settings.
  5. Else, (the extension has no settings anywhere in either profile), write to the modal profile.

These, I think, are sensible default behaviors - specifically because:

Handling settings resolution ("read" behavior)

When reading settings, personal profile always has precedent. Modal profile has lower precedent.

Impact on "imported" profiles, or profiles gotten from other users

This behavior nicely keeps a user's own settings as overrides when importing community-created profiles.

E.g. If I import a "Python" profile from my community, I don't lose my custom Live Share settings upon import.

Rendering in VS Code Settings UI

This would have a 3-level interface. Instead of "User" meaning "Profile" in the screenshot below, there would be separate tabs for User | Profile | Workspace:

Image

Since "User" has already come to mean "profile", the word "Personal" might work better: Personal | Profile | Workspace might be even more clear.

Better yet: naming the profile in the tab makes it super obvious what profile is applied and where setting values will be stored: Personal | 'Python' Profile | Workspace. This is nice because the answer to "which should I use" becomes much more intuitive.

Education

Probably, this is most simply communicated to users by distinguishing between "User Settings" or "Personal Settings" and "Profile Settings".

The algorithms for how settings are read and written can be more described concisely as:

When configuring an extension for the first time, VS Code writes settings to your active Profile. When you configure a User-level setting, or if you move a setting from the Profile to your User config, VS Code will remember this and treat the setting as a User-level config on future updates. If a setting exists at the User level and also in the Profile, the value from your personal User profile will have priority over the Profile setting.

This allows you to freely switch between your own profiles, as well as community-maintained profiles, without losing personal settings such as usernames, personal window styles, and other settings which you have set in your personal User config.


Is there an option to do something like this today? It is being considered for future development?

I checked the Profiles docs and could not find any mention of handling for profile overlays.

the-exodus commented 1 year ago

I came here to report the same issue, although from the direction I come from I feel it would make more sense to solve it by just applying the profile settings.json on top of the user settings.

So when switching to a profile it would combine the default settings with the user settings, as usual, and then just smack the profile/settings.json on top, before actually committing the settings-object to vscode.

In case a profile wants to revert a user setting to the default value I suppose the property could just be set to undefined in that json, in which case the settings "manager" would just grab the default value for it.

The reason I came here was terminal.integrated.fontFamily which I've now had to set in every profile I've created...

sandy081 commented 1 year ago

/duplicate

15909

vscodenpa commented 1 year ago

Thanks for creating this issue! We figured it's covering the same as another one we already have. Thus, we closed this one as a duplicate. You can search for similar existing issues. See also our issue reporting guidelines.

Happy Coding!

aaronsteers commented 1 year ago

@sandy081 - That issue doesn't mention the challenges with getting/setting values from multiple files. It seems that item (written pre-Profiles) assumes that we're importing/grafting a file's contents on top of the main one.

Would that presume that Profiles keep working how they do today, and the user would manually curate their own personal settings file(s)? Or would that proposal have a context for layering what we now call "Profiles" on top of each other? And is the scope of that issue expected to expand to include settings UI support as well?

For ref:

sandy081 commented 1 year ago

@aaronsteers Thanks for the input and also for the proposal. Initially I felt that your requirement is similar to extending from default profile. It seems you have two basic requirements

  1. Ability to have user settings applied across all profiles
  2. Ability to have extensions installed across all profiles - https://github.com/microsoft/vscode/issues/157492

There is already feature request for 2nd. I will track this as a feature request for 1st.

Since profiles feature is a very new one, we are trying to collect feedback before adding more features. This issue, 157492 and 15909 are most asked and very much related to each other.

We want to digest all requirements around this and come up with a good solution.

Thanks.

rennsax commented 1 year ago

@sandy081 That's the problem I've encountered with today. It's awful to install a generally-used extension to all my profiles. I recommend:

  1. DON'T reinstall extensions at each profile. It may be elegant to just maintain some pointers to extensions, which denote the extensions available at the certain profile. When no profile refers an extension, the extension is removed. (Just like the garbage collection strategy of some language, Java for example.)
  2. Ability to inherit the default profile conveniently. I suggest enable the user's setting.json when settings of the profile is activated. Settings of the profile just OVERRIDE user's settings.json. The logic is similar to user config and workplace config.
  3. Ability to choose when installing an extension: install for all profiles.

The Profiles feature is what I'm eagerly desiring for a long period. I think the improvement of this feature would make it easy to config a new develop environment. I sincerely hope it'll be better in the future release.

Thanks again.

sandy081 commented 1 year ago

DON'T reinstall extensions at each profile. It may be elegant to just maintain some pointers to extensions, which denote the extensions available at the certain profile. When no profile refers an extension, the extension is removed. (Just like the garbage collection strategy of some language, Java for example.)

This is what we do internally when you install same extension in multiple profiles.

sandy081 commented 1 year ago

Here is the proposed solution:

From the settings UI, you can make a setting to apply it for all profiles. Following example demonstrates making files.autoSave setting to be applied for all profiles.

image image
rennsax commented 1 year ago

@sandy081 With this feature installed, when I customize my settings through the plain text settings.json, I still need to go to the Settings UI page and click the button?

sheldonhull commented 1 year ago

Here is the proposed solution:

From the settings UI, you can make a setting to apply it for all profiles. Following example demonstrates making files.autoSave setting to be applied for all profiles.

image image

I'd have to also have something either in a parent json object or such to be happy with this. If this is just moving the setting under something like:

"globalsettings": {
    // Move in here
}

I'd be happy with reorganizing my settings slightly to support the global settings, as long as the profile setting a similar option would take precedence due to the last option merge = source of truth.

sandy081 commented 1 year ago

@Eitheages

With this feature installed, when I customize my settings through the plain text settings.json, I still need to go to the Settings UI page and click the button?

Not needed, underneath there will be a new setting (workbench.profiles.applicationSettings just came up with is name)that stores what settings are scoped to all profiles. So you can simply add the setting you want to be applied across all profiles to this new setting in the json file.

sandy081 commented 1 year ago

I'd be happy with reorganizing my settings slightly to support the global settings, as long as the profile setting a similar option would take precedence due to the last option merge = source of truth.

I am not sure what exactly you mean here. But if you are wanting to override such a setting, which is applied in all profiles, at the profile level, then it is not supported. What you wanted is hierarchy and this is not meant for that.

jmevel commented 1 year ago

@Eitheages

With this feature installed, when I customize my settings through the plain text settings.json, I still need to go to the Settings UI page and click the button?

Not needed, underneath there will be a new setting (workbench.profiles.applicationSettings just came up with is name)that stores what settings are scoped to all profiles. So you can simply add the setting you want to be applied across all profiles to this new setting in the json file.

Wouldn't it be possible to be able to inherit profiles instead of having one Master settings file?

There are some settings I would like to share across multiple profiles at home when I'm doing my own personal stuff. I'd like to apply some of these settings to my work profile as well but not all of them!

Maybe I'm going to far and at this point it would be too complicated to implement this feature but having profile inheritance would give us a great flexibility in terms of customizing our IDE with our different profiles.

brettcannon commented 1 year ago

So you can simply add the setting you want to be applied across all profiles to this new setting in the json file.

What is the application order going to be for the settings? For instance, if I want indentation to be 4 spaces in general, but 2 on a specific profile, will the values in workbench.profiles.applicationSettings take the least precedence so the 2-space setting in the profile overrides the 4-space setting I have set as my application setting?

sandy081 commented 1 year ago

Maybe I'm going to far and at this point it would be too complicated to implement this feature but having profile inheritance would give us a great flexibility in terms of customizing our IDE with our different profiles.

Agreed that profile inheritance gives much more flexibility and it is a powerful feature that needs considerable effor to design and implement with good UX. I would not prefer to make this one solution of all features. Its best if some small features can be supported independently and this is one of them.

@brettcannon There is no hierarchy supported here. A setting to application settings list will be applied to all profiles and cannot be overridden at profile level.

brettcannon commented 1 year ago

There is no hierarchy supported here. A setting to application settings list will be applied to all profiles and cannot be overridden at profile level.

So I can't set a default indentation level for e.g. Python files, but then override that in a profile that is specific to a workspace/repo?

sandy081 commented 1 year ago

Thats correct

cweagans commented 1 year ago

I'm not sure how a settings block that applies to all profiles actually helps. Profile inheritance seems like it'd be much more useful and solve several outstanding issues. It also seems relatively straightforward to design, especially since there are extensions in the marketplace that have already solved the problem in an elegant, usable way.

Can you help shed some light on why the path that you've outlined is better?

sandy081 commented 1 year ago

These two are different requirements. Inheritance is much a bigger feature than this. Why would I like to inherit if I want just one setting to be applied across all profiles?

cweagans commented 1 year ago

IMO, it's extremely rare for one setting to be the same across all profiles. Inheritance solves both cases though.

galloppinggryphon commented 1 year ago

IMO, it's extremely rare for one setting to be the same across all profiles. Inheritance solves both cases though.

I think previous posters have demonstrated that it's not a rare or unusual use-case to share settings between profiles. Not just shared plugins, but settings that configure the workspace, like "editor.minimap.enabled": false.

Some plugins just make more sense if they're 'global' by default, e.g. Project Manager, or themes.

The statusbar-commands plugin differentiates between global/user settings and profile settings. It applies settings under statusbar_command.commands from the profile settings and statusbar_command.applicationCommands from global/user settings. So that's one way of doing it.

cweagans commented 1 year ago

The statusbar-commands plugin differentiates between global/user settings and profile settings.

Why should every plugin implement that differentiation when there's a relatively straightforward way of having VS Code itself handle it? Profile inheritance solves both use cases: config applied across all profiles and config that is only set in one profile (that is either not set in the base profile or is overriding the base profile).