"` to see a live preview of the regex scope in [the scope visualizer](./scope-visualizer.md). It updates in real time every time you save `regex_scope_types.csv`.
+
+:::
+
+For example, here's what `"visualize dotted"` would show with the scope type `dotted,"[\w.]+"`:
+
+
+ 
+
+
+You can then use commands such as
+
+- `"take dotted sun"` to select `user.text` (line 10)
+- `"copy dotted urge"` to copy `user.chrome_mod` (line 11)
+- `"take every dotted urge"` to select `user.chrome_mod`, `shift`, and `a`
+
+## Examples
+
+| Spoken form | Regex | Notes | Example |
+| ------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ---------------------------- |
+| dotted | `"[\w.]+"` | Matches dotted expression | `one.two.three` |
+| pair math | `"\$[^$]*\$"` | Matches latex inlined math expression. May fail to match if line has unmatched expressions. | `$e^{\pi i}=-1$` |
+| inside math | `"[^$]*"` | Matches interior of a latex inlined math expression | `e^{\pi i}=-1` |
+| chain pipe | `(?:%>%\|%<>%\|%T>%\|\|>)` | Matches R pipe operators | `%>%`, `%<>%`, `%T>%`, `\|>` |
+| inside chain | `(?<=(?:%>%\|%<>%\|%T>%\|\|>)\s*)\S.*?\S(?=\s*(?:%>%\|%<>%\|%T>%\|\|>))` | Matches content between pipe operators in R chains | `filter(x > 0)` |
+| head chain | `(?<=(?:%>%\|%<>%\|%T>%\|\|>)\s*)\S[^\|%\n]*` | Matches content from current position until next pipe operator | `mutate(y = x * 2) %>%` |
+| tail chain | `\S.*?\S?(?=\s*(?:%>%\|%<>%\|%T>%\|\|>))` | Matches content from pipe until current position | ` %>% filter(x > 0)` |
+
+:::warning
+
+Regex matches cannot cross line boundaries (so multiline matches are not supported). The regexes also have the unicode flag set.
+
+:::
diff --git a/packages/app-web-docs/src/docs/user/customization.md b/packages/app-web-docs/src/docs/user/customization.md
index 916615b5c2f..b6877b64fda 100644
--- a/packages/app-web-docs/src/docs/user/customization.md
+++ b/packages/app-web-docs/src/docs/user/customization.md
@@ -2,21 +2,21 @@
Cursorless consists of
-- an IDE plugin (eg a VSCode extension), and
+- an IDE plugin (eg a VS Code extension), and
- a set of Talon files that define spoken commands
Because of this split, Cursorless has user settings available both on the IDE side, and on the Talon side. The rule of thumb is that anything that changes spoken forms happens Talon-side; everything else is IDE-side.
## IDE-side settings
-The IDE settings can be accessed by saying `"cursorless settings"` with your IDE (eg VSCode) focused.
+The IDE settings can be accessed by saying `"cursorless settings"` with your IDE (eg VS Code) focused.
## Talon-side settings
-Many of the spoken forms used in cursorless can be easily customized without
-needing to fork cursorless or modify the talon / python files contained
+Many of the spoken forms used in Cursorless can be easily customized without
+needing to fork Cursorless or modify the talon / python files contained
therein. If you find that your customization needs cannot be met without making
-changes to cursorless files, please [file an
+changes to Cursorless files, please [file an
issue](https://github.com/cursorless-dev/cursorless/issues/new) so we can
improve customization.
@@ -35,8 +35,8 @@ Note that these csv's:
- ignore leading / trailing whitespace on identifiers and spoken forms
If the spoken form begins with a `-`, it will be disabled. Please do not remove
-any lines, because that will trigger cursorless to add them back on next
-reload, as cursorless uses these lines to track disabled spoken forms.
+any lines, because that will trigger Cursorless to add them back on next
+reload, as Cursorless uses these lines to track disabled spoken forms.
### Changing a spoken form
@@ -54,56 +54,9 @@ When new actions, scope types, etc are added, Cursorless will detect that they'r
If you'd like to remove an action, scope type, etc, you can simply set the
spoken form in the first column to any thing starting with `-`. Please don't
-delete any lines, as that will trigger cursorless to automatically add the
+delete any lines, as that will trigger Cursorless to automatically add the
spoken form back on talon restart.
-## \[Experimental\] Cursorless custom IDE actions
-
-You can use Cursorless to run any built-in IDE command on a specific target.
-
-Just add your custom commands to: `experimental/actions_custom.csv`. For example, if you wanted to be able to say `"push down "` to move the line(s) containing target `` downwards, you could do the following:
-
-```csv
-Spoken form, VSCode command
-push down, editor.action.moveLinesDownAction
-```
-
-Now when you say eg "push down air and bat", cursorless will first select the two tokens with a gray hat over the `a` and `b`, then issue the VSCode command `editor.action.moveLinesDownAction`, and then restore your original selection.
-
-## \[Experimental\] Cursorless custom regex scopes
-
-You can define custom scopes using regexes in `user/cursorless-settings/experimental/regex_scope_types.csv`
-
-:::tip
-
-Use `"visualize "` to see a live preview of the regex scope in [the scope visualizer](./scope-visualizer.md). It updates in real time every time you save `regex_scope_types.csv`.
-
-:::
-
-For example, here's what `"visualize dotted"` would show with the scope type `dotted,"[\w.]+"`:
-
-
- 
-
-
-You can then use commands such as
-
-- `"take dotted sun"` to select `user.text` (line 10)
-- `"copy dotted urge"` to copy `user.chrome_mod` (line 11)
-- `"take every dotted urge"` to select `user.chrome_mod`, `shift`, and `a`
-
-:::tip
-
-> Check out [our wiki page](https://github.com/cursorless-dev/cursorless/wiki/Custom-regex-scopes) for a recipe book of user-created regex scopes!
-
-:::
-
-:::warning
-
-Regex matches cannot cross line boundaries (so multiline matches are not supported). The regexes also have the unicode flag set.
-
-:::
-
## Toggling "hat" display
It is possible to show / hide the hats with a command. Keep in mind that many users, often after less than a week using Cursorless, find that their brain starts to tune out the hat display. Some start to miss them when they're gone 🥲
@@ -139,101 +92,3 @@ The word separators are characters that defines the boundary between words in a
"cursorless.wordSeparators": ["_", "-"]
}
```
-
-## Cursorless public API
-
-Cursorless exposes a couple talon actions and captures that you can use to define your own custom command grammar leveraging cursorless targets.
-
-### Public Talon captures
-
-- ``
- Represents a cursorless target, such as `"air"`, `"this"`, `"air past bat"`, `"air and bat"`, `"funk air past token bat and class cap"`, etc
-
-- ``
- Represents a cursorless destination, such as `"to air"`, `"before this"`, `"after air and bat"`, etc
-
-### Public Talon actions
-
-- `user.cursorless_command(action_id: str, target: cursorless_target)`:
- Perform a Cursorless command on the given target
- eg: `user.cursorless_command("setSelection", cursorless_target)`.
- Note that for `"bring"` (`replaceWithTarget`), `cursorless_target` will be the source of the bring and the destination will be the current selection(s), as if you had said `"bring "`
-- `user.cursorless_ide_command(command_id: str, target: cursorless_target)`:
- Performs a built-in IDE command on the given target
- eg: `user.cursorless_ide_command("editor.action.addCommentLine", cursorless_target)`
-- `user.cursorless_get_text(target: CursorlessTarget, hide_decorations: bool = False) -> str`
- Get text from target. If `hide_decorations` is `true`, will not show decorations.
-- `user.cursorless_get_text_list(target: CursorlessTarget, hide_decorations: bool = False) -> list[str]`
- Get texts from multiple targets. If `hide_decorations` is `true`, will not show decorations.
-- `user.cursorless_insert(destination: CursorlessDestination, text: Union[str, List[str]])`:
- Insert text at destination.
- eg: `user.cursorless_insert(cursorless_destination, "hello")`
-- `user.cursorless_create_destination(target: CursorlessTarget, insertion_mode: Literal["to", "before", "after"] = "to") -> CursorlessDestination`:
- Create a destination from a target. The insertion mode can be `to`, `before`, or `after`, and defaults to `to`, which will replace the target. See [How do I run a custom Python transformation on a target?](./how-to.md#how-do-i-run-a-custom-python-transformation-on-a-target) for example usage.
-- `user.cursorless_reformat(target: CursorlessTarget, formatters: str)`
- Reformat target with specified formatters.
- eg: `user.cursorless_reformat(cursorless_target, "ALL_CAPS")`
-
-#### Snippet actions
-
-- `user.cursorless_insert_snippet(body: str, destination: Optional[CursorlessDestination], scope_type: Optional[Union[str, list[str]]])`: Insert a snippet with the given body. The body should be a single string, which could contain newline `\n` characters, rather than a list of strings as is expected in our snippet json representation. Destination is where the snippet will be inserted. If omitted will default to current selection. An optional scope type can be provided for the target to expand to. `"snip if after air"` for example could be desired to go after the statement containing `air` instead of the token.
-- `user.cursorless_wrap_with_snippet(body, target, variable_name, scope)`: Wrap the given target with a snippet with the given body. The body should be a single string, which could contain newline `\n` characters, rather than a list of strings as is expected in our snippet json representation. Note that `variable_name` should be one of the variables defined in `body`. Eg, if `body` has a variable `$foo`, you can pass in `"foo"` for `variable_name`, and `target` will be inserted into the position of `$foo` in the given named snippet. The `scope` variable can be used to automatically expand the target to the given scope type, eg `"line"`.
-
-### Example of combining capture and action
-
-```talon
-add dock string :
- user.cursorless_command("editNewLineAfter", cursorless_target)
- "\"\"\"\"\"\""
- key(left:3)
-
-push down:
- user.cursorless_ide_command("editor.action.moveLinesDownAction", cursorless_target)
-```
-
-### Example of custom formatter command
-
-The below command will allow you to say `camel form blue air`.
-_You can disable the default Cursorless reformat command by prefixing the spoken form in `actions.csv` with a dash. `-format, applyFormatter`_
-
-```talon
- form :
- user.cursorless_reformat(cursorless_target, formatters)
-```
-
-### Experimental custom command action
-
-:::warning
-
-This feature is experimental! Not as thoroughly tested as the rest of Cursorless and might change in the future. Early adopters should subscribe to this [discussion](https://github.com/cursorless-dev/cursorless/discussions/2942) to get updates about breaking changes\_
-
-:::
-
-`user.cursorless_x_custom_command(command: string, *args)`
-
-Run a custom Cursorless command by parsing the specified command string. Supports a subset of the Cursorless grammar, with **default** spoken forms (not your custom spoken forms). See https://www.cursorless.org/custom-command-railroad to see the subset of our grammar that we support today.
-
-- Utilizes default Cursorless spoken forms in the command string.
-- Optional target arguments can be interpolated in the command string. (see examples below)
-
-#### Examples
-
-In order to map `"scratch"` to perform `"chuck block"`:
-
-```talon
-scratch: user.cursorless_x_custom_command("chuck block")
-```
-
-To map `"scratch air"` => `"chuck block air"`
-
-```talon
-scratch :
- user.cursorless_x_custom_command("chuck block ", cursorless_target)
-```
-
-To map `"combine air plus bat"` => `"bring block air after bat"`
-
-```talon
-combine plus :
- user.cursorless_x_custom_command("bring block after ", cursorless_target_1, cursorless_target_2)
-```
diff --git a/packages/app-web-docs/src/docs/user/experimental/custom-command-action.md b/packages/app-web-docs/src/docs/user/experimental/custom-command-action.md
new file mode 100644
index 00000000000..4acc45fa520
--- /dev/null
+++ b/packages/app-web-docs/src/docs/user/experimental/custom-command-action.md
@@ -0,0 +1,36 @@
+# Experimental custom command action
+
+:::warning
+
+This feature is experimental! Not as thoroughly tested as the rest of Cursorless and might change in the future. Early adopters should subscribe to this [discussion](https://github.com/cursorless-dev/cursorless/discussions/2942) to get updates about breaking changes\_
+
+:::
+
+`user.cursorless_x_custom_command(command: string, *args)`
+
+Run a custom Cursorless command by parsing the specified command string. Supports a subset of the Cursorless grammar, with **default** spoken forms (not your custom spoken forms). See https://www.cursorless.org/custom-command-railroad to see the subset of our grammar that we support today.
+
+- Utilizes default Cursorless spoken forms in the command string.
+- Optional target arguments can be interpolated in the command string. (see examples below)
+
+## Examples
+
+In order to map `"scratch"` to perform `"chuck block"`:
+
+```talon
+scratch: user.cursorless_x_custom_command("chuck block")
+```
+
+To map `"scratch air"` => `"chuck block air"`
+
+```talon
+scratch :
+ user.cursorless_x_custom_command("chuck block ", cursorless_target)
+```
+
+To map `"combine air plus bat"` => `"bring block air after bat"`
+
+```talon
+combine plus :
+ user.cursorless_x_custom_command("bring block after ", cursorless_target_1, cursorless_target_2)
+```
diff --git a/packages/app-web-docs/src/docs/user/experimental/keyboard/modal.md b/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md
similarity index 60%
rename from packages/app-web-docs/src/docs/user/experimental/keyboard/modal.md
rename to packages/app-web-docs/src/docs/user/experimental/keyboard/README.md
index 8eb08b1b848..31a867803d5 100644
--- a/packages/app-web-docs/src/docs/user/experimental/keyboard/modal.md
+++ b/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md
@@ -2,17 +2,33 @@
Cursorless has an experimental modal keyboard interface. This allows you to switch to Cursorless mode, and then you can use your keyboard to control Cursorless without holding any modifier keys, similar to how `vim` works.
-The cursorless keyboard interface works by moving a highlight around, and allowing you to perform actions on the highlighted target.
+The Cursorless keyboard interface works by moving a highlight around, and allowing you to perform actions on the highlighted target.



+## Using modal mode
+
+Keyboard commands are built incrementally around the highlighted target. First target a mark, then apply any scopes or modifiers, and finally perform an action. This is the reverse of the spoken command order because each keyboard command updates the highlight for the next command.
+
+With the example keybindings below:
+
+| Keys | Result | Spoken equivalent |
+| ------------------- | -------------------------------------------- | ----------------- |
+| `d`, `a` | Target the default hat over `a` | `"air"` |
+| `g`, `a` | Target the green hat over `a` | `"green air"` |
+| `d`, `a`, `sf` | Expand the target to its containing function | `"funk air"` |
+| `d`, `a`, `sf`, `t` | Select the containing function | `"take funk air"` |
+| `sf`, `t` | Select the function containing the cursor | `"take funk"` |
+
+The keys used for actions, targets, and modifiers are context-sensitive. For example, after you press `d` for the default color, Cursorless waits for the character beneath the hat. Multi-key mappings such as `sf` are supported, but a pause does not complete a partial key sequence.
+
## Set up / config
### `keybindings.json`
-Paste the following into your [VSCode `keybindings.json`](https://code.visualstudio.com/docs/getstarted/keybindings#_advanced-customization):
+Paste the following into your [VS Code `keybindings.json`](https://code.visualstudio.com/docs/getstarted/keybindings#_advanced-customization):
```json
{
@@ -32,7 +48,24 @@ Paste the following into your [VSCode `keybindings.json`](https://code.visualstu
}
```
-Any keybindings that use modifier keys should go in `keybindings.json` as well, with a `"when": "cursorless.keyboard.modal.mode` clause.
+Any keybindings that use modifier keys should go in `keybindings.json` as well, with a `"when": "cursorless.keyboard.modal.mode"` clause.
+
+For example, these bindings use modifier keys to target a default or green hat. After pressing either shortcut, press the character beneath the hat:
+
+```json
+ {
+ "key": "ctrl+t",
+ "command": "cursorless.keyboard.targeted.targetHat",
+ "args": { "color": "default" },
+ "when": "cursorless.keyboard.modal.mode && editorTextFocus"
+ },
+ {
+ "key": "ctrl+shift+t",
+ "command": "cursorless.keyboard.targeted.targetHat",
+ "args": { "color": "green" },
+ "when": "cursorless.keyboard.modal.mode && editorTextFocus"
+ }
+```
The above allows you to press `ctrl-c` to switch to Cursorless mode and `escape` to exit Cursorless mode.
@@ -40,7 +73,7 @@ If you're already in Cursorless mode, pressing `ctrl-c` again will target the cu
### `settings.json`
-To bind keys that do not have modifiers (eg just pressing `a`), add entries like the following to your [VSCode `settings.json`](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) (or edit these settings in the VSCode settings gui by saying `"cursorless settings"`):
+To bind keys that do not have modifiers (eg just pressing `a`), add entries like the following to your [VS Code `settings.json`](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) (or edit these settings in the VS Code settings gui by saying `"cursorless settings"`):
```json
"cursorless.experimental.keyboard.modal.keybindings.scope": {
@@ -86,7 +119,7 @@ To bind keys that do not have modifiers (eg just pressing `a`), add entries like
"cursorless.experimental.keyboard.modal.keybindings.color": {
"d": "default",
"b": "blue",
- "g": "yellow",
+ "g": "green",
"r": "red"
},
"cursorless.experimental.keyboard.modal.keybindings.shape": {
@@ -123,4 +156,4 @@ Any supported scopes, actions, or colors can be added to these sections, using t
The above allows you to press `d` followed by any letter to highlight the given token, `i` to expand to its containing line, and `t` to select the given target.
-Note that key sequences are supported, eg mapping the sequence `af` to the fold action.
+Key sequences are supported, for example mapping `af` to the fold action. One mapping cannot be a prefix of another; Cursorless reports those mappings as conflicting.
diff --git a/packages/app-web-docs/src/docs/user/how-to.md b/packages/app-web-docs/src/docs/user/how-to.md
index 163ffeb83ad..3ae59254cd2 100644
--- a/packages/app-web-docs/src/docs/user/how-to.md
+++ b/packages/app-web-docs/src/docs/user/how-to.md
@@ -14,9 +14,9 @@ To replace a target with the contents of the clipboard, say `"paste to "
:::
-## How do I run a VSCode task / bash shell command on a target?
+## How do I run a VS Code task / bash shell command on a target?
-1. Add a [VSCode task](https://code.visualstudio.com/docs/editor/variables-reference) to your `tasks.json` (say `"please open tasks"`):
+1. Add a [VS Code task](https://code.visualstudio.com/docs/editor/variables-reference) to your `tasks.json` (say `"please open tasks"`):
```json
{
@@ -43,7 +43,7 @@ You can now say eg `"echo air past bat"`.
:::info
-See the [Talon-side api docs](./customization.md#cursorless-public-api) for more on creating custom Cursorless commands
+See the [Talon-side api docs](./public-talon-api.md) for more on creating custom Cursorless commands
:::
@@ -78,7 +78,7 @@ Now, for example if you have a target `aardvark` with a hat over the `a`, you ca
:::info
-See the [Talon-side api docs](./customization.md#cursorless-public-api) for more on creating custom Cursorless commands
+See the [Talon-side api docs](./public-talon-api.md) for more on creating custom Cursorless commands
:::
diff --git a/packages/app-web-docs/src/docs/user/installation.md b/packages/app-web-docs/src/docs/user/installation.md
index f64d064bb96..7e8da1d81d7 100644
--- a/packages/app-web-docs/src/docs/user/installation.md
+++ b/packages/app-web-docs/src/docs/user/installation.md
@@ -3,10 +3,10 @@
1. Install [Talon](https://talonvoice.com/)
- Make sure a speech engine is installed (click the Talon tray icon, then select one from the `Speech Recognition` menu)
2. Install the [community Talon commands](https://github.com/talonhub/community).
- _(Or see [here](https://github.com/cursorless-dev/cursorless/wiki/Talon-home-requirements) if you prefer not to use community.)_
-3. Install [VSCode](https://code.visualstudio.com/)
-4. Install the [VSCode talon extension pack](https://marketplace.visualstudio.com/items?itemName=pokey.talon)
-5. Install the [Cursorless VSCode extension](https://marketplace.visualstudio.com/items?itemName=pokey.cursorless)
+ _(Or see [here](./talon-dependencies.md) if you prefer not to use community.)_
+3. Install [VS Code](https://code.visualstudio.com/)
+4. Install the [VS Code talon extension pack](https://marketplace.visualstudio.com/items?itemName=pokey.talon)
+5. Install the [Cursorless VS Code extension](https://marketplace.visualstudio.com/items?itemName=pokey.cursorless)
6. Follow the instructions below to install the Talon side of Cursorless.
7. Restart Talon.
diff --git a/packages/app-web-docs/src/docs/user/learning-resources.md b/packages/app-web-docs/src/docs/user/learning-resources.md
index 91a21e67ec8..547d9392eed 100644
--- a/packages/app-web-docs/src/docs/user/learning-resources.md
+++ b/packages/app-web-docs/src/docs/user/learning-resources.md
@@ -18,6 +18,7 @@ These resources can help you learn Cursorless, from your first commands through
- [Cursorless cheatsheet](https://www.cursorless.org/cheatsheet) - Look up actions, scopes, modifiers, and other spoken forms.
- [Scope visualizer](./scope-visualizer.md) - Explore which Cursorless scopes are available in your code.
+- [Cursorless katas](https://github.com/Will-Sommers/cursorless-katas) - Exercises and challenges.
## Talon and community resources
diff --git a/packages/app-web-docs/src/docs/user/local-command-history.md b/packages/app-web-docs/src/docs/user/local-command-history.md
index cea882d5856..f892d584591 100644
--- a/packages/app-web-docs/src/docs/user/local-command-history.md
+++ b/packages/app-web-docs/src/docs/user/local-command-history.md
@@ -4,7 +4,7 @@ By default, Cursorless doesn't capture anything about your usage. However, we do
The idea is that these statistics can be used in the future for doing local analyses to determine ways you can improve your Cursorless efficiency. We may also support a way for you to send your statistics to us for analysis in the future, but this will be opt-in only.
-To enable local, sanitized command logging, enable the [`cursorless.commandHistory`](vscode://settings/cursorless.commandHistory) VSCode setting. You should see a checkbox in the settings UI when you say `"cursorless settings"`. You can also set it manually in your `settings.json`:
+To enable local, sanitized command logging, enable the [`cursorless.commandHistory`](vscode://settings/cursorless.commandHistory) VS Code setting. You should see a checkbox in the settings UI when you say `"cursorless settings"`. You can also set it manually in your `settings.json`:
```json
"cursorless.commandHistory": true
diff --git a/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx b/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx
index faa8b47f9dc..29b0fe23a44 100644
--- a/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx
+++ b/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx
@@ -19,6 +19,7 @@ Default: `bounds`
## Examples
- `"take bounds round blue air"` - Selects only the parentheses containing the token containing letter `a` with a blue hat.
+- `"chuck bounds blue air"` - Removes the boundaries containing the token containing letter `a` with a blue hat.
## Visualization
@@ -30,4 +31,8 @@ Default: `bounds`
+### `"chuck bounds air"`
+
+
+
diff --git a/packages/app-web-docs/src/docs/user/public-talon-api.md b/packages/app-web-docs/src/docs/user/public-talon-api.md
new file mode 100644
index 00000000000..c9e75a09aa6
--- /dev/null
+++ b/packages/app-web-docs/src/docs/user/public-talon-api.md
@@ -0,0 +1,70 @@
+# Public Talon API
+
+Cursorless exposes Talon actions and captures that you can use to define custom command grammars with Cursorless targets.
+
+## Public Talon captures
+
+- ``
+ Represents a Cursorless target, such as `"air"`, `"this"`, `"air past bat"`, `"air and bat"`, `"funk air past token bat and class cap"`, etc
+
+- ``
+ Represents a Cursorless destination, such as `"to air"`, `"before this"`, `"after air and bat"`, etc
+
+## Public Talon actions
+
+- `user.cursorless_command(action_id: str, target: cursorless_target)`:
+ Perform a Cursorless command on the given target
+ eg: `user.cursorless_command("setSelection", cursorless_target)`.
+ Note that for `"bring"` (`replaceWithTarget`), `cursorless_target` will be the source of the bring and the destination will be the current selection(s), as if you had said `"bring "`
+- `user.cursorless_ide_command(command_id: str, target: cursorless_target)`:
+ Performs a built-in IDE command on the given target
+ eg: `user.cursorless_ide_command("editor.action.addCommentLine", cursorless_target)`
+- `user.cursorless_get_text(target: CursorlessTarget, hide_decorations: bool = False) -> str`
+ Get text from target. If `hide_decorations` is `true`, will not show decorations.
+- `user.cursorless_get_text_list(target: CursorlessTarget, hide_decorations: bool = False) -> list[str]`
+ Get texts from multiple targets. If `hide_decorations` is `true`, will not show decorations.
+- `user.cursorless_insert(destination: CursorlessDestination, text: Union[str, List[str]])`:
+ Insert text at destination.
+ eg: `user.cursorless_insert(cursorless_destination, "hello")`
+- `user.cursorless_create_destination(target: CursorlessTarget, insertion_mode: Literal["to", "before", "after"] = "to") -> CursorlessDestination`:
+ Create a destination from a target. The insertion mode can be `to`, `before`, or `after`, and defaults to `to`, which will replace the target. See [How do I run a custom Python transformation on a target?](./how-to.md#how-do-i-run-a-custom-python-transformation-on-a-target) for example usage.
+- `user.cursorless_reformat(target: CursorlessTarget, formatters: str)`
+ Reformat target with specified formatters.
+ eg: `user.cursorless_reformat(cursorless_target, "ALL_CAPS")`
+
+### Snippet actions
+
+- `user.cursorless_insert_snippet(body: str, destination: Optional[CursorlessDestination], scope_type: Optional[Union[str, list[str]]])`: Insert a snippet with the given body. The body should be a single string, which could contain newline `\n` characters, rather than a list of strings as is expected in our snippet json representation. Destination is where the snippet will be inserted. If omitted will default to current selection. An optional scope type can be provided for the target to expand to. `"snip if after air"` for example could be desired to go after the statement containing `air` instead of the token.
+- `user.cursorless_wrap_with_snippet(body, target, variable_name, scope)`: Wrap the given target with a snippet with the given body. The body should be a single string, which could contain newline `\n` characters, rather than a list of strings as is expected in our snippet json representation. Note that `variable_name` should be one of the variables defined in `body`. Eg, if `body` has a variable `$foo`, you can pass in `"foo"` for `variable_name`, and `target` will be inserted into the position of `$foo` in the given named snippet. The `scope` variable can be used to automatically expand the target to the given scope type, eg `"line"`.
+
+## Example of combining capture and action
+
+```talon
+add dock string :
+ user.cursorless_command("editNewLineAfter", cursorless_target)
+ "\"\"\"\"\"\""
+ key(left:3)
+
+push down:
+ user.cursorless_ide_command("editor.action.moveLinesDownAction", cursorless_target)
+```
+
+## Example of custom formatter command
+
+The command below will allow you to say `camel form blue air`.
+_You can disable the default Cursorless reformat command by prefixing the spoken form in `actions.csv` with a dash. `-format, applyFormatter`_
+
+```talon
+ form :
+ user.cursorless_reformat(cursorless_target, formatters)
+```
+
+## Example of custom search engine command
+
+The command below will allow you to say `"google scout "`. It supports all search engines defined in your [`search_engine.talon-list`](https://github.com/talonhub/community/blob/cc8f13d5cb3be2501d35150b8bf2d1cdf60eaab6/core/websites_and_search_engines/search_engine.talon-list) in Talon Community repository.
+
+```talon
+{user.search_engine} scout :
+ text = user.cursorless_get_text(cursorless_target)
+ user.search_with_search_engine(search_engine, text)
+```
diff --git a/packages/app-web-docs/src/docs/user/recommendations.md b/packages/app-web-docs/src/docs/user/recommendations.md
new file mode 100644
index 00000000000..f9ccaeb4f55
--- /dev/null
+++ b/packages/app-web-docs/src/docs/user/recommendations.md
@@ -0,0 +1,8 @@
+# Recommendations
+
+These optional recommendations can improve your Cursorless workflow but are not required by Cursorless.
+
+## VS Code
+
+- To show search results in an editor instead of the sidebar, set `"search.mode"` to `"reuseEditor"`.
+- To inspect VS Code's default keyboard shortcuts and their command identifiers, run **Preferences: Open Default Keyboard Shortcuts (JSON)** (`"please default keyboard"`).
diff --git a/packages/app-web-docs/src/docs/user/release-notes/0.28.0.md b/packages/app-web-docs/src/docs/user/release-notes/0.28.0.md
index 68298146047..5b440248e18 100644
--- a/packages/app-web-docs/src/docs/user/release-notes/0.28.0.md
+++ b/packages/app-web-docs/src/docs/user/release-notes/0.28.0.md
@@ -32,8 +32,8 @@ But here are some highlights:
- [Stable hats](../hat-assignment.md) ([#1252](https://github.com/cursorless-dev/cursorless/pull/1252)) keep hats from moving around so much while you edit. This change is something you may or may not have consciously noticed, but if you spontaneously experienced a deep feeling of oneness and calm at some point in the past six months, the newly meditative hats might have been the cause 🎩🧘
- Improved support for very large hats. A trend among users has been to slightly increase their line height (eg 1.6) and then use a very large hat size (eg 70) to make the hats more visible. This works great, but adjacent hats would overlap. Now, we automatically detect clashing hats and stop them from growing horizontally if they'd overlap ([#1687](https://github.com/cursorless-dev/cursorless/pull/1687)). @pokey is now running with a line height of 1.6 and a hat size of 70, after getting serious hat-size envy during some user screenshares on discord 👒. If you want to join the big hat revolution, say `"show settings say line height"` to mess with your line height, then `"cursorless settings"` to mess with your hat size
- Lots of improvements to our Go language support (thanks [@josharian](https://github.com/josharian)!)
-- Expanded our [Talon-side custom API](../customization.md#public-talon-actions) to
- - allow [snippet wrapping / insertion](../customization.md#snippet-actions) ([#1329](https://github.com/cursorless-dev/cursorless/pull/1329)), used eg for [Cursorless mathfly 🎬](https://youtu.be/v0j2_W97_s0), and
+- Expanded our [Talon-side custom API](../public-talon-api.md#public-talon-actions) to
+ - allow [snippet wrapping / insertion](../public-talon-api.md#snippet-actions) ([#1329](https://github.com/cursorless-dev/cursorless/pull/1329)), used eg for [Cursorless mathfly 🎬](https://youtu.be/v0j2_W97_s0), and
- include actions such as `"bring"` ([#1226](https://github.com/cursorless-dev/cursorless/pull/1226)).
- `"snippet funk"` now behaves differently if you're in a class vs at module level ([#1487](https://github.com/cursorless-dev/cursorless/pull/1487)). This feature is almost certainly not worth calling out in the release notes, but @pokey was really excited about it, so let's not spoil his fun. More broadly, this feature enables you to have different snippets inserted depending whether you're in a particular Cursorless scope.
@@ -53,13 +53,13 @@ In addition all the features we've shipped this year, we have made significant i
Here are some highlights:
-- Abstracted away all references to VSCode's apis, which will enable us to launch Cursorless in other IDEs, such as JetBrains, emacs, etc, as well as integrate with [Rango](https://github.com/david-tejada/rango/), and even work globally using OCR / accessibility APIs to place hats anywhere on the screen. Stay tuned
+- Abstracted away all references to VS Code's apis, which will enable us to launch Cursorless in other IDEs, such as JetBrains, emacs, etc, as well as integrate with [Rango](https://github.com/david-tejada/rango/), and even work globally using OCR / accessibility APIs to place hats anywhere on the screen. Stay tuned
- Added tests for our spoken forms ([#1637](https://github.com/cursorless-dev/cursorless/pull/1637)), which means we now have full end-to-end coverage all the way from spoken form to action to editor state for 2,757 different commands (and counting!), so you can be sure if a command works today, it will work tomorrow
-- Switched to a pnpm monorepo ([#1281](https://github.com/cursorless-dev/cursorless/pull/1281)) to allow us to share code / source of truth between Cursorless VSCode, Cursorless for other IDEs, Cursorless on the web, Cursorless docs, etc. See [the video 🎬](https://youtu.be/Od7BZHc7w6c) to learn more. Who knows, you might even switch your project to a pnpm monorepo after watching
+- Switched to a pnpm monorepo ([#1281](https://github.com/cursorless-dev/cursorless/pull/1281)) to allow us to share code / source of truth between Cursorless VS Code, Cursorless for other IDEs, Cursorless on the web, Cursorless docs, etc. See [the video 🎬](https://youtu.be/Od7BZHc7w6c) to learn more. Who knows, you might even switch your project to a pnpm monorepo after watching
- Switch to [pure DI](https://blog.ploeh.dk/2014/06/10/pure-di/) to make it easier to test and reason about our code, and to make it easier to support other IDEs
- Built a new way to represent our language-specific (tree-sitter) scopes that makes them vastly more powerful, enabling features like the scope visualizer, next-gen grammar, etc ([#629](https://github.com/cursorless-dev/cursorless/pull/629))
- Crystallized our notion of "destinations", a concept that unifes "bring air **to bat**", "paste **after funk drum**", "snip funk **before this**", "**pour line**", and "**drink item**" ([#1605](https://github.com/cursorless-dev/cursorless/pull/1605)). This change will enable functionality like `"bring type air to bat"` when `bat` doesn't yet have a type ([#1631](https://github.com/cursorless-dev/cursorless/issues/1631)), and many other improvements. We'll be updating the docs to reflect this new understanding shortly.
-- Built a utility that can automatically generate the spoken form that was used to issue a command ([#1671](https://github.com/cursorless-dev/cursorless/pull/1671)). This function will enable us to automatically customize the docs using your personal spoken forms, as well as allow you to see what spoken form you would use to issue a command from one of [@pokey's videos 🎬](https://www.youtube.com/@PokeyRuleJams), and allow us to create interactive tutorials running in VSCode that will use your custom spoken forms.
+- Built a utility that can automatically generate the spoken form that was used to issue a command ([#1671](https://github.com/cursorless-dev/cursorless/pull/1671)). This function will enable us to automatically customize the docs using your personal spoken forms, as well as allow you to see what spoken form you would use to issue a command from one of [@pokey's videos 🎬](https://www.youtube.com/@PokeyRuleJams), and allow us to create interactive tutorials running in VS Code that will use your custom spoken forms.
## 📈 What's next?
@@ -67,7 +67,7 @@ Here are some highlights:
Tough to pick favorites, but here are three highlights from our [short-term roadmap](https://github.com/cursorless-dev/cursorless/milestone/10):
-- A VSCode sidebar that shows you which scopes are present in your current file, updated in real-time. Combined with the [scope visualizer](../scope-visualizer.md), we hope this will be an antidote to the Cursorless cheatsheet's "what on Earth are all these scopes and are any of them relevant to me?" problem. Here's a sneak preview (🤫):  In case you don't recognize some of those scope types, that's because it will show your [custom spoken forms](../customization.md), and mine are probably different from yours!
+- A VS Code sidebar that shows you which scopes are present in your current file, updated in real-time. Combined with the [scope visualizer](../scope-visualizer.md), we hope this will be an antidote to the Cursorless cheatsheet's "what on Earth are all these scopes and are any of them relevant to me?" problem. Here's a sneak preview (🤫):  In case you don't recognize some of those scope types, that's because it will show your [custom spoken forms](../customization.md), and mine are probably different from yours!
- Migrate all scopes for every language to next-gen scopes, enabling next-gen inference (eg `"every funk air past bat"`), scope visualizer, tree view, etc. This is an area where we would love contributions from our more adventurous users. We've built some powerful tooling here so the DX is 🔥; you're going to have a blast if you're into hot-reloading, beautifully rendered syntax trees. Come find us on Slack and Discord if you're interested
- A major docs restructure to make it easier to find what you're looking for and understand how it all fits together. The new docs will include many more examples, including examples automatically generated from our test cases, which includes basically everything you can possibly do with Cursorless (did we mention we have >2.5k full end-to-end tests? Not like we're bragging or anything 🙄 💅)
@@ -75,8 +75,8 @@ Tough to pick favorites, but here are three highlights from our [short-term road
Here are a few highlights from our [medium-term roadmap](https://github.com/cursorless-dev/cursorless/milestone/8):
-- Cursorless on vscode.dev / other VSCode web clients ([#1023](https://github.com/cursorless-dev/cursorless/issues/1023))
-- Interactive tutorials running in VSCode ([#934](https://github.com/cursorless-dev/cursorless/issues/934))
+- Cursorless on vscode.dev / other VS Code web clients ([#1023](https://github.com/cursorless-dev/cursorless/issues/1023))
+- Interactive tutorials running in VS Code ([#934](https://github.com/cursorless-dev/cursorless/issues/934))
- Cursorless for other IDEs, such as JetBrains, emacs, etc
- A vastly expanded Talon-side API to enable much more powerful custom grammars ([#494](https://github.com/cursorless-dev/cursorless/issues/494))
- Bookmarking targets to allow more complex commands, even across multiple files ([#46](https://github.com/cursorless-dev/cursorless/issues/46))
diff --git a/packages/app-web-docs/src/docs/user/release-notes/0.29.0.md b/packages/app-web-docs/src/docs/user/release-notes/0.29.0.md
index aafaf1adfba..bb524205e3c 100644
--- a/packages/app-web-docs/src/docs/user/release-notes/0.29.0.md
+++ b/packages/app-web-docs/src/docs/user/release-notes/0.29.0.md
@@ -36,7 +36,7 @@ Yep, they're here. I'll let myself speak for myself here ([video 🎬](https://y
### Cursorless everywhere
-We're taking those first wobbly, beautiful steps out of VSCode 🐣🥲. We have now shipped very early, experimental support for [Cursorless in Neovim](https://github.com/hands-free-vim/cursorless.nvim). It's still missing hats and a parse tree, but the engine is there. We've landed; now we'll expand. Big shout-out to the dream team, [@saidelike](https://github.com/saidelike) and [@fidgetingbits](https://github.com/fidgetingbits), for the long hours and shower of tears as this came together. This one shipped with continuous delivery, because we're psycho about CD, so any improvements to Cursorless will automatically make their way into Neovim using the confusingly-named Lazy package manager 🤔
+We're taking those first wobbly, beautiful steps out of VS Code 🐣🥲. We have now shipped very early, experimental support for [Cursorless in Neovim](https://github.com/hands-free-vim/cursorless.nvim). It's still missing hats and a parse tree, but the engine is there. We've landed; now we'll expand. Big shout-out to the dream team, [@saidelike](https://github.com/saidelike) and [@fidgetingbits](https://github.com/fidgetingbits), for the long hours and shower of tears as this came together. This one shipped with continuous delivery, because we're psycho about CD, so any improvements to Cursorless will automatically make their way into Neovim using the confusingly-named Lazy package manager 🤔
We also have an internal experiment with a version of Cursorless that runs literally anywhere, using accessibility APIs. This one is so experimental that I'll probably get in trouble for even mentioning it. So definitely don't heckle @AndreasArvidsson and @phillco to tell you how to play with this completely not-ready-for-primetime early experiment.
@@ -50,7 +50,7 @@ ICYMI Cursorless went to Strange Loop. The talk was so wild that they had to clo
### Improved Talon-side API
-We beefed up our Talon-side API to allow you to build your own grammars on top of Cursorless. See the [talon-side api docs](https://www.cursorless.org/docs/user/customization#public-talon-actions) for more.
+We beefed up our Talon-side API to allow you to build your own grammars on top of Cursorless. See the [Talon-side API docs](../public-talon-api.md#public-talon-actions) for more.
We also have an undocumented, secret action that has a built-in parser for building arbitrarily powerful custom commands on the fly. You should also definitely not heckle @AndreasArvidsson and @phillco to tell you how to use this one either.
@@ -60,7 +60,7 @@ The keyboard interface continues to grow and is getting close to feature-parity
### Falling back
-You know when you're in a text box or the VSCode integrated terminal and you're like "Man, I wish I could bring that line right to my cursor"? Do it. Go on. `"bring line air"`. You can also use some hatless Cursorless commands on your cursor in that text box (`"quad wrap token"`, `"chuck line"`, etc etc etc nbd 🙄)
+You know when you're in a text box or the VS Code integrated terminal and you're like "Man, I wish I could bring that line right to my cursor"? Do it. Go on. `"bring line air"`. You can also use some hatless Cursorless commands on your cursor in that text box (`"quad wrap token"`, `"chuck line"`, etc etc etc nbd 🙄)
### Cursorless sidebar
@@ -78,7 +78,7 @@ Have a look at our [1.0 milestone](https://github.com/cursorless-dev/cursorless/
After that, see our [medium-](https://github.com/cursorless-dev/cursorless/milestone/10) and [long-term roadmaps](https://github.com/cursorless-dev/cursorless/milestone/8), including:
-- Cursorless on vscode.dev / other VSCode web clients ([#1023](https://github.com/cursorless-dev/cursorless/issues/1023)). We're a lot closer to this one now, having already completely abstracted all node references from our core engine.
+- Cursorless on vscode.dev / other VS Code web clients ([#1023](https://github.com/cursorless-dev/cursorless/issues/1023)). We're a lot closer to this one now, having already completely abstracted all node references from our core engine.
- Cursorless for more IDEs, such as JetBrains, emacs, etc
- Cursorless everywhere using accessibility comes out of secret mode
- Vastly expanded Talon-side API comes out of secret mode ([#494](https://github.com/cursorless-dev/cursorless/issues/494))
diff --git a/packages/app-web-docs/src/docs/user/release-notes/1.0.0.md b/packages/app-web-docs/src/docs/user/release-notes/1.0.0.md
index 9fff968cb22..82b92cc89d6 100644
--- a/packages/app-web-docs/src/docs/user/release-notes/1.0.0.md
+++ b/packages/app-web-docs/src/docs/user/release-notes/1.0.0.md
@@ -28,7 +28,7 @@ Here are some highlights:
### Next-gen scope definitions
-- Migrated all text-based scopes and most language-specific ones from our legacy definitions to next-gen scope definitions, enabling next-gen inference (eg `"every funk air past bat"`), scope visualization, scope tree view, etc. We're just down to a few pesky scopes in Clojure, CSS, LaTeX, Ruby, Rust, and Scala. If you use one of these languages, we're looking for volunteers to [knock out the last few scopes](https://www.cursorless.org/docs/contributing/adding-a-new-scope/)!
+- Migrated all text-based scopes and most language-specific ones from our legacy definitions to next-gen scope definitions, enabling next-gen inference (eg `"every funk air past bat"`), scope visualization, scope tree view, etc. We're just down to a few pesky scopes in Clojure, CSS, LaTeX, Ruby, Rust, and Scala. If you use one of these languages, we're looking for volunteers to [knock out the last few scopes](../../contributing/adding-a-new-scope.md)!
### Community integration
diff --git a/packages/app-web-docs/src/docs/user/release-notes/1.1.0.md b/packages/app-web-docs/src/docs/user/release-notes/1.1.0.md
index 9960c7f1d76..044cd89e482 100644
--- a/packages/app-web-docs/src/docs/user/release-notes/1.1.0.md
+++ b/packages/app-web-docs/src/docs/user/release-notes/1.1.0.md
@@ -47,7 +47,7 @@ Every language Cursorless supports now uses our next-gen scope engine, enabling
The docs got some serious love this cycle:
-- **Language-specific scope visualizations in docs**: The [language pages](https://www.cursorless.org/docs/user/languages) now show visualizations of what each scope looks like in each language, making it easier to understand exactly what each scope targets ([#3016](https://github.com/cursorless-dev/cursorless/pull/3016))
+- **Language-specific scope visualizations in docs**: The [language pages](../languages/README.md) now show visualizations of what each scope looks like in each language, making it easier to understand exactly what each scope targets ([#3016](https://github.com/cursorless-dev/cursorless/pull/3016))
- **Missing scopes contributor page**: A new page helps contributors identify which scopes are missing for each language ([#2978](https://github.com/cursorless-dev/cursorless/pull/2978))
- **Containment icons in scope visualizer**: The scope visualizer now shows containment relationships with icons ([#3085](https://github.com/cursorless-dev/cursorless/pull/3085))

diff --git a/packages/app-web-docs/src/docs/user/release-notes/2022-year-in-review.md b/packages/app-web-docs/src/docs/user/release-notes/2022-year-in-review.md
index 7cfd03dfaf5..6cbdd698244 100644
--- a/packages/app-web-docs/src/docs/user/release-notes/2022-year-in-review.md
+++ b/packages/app-web-docs/src/docs/user/release-notes/2022-year-in-review.md
@@ -32,7 +32,7 @@ In the near term, we're planning to work on the following:
- [Interactive tutorials that run within your editor](https://github.com/cursorless-dev/cursorless/issues/934)
- [Bookmarking targets to allow more complex commands, even across multiple files](https://github.com/cursorless-dev/cursorless/issues/46)
- [A way to highlight newly released features](https://github.com/cursorless-dev/cursorless/issues/491)
-- [A phrase-level undo command in VSCode](https://github.com/cursorless-dev/cursorless/issues/317)
+- [A phrase-level undo command in VS Code](https://github.com/cursorless-dev/cursorless/issues/317)
- [Better support for custom user grammars built on top of the Cursorless engine](https://github.com/cursorless-dev/cursorless/issues/494)
- Changes that will enable more fluent chaining, such as [modifying the target of a bring in a single phrase](https://github.com/cursorless-dev/cursorless/issues/414)
- [Videos](https://github.com/cursorless-dev/cursorless/discussions/506)!
diff --git a/packages/app-web-docs/src/docs/user/scope-sidebar.md b/packages/app-web-docs/src/docs/user/scope-sidebar.md
index bc9bfd963b5..4eb465f8fb5 100644
--- a/packages/app-web-docs/src/docs/user/scope-sidebar.md
+++ b/packages/app-web-docs/src/docs/user/scope-sidebar.md
@@ -31,7 +31,7 @@ Each step shows a command to say and usually advances automatically when you com
### Start a tutorial
-With VSCode focused, say `"cursorless tutorial"` to start or continue the Introduction tutorial.
+With VS Code focused, say `"cursorless tutorial"` to start or continue the Introduction tutorial.
To choose a tutorial, say `"tutorial list"`, then click its name or say `"tutorial "`. For example, say `"tutorial two"` to start or continue Basic coding.
diff --git a/packages/app-web-docs/src/docs/user/talon-dependencies.md b/packages/app-web-docs/src/docs/user/talon-dependencies.md
new file mode 100644
index 00000000000..85e7416a483
--- /dev/null
+++ b/packages/app-web-docs/src/docs/user/talon-dependencies.md
@@ -0,0 +1,34 @@
+# Talon dependencies
+
+Cursorless uses several definitions from [Talon Community](https://github.com/talonhub/community). If your Talon setup includes Talon Community and you have not removed any of the dependencies listed below, you can safely ignore this page.
+
+If you use Cursorless without Talon Community—or maintain a custom fork—you must provide these definitions somewhere in your Talon user directory.
+
+## Core dependencies
+
+Cursorless will not work without the following:
+
+- [VS Code command client](https://github.com/pokey/talon-vscode-command-client), which Talon Community includes in [`apps/vscode/vscode_command_client.py`](https://github.com/talonhub/community/blob/main/apps/vscode/vscode_command_client.py)
+- [`user.any_alphanumeric_key` capture](https://github.com/talonhub/community/blob/607c3415f5f29a5f75db6fe5648e37f514f62ac5/core/keys/keys.py#L71-L74)
+- [`vscode` app definition](https://github.com/talonhub/community/blob/d57d65ae65a4b2d542ccfe44bc369569d46479c5/apps/vscode/vscode.py#L8)
+
+## Feature dependencies
+
+The following definitions are required only for the corresponding commands or modifiers.
+
+### Homophones: `"phones"`
+
+- [`user.homophones_get(word: str) -> list[str]` action](https://github.com/talonhub/community/blob/c80cf0f9495b0b8b4594764e827e1355101ca2ba/code/homophones.py#L198-L203)
+
+### Formatting: `"format camel"`
+
+- [`user.formatters` capture](https://github.com/talonhub/community/blob/c80cf0f9495b0b8b4594764e827e1355101ca2ba/code/formatters.py#L177-L180)
+- [`user.reformat_text(text: str, formatters: str) -> str` action](https://github.com/talonhub/community/blob/c80cf0f9495b0b8b4594764e827e1355101ca2ba/code/formatters.py#L272-L275)
+
+### Counted scopes: `"two tokens"`
+
+- [`number_small` capture](https://github.com/talonhub/community/blob/7e90a2ee91bc6e9e54b76bd5b4d4b9274372bdc3/core/numbers/numbers.py#L292-L294)
+
+### Ordinal scopes: `"first token"`
+
+- [`user.ordinals_small` capture](https://github.com/talonhub/community/blob/7e90a2ee91bc6e9e54b76bd5b4d4b9274372bdc3/core/numbers/ordinals.py#L69-L72)
diff --git a/packages/app-web-docs/src/docs/user/targets.md b/packages/app-web-docs/src/docs/user/targets.md
index 07e53a6a6b1..b9ce2dfcda2 100644
--- a/packages/app-web-docs/src/docs/user/targets.md
+++ b/packages/app-web-docs/src/docs/user/targets.md
@@ -12,7 +12,7 @@ There are several types of marks:
#### Decorated symbol
-This is the first type of mark you'll notice when you start using cursorless. You'll see that for every token on the screen, one of its characters will have a hat on top of it. We can refer to the given token by saying the name of the character that has a hat, along with the color if the hat is not gray, and the shape of the hat if the hat is not the default dot:
+This is the first type of mark you'll notice when you start using Cursorless. You'll see that for every token on the screen, one of its characters will have a hat on top of it. We can refer to the given token by saying the name of the character that has a hat, along with the color if the hat is not gray, and the shape of the hat if the hat is not the default dot:
- `"air"` (if the color is gray)
- `"blue bat"`
@@ -44,9 +44,9 @@ The following colors are supported. Note that to target the default (gray) hat y
| `"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.
+You can enable or disable colors in your VS Code 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 VS Code settings, either say "show settings", or go to File --> Preferences --> Settings.
-You can also tweak the visible colors for any of these colors in your VSCode settings, by searching for [`cursorless.colors`](vscode://settings/cursorless.colors) and changing the hex color code next to the internal ID for the given shape as listed above. Note that you can configure different colors for dark and light themes. See our [visual accessibility guide](./visual-accessibility.md) for more on visual accessibility.
+You can also tweak the visible colors for any of these colors in your VS Code settings, by searching for [`cursorless.colors`](vscode://settings/cursorless.colors) and changing the hex color code next to the internal ID for the given shape as listed above. Note that you can configure different colors for dark and light themes. See our [visual accessibility guide](./visual-accessibility.md) for more on visual accessibility.
If you find these color names unintuitive / tough to remember, their
spoken forms can be [customized](./customization.md) like any other spoken form
@@ -73,13 +73,13 @@ The following shapes are supported. Note that to target the default (dot) shape
| `"cross"` |  | `crosshairs` | ❌ |
| `"eye"` |  | `eye` | ❌ |
-You can enable or disable shapes in your VSCode settings, by searching for [`cursorless.hatEnablement.shapes`](vscode://settings/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.
+You can enable or disable shapes in your VS Code settings, by searching for [`cursorless.hatEnablement.shapes`](vscode://settings/cursorless.hatEnablement.shapes) and checking the box next to the internal ID for the given shape as listed above. To navigate to your VS Code settings, either say "show settings", or go to File --> Preferences --> Settings.
If you find these shape names unintuitive / tough to remember, their
spoken forms can be [customized](./customization.md) like any other spoken form
-in cursorless. If you change a spoken form to be more than one syllable, you
+in Cursorless. If you change a spoken form to be more than one syllable, you
can change the penalty in the [`cursorless.hatPenalties.shapes`](vscode://settings/cursorless.hatPenalties.shapes) setting to the
-number of syllables you use, so that cursorless can optimize hat allocation to
+number of syllables you use, so that Cursorless can optimize hat allocation to
minimize syllables.
#### `"this"`
@@ -95,7 +95,7 @@ Note that if you say `"this"` with an empty selection, it refers to the token co
#### `"that"`
-The word `"that"` can be used as a mark to refer to the target of the previous cursorless command.
+The word `"that"` can be used as a mark to refer to the target of the previous Cursorless command.
- `"pre that"`
- `"round wrap that"`
@@ -110,7 +110,7 @@ The word `"row"` followed by a number can be used to refer to a line by its line
#### `"up "` / `"down "`
-The word `"up"` or `"down"` followed by a number can be used to refer to the line that is `` lines above or below the cursor. The line may be outside of the viewport. In the case of multiple selections, this mark only refers to the line relative to the primary selection. You can turn on relative line numbers in the VSCode settings to make these marks easier to use.
+The word `"up"` or `"down"` followed by a number can be used to refer to the line that is `` lines above or below the cursor. The line may be outside of the viewport. In the case of multiple selections, this mark only refers to the line relative to the primary selection. You can turn on relative line numbers in the VS Code settings to make these marks easier to use.
- `"copy up one"`
- `"comment down two"`
@@ -165,7 +165,7 @@ These `"every"` ranges also play nicely with exclusive ranges, eg `"take every f
### List targets
-In addition to range targets, cursorless supports list targets, which allow you to refer to multiple targets at the same time. When combined with the `"take"` action, this will result in multiple cursors, for other actions, such as `"chuck"` the action will be applied to all the different targets at once.
+In addition to range targets, Cursorless supports list targets, which allow you to refer to multiple targets at the same time. When combined with the `"take"` action, this will result in multiple cursors, for other actions, such as `"chuck"` the action will be applied to all the different targets at once.
- `"take [blue] air and [green] bat"`
- `"take funk [blue] air and [green] bat"` (note second target inherits `"funk"`)
diff --git a/packages/app-web-docs/src/docs/user/troubleshooting.md b/packages/app-web-docs/src/docs/user/troubleshooting.md
new file mode 100644
index 00000000000..200aa37b661
--- /dev/null
+++ b/packages/app-web-docs/src/docs/user/troubleshooting.md
@@ -0,0 +1,39 @@
+# Troubleshooting
+
+Here is a list of common issues you might encounter, along with possible solutions:
+
+## Typing a letter after a command without a mark
+
+Due to the way that Cursorless allows you to omit marks (eg `"take funk"` instead of `"take funk this"`), the grammar can be slightly ambiguous to parse. The most common example will be if you omit the mark (eg `"change funk"`), and then try to type a letter (`"air"`). In that case, when you say `"change funk air"`, Talon will parse it as a single command to change the function with a gray hat over an `a`, which is usually what you mean. However, if you did want to change the function containing the cursor, and then type `"a"`, then the parse will be incorrect. To work around this limitation, there are a few options:
+
+- **Option 1**: pause after `"change funk"` so that it is broken into two separate command phrases `"change funk"`, then `"air"`
+- **Option 2**: say `"change funk this air"` instead, so that you make the mark explicit
+- **Option 3**: add the command `then: skip()` to a Talon file, which makes a command called `"then"` that does nothing, but can be used to break up the command phrase. Then you can say `"change funk then air"`
+
+## `"red"`
+
+A similar ambiguity can arise if you use the default color name for `red` and the default letter name for `r` defined in community, both of which are `"red"`. In this case, if you say `"change red air"`, it could be interpreted as either of the following:
+
+- `"change red"` (referring to token with a gray hat over `r`), followed by `"air"` (to type the letter `a`), or
+- `"change red air"` (referring to the red hat over an `a`).
+
+Most of the time you’ll mean the latter, and that is how Talon will interpret the command. But occasionally you’ll want the former. As above, you have a few options:
+
+- **Option 1**: pause after `"change red"` so that it is broken into two separate command phrases `"change red"`, then `"air"`
+- **Option 2**: change `r` to be eg `"risk"` or `"ram"` in your [Talon alphabet](https://github.com/talonhub/community/blob/f4cab180efc41bfd4be073079df716130967349e/core/keys/letter.talon-list#L23) to avoid the conflict
+- **Option 3**: map a `then: skip()` command as above. Then when you actually want the first behaviour, you’ll say `"change red then air"`
+
+## When a variable is grayed out, the red hat looks pink
+
+When you have an unused variable, VS Code will make it semi-transparent. Unfortunately, this transparency also applies to any Cursorless hats over the variable, so if you are using a light background, then any red hat on the variable will be blended with the light background and look pink. We have filed [an issue](https://github.com/microsoft/vscode/issues/138986) with VS Code to fix this one, but it might be a while.
+
+In the meantime, your best bet is probably to disable the pink hat and instead enable `userColor1`, which has a default voice command of `"navy"`. To do so, search for `cursorless.hatEnablement.colors` in your VS Code settings, and uncheck the box next to `pink` and check the one next to `userColor1`. Then when you pull up the cheatsheet you should see that `"pink"` has been replaced by `"navy"`, and a new navy hat color should show up in your editor instead of pink.
+
+## Decorations don't scale with editor zoom
+
+There are two relevant types of zoom actions in VS Code.
+
+- `workbench.action.zoomIn` scales all UI. Cursorless deals with this as expected.
+- `editor.action.fontZoomIn` scales only the editor font. _This will trigger the issue._ This action does not have a keybinding by default. `Ctrl` + mouse wheel also triggers it when the `editor.mouseWheelZoom` setting is enabled.
+
+To avoid the issue, use `workbench.action.zoomIn` to zoom the entire UI instead of changing only the editor font size.
diff --git a/packages/app-web-docs/src/docs/user/updating.md b/packages/app-web-docs/src/docs/user/updating.md
index 71aafdaca18..d478c3a809f 100644
--- a/packages/app-web-docs/src/docs/user/updating.md
+++ b/packages/app-web-docs/src/docs/user/updating.md
@@ -2,12 +2,12 @@
Cursorless consists of two components:
-- A VSCode extension, and
+- A VS Code extension, and
- A set of Talon files to define the spoken commands
-## Updating the VSCode extension
+## Updating the VS Code extension
-The VSCode extension will update automatically, unless for some reason you have auto-updating disabled, in which case you will have to [update the extension manually](https://code.visualstudio.com/docs/editor/extension-marketplace#_update-an-extension-manually).
+The VS Code extension will update automatically, unless for some reason you have auto-updating disabled, in which case you will have to [update the extension manually](https://code.visualstudio.com/docs/editor/extension-marketplace#_update-an-extension-manually).
## Updating the Talon side
diff --git a/packages/lib-common/src/references/modifierReferences.ts b/packages/lib-common/src/references/modifierReferences.ts
index 69cc4758023..72bd325fb0f 100644
--- a/packages/lib-common/src/references/modifierReferences.ts
+++ b/packages/lib-common/src/references/modifierReferences.ts
@@ -388,6 +388,10 @@ Relative modifiers select scopes before or after the input target. Without \`"ev
command: `${SET_SELECTION} ${VAR_SPOKEN_FORM} ${PARENTHESES} ${TARGET}`,
description: `Selects only the parentheses containing the ${TARGET_DESC}.`,
},
+ {
+ command: `${REMOVE} ${VAR_SPOKEN_FORM} ${TARGET}`,
+ description: `Removes the boundaries containing the ${TARGET_DESC}.`,
+ },
],
},
leading: {
diff --git a/packages/lib-vscode-tutorial-webview/README.md b/packages/lib-vscode-tutorial-webview/README.md
index 5be2e3d9a90..f24f909f2e0 100644
--- a/packages/lib-vscode-tutorial-webview/README.md
+++ b/packages/lib-vscode-tutorial-webview/README.md
@@ -1,7 +1,7 @@
-# Cursorless VSCode Tutorial Webview
+# Cursorless VS Code Tutorial Webview
This package holds the Javascript and CSS for the webview that is displayed when
-the user opens any tutorial in VSCode. It is rendered in the sidebar.
+the user opens any tutorial in VS Code. It is rendered in the sidebar.
## Development
diff --git a/packages/test-runner/README.md b/packages/test-runner/README.md
index 4c41a3ca2d5..8a255f376ba 100644
--- a/packages/test-runner/README.md
+++ b/packages/test-runner/README.md
@@ -1,6 +1,6 @@
# Test runner
-This package contains the machinery used to test Cursorless, both in CI and locally, across various contexts (eg VSCode, Talon, Neovim, unit tests). Note that it does not actually contain any tests itself; those are either embedded in `.test.ts` files either next to the code they're testing or in standalone `*-e2e` packages.
+This package contains the machinery used to test Cursorless, both in CI and locally, across various contexts (eg VS Code, Talon, Neovim, unit tests). Note that it does not actually contain any tests itself; those are either embedded in `.test.ts` files either next to the code they're testing or in standalone `*-e2e` packages.
This package bundles tests into `.mjs` files and includes scripts used to run tests.
diff --git a/resources/fixtures/recorded/docs/modifiers/excludeInterior2.yml b/resources/fixtures/recorded/docs/modifiers/excludeInterior2.yml
new file mode 100644
index 00000000000..35a644fa8e8
--- /dev/null
+++ b/resources/fixtures/recorded/docs/modifiers/excludeInterior2.yml
@@ -0,0 +1,26 @@
+languageId: typescript
+command:
+ version: 7
+ spokenForm: chuck bounds air
+ action:
+ name: remove
+ target:
+ type: primitive
+ mark: {type: decoratedSymbol, symbolColor: default, character: a}
+ modifiers:
+ - {type: excludeInterior}
+ usePrePhraseSnapshot: false
+initialState:
+ documentContents: (aaa)
+ selections:
+ - anchor: {line: 0, character: 0}
+ active: {line: 0, character: 0}
+ marks:
+ default.a:
+ start: {line: 0, character: 1}
+ end: {line: 0, character: 4}
+finalState:
+ documentContents: aaa
+ selections:
+ - anchor: {line: 0, character: 0}
+ active: {line: 0, character: 0}