Updated hat shapes (#1868)

* Updated hat shape svg for increased area
* svg all now have the same size and proportions which means that we
don't have to do as much tweaking in typescript
* hats have an increased default height

main

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/86a9a80b-fbd4-477f-8c6f-082adbc7f4dd)

pr1868

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/5431585d-e722-4645-982a-536d0a0d3b18)

matt 2.1

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/4708606d-4228-4863-91db-54d56c684741)

matt 2.3

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/edd19b7f-4f11-4c8d-a2fe-369ce290f280)


pr1868 vs 2.1 vs 2.3

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/e681962c-9166-4983-9fc3-c8b0e3b29a2c)

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/ed33ff22-f08d-4d02-8234-a4f664da7ffd)

![image](https://github.com/cursorless-dev/cursorless/assets/3511326/f5512cb7-291b-4ffe-9ff3-3a2a7eb47a22)



## Checklist

- [x] Do a pass through looking at the hat sorting to see if we want to
reorder them
- [x] Check that the order of hats in constants is same as order in
package.json
- [ ] Send message to users indicating that if they have used the
individual hat adjustments setting, they may want to reset it and start
over because things have changed
- [/] I have added
[tests](https://www.cursorless.org/docs/contributing/test-case-recorder/)
- [/] I have updated the
[docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and
[cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet)
- [/] I have not broken the cheatsheet

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Phil Cohen <phillip@phillip.io>
Co-authored-by: Pokey Rule <755842+pokey@users.noreply.github.com>
This commit is contained in:
Andreas Arvidsson 2023-10-24 12:13:00 +02:00 committed by GitHub
parent 0fe8395078
commit 71ccbdd393
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 285 additions and 125 deletions

View File

@ -0,0 +1,6 @@
---
tags: [enhancement]
pullRequest: 1868
---
- Updated the default Cursorless hat shapes. All the hat shapes have been reworked with the goal to improve visibility. Many of the shapes have been made thicker to enhance color recognition. See the [shape docs](https://www.cursorless.org/docs/#shapes) for more info.

View File

@ -6,3 +6,5 @@ g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -82,16 +82,16 @@ The following shapes are supported. Note that to target the default (dot) shape
| Spoken form | Shape | Internal ID | Enabled by default? |
| ----------- | ----------------------------------------------- | ------------ | ------------------- |
| N/A | ![Default](../../images/hats/default.svg) | `default` | ✅ |
| `"ex"` | ![Ex](../../images/hats/ex.svg) | `ex` | ❌ |
| `"bolt"` | ![Bolt](../../images/hats/bolt.svg) | `bolt` | ❌ |
| `"curve"` | ![Curve](../../images/hats/curve.svg) | `curve` | ❌ |
| `"fox"` | ![Fox](../../images/hats/fox.svg) | `fox` | ❌ |
| `"frame"` | ![Frame](../../images/hats/frame.svg) | `frame` | ❌ |
| `"play"` | ![Play](../../images/hats/play.svg) | `play` | ❌ |
| `"wing"` | ![Wing](../../images/hats/wing.svg) | `wing` | ❌ |
| `"hole"` | ![Hole](../../images/hats/hole.svg) | `hole` | ❌ |
| `"frame"` | ![Frame](../../images/hats/frame.svg) | `frame` | ❌ |
| `"curve"` | ![Curve](../../images/hats/curve.svg) | `curve` | ❌ |
| `"eye"` | ![Eye](../../images/hats/eye.svg) | `eye` | ❌ |
| `"play"` | ![Play](../../images/hats/play.svg) | `play` | ❌ |
| `"ex"` | ![Ex](../../images/hats/ex.svg) | `ex` | ❌ |
| `"cross"` | ![Crosshairs](../../images/hats/crosshairs.svg) | `crosshairs` | ❌ |
| `"bolt"` | ![Bolt](../../images/hats/bolt.svg) | `bolt` | ❌ |
| `"eye"` | ![Eye](../../images/hats/eye.svg) | `eye` | ❌ |
You can enable or disable shapes in your VSCode settings, by searching for `cursorless.hatEnablement.shapes` 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.

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 377.73 272.77" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M377.73,48V0s-84.23,168.46-125,162.43c-31.64-4.68-113.06-108.7-113.06-108.7L6,214.53,0,272.77S99.58,118.5,141,126.22C171.82,132,262,242.79,262,242.79Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 4V0C12 0 9 5 8 5C7 5 3 0 3 0L0 5V9C0 9 3 5 4 5C5 5 9 9 9 9L12 4Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 202 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 393.6 253.72" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M199.64,0l-57.3,96.45A6.3,6.3,0,0,1,138,99.31L0,129.21H0l137.38,30a6.25,6.25,0,0,1,4.09,2.69l58.17,91.79h0l57.22-88.78A6.23,6.23,0,0,1,261,162l132.56-32.8h0L261.18,96.14a6.22,6.22,0,0,1-4.4-3m-13.69,51.54c-14.67,11-26.6,25.35-43.45,25.34-17.76,0-26.48-11.68-40.35-23.72-8.41-7.31-32.18-12.12-52.47-15.14a3.27,3.27,0,0,1,.16-6.5c20.58-2.22,44.9-5.84,54.21-13.16,14.18-11.14,20.61-23.15,38.45-23.15,17.05,0,25.15,13,40.25,22.82,8.87,5.76,32.13,10.89,52.43,13.17a3.26,3.26,0,0,1,.06,6.5C272.66,133.41,251.75,138.18,243.09,144.64Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.25 0C5.25 0 4.5 1.5 3.5 2.5C2.49483 3.50517 0 3.75 0 3.75V5.25C0 5.25 2.49483 5.49483 3.5 6.5C4.5 7.5 5.25 9 5.25 9H6.75C6.75 9 7.5 7.5 8.5 6.5C9.50517 5.49483 12 5.25 12 5.25V3.75C12 3.75 9.50517 3.50517 8.5 2.5C7.5 1.5 6.75 0 6.75 0H5.25ZM5.75 6.5H6.25C6.25 6.5 6.58435 5.25599 7 5C7.41565 4.74401 8.75 4.75 8.75 4.75V4.25C8.75 4.25 7.41565 4.25599 7 4C6.58435 3.74401 6.25 2.5 6.25 2.5H5.75C5.75 2.5 5.41565 3.74401 5 4C4.58435 4.25599 3.25 4.25 3.25 4.25V4.75C3.25 4.75 4.58435 4.74401 5 5C5.41565 5.25599 5.75 6.5 5.75 6.5Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 705 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 385.47 189.48" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M192.74,72.63c106.44,0,192.73,64.71,192.73,116.85C385.47,84.84,299.18,0,192.74,0S0,84.84,0,189.48C0,137.34,86.29,72.63,192.74,72.63Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.00016 3.5C10 3.5 12 7.07378 12 9C12 4 10.5 0 6.00016 0C1.50032 0 0 4 0 9C0 7.07378 2.00032 3.5 6.00016 3.5Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 244 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 308.34 254.24" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><ellipse class="cls-1" cx="154.17" cy="127.12" rx="154.17" ry="127.12"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 9C9.31371 9 12 6.98528 12 4.5C12 2.01472 9.31371 0 6 0C2.68629 0 0 2.01472 0 4.5C0 6.98528 2.68629 9 6 9Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 242 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 372.92 260.67" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M357.28,259s-122.15-87.78-171.37-87.78c-48.56,0-169.68,87.85-169.68,87.85-14.19,6.3-22.33-8-10.64-16.56,0,0,113.1-77.8,113.1-112.2C118.69,95.71,1.84,13.76,1.84,13.76-3,8.54,3.83-2.5,11.6.57c0,0,124.6,88.88,174.31,88.88,48,0,174.35-88.12,174.35-88.12,6.3-5.23,15.94,6.41,11.55,10.07,0,0-118.69,85-118.69,119,0,34.4,115,114.44,115,114.44C376.66,253.52,369.29,263.89,357.28,259Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.99997 9C9.99997 9 7.5 6.5 6 6.5C4.5 6.5 2 9 2 9C2 9 0.999999 9 0 9C0 9 2.5 6 2.5 4.5C2.5 3 6.5473e-05 0 6.5473e-05 0C6.5473e-05 0 1 0 2 0C2 0 4.5 2.5 6 2.5C7.5 2.5 9.99997 0 9.99997 0C11 0 12 0 12 0C12 0 9.5 3 9.5 4.5C9.5 6 12 9 12 9C12 9 11 9 9.99997 9Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 391 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 429 223.69" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M425.73,108.83,217.14.3a2.82,2.82,0,0,0-2.25-.12,2.55,2.55,0,0,0-2.1.11L3.26,109.11c-4.35,2-4.35,3.7,0,5.75l208.6,108.53a2.83,2.83,0,0,0,2.25.13,2.59,2.59,0,0,0,2.1-.11L425.73,114.59C430.09,112.54,430.09,110.88,425.73,108.83ZM212.61,186.55c-55.43,0-63.85-36.44-63.85-74.7s8.65-78.49,64.07-78.49,61.41,40.23,61.41,78.49S268,186.55,212.61,186.55Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 4L6.5 0H5.5L0 4V5L5.5 9H6.5L12 5V4ZM6 7.5C6 7.5 4.5 6.5 4.5 4.5C4.5 2.5 6.01103 1.5 6 1.5C6 1.5 7.5 2.5 7.5 4.5C7.5 6.5 6 7.5 6 7.5Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 270 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 397.01 264.7" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M202.63,262.78,393.87,22c9.57-17.55-4.67-30.45-17.29-13.74-43.06,57-133.84,112.18-178.08,112.18S63,64.71,19.21,8.27C4.76-10.33-6.36,6.05,4.13,22l191.2,240.77A4.44,4.44,0,0,0,202.63,262.78Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.00001 9L0 0C0 0 3.71818 2.5 6 2.5C8.28182 2.5 12 0 12 0L6.00001 9Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 203 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 385.08 254.31" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M0,7.54V246.76a7.78,7.78,0,0,0,8,7.55H377.08a7.78,7.78,0,0,0,8-7.55V7.54a7.78,7.78,0,0,0-8-7.54H8A7.78,7.78,0,0,0,0,7.54ZM311.72,201.38H73.36a7.78,7.78,0,0,1-8-7.55V60.48a7.78,7.78,0,0,1,8-7.55H311.72a7.78,7.78,0,0,1,8,7.55V193.83A7.78,7.78,0,0,1,311.72,201.38Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0.000115976V8.99988H12V0L0 0.000115976ZM9.5 6.5H6H2.5V4.5V2.5H6H9.5V4.5V6.5Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 213 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 371.81 282.71" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M274.63,161.13l61.81-19.78-61.81-19.77,97.18-51.09L252,78.74,259.68,0,212.57,64.13l-26.66,4.33-29.7-3.67L106.16,0l7.68,78.32L0,70.49,93.11,121,29.4,141.35l63.71,20.38L0,212.22l113.84-7.83-7.68,78.32,49.47-66.06,29.42-4.54,28.19,4.33,46.44,66.27L252,204l119.85,8.25Zm-89.58,31c-42.53,0-77-22.74-77-50.8s34.47-50.8,77-50.8,77,22.75,77,50.8S227.57,192.15,185.05,192.15Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.5 4.5L0 7H2.5L3.5 9L6 7.5L8.5 9L9.5 7H12L10.5 4.5L12 2H9.5L8.5 0L6 1.5L3.5 0L2.5 2H0M6 5.5L4 6.5L3 4.5L4 2.5L6 3.5L8 2.5L9 4.5L8 6.5L6 5.5Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 622 B

After

Width:  |  Height:  |  Size: 276 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400.5 258.42" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M394.51,125.73,12.2.35C3-2.39-4.2,11.84,4.08,16c47.5,23.9,112.66,74.55,112.23,113.21-.46,41.6-64.86,89.06-112.23,112.55-8.31,4.11-2.8,19.07,6.43,16.33l384-125.71C402.49,130,402.49,128.09,394.51,125.73Z"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 4.49999L0 9C0 9 3 6.2746 3 4.49999C3 2.72537 0 0 0 0L12 4.49999Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 202 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 371.81 234.76" width="1em" height="1em"><defs><style>.cls-1{fill:#666666;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M371.81,234.42h0s-153.27-57.29-185.9-54.08h0C154.36,177.24,0,234.76,0,234.76H0L158.55,101.69c.6-.49-.39,1.87-.23,1.12L186.24,0h0l26.84,101.37"/></g></g></svg>
<svg width="1em" height="1em" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 0C6 0 7 3 8.5 4.5C10 6 12 7 12 7V9C12 9 8.5 7 6 7C3.5 7 0 9 0 9V7C0 7 2 6 3.5 4.5C5 3 6 0 6 0Z" fill="#666666"/>
</svg>

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 231 B

View File

@ -363,7 +363,7 @@
}
},
"default": {
"default": "#aaa7bb",
"default": "#B9B6CD",
"blue": "#089ad3",
"green": "#36B33F",
"red": "#E02D28",
@ -651,48 +651,48 @@
"type": "object",
"order": 3,
"properties": {
"ex": {
"bolt": {
"type": "boolean"
},
"curve": {
"type": "boolean"
},
"fox": {
"type": "boolean"
},
"frame": {
"type": "boolean"
},
"play": {
"type": "boolean"
},
"wing": {
"type": "boolean"
},
"hole": {
"type": "boolean"
},
"frame": {
"type": "boolean"
},
"curve": {
"type": "boolean"
},
"eye": {
"type": "boolean"
},
"play": {
"type": "boolean"
},
"bolt": {
"ex": {
"type": "boolean"
},
"crosshairs": {
"type": "boolean"
},
"eye": {
"type": "boolean"
}
},
"default": {
"ex": false,
"bolt": false,
"curve": false,
"fox": false,
"frame": false,
"play": false,
"wing": false,
"hole": false,
"frame": false,
"curve": false,
"eye": false,
"play": false,
"bolt": false,
"crosshairs": false
"ex": false,
"crosshairs": false,
"eye": false
},
"additionalProperties": false
},
@ -742,48 +742,48 @@
"description": "How much to penalize each hat shape. Number of syllables is a good default",
"type": "object",
"properties": {
"ex": {
"bolt": {
"type": "number"
},
"curve": {
"type": "number"
},
"fox": {
"type": "number"
},
"frame": {
"type": "number"
},
"play": {
"type": "number"
},
"wing": {
"type": "number"
},
"hole": {
"type": "number"
},
"frame": {
"type": "number"
},
"curve": {
"type": "number"
},
"eye": {
"type": "number"
},
"play": {
"type": "number"
},
"bolt": {
"ex": {
"type": "number"
},
"crosshairs": {
"type": "number"
},
"eye": {
"type": "number"
}
},
"default": {
"ex": 1,
"bolt": 1,
"curve": 1,
"fox": 1,
"frame": 1,
"play": 1,
"wing": 1,
"hole": 1,
"frame": 1,
"curve": 1,
"eye": 1,
"play": 1,
"bolt": 1,
"crosshairs": 1
"ex": 1,
"crosshairs": 1,
"eye": 1
},
"additionalProperties": false
},
@ -795,7 +795,11 @@
"sizeAdjustment": 0,
"verticalOffset": 0
},
"ex": {
"bolt": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"curve": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
@ -803,6 +807,14 @@
"sizeAdjustment": 0,
"verticalOffset": 0
},
"frame": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"play": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"wing": {
"sizeAdjustment": 0,
"verticalOffset": 0
@ -811,29 +823,17 @@
"sizeAdjustment": 0,
"verticalOffset": 0
},
"frame": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"curve": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"eye": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"play": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"bolt": {
"ex": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"crosshairs": {
"sizeAdjustment": 0,
"verticalOffset": 0
},
"eye": {
"sizeAdjustment": 0,
"verticalOffset": 0
}
}
},
@ -925,16 +925,16 @@
"additionalProperties": {
"type": "string",
"enum": [
"ex",
"bolt",
"curve",
"fox",
"frame",
"play",
"wing",
"hole",
"frame",
"curve",
"eye",
"play",
"bolt",
"crosshairs"
"ex",
"crosshairs",
"eye"
]
}
},
@ -1051,8 +1051,8 @@
"populate-dist": "tsx --conditions=cursorless:bundler ./src/scripts/populateDist/index.ts",
"init-launch-sandbox": "tsx --conditions=cursorless:bundler src/scripts/initLaunchSandbox.ts",
"preprocess-svg-hats": "tsx --conditions=cursorless:bundler src/scripts/preprocessSvgHats.ts",
"hat-adjustment-add": "tsx --conditions=cursorless:bundler src/scripts/hatAssignments/add.ts",
"hat-adjustment-average": "tsx --conditions=cursorless:bundler src/scripts/hatAssignments/add.ts",
"hat-adjustment-add": "tsx --conditions=cursorless:bundler src/scripts/hatAdjustments/add.ts",
"hat-adjustment-average": "tsx --conditions=cursorless:bundler src/scripts/hatAdjustments/average.ts",
"compile": "tsc --build",
"watch": "tsc --build --watch",
"clean": "rm -rf ./out tsconfig.tsbuildinfo ./dist"

View File

@ -131,6 +131,7 @@ async function createVscodeIde(context: vscode.ExtensionContext) {
const hats = new VscodeHats(
vscodeIDE,
vscodeApi,
context,
vscodeIDE.runMode === "test"
? new FakeFontMeasurements()

View File

@ -1,7 +1,8 @@
import type { ExtensionContext } from "vscode";
import type { State, StateData, StateKey } from "@cursorless/common";
import { STATE_DEFAULTS } from "@cursorless/common";
import type { ExtensionContext } from "vscode";
import { VERSION_KEY } from "../../ReleaseNotes";
import { PERFORMED_PR_1868_SHAPE_UPDATE_INIT_KEY } from "./hats/performPr1868ShapeUpdateInit";
export default class VscodeGlobalState implements State {
constructor(private extensionContext: ExtensionContext) {
@ -9,6 +10,7 @@ export default class VscodeGlobalState implements State {
extensionContext.globalState.setKeysForSync([
...Object.keys(STATE_DEFAULTS),
VERSION_KEY,
PERFORMED_PR_1868_SHAPE_UPDATE_INIT_KEY,
]);
}

View File

@ -10,16 +10,16 @@ export const HAT_COLORS = [
] as const;
export const HAT_NON_DEFAULT_SHAPES = [
"ex",
"bolt",
"curve",
"fox",
"frame",
"play",
"wing",
"hole",
"frame",
"curve",
"eye",
"play",
"bolt",
"ex",
"crosshairs",
"eye",
] as const;
export const HAT_SHAPES = ["default", ...HAT_NON_DEFAULT_SHAPES] as const;

View File

@ -1,9 +1,11 @@
import {
Listener,
Messages,
Notifier,
PathChangeListener,
walkFiles,
} from "@cursorless/common";
import { VscodeApi } from "@cursorless/vscode-common";
import { cloneDeep, isEqual } from "lodash";
import * as fs from "node:fs";
import * as path from "node:path";
@ -21,6 +23,7 @@ import {
IndividualHatAdjustmentMap,
defaultShapeAdjustments,
} from "./shapeAdjustments";
import { performPr1868ShapeUpdateInit } from "./performPr1868ShapeUpdateInit";
const CURSORLESS_HAT_SHAPES_SUFFIX = ".svg";
@ -64,7 +67,9 @@ export default class VscodeHatRenderer {
private hatShapeOverrides: Record<string, string> = {};
constructor(
private vscodeApi: VscodeApi,
private extensionContext: vscode.ExtensionContext,
private messages: Messages,
private enabledHatStyles: VscodeEnabledHatStyleManager,
private fontMeasurements: FontMeasurements,
) {
@ -190,6 +195,16 @@ export default class VscodeHatRenderer {
.getConfiguration("cursorless")
.get<IndividualHatAdjustmentMap>("individualHatAdjustments")!;
performPr1868ShapeUpdateInit(
this.extensionContext,
this.vscodeApi,
this.messages,
this.enabledHatStyles.hatStyleMap,
userSizeAdjustment,
userVerticalOffset,
userIndividualAdjustments,
);
const hatSvgMap = Object.fromEntries(
HAT_SHAPES.map((shape) => {
const { sizeAdjustment = 0, verticalOffset = 0 } =

View File

@ -8,7 +8,7 @@ import {
Range,
TextEditor,
} from "@cursorless/common";
import { toVscodeRange } from "@cursorless/vscode-common";
import { toVscodeRange, VscodeApi } from "@cursorless/vscode-common";
import * as vscode from "vscode";
import { Disposable } from "vscode";
import { VscodeHatStyleName } from "../hatStyles.types";
@ -27,6 +27,7 @@ export class VscodeHats implements Hats {
constructor(
private ide: VscodeIDE,
vscodeApi: VscodeApi,
extensionContext: vscode.ExtensionContext,
fontMeasurements: FontMeasurements,
) {
@ -34,7 +35,9 @@ export class VscodeHats implements Hats {
extensionContext,
);
this.hatRenderer = new VscodeHatRenderer(
vscodeApi,
extensionContext,
ide.messages,
this.enabledHatStyleManager,
fontMeasurements,
);

View File

@ -0,0 +1,115 @@
import { Messages, showInfo } from "@cursorless/common";
import { VscodeApi } from "@cursorless/vscode-common";
import * as vscode from "vscode";
import { ExtendedHatStyleMap } from "../VscodeEnabledHatStyleManager";
import { IndividualHatAdjustmentMap } from "./shapeAdjustments";
/**
* We set this key in global state the first time they user gets the new shapes from #1868. We use this to
* determine whether or not to show them messages about resetting their hat adjustments.
*/
export const PERFORMED_PR_1868_SHAPE_UPDATE_INIT_KEY =
"performedPr1868ShapeUpdateInit";
/**
* If this is the first time the user has gotten the new shapes from #1868, we
* show them a message about resetting their hat adjustments if they have done
* any customization.
*
* We can probably remove this after a while.
*/
export async function performPr1868ShapeUpdateInit(
extensionContext: vscode.ExtensionContext,
vscodeApi: VscodeApi,
messages: Messages,
hatStyleMap: ExtendedHatStyleMap,
userSizeAdjustment: number,
userVerticalOffset: number,
userIndividualAdjustments: IndividualHatAdjustmentMap,
) {
if (
// Only show in focused window
!vscodeApi.window.state.focused ||
// Only run on initial update to new hat shapes
extensionContext.globalState.get<boolean>(
PERFORMED_PR_1868_SHAPE_UPDATE_INIT_KEY,
)
) {
return;
}
// Whether or not we end up showing anything, we don't want to show this
// message after the first time they get the new hats. If they make adjustments
// in the future, they've done so with the new hats in mind.
await extensionContext.globalState.update(
PERFORMED_PR_1868_SHAPE_UPDATE_INIT_KEY,
true,
);
let shownMessage = false;
// If they have any individual adjustments, we should tell them to reset them
if (
Object.values(userIndividualAdjustments)
.flatMap((entry) => Object.values(entry))
.some((value) => value != null && value !== 0)
) {
shownMessage = true;
const PERFORM_RESET = "Perform reset";
const TAKE_ME_THERE = "Take me there";
const result = await showInfo(
messages,
"maybeUpdateIndividualHatSettings",
"The hat shapes have been updated; you probably want to reset your individual hat adjustments.",
PERFORM_RESET,
TAKE_ME_THERE,
);
if (result === TAKE_ME_THERE) {
await vscode.commands.executeCommand(
"workbench.action.openSettingsJson",
{
revealSetting: { key: "cursorless.individualHatAdjustments" },
},
);
} else if (result === PERFORM_RESET) {
await vscode.workspace
.getConfiguration("cursorless")
.update("individualHatAdjustments", undefined, true);
}
}
// If they have any global adjustments, they may want to tweak them
if (
(userSizeAdjustment !== 0 || userVerticalOffset !== 0) &&
// Don't bother if they have no shapes enabled, as the default shape
// is similar enough in size / offset to the old default shape
hasAnyShapesEnabled(hatStyleMap)
) {
const TAKE_ME_THERE = "Take me there";
const message = shownMessage
? "You may also want to tweak your global hat settings."
: "The hat shapes have been updated; you may want to tweak your hat settings.";
const result = await showInfo(
messages,
"maybeUpdateGlobalHatSettings",
message,
TAKE_ME_THERE,
);
if (result === TAKE_ME_THERE) {
await vscode.commands.executeCommand(
"workbench.action.openSettings",
`@ext:${extensionContext.extension.id}`,
);
}
}
}
function hasAnyShapesEnabled(hatStyleMap: ExtendedHatStyleMap) {
// A bit of a hack, but if they have any shapes enabled, they'll have keys
// like `blue-fox`, which contain a `-`. If they don't have any shapes
// enabled, they'll only have keys like `blue`, `default, etc.
return Object.keys(hatStyleMap).some((key) => key.includes("-"));
}

View File

@ -7,49 +7,38 @@ export interface HatAdjustments {
export type IndividualHatAdjustmentMap = Record<HatShape, HatAdjustments>;
export const DEFAULT_HAT_HEIGHT_EM = 0.29;
export const DEFAULT_VERTICAL_OFFSET_EM = 0.032;
export const DEFAULT_HAT_HEIGHT_EM = 0.36;
export const DEFAULT_VERTICAL_OFFSET_EM = 0.05;
export const defaultShapeAdjustments: IndividualHatAdjustmentMap = {
default: {
sizeAdjustment: -14,
verticalOffset: -0.35,
sizeAdjustment: -30,
},
ex: {
sizeAdjustment: 10,
sizeAdjustment: -15,
},
fox: {
sizeAdjustment: 10,
sizeAdjustment: -10,
},
wing: {
sizeAdjustment: 15.5,
verticalOffset: 1.1,
sizeAdjustment: -2.5,
},
hole: {
sizeAdjustment: 32.5,
verticalOffset: -2,
sizeAdjustment: -5.5,
},
frame: {
sizeAdjustment: -15,
verticalOffset: -2.25,
sizeAdjustment: -20,
},
curve: {
sizeAdjustment: -21,
verticalOffset: -3.15,
sizeAdjustment: -6,
verticalOffset: -3,
},
eye: {
sizeAdjustment: -6.5,
verticalOffset: -1,
},
play: {
sizeAdjustment: -8,
verticalOffset: -0.5,
sizeAdjustment: -4.5,
},
play: {},
bolt: {
sizeAdjustment: 22.5,
},
crosshairs: {
sizeAdjustment: 29.5,
verticalOffset: -1,
sizeAdjustment: -5.5,
},
crosshairs: {},
};

View File

@ -9,9 +9,13 @@ async function main() {
const dumper = new parser.XMLBuilder({
ignoreAttributes: false,
suppressEmptyNode: true,
format: true,
});
readdirSync(directory, { withFileTypes: true }).forEach(async (dirent) => {
for (const dirent of readdirSync(directory, { withFileTypes: true })) {
if (!dirent.isFile() || !dirent.name.endsWith(".svg")) {
continue;
}
const filePath = path.join(directory, dirent.name);
const rawSvg = await fsp.readFile(filePath, { encoding: "utf8" });
const svgJson = new parser.XMLParser({ ignoreAttributes: false }).parse(
@ -30,11 +34,11 @@ async function main() {
const outputSvg = dumper
.build(svgJson)
.replace(/fill="[^"]+"/, `fill="#666666"`)
.replace(/fill:[^;]+;/, `fill:#666666;`);
.replace(/fill="(?!none)[^"]+"/g, 'fill="#666666"')
.replace(/fill:(?!none)[^;]+;/g, "fill:#666666;");
await fsp.writeFile(filePath, outputSvg);
});
}
}
main();

View File

@ -84,8 +84,9 @@ export async function getExtensionApiStrict<T>(extensionId: string) {
return (await extension.activate()) as T;
}
export const EXTENSION_ID = "pokey.cursorless";
export const getCursorlessApi = () =>
getExtensionApiStrict<CursorlessApi>("pokey.cursorless");
getExtensionApiStrict<CursorlessApi>(EXTENSION_ID);
export const getParseTreeApi = () =>
getExtensionApiStrict<ParseTreeApi>("pokey.parse-tree");