Add support for profiles.defaults in defaults.json #7321

Closed
opened 2026-01-31 01:00:59 +00:00 by claunia · 4 comments
Owner

Originally created by @carlos-zamora on GitHub (Apr 7, 2020).

Originally assigned to: @carlos-zamora on GitHub.

Description of the new feature/enhancement

defaults.json only supports "profiles" as a list, not an object. This means that profiles.defaults cannot be used to present the default values for profiles.

Proposed technical implementation details (optional)

This is a surprisingly large change with very little gain. The CascadiaSettings::LoadAll() function must be rewritten to match the following order:

  1. load defaults/profiles.defaults = A
  2. load defaults/profiles.list = B
    • apply [A] to [B]
    • apply [B] to [B]
  3. load dynamics = C
    • apply [A] to [C]
  4. load user/profiles.defaults = D
    • apply [D] to all existing profiles [B, C]
  5. load user/profiles.list = E
    • apply [A] to [E]
    • apply [D] to [E]
    • apply [E] to [E]

Additionally, dynamic profiles add an additional level of complexity. Each dynamic profile generator relies on DefaultProfileUtils' CreateDefaultProfile. We need to layer defaults/profiles.defaults here. But defaults/profiles.defaults is saved in CascadiaSettings. So we need to find a way to ensure that a construction of a Profile object has defaults/profiles.defaults layers already.

Originally created by @carlos-zamora on GitHub (Apr 7, 2020). Originally assigned to: @carlos-zamora on GitHub. # Description of the new feature/enhancement defaults.json only supports `"profiles"` as a list, not an object. This means that `profiles.defaults` cannot be used to present the default values for `profiles`. # Proposed technical implementation details (optional) This is a surprisingly large change with very little gain. The `CascadiaSettings::LoadAll()` function must be rewritten to match the following order: 1. load defaults/profiles.defaults = A 2. load defaults/profiles.list = B - apply [A] to [B] - apply [B] to [B] 3. load dynamics = C - apply [A] to [C] 4. load user/profiles.defaults = D - apply [D] to all existing profiles [B, C] 5. load user/profiles.list = E - apply [A] to [E] - apply [D] to [E] - apply [E] to [E] Additionally, dynamic profiles add an additional level of complexity. Each dynamic profile generator relies on DefaultProfileUtils' `CreateDefaultProfile`. We need to layer defaults/profiles.defaults here. But defaults/profiles.defaults is saved in `CascadiaSettings`. So we need to find a way to ensure that a construction of a Profile object has defaults/profiles.defaults layers already.
claunia added the Resolution-Fix-CommittedArea-SettingsIssue-TaskProduct-Terminal labels 2026-01-31 01:00:59 +00:00
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 8, 2020):

We may want to consider a "prototype Profile" object that we .Clone(). This simplifies the flow:

  1. Create a new Profile = Prototype
  2. layer defaults/profiles.defaults on [Prototype]
  3. load defaults/profiles.list
    • copy [Prototype] = B
    • layer list[i] on [B]
  4. load dynamics
    • copy [Prototype] = C
    • dynamic loader changes [C]
  5. layer user/profiles.defaults on [Prototype]
    • layer user defaults on all existing profiles [B, C]
  6. load user/profiles.list
    • copy [Prototype] = D
    • layer list[i] on [D]
(as something closer to pseudocode)
  1. Prototype = new Profile()
  2. Prototype.layer(defaults.json profiles.defaults)
  3. load defaults/profiles.list; for each:
    • B = Prototype.Clone()
    • B.layer(list[i])
  4. load dynamics
    • C = Prototype.Clone()
    • (dynamic loader applies changes to C)
  5. Prototype.layer(user.json profiles.defaults)
    • B.layer(user.json profiles.defaults) (apply to stock profiles)
    • C.layer(user.json profiles.defaults) (apply to dynamic profiles)
  6. load user/profiles.list; for each:
    • D = Prototype.Clone()
    • D.layer(list[i])

If you notice that 1-2 and 4-5 are the same operation, gold star. This will also reduce the difference between "defaults.json" and "settings.json".

@DHowett-MSFT commented on GitHub (Apr 8, 2020): We may want to consider a "prototype Profile" object that we `.Clone()`. This simplifies the flow: 0. Create a new Profile = Prototype 1. layer defaults/profiles.defaults on [Prototype] 2. load defaults/profiles.list - copy [Prototype] = B - layer list[i] on [B] 3. load dynamics - copy [Prototype] = C - dynamic loader changes [C] 4. layer user/profiles.defaults on [Prototype] - layer user defaults on all existing profiles [B, C] 5. load user/profiles.list - copy [Prototype] = D - layer list[i] on [D] <details> <summary>(as something closer to pseudocode)</summary> 0. `Prototype = new Profile()` 1. `Prototype.layer(defaults.json profiles.defaults)` 2. load defaults/profiles.list; for each: - `B = Prototype.Clone()` - `B.layer(list[i])` 3. load dynamics - `C = Prototype.Clone()` - (dynamic loader applies changes to `C`) 4. `Prototype.layer(user.json profiles.defaults)` - `B.layer(user.json profiles.defaults)` (apply to stock profiles) - `C.layer(user.json profiles.defaults)` (apply to dynamic profiles) 5. load user/profiles.list; for each: - `D = Prototype.Clone()` - `D.layer(list[i])` </details> If you notice that 1-2 and 4-5 are _the same operation_, gold star. This will also reduce the difference between "defaults.json" and "settings.json".
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 10, 2020):

Tagging into v1.x. We should figure out the settings model in advance of doing the settings UI.

@DHowett-MSFT commented on GitHub (Apr 10, 2020): Tagging into v1.x. We should figure out the settings model in advance of doing the settings UI.
Author
Owner

@JustinGrote commented on GitHub (Apr 22, 2020):

Related to this, defaults.json should have the "defaults" and "list" subformat as well by default. The more "OneOf" entries in the JSON schema that can be removed for the various configuration iterations that can be removed, the better for code generation tools like my MSTerminalSettings 2.0 powershell module.

@JustinGrote commented on GitHub (Apr 22, 2020): Related to this, defaults.json should have the "defaults" and "list" subformat as well by default. The more "OneOf" entries in the JSON schema that can be removed for the various configuration iterations that can be removed, the better for code generation tools like my MSTerminalSettings 2.0 powershell module.
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 22, 2020):

That's not exactly "related to" this issue insofar as it literally just is this issue. 😄
We just about did this for v1, but recognized that it would be too great a change for us to feel comfortable with ☹️

@DHowett-MSFT commented on GitHub (Apr 22, 2020): That's not exactly "related to" this issue insofar as it literally just _is_ this issue. :smile: We just about did this for v1, but recognized that it would be too great a change for us to feel comfortable with ☹️
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#7321