From 6ab802b365f9f7f6687e9da71a880ea1a40a3459 Mon Sep 17 00:00:00 2001 From: Trillium Smith Date: Mon, 9 Mar 2026 00:52:24 -0700 Subject: [PATCH 1/3] feat: add userColor3 and userColor4 hat colors Add two additional user-configurable hat colors (userColor3, userColor4) to support users who need more than 2 custom colors. Some users configure colors like plum, teal, black, and white, exceeding the current limit of 2 user-defined colors. --- cursorless-talon/src/marks/decorated_mark.py | 2 + cursorless-talon/src/spoken_forms.json | 4 +- .../types/command/legacy/CommandV0V1.types.ts | 4 +- .../legacy/PartialTargetDescriptorV3.types.ts | 4 +- .../legacy/targetDescriptorV2.types.ts | 4 +- .../defaultSpokenForms/marks.ts | 2 + .../src/docs/user/README.md | 22 +++++----- packages/cursorless-vscode/package.json | 44 ++++++++++++++++--- .../src/ide/vscode/hatStyles.types.ts | 2 + 9 files changed, 69 insertions(+), 19 deletions(-) diff --git a/cursorless-talon/src/marks/decorated_mark.py b/cursorless-talon/src/marks/decorated_mark.py index df219477f2..4ab6650b0a 100644 --- a/cursorless-talon/src/marks/decorated_mark.py +++ b/cursorless-talon/src/marks/decorated_mark.py @@ -51,6 +51,8 @@ def cursorless_decorated_symbol(m) -> DecoratedSymbol: "yellow": True, "userColor1": False, "userColor2": False, + "userColor3": False, + "userColor4": False, } DEFAULT_SHAPE_ENABLEMENT = { diff --git a/cursorless-talon/src/spoken_forms.json b/cursorless-talon/src/spoken_forms.json index b864dad1e8..e659601dfc 100644 --- a/cursorless-talon/src/spoken_forms.json +++ b/cursorless-talon/src/spoken_forms.json @@ -245,7 +245,9 @@ "pink": "pink", "yellow": "yellow", "navy": "userColor1", - "apricot": "userColor2" + "apricot": "userColor2", + "userColor3": "userColor3", + "userColor4": "userColor4" }, "hat_shape": { "ex": "ex", diff --git a/packages/common/src/types/command/legacy/CommandV0V1.types.ts b/packages/common/src/types/command/legacy/CommandV0V1.types.ts index c78e5fd516..19afb7425d 100644 --- a/packages/common/src/types/command/legacy/CommandV0V1.types.ts +++ b/packages/common/src/types/command/legacy/CommandV0V1.types.ts @@ -120,7 +120,9 @@ type HatColor = | "pink" | "yellow" | "userColor1" - | "userColor2"; + | "userColor2" + | "userColor3" + | "userColor4"; type HatNonDefaultShape = | "ex" | "fox" diff --git a/packages/common/src/types/command/legacy/PartialTargetDescriptorV3.types.ts b/packages/common/src/types/command/legacy/PartialTargetDescriptorV3.types.ts index d88f46ef70..d61bde42d0 100644 --- a/packages/common/src/types/command/legacy/PartialTargetDescriptorV3.types.ts +++ b/packages/common/src/types/command/legacy/PartialTargetDescriptorV3.types.ts @@ -6,7 +6,9 @@ type HatColor = | "pink" | "yellow" | "userColor1" - | "userColor2"; + | "userColor2" + | "userColor3" + | "userColor4"; type HatNonDefaultShape = | "ex" | "fox" diff --git a/packages/common/src/types/command/legacy/targetDescriptorV2.types.ts b/packages/common/src/types/command/legacy/targetDescriptorV2.types.ts index fdb2eb4b35..c2bd8176e6 100644 --- a/packages/common/src/types/command/legacy/targetDescriptorV2.types.ts +++ b/packages/common/src/types/command/legacy/targetDescriptorV2.types.ts @@ -6,7 +6,9 @@ type HatColor = | "pink" | "yellow" | "userColor1" - | "userColor2"; + | "userColor2" + | "userColor3" + | "userColor4"; type HatNonDefaultShape = | "ex" | "fox" diff --git a/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts b/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts index f998f66314..ebbd4aab16 100644 --- a/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts +++ b/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts @@ -8,6 +8,8 @@ const hatColors: Record = { yellow: "yellow", userColor1: "navy", userColor2: "apricot", + userColor3: "userColor3", + userColor4: "userColor4", default: null, }; diff --git a/packages/cursorless-org-docs/src/docs/user/README.md b/packages/cursorless-org-docs/src/docs/user/README.md index 93b9a11070..9daf6445c6 100644 --- a/packages/cursorless-org-docs/src/docs/user/README.md +++ b/packages/cursorless-org-docs/src/docs/user/README.md @@ -53,16 +53,18 @@ Combining this with an action, we might say `"take blue air"` to select the toke The following colors are supported. Note that to target the default (gray) hat you don't need to specify a color. -| Spoken form | Color | Internal ID | Enabled by default? | -| ----------- | ------- | ------------ | ------------------- | -| N/A | grey | `default` | ✅ | -| `"blue"` | blue | `blue` | ✅ | -| `"green"` | green | `green` | ✅ | -| `"red"` | red | `red` | ✅ | -| `"pink"` | pink | `pink` | ✅ | -| `"yellow"` | yellow | `yellow` | ✅ | -| `"navy"` | navy | `userColor1` | ❌ | -| `"apricot"` | apricot | `userColor2` | ❌ | +| Spoken form | Color | Internal ID | Enabled by default? | +| -------------- | ------- | ------------ | ------------------- | +| N/A | grey | `default` | ✅ | +| `"blue"` | blue | `blue` | ✅ | +| `"green"` | green | `green` | ✅ | +| `"red"` | red | `red` | ✅ | +| `"pink"` | pink | `pink` | ✅ | +| `"yellow"` | yellow | `yellow` | ✅ | +| `"navy"` | navy | `userColor1` | ❌ | +| `"apricot"` | apricot | `userColor2` | ❌ | +| `"userColor3"` | user 3 | `userColor3` | ❌ | +| `"userColor4"` | user 4 | `userColor4` | ❌ | You can enable or disable colors in your VSCode settings, by searching for [`cursorless.hatEnablement.colors`](vscode://settings/cursorless.hatEnablement.colors) and checking the box next to the internal ID for the given shape as listed above. To navigate to your VSCode settings, either say "show settings", or go to File --> Preferences --> Settings. diff --git a/packages/cursorless-vscode/package.json b/packages/cursorless-vscode/package.json index 34d14befbd..f8d7399328 100644 --- a/packages/cursorless-vscode/package.json +++ b/packages/cursorless-vscode/package.json @@ -427,6 +427,12 @@ }, "userColor2": { "type": "string" + }, + "userColor3": { + "type": "string" + }, + "userColor4": { + "type": "string" } }, "default": { @@ -437,7 +443,9 @@ "pink": "#E06CAA", "yellow": "#E5C02C", "userColor1": "#6a00ff", - "userColor2": "#ffd8b1" + "userColor2": "#ffd8b1", + "userColor3": "#6b8e23", + "userColor4": "#e0e0e0" }, "additionalProperties": false }, @@ -469,6 +477,12 @@ }, "userColor2": { "type": "string" + }, + "userColor3": { + "type": "string" + }, + "userColor4": { + "type": "string" } }, "default": { @@ -479,7 +493,9 @@ "pink": "#e0679f", "yellow": "#edb62b", "userColor1": "#6a00ff", - "userColor2": "#ffd8b1" + "userColor2": "#ffd8b1", + "userColor3": "#6b8e23", + "userColor4": "#e0e0e0" }, "additionalProperties": false }, @@ -700,6 +716,12 @@ }, "userColor2": { "type": "boolean" + }, + "userColor3": { + "type": "boolean" + }, + "userColor4": { + "type": "boolean" } }, "default": { @@ -709,7 +731,9 @@ "pink": true, "yellow": true, "userColor1": false, - "userColor2": false + "userColor2": false, + "userColor3": false, + "userColor4": false }, "additionalProperties": false }, @@ -792,6 +816,12 @@ }, "userColor2": { "type": "number" + }, + "userColor3": { + "type": "number" + }, + "userColor4": { + "type": "number" } }, "default": { @@ -801,7 +831,9 @@ "pink": 1, "yellow": 1, "userColor1": 1, - "userColor2": 1 + "userColor2": 1, + "userColor3": 1, + "userColor4": 1 }, "additionalProperties": false }, @@ -1106,7 +1138,9 @@ "pink", "yellow", "userColor1", - "userColor2" + "userColor2", + "userColor3", + "userColor4" ] } }, diff --git a/packages/cursorless-vscode/src/ide/vscode/hatStyles.types.ts b/packages/cursorless-vscode/src/ide/vscode/hatStyles.types.ts index b8a7021e92..9d19dd8f93 100644 --- a/packages/cursorless-vscode/src/ide/vscode/hatStyles.types.ts +++ b/packages/cursorless-vscode/src/ide/vscode/hatStyles.types.ts @@ -7,6 +7,8 @@ export const HAT_COLORS = [ "yellow", "userColor1", "userColor2", + "userColor3", + "userColor4", ] as const; export const HAT_NON_DEFAULT_SHAPES = [ From afdebbac21dd96425e7e3598371312a24db7e514 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 11 Mar 2026 10:15:36 +0100 Subject: [PATCH 2/3] Update spoken formed to be usable by conformer --- cursorless-talon/src/spoken_forms.json | 4 ++-- .../defaultSpokenForms/marks.ts | 4 ++-- .../src/docs/user/README.md | 24 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cursorless-talon/src/spoken_forms.json b/cursorless-talon/src/spoken_forms.json index e659601dfc..c11fb9d3d6 100644 --- a/cursorless-talon/src/spoken_forms.json +++ b/cursorless-talon/src/spoken_forms.json @@ -246,8 +246,8 @@ "yellow": "yellow", "navy": "userColor1", "apricot": "userColor2", - "userColor3": "userColor3", - "userColor4": "userColor4" + "user color three": "userColor3", + "user color four": "userColor4" }, "hat_shape": { "ex": "ex", diff --git a/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts b/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts index ebbd4aab16..a0750e1b51 100644 --- a/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts +++ b/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/marks.ts @@ -8,8 +8,8 @@ const hatColors: Record = { yellow: "yellow", userColor1: "navy", userColor2: "apricot", - userColor3: "userColor3", - userColor4: "userColor4", + userColor3: "user color three", + userColor4: "user color four", default: null, }; diff --git a/packages/cursorless-org-docs/src/docs/user/README.md b/packages/cursorless-org-docs/src/docs/user/README.md index 9daf6445c6..c98f07bc37 100644 --- a/packages/cursorless-org-docs/src/docs/user/README.md +++ b/packages/cursorless-org-docs/src/docs/user/README.md @@ -53,18 +53,18 @@ Combining this with an action, we might say `"take blue air"` to select the toke The following colors are supported. Note that to target the default (gray) hat you don't need to specify a color. -| Spoken form | Color | Internal ID | Enabled by default? | -| -------------- | ------- | ------------ | ------------------- | -| N/A | grey | `default` | ✅ | -| `"blue"` | blue | `blue` | ✅ | -| `"green"` | green | `green` | ✅ | -| `"red"` | red | `red` | ✅ | -| `"pink"` | pink | `pink` | ✅ | -| `"yellow"` | yellow | `yellow` | ✅ | -| `"navy"` | navy | `userColor1` | ❌ | -| `"apricot"` | apricot | `userColor2` | ❌ | -| `"userColor3"` | user 3 | `userColor3` | ❌ | -| `"userColor4"` | user 4 | `userColor4` | ❌ | +| Spoken form | Color | Internal ID | Enabled by default? | +| -------------------- | ------- | ------------ | ------------------- | +| N/A | grey | `default` | ✅ | +| `"blue"` | blue | `blue` | ✅ | +| `"green"` | green | `green` | ✅ | +| `"red"` | red | `red` | ✅ | +| `"pink"` | pink | `pink` | ✅ | +| `"yellow"` | yellow | `yellow` | ✅ | +| `"navy"` | navy | `userColor1` | ❌ | +| `"apricot"` | apricot | `userColor2` | ❌ | +| `"user color three"` | user 3 | `userColor3` | ❌ | +| `"user color four"` | user 4 | `userColor4` | ❌ | You can enable or disable colors in your VSCode settings, by searching for [`cursorless.hatEnablement.colors`](vscode://settings/cursorless.hatEnablement.colors) and checking the box next to the internal ID for the given shape as listed above. To navigate to your VSCode settings, either say "show settings", or go to File --> Preferences --> Settings. From 154974554b30013e503a516a2bd379054641782e Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 11 Mar 2026 10:24:17 +0100 Subject: [PATCH 3/3] update readme --- .../src/docs/user/README.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/cursorless-org-docs/src/docs/user/README.md b/packages/cursorless-org-docs/src/docs/user/README.md index c98f07bc37..340161fb40 100644 --- a/packages/cursorless-org-docs/src/docs/user/README.md +++ b/packages/cursorless-org-docs/src/docs/user/README.md @@ -53,18 +53,18 @@ Combining this with an action, we might say `"take blue air"` to select the toke The following colors are supported. Note that to target the default (gray) hat you don't need to specify a color. -| Spoken form | Color | Internal ID | Enabled by default? | -| -------------------- | ------- | ------------ | ------------------- | -| N/A | grey | `default` | ✅ | -| `"blue"` | blue | `blue` | ✅ | -| `"green"` | green | `green` | ✅ | -| `"red"` | red | `red` | ✅ | -| `"pink"` | pink | `pink` | ✅ | -| `"yellow"` | yellow | `yellow` | ✅ | -| `"navy"` | navy | `userColor1` | ❌ | -| `"apricot"` | apricot | `userColor2` | ❌ | -| `"user color three"` | user 3 | `userColor3` | ❌ | -| `"user color four"` | user 4 | `userColor4` | ❌ | +| Spoken form | Color | Internal ID | Enabled by default? | +| ---------------- | ------- | ------------ | ------------------- | +| N/A | grey | `default` | ✅ | +| `"blue"` | blue | `blue` | ✅ | +| `"green"` | green | `green` | ✅ | +| `"red"` | red | `red` | ✅ | +| `"pink"` | pink | `pink` | ✅ | +| `"yellow"` | yellow | `yellow` | ✅ | +| `"navy"` | navy | `userColor1` | ❌ | +| `"apricot"` | apricot | `userColor2` | ❌ | +| `"user color 3"` | user 3 | `userColor3` | ❌ | +| `"user color 4"` | user 4 | `userColor4` | ❌ | You can enable or disable colors in your VSCode settings, by searching for [`cursorless.hatEnablement.colors`](vscode://settings/cursorless.hatEnablement.colors) and checking the box next to the internal ID for the given shape as listed above. To navigate to your VSCode settings, either say "show settings", or go to File --> Preferences --> Settings.