Skip to content
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

GUID generation for dynamic fragments (#320) #460

Merged
merged 1 commit into from
Jan 20, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 60 additions & 15 deletions TerminalDocs/json-fragment-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ ms.topic: how-to

JSON fragment extensions are snippets of JSON that application developers can write to add new profiles to users' settings, or even modify certain existing profiles. They can also be used to add new color schemes to users' settings.

## Structure of the JSON files
## Structure of the JSON files

The JSON file should be split up into 2 lists, one for profiles and one for schemes. Here is an example of a json file that adds a new profile, modifies an existing profile, and creates a new color scheme:
The JSON file should be split up into 2 lists, one for profiles and one for schemes. Here is an example of a json file that adds a new profile, modifies an existing profile, and creates a new color scheme:

```JSON
```JSON
{
"profiles": [
{
// update the profile with the GUID below
"updates": "{2c4de342-38b7-51cf-b940-23e9ae97f518}",
// update a profile by using its GUID
"updates": "{2ece5bfe-50ed-5f3a-ab87-5cd4baafed2b}",
"fontSize": 16,
"fontWeight": "thin"
},
Expand All @@ -37,14 +37,13 @@ The JSON file should be split up into 2 lists, one for profiles and one for sche
{
// create a new color scheme
"name": "Postmodern Tango Light",

"black": "#0C0C0C",
"red": "#C50F1F",
"green": "#13A10E",
"yellow": "#C19C00",
"blue": "#0037DA",
"purple": "#881798",
"cyan": "#3A96DD",
"cyan": "#3A96DD",
"white": "#CCCCCC",
"brightBlack": "#767676",
"brightRed": "#E74856",
Expand All @@ -65,25 +64,71 @@ In the `"schemes"` list, a new color scheme called "Postmodern Tango Light" is d

Of course, if the developer only wishes to add/modify profiles without adding color schemes (and vice-versa), only the relevant list needs to be present and the other list can be omitted.

## How to determine the GUID of an existing profile
## Profile GUIDs

As previously stated profile GUIDs are a way to reference profiles and let users update and extend them without worrying about location or name changes. The only profiles that can be modified through fragments are the default profiles, Command Prompt and PowerShell, as well as [dynamic profiles](./dynamic-profiles.md). Providing a GUID is optional, however, strongly encouraged.

The GUIDs are generated using a Version 5 UUID generator which supports BOM-less UTF-16LE encoding.

The namespace GUID for Windows Terminal in case of profiles created by plugins and fragments is `{f65ddb7e-706b-4499-8a50-40313caf510a}`. Profiles created by the Windows Terminal Team use a separate GUID (`{2bde4a90-d05f-401c-9492-e40884ead1d8}`). This is done to disambiguate profiles created by the Windows Terminal Team from profiles created by plugins or fragments so they can never accidentally collide.

### How to determine the GUID of an existing profile

To determine the GUID of a profile to be updated it depends on what kind of profile it is:

A profile shipped by a third party stored in a standard Windows Terminal Fragment location requires the profile & fragment namespace GUID `{f65ddb7e-706b-4499-8a50-40313caf510a}`, the application namespace GUID, and the profile name. For a profile fragment named 'Git Bash' supplied by the application 'Git' the generated GUID is: `{2ece5bfe-50ed-5f3a-ab87-5cd4baafed2b}`.

A profile automatically generated by Windows Terminal requires the Windows Terminal internal GUID `{2bde4a90-d05f-401c-9492-e40884ead1d8}` and the profile name. For a profile named 'Ubuntu' automatically generated during WSL installation, the resulting GUID is: `{2c4de342-38b7-51cf-b940-2309a097f518}`. In contrast to the previous fragment example there is no 'application name' involved.

### Generating a new profile GUID

To generate a GUID for a completely new profile prior to distributing it you can use the following Python 3 example. It generates a GUID based on the profile & fragment namespace GUID for a profile called 'Git Bash' stored in a standard Windows Terminal Fragments folder under the 'Git' application name, conveniently matching the sanity check.

```python
import uuid

The only profiles that can be modified through fragments are the default profiles, Command Prompt and PowerShell, as well as [dynamic profiles](./dynamic-profiles.md). To determine the GUID of the profile to be updated, use a Version 5 UUID generator with the following namespace GUID and name:
# The Windows Terminal namespace GUID for custom profiles & fragments
terminalNamespaceGUID = uuid.UUID("{f65ddb7e-706b-4499-8a50-40313caf510a}")

- The namespace GUID: `{2BDE4A90-D05F-401C-9492-E40884EAD1D8}`
- The name of the profile to be updated
# The Application Namespace GUID
appNamespaceGUID = uuid.uuid5(terminalNamespaceGUID, "Git".encode("UTF-16LE").decode("ASCII"))

As a sanity check, a profile called 'Ubuntu' will get the generated GUID: `{2C4DE342-38B7-51CF-B940-2309A097F518}`
# Calculate the example GUID for the 'Git Bash' profile
profileGUID = uuid.uuid5(appNamespaceGUID, "Git Bash".encode("UTF-16LE").decode("ASCII"))

# Output the GUID
print(profileGUID)

```

### Calculating a GUID for a built in profile

To calculate a GUID for a built in profile, such as the automatically generated WSL profiles, you can use the following Python 3 example. It calculates a GUID based on the Windows Terminal namespace GUID for a profile called 'Ubuntu' that was automatically generated for the WSL distribution, conveniently matching the sanity check.

```python
import uuid

# The Windows Terminal namespace GUID automatically generated profiles
terminalNamespaceGUID = uuid.UUID("{2bde4a90-d05f-401c-9492-e40884ead1d8}")

# Calculate the example GUID for the 'Git Bash' profile
profileGUID = uuid.uuid5(terminalNamespaceGUID, "Ubuntu".encode("UTF-16LE").decode("ASCII"))

# Output the GUID
print(profileGUID)

```

## Minimum requirements for settings added with fragments
## Minimum requirements for settings added with fragments

There are some minimal restrictions on what can be added to user settings using JSON fragments:

- For new profiles added via fragments, the new profile must, at a minimum, define a name for itself.
- For new color schemes added via fragments, the new color scheme must define a name for itself, as well as define every color in the color table (i.e. the colors "black" through "brightYellow" in the example image above).
- For new color schemes added via fragments, the new color scheme must define a name for itself, as well as define every color in the color table (i.e. the colors "black" through "brightWhite" in the example image above).

## Where to place the JSON fragment files

The location to place the JSON fragment files varies depending on the installation method of the application that wishes to place them.
The location to place the JSON fragment files varies depending on the installation method of the application that wishes to place them.

### Microsoft Store applications

Expand Down