From e4d4cee1982717ff02c069353387ed460453aab1 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 11:20:57 +0200 Subject: [PATCH 1/8] Added chuck bounds example --- .../docs/user/modifiers/excludeInterior.mdx | 5 ++++ .../src/references/modifierReferences.ts | 4 +++ .../docs/modifiers/excludeInterior2.yml | 26 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 resources/fixtures/recorded/docs/modifiers/excludeInterior2.yml 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 faa8b47f9d..29b0fe23a4 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/lib-common/src/references/modifierReferences.ts b/packages/lib-common/src/references/modifierReferences.ts index 69cc475802..72bd325fb0 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/resources/fixtures/recorded/docs/modifiers/excludeInterior2.yml b/resources/fixtures/recorded/docs/modifiers/excludeInterior2.yml new file mode 100644 index 0000000000..35a644fa8e --- /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} From 4c6de18f759ee8fa2ade7d85244636d3789a1aad Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 11:39:26 +0200 Subject: [PATCH 2/8] Talon dependencies --- .../app-web-docs/sidebarItemsGenerator.ts | 2 +- .../src/docs/user/talon-dependencies.md | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 packages/app-web-docs/src/docs/user/talon-dependencies.md diff --git a/packages/app-web-docs/sidebarItemsGenerator.ts b/packages/app-web-docs/sidebarItemsGenerator.ts index 0b6f71dd44..ef238f166f 100644 --- a/packages/app-web-docs/sidebarItemsGenerator.ts +++ b/packages/app-web-docs/sidebarItemsGenerator.ts @@ -42,7 +42,7 @@ const items: (Group | string)[] = [ }, { label: "Advanced", - items: ["Unicode support", "Experimental features"], + items: ["Unicode support", "Experimental features", "Talon dependencies"], }, { label: "Project", 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 0000000000..85e7416a48 --- /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) From 22763946ff9ae234b411e810cdbff588a50dd846 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 11:54:39 +0200 Subject: [PATCH 3/8] keyboard --- .../app-web-docs/sidebarItemsGenerator.ts | 2 +- .../keyboard/{modal.md => README.md} | 39 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) rename packages/app-web-docs/src/docs/user/experimental/keyboard/{modal.md => README.md} (67%) diff --git a/packages/app-web-docs/sidebarItemsGenerator.ts b/packages/app-web-docs/sidebarItemsGenerator.ts index ef238f166f..59061caf1f 100644 --- a/packages/app-web-docs/sidebarItemsGenerator.ts +++ b/packages/app-web-docs/sidebarItemsGenerator.ts @@ -42,7 +42,7 @@ const items: (Group | string)[] = [ }, { label: "Advanced", - items: ["Unicode support", "Experimental features", "Talon dependencies"], + items: ["Talon dependencies", "Unicode support", "Experimental features"], }, { label: "Project", 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 67% 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 8eb08b1b84..f3fd9699cb 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 @@ -8,6 +8,22 @@ The cursorless keyboard interface works by moving a highlight around, and allowi ![Bring demo](images/keyboardBring.gif) ![Pour demo](images/keyboardPour.gif) +## 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` @@ -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. @@ -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. From ef4de567599ed46ce822fef749bdd99b3c18885a Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 12:18:24 +0200 Subject: [PATCH 4/8] trouble shooting --- .../app-web-docs/sidebarItemsGenerator.ts | 7 +++- .../src/docs/user/learning-resources.md | 1 + .../src/docs/user/troubleshooting.md | 39 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 packages/app-web-docs/src/docs/user/troubleshooting.md diff --git a/packages/app-web-docs/sidebarItemsGenerator.ts b/packages/app-web-docs/sidebarItemsGenerator.ts index 59061caf1f..de4bb2eff0 100644 --- a/packages/app-web-docs/sidebarItemsGenerator.ts +++ b/packages/app-web-docs/sidebarItemsGenerator.ts @@ -12,7 +12,12 @@ const items: (Group | string)[] = [ "Cursorless", { label: "Getting started", - items: ["Installation", "Learning resources", "How-to guides"], + items: [ + "Installation", + "Learning resources", + "How-to guides", + "Troubleshooting", + ], }, { label: "Reference", 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 91a21e67ec..547d9392ee 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/troubleshooting.md b/packages/app-web-docs/src/docs/user/troubleshooting.md new file mode 100644 index 0000000000..200aa37b66 --- /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. From d9c2d5f1322429bf401a434a8de6c3f788ca49e5 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 13:23:41 +0200 Subject: [PATCH 5/8] customisation --- CHANGELOG.md | 2 +- .../node/command-server/README.md | 2 +- .../app-web-docs/sidebarItemsGenerator.ts | 10 +- .../src/docs/contributing/CONTRIBUTING.mdx | 32 ++-- .../contributing/adding-a-new-language.md | 4 +- .../docs/contributing/adding-a-new-scope.md | 2 +- .../neovim-test-infrastructure.md | 8 +- .../docs/contributing/cursorless-in-neovim.md | 8 +- .../docs/contributing/test-case-recorder.md | 2 +- .../src/docs/contributing/tests.md | 6 +- packages/app-web-docs/src/docs/user/README.md | 2 +- .../src/docs/user/custom-ide-actions.md | 36 +++++ .../src/docs/user/custom-regex-scopes.md | 39 +++++ .../src/docs/user/customization.md | 149 +----------------- .../experimental/custom-command-action.md | 36 +++++ .../docs/user/experimental/keyboard/README.md | 4 +- packages/app-web-docs/src/docs/user/how-to.md | 8 +- .../src/docs/user/installation.md | 6 +- .../src/docs/user/local-command-history.md | 2 +- .../src/docs/user/public-talon-api.md | 70 ++++++++ .../src/docs/user/recommendations.md | 8 + .../src/docs/user/release-notes/0.28.0.md | 12 +- .../src/docs/user/release-notes/0.29.0.md | 6 +- .../user/release-notes/2022-year-in-review.md | 2 +- .../src/docs/user/scope-sidebar.md | 2 +- .../app-web-docs/src/docs/user/targets.md | 8 +- .../app-web-docs/src/docs/user/updating.md | 6 +- .../lib-vscode-tutorial-webview/README.md | 4 +- packages/test-runner/README.md | 2 +- 29 files changed, 265 insertions(+), 213 deletions(-) create mode 100644 packages/app-web-docs/src/docs/user/custom-ide-actions.md create mode 100644 packages/app-web-docs/src/docs/user/custom-regex-scopes.md create mode 100644 packages/app-web-docs/src/docs/user/experimental/custom-command-action.md create mode 100644 packages/app-web-docs/src/docs/user/public-talon-api.md create mode 100644 packages/app-web-docs/src/docs/user/recommendations.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 957bf88d51..967c7b03bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ - 2026-08-30: Overhauled the user documentation with generated and grouped action, modifier, and scope reference pages, richer descriptions and examples, dedicated paired-delimiter and target guides, and a streamlined landing page. ([#3303](https://github.com/cursorless-dev/cursorless/pull/3303); [#3304](https://github.com/cursorless-dev/cursorless/pull/3304); [#3305](https://github.com/cursorless-dev/cursorless/pull/3305); [#3306](https://github.com/cursorless-dev/cursorless/pull/3306); [#3307](https://github.com/cursorless-dev/cursorless/pull/3307); [#3308](https://github.com/cursorless-dev/cursorless/pull/3308); [#3309](https://github.com/cursorless-dev/cursorless/pull/3309); [#3310](https://github.com/cursorless-dev/cursorless/pull/3310); [#3311](https://github.com/cursorless-dev/cursorless/pull/3311); [#3312](https://github.com/cursorless-dev/cursorless/pull/3312); [#3313](https://github.com/cursorless-dev/cursorless/pull/3313); [#3314](https://github.com/cursorless-dev/cursorless/pull/3314); [#3315](https://github.com/cursorless-dev/cursorless/pull/3315); [#3316](https://github.com/cursorless-dev/cursorless/pull/3316)) - 2026-05-03: Add support for if and for statements in Talon-script. [`#3274`](https://github.com/cursorless-dev/cursorless/pull/3274) - 2026-03-12: Added `userColor3` and `userColor4` as additional user-configurable hat colors. They are disabled by default until you enable and name them. ([#3206](https://github.com/cursorless-dev/cursorless/pull/3206)) -- 2026-03-11: Moved scope tests out of VSCode so they can run as regular unit tests with faster local and CI feedback. ([#3210](https://github.com/cursorless-dev/cursorless/pull/3210)) +- 2026-03-11: Moved scope tests out of VS Code so they can run as regular unit tests with faster local and CI feedback. ([#3210](https://github.com/cursorless-dev/cursorless/pull/3210)) - 2026-03-11: Git actions can now stage and unstage entire files, not just partial selections. ([#3209](https://github.com/cursorless-dev/cursorless/pull/3209)) - 2026-03-01: Greatly expanded scope fixtures and supported scope facets across many languages, including C, C++, C#, Dart, Go, Java, Kotlin, PHP, Rust, Scala, and TypeScript. This work added missing coverage for type aliases, interface methods, enum arguments and argument lists, lambda returns, resources, and more. ([#3198](https://github.com/cursorless-dev/cursorless/pull/3198)) - 2026-02-28: Added missing scope facets for Clojure and Dart, continuing the 2026 scope-coverage expansion. ([#3197](https://github.com/cursorless-dev/cursorless/pull/3197); [#3196](https://github.com/cursorless-dev/cursorless/pull/3196)) diff --git a/packages/app-neovim/cursorless.nvim/node/command-server/README.md b/packages/app-neovim/cursorless.nvim/node/command-server/README.md index 4decab2819..1a22bae162 100644 --- a/packages/app-neovim/cursorless.nvim/node/command-server/README.md +++ b/packages/app-neovim/cursorless.nvim/node/command-server/README.md @@ -1,3 +1,3 @@ # Command server -This directory contains a minified version of a `command-server`, which enables us to communicate with node from Talon. It is based on [command-server we use for VSCode](https://github.com/pokey/command-server/), but modified to run in a Neovim node subprocess. It can be built by following the instructions from https://github.com/hands-free-vim/command-server/tree/neovim#build +This directory contains a minified version of a `command-server`, which enables us to communicate with node from Talon. It is based on [command-server we use for VS Code](https://github.com/pokey/command-server/), but modified to run in a Neovim node subprocess. It can be built by following the instructions from https://github.com/hands-free-vim/command-server/tree/neovim#build diff --git a/packages/app-web-docs/sidebarItemsGenerator.ts b/packages/app-web-docs/sidebarItemsGenerator.ts index de4bb2eff0..1a29caa5ff 100644 --- a/packages/app-web-docs/sidebarItemsGenerator.ts +++ b/packages/app-web-docs/sidebarItemsGenerator.ts @@ -14,6 +14,7 @@ const items: (Group | string)[] = [ label: "Getting started", items: [ "Installation", + "Recommendations", "Learning resources", "How-to guides", "Troubleshooting", @@ -34,7 +35,14 @@ const items: (Group | string)[] = [ "Supported languages", { label: "Customization", - items: ["Customization", "Hat assignment", "Visual Accessibility"], + items: [ + "Customization", + "Hat assignment", + "Visual Accessibility", + "Custom IDE actions", + "Custom regex scopes", + "Public Talon API", + ], }, { label: "Tools", diff --git a/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx b/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx index 39588754de..84235f7955 100644 --- a/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx +++ b/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx @@ -3,7 +3,7 @@ import TabItem from "@theme/TabItem"; # Contributing -Welcome! So glad you've decided to help make Cursorless better. You'll want to start by getting [set up](#initial-setup) and learning how to [run / test a local copy of the extension](#running--testing-extension-locally). You may also find the [VSCode API docs](https://code.visualstudio.com/api) helpful to learn about VSCode extension development. +Welcome! So glad you've decided to help make Cursorless better. You'll want to start by getting [set up](#initial-setup) and learning how to [run / test a local copy of the extension](#running--testing-extension-locally). You may also find the [VS Code API docs](https://code.visualstudio.com/api) helpful to learn about VS Code extension development. ## Initial setup @@ -12,13 +12,13 @@ Welcome! So glad you've decided to help make Cursorless better. You'll want to s - [Git](https://git-scm.com/) - [Node.js](https://nodejs.org/en/) - [Corepack](https://nodejs.org/api/corepack.html) or [pnpm](https://pnpm.io/installation) -- [VSCode](https://code.visualstudio.com/) or [VSCodium](https://vscodium.com/) - Both VSCode and VSCodium will be referred to as VSCode except when instructions differ between the editors. +- [VS Code](https://code.visualstudio.com/) or [VSCodium](https://vscodium.com/) + Both VS Code and VSCodium will be referred to as VS Code except when instructions differ between the editors. ### Steps 1. Clone [`cursorless`](https://github.com/cursorless-dev/cursorless) locally. Note that it doesn't matter where you clone it, as long as you _**do not**_ clone it into your Talon user directory. -2. Open the newly created `cursorless` directory in VSCode. If you're on Windows, don't use WSL (see [#919](https://github.com/cursorless-dev/cursorless/issues/919) for discussion / workaround). +2. Open the newly created `cursorless` directory in VS Code. If you're on Windows, don't use WSL (see [#919](https://github.com/cursorless-dev/cursorless/issues/919) for discussion / workaround). 3. Run the following in the terminal: ```bash @@ -29,7 +29,7 @@ Welcome! So glad you've decided to help make Cursorless better. You'll want to s - + ```bash code --profile=cursorlessDevelopment @@ -47,13 +47,13 @@ Welcome! So glad you've decided to help make Cursorless better. You'll want to s - and then close the window that opens (eg say `"window close"`). This step is necessary to create the [VSCode settings profile](https://code.visualstudio.com/updates/v1_72#_settings-profiles) that acts as a sandbox containing a specific set of VSCode extensions that will be run alongside Cursorless when you launch Cursorless in debug or test mode. Once https://github.com/microsoft/vscode/issues/172046 is resolved, we will be able to remove this step, as the profile can then automatically be created. + and then close the window that opens (eg say `"window close"`). This step is necessary to create the [VS Code settings profile](https://code.visualstudio.com/updates/v1_72#_settings-profiles) that acts as a sandbox containing a specific set of VS Code extensions that will be run alongside Cursorless when you launch Cursorless in debug or test mode. Once https://github.com/microsoft/vscode/issues/172046 is resolved, we will be able to remove this step, as the profile can then automatically be created. 5. Run the following in the terminal: - + ```bash pnpm init-vscode-sandbox @@ -83,11 +83,11 @@ Welcome! So glad you've decided to help make Cursorless better. You'll want to s - Said command adds extensions to the aforementioned settings profile that acts as a sandbox containing a specific set of VSCode extensions that will be run alongside Cursorless when you launch Cursorless in debug or test mode. This approach is [suggested](https://code.visualstudio.com/updates/v1_72#_extension-debugging-in-a-clean-environment) by the VSCode documentation. If you need to update any of the extension dependencies in the sandbox, you can add `--force` to the command. If you'd like to use additional extensions when debugging locally, you can use the following command: + Said command adds extensions to the aforementioned settings profile that acts as a sandbox containing a specific set of VS Code extensions that will be run alongside Cursorless when you launch Cursorless in debug or test mode. This approach is [suggested](https://code.visualstudio.com/updates/v1_72#_extension-debugging-in-a-clean-environment) by the VS Code documentation. If you need to update any of the extension dependencies in the sandbox, you can add `--force` to the command. If you'd like to use additional extensions when debugging locally, you can use the following command: - + ```bash code --profile=cursorlessDevelopment --install-extension some.extension @@ -109,7 +109,7 @@ Welcome! So glad you've decided to help make Cursorless better. You'll want to s Note that you do not need to install the Cursorless extension into the `cursorlessDevelopment` profile. A local development version of Cursorless will be automatically installed there every time you debug the extension, as described below. - Also note that if you are adding support for a new language that isn't in the default list of [language identifiers](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers) supported by VSCode, you may need to add an extension dependency. See [Adding a new language](./adding-a-new-language.md#2-ensure-file-type-is-supported-by-vscode) for more details. + Also note that if you are adding support for a new language that isn't in the default list of [language identifiers](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers) supported by VS Code, you may need to add an extension dependency. See [Adding a new language](./adding-a-new-language.md#2-ensure-file-type-is-supported-by-vs-code) for more details. 6. Copy / symlink [`cursorless-talon-dev`](../../cursorless-talon-dev) into your Talon user directory for some useful voice commands for developing Cursorless. @@ -118,16 +118,16 @@ Welcome! So glad you've decided to help make Cursorless better. You'll want to s In order to test out your local version of the extension or to run unit tests locally, you need to run the extension in debug mode. To do so you need to do the following: -1. Open the Cursorless repository in VSCode (with your regular default profile, _**not**_ with the `cursorlessDevelopment` profile) +1. Open the Cursorless repository in VS Code (with your regular default profile, _**not**_ with the `cursorlessDevelopment` profile) 2. Say `"debug extension"` to run the extension. If you want to run the tests instead, say `"debug test"`. -If you don't have the `cursorless-talon-dev` files in your Talon user directory as described in step 6 above, then you instead need to run the `workbench.action.debug.selectandstart` command in VSCode and then select either "Run extension" or "Extension tests". +If you don't have the `cursorless-talon-dev` files in your Talon user directory as described in step 6 above, then you instead need to run the `workbench.action.debug.selectandstart` command in VS Code and then select either "Run extension" or "Extension tests". ### Running a subset of tests The entire test suite takes a little while to run (1-2 mins), so you may want to run just a subset of the tests. -To specify the set of tests to run, say `"debug generate subset"`, or if you haven't installed the cursorless-talon-dev files, run the VSCode task "Generate test subset file". To do this, choose "Tasks: Run Task" from the command palette. +To specify the set of tests to run, say `"debug generate subset"`, or if you haven't installed the cursorless-talon-dev files, run the VS Code task "Generate test subset file". To do this, choose "Tasks: Run Task" from the command palette. To run the specified subset of tests, say `"debug test subset"` (or use the "Extension tests (subset)" launch config). @@ -151,7 +151,7 @@ Run the `workbench.action.debug.selectandstart` command and then select See [test-case-recorder.md](./test-case-recorder.md). -It is also possible to write manual tests. When doing so, we have a convention that any test that must be run within a VSCode context (eg because it imports `"vscode"`), should be placed in a file with the suffix `.vscode.test.ts`. All other tests should end with just `.test.ts`. This allows us to run non-VSCode tests locally outside of VSCode using `pnpm test`. The non-VSCode tests run much faster than the full VSCode test suite. +It is also possible to write manual tests. When doing so, we have a convention that any test that must be run within a VS Code context (eg because it imports `"vscode"`), should be placed in a file with the suffix `.vscode.test.ts`. All other tests should end with just `.test.ts`. This allows us to run non-VS Code tests locally outside of VS Code using `pnpm test`. The non-VS Code tests run much faster than the full VS Code test suite. ## Parse tree support @@ -159,7 +159,7 @@ It is also possible to write manual tests. When doing so, we have a convention t See [docs](./adding-a-new-language.md). -### Testing Cursorless with a local version of the VSCode parse tree extension +### Testing Cursorless with a local version of the VS Code parse tree extension First bundle the parse tree extension into a `.vsix`, using something like the following: @@ -171,7 +171,7 @@ vsce package -o bundle.vsix Once you have your package then you can install it into the sandbox using the following command: - + ```bash code --profile=cursorlessDevelopment --install-extension bundle.vsix diff --git a/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md b/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md index d213dd8b1d..d3b2144f86 100644 --- a/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md +++ b/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md @@ -9,9 +9,9 @@ of a document. See the [docs](https://github.com/pokey/vscode-parse-tree/#adding-a-new-language) there for how to add support for a new parser -## 2. Ensure file type is supported by VSCode +## 2. Ensure file type is supported by VS Code -If you are adding support for a new language that isn't natively detected by VSCode, you will need to add the appropriate extension to the list of dependencies. The list of languages officially supported by VSCode is listed [in the VSCode docs](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers). If your language is in that list, you can skip this step and proceed to step 3. If your language is not in that list, you need to find a VSCode extension that adds support for your language, and add the id of the given extension to [`packages/lib-common/src/extensionDependencies.ts`](../../../../../packages/lib-common/src/extensionDependencies.ts) and then re-run `pnpm init-vscode-sandbox` to ensure it is installed. If you do not do this you will encounter errors when attempting to execute cursorless commands in the next step. See [#1895](https://github.com/cursorless-dev/cursorless/issues/1895) for more info. +If you are adding support for a new language that isn't natively detected by VS Code, you will need to add the appropriate extension to the list of dependencies. The list of languages officially supported by VS Code is listed [in the VS Code docs](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers). If your language is in that list, you can skip this step and proceed to step 3. If your language is not in that list, you need to find a VS Code extension that adds support for your language, and add the id of the given extension to [`packages/lib-common/src/extensionDependencies.ts`](../../../../../packages/lib-common/src/extensionDependencies.ts) and then re-run `pnpm init-vscode-sandbox` to ensure it is installed. If you do not do this you will encounter errors when attempting to execute cursorless commands in the next step. See [#1895](https://github.com/cursorless-dev/cursorless/issues/1895) for more info. ## 3. Register your language with Cursorless diff --git a/packages/app-web-docs/src/docs/contributing/adding-a-new-scope.md b/packages/app-web-docs/src/docs/contributing/adding-a-new-scope.md index 5561f9a463..b69ac7e243 100644 --- a/packages/app-web-docs/src/docs/contributing/adding-a-new-scope.md +++ b/packages/app-web-docs/src/docs/contributing/adding-a-new-scope.md @@ -70,7 +70,7 @@ The tests generated in step 4 only include the code example. Now that you've tol 1. Say `"debug edit subset"` and alter the file to include just the name of your language. 2. Run `pnpm test:update:subset` from the repository root to update the fixtures for the selected subset of tests. If you want to update all fixtures instead, run `pnpm test:update`. -3. Check that the fixtures now look as expected, and no other tests for your language have been altered. The VSCode source control side bar is useful for this purpose. For help understanding the scope test format, see the [scope test format docs](./scope-test-format.md). +3. Check that the fixtures now look as expected, and no other tests for your language have been altered. The VS Code source control side bar is useful for this purpose. For help understanding the scope test format, see the [scope test format docs](./scope-test-format.md). ## 7. File a PR! diff --git a/packages/app-web-docs/src/docs/contributing/architecture/neovim-test-infrastructure.md b/packages/app-web-docs/src/docs/contributing/architecture/neovim-test-infrastructure.md index 215a37f5a1..3b267d94f1 100644 --- a/packages/app-web-docs/src/docs/contributing/architecture/neovim-test-infrastructure.md +++ b/packages/app-web-docs/src/docs/contributing/architecture/neovim-test-infrastructure.md @@ -33,7 +33,7 @@ packages/test-runner/src/config/init.lua This is supported on Windows, Linux and OSX. -It starts by running the `Neovim: Test` launch config from `.vscode/launch.json`. This dictates VSCode to attach to the `node` process that is spawned by `nvim` (more on this later). Note that it will only attach when the dependencies have been solved, which is indicated by the `"Neovim: Build extension and tests"` task: +It starts by running the `Neovim: Test` launch config from `.vscode/launch.json`. This dictates VS Code to attach to the `node` process that is spawned by `nvim` (more on this later). Note that it will only attach when the dependencies have been solved, which is indicated by the `"Neovim: Build extension and tests"` task: ```json { @@ -65,7 +65,7 @@ This effectively runs a series of dependency tasks from `.vscode/tasks.json`: Most of the tasks deal with building the Cursorless code except `"Neovim: Launch neovim (test)"` and `"Neovim: Show logs"` which are self explanatory. -The `Neovim: Launch neovim (test)` task effectively starts `nvim` as a detached process. It is important because it means VSCode won't wait for `nvim` to exit before considering the task as finished. For example, for Windows it executes the `debug-neovim.bat` script : +The `Neovim: Launch neovim (test)` task effectively starts `nvim` as a detached process. It is important because it means VS Code won't wait for `nvim` to exit before considering the task as finished. For example, for Windows it executes the `debug-neovim.bat` script : ```json { @@ -159,9 +159,9 @@ local function load_extensions() However, because `nvim` was started with `"NVIM_NODE_HOST_DEBUG": "1"`, when `node` is spawned, `node` will hang and wait for a debugger to attach (`--inspect-brk`). Consequently, `nvim` won't finish loading yet (i.e. it won't finish loading `init.lua`). -This is handy because it allows VSCode to finish all the tasks required for building the Cursorless neovim package (`app-neovim`, exposed to Neovim under `node/cursorless-neovim`) and the test runner package (`test-runner`, exposed under `node/test-runner`), which will finally trigger VSCode to attach to the `node` process. +This is handy because it allows VS Code to finish all the tasks required for building the Cursorless neovim package (`app-neovim`, exposed to Neovim under `node/cursorless-neovim`) and the test runner package (`test-runner`, exposed under `node/test-runner`), which will finally trigger VS Code to attach to the `node` process. -When VSCode attaches to the `node` process, `CursorlessLoadExtension()` is called to load the Cursorless neovim plugin and `TestRunnerRun()` is called to start the tests. +When VS Code attaches to the `node` process, `CursorlessLoadExtension()` is called to load the Cursorless neovim plugin and `TestRunnerRun()` is called to start the tests. This ends up calling `TestRunnerRun()` from `packages/test-runner/src/index.ts` which calls `run()`: diff --git a/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md b/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md index 5118fc2b32..022bfcc2e1 100644 --- a/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md +++ b/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md @@ -24,7 +24,7 @@ On Windows, open the Control Panel, navigate to `User Accounts > User Accounts`. ### 4. (Windows only) Create symlinks for the built plugins -This step is only required on Windows if you don't run VSCode with Administrator privileges. +This step is only required on Windows if you don't run VS Code with Administrator privileges. Open a `cmd.exe` with Administrator privileges and create the symbolic links between the source folders and the `packages/app-neovim/cursorless.nvim` destination folder: @@ -39,13 +39,13 @@ Note that the `C:\path\to\cursorless` path above should match your cloned cursor In order to test out your local version of the extension or to run unit tests locally, you need to run the extension in debug mode. To do so you need to do the following: -1. Open the Cursorless repository in VSCode (with your regular default profile, _**not**_ with the `cursorlessDevelopment` profile) +1. Open the Cursorless repository in VS Code (with your regular default profile, _**not**_ with the `cursorlessDevelopment` profile) 2. Say `"neovim log"` to open the neovim log. 3. Say `"debug neovim"` to run the extension. If you want to run the tests instead, say `"debug test neovim"`. -NOTE: This will spawn a standalone nvim instance that is independent of VSCode. Consequently after you're done debugging, you need to close nvim. +NOTE: This will spawn a standalone nvim instance that is independent of VS Code. Consequently after you're done debugging, you need to close nvim. -If you don't have the `cursorless-talon-dev` files in your Talon user directory as described in step 6 of [CONTRIBUTING.mdx](./CONTRIBUTING.mdx#initial-setup), then you instead need to run the `workbench.action.debug.selectandstart` command in VSCode and then select either "Neovim: Run" or "Neovim: Test". +If you don't have the `cursorless-talon-dev` files in your Talon user directory as described in step 6 of [CONTRIBUTING.mdx](./CONTRIBUTING.mdx#initial-setup), then you instead need to run the `workbench.action.debug.selectandstart` command in VS Code and then select either "Neovim: Run" or "Neovim: Test". ### Running lua tests diff --git a/packages/app-web-docs/src/docs/contributing/test-case-recorder.md b/packages/app-web-docs/src/docs/contributing/test-case-recorder.md index fb584e2a1d..726303890f 100644 --- a/packages/app-web-docs/src/docs/contributing/test-case-recorder.md +++ b/packages/app-web-docs/src/docs/contributing/test-case-recorder.md @@ -22,7 +22,7 @@ command run, and the final state, all in the form of a yaml document. See new directory. Using `/` will create nested subdirectories. 1. Issue any cursorless voice command, eg `"take air"`. This will result in a new test case being generated in the Cursorless directory. You can verify by - returning to the main VSCode window and looking at the source control + returning to the main VS Code window and looking at the source control sidebar to see the new yaml file. 1. Repeat as many cursorless voice commands as you want recorded. Each command you issue will generate a test case in the form of a new yaml file. diff --git a/packages/app-web-docs/src/docs/contributing/tests.md b/packages/app-web-docs/src/docs/contributing/tests.md index a8de610b61..11f42bcb1f 100644 --- a/packages/app-web-docs/src/docs/contributing/tests.md +++ b/packages/app-web-docs/src/docs/contributing/tests.md @@ -10,18 +10,18 @@ Our tests fall broadly into three categories: We run the above tests in various contexts, both locally and in CI. The contexts are: -- **VSCode**: Today, many of our tests must run within a VSCode context. For some of our tests, this is desirable, because they are designed to test that our code works in VSCode. However, many of our tests (such as scope tests and recorded tests) are not really VSCode-specific, but we haven't yet built the machinery to run them in a more isolated context, which would be much faster. These tests are run separately from the default unit test pass. +- **VS Code**: Today, many of our tests must run within a VS Code context. For some of our tests, this is desirable, because they are designed to test that our code works in VS Code. However, many of our tests (such as scope tests and recorded tests) are not really VS Code-specific, but we haven't yet built the machinery to run them in a more isolated context, which would be much faster. These tests are run separately from the default unit test pass. - **Unit tests**: Many of our tests can run in a neutral context, without requiring an actual IDE with editors, etc. Most of these are unit tests in the traditional sense of the word, testing the logic of a small unit of code, such as a function. - **Talon**: For each of our recorded tests, we test that saying the spoken form of the command in Talon results in the command payload that we expect. Note that these tests can only be run locally today. - **Neovim**: We run a subset of our recorded tests within Neovim to ensure that the given subset of Cursorless works within Neovim. We also have a few lua unit tests that must be run in Neovim. These test the lua functions that Cursorless needs in order to interact with Neovim. To learn more about our Neovim test infrastructure, see [Neovim test infrastructure](./architecture/neovim-test-infrastructure.md). -You can get an overview of the various test contexts that exist locally by looking at our VSCode launch configs, which include not only our VSCode tests, but all of our tests. +You can get an overview of the various test contexts that exist locally by looking at our VS Code launch configs, which include not only our VS Code tests, but all of our tests. ## Common commands - `pnpm test` runs the default `test` script for each workspace package. In practice, this is the fast unit-oriented test pass. - `pnpm test:update` runs the test suite in fixture-update mode across the workspace. - `pnpm test:update:subset` runs fixture updates only for the tests selected in `packages/test-runner/testSubsetGrep.properties`. -- `pnpm -F @cursorless/test-runner test:vscode` runs the VSCode test runner. +- `pnpm -F @cursorless/test-runner test:vscode` runs the VS Code test runner. - `pnpm -F @cursorless/test-runner test:neovim` runs the Neovim test runner. - `pnpm -F @cursorless/test-runner test:talonjs` runs the Talon-JS test runner. diff --git a/packages/app-web-docs/src/docs/user/README.md b/packages/app-web-docs/src/docs/user/README.md index b307112c66..e408256ab8 100644 --- a/packages/app-web-docs/src/docs/user/README.md +++ b/packages/app-web-docs/src/docs/user/README.md @@ -8,7 +8,7 @@ Welcome to Cursorless! If you're new, start with the [learning resources](./lear This guide assumes you've already [installed Cursorless](./installation.md). -Once you understand the concepts, you can browse the [online cheatsheet](https://www.cursorless.org/cheatsheet), or pull up a local cheatsheet with your custom spoken forms by saying `"cursorless cheatsheet"` or `"cursorless reference"` with VSCode focused. You can return to these docs by saying `"cursorless docs"` or `"cursorless help"` within VSCode. +Once you understand the concepts, you can browse the [online cheatsheet](https://www.cursorless.org/cheatsheet), or pull up a local cheatsheet with your custom spoken forms by saying `"cursorless cheatsheet"` or `"cursorless reference"` with VS Code focused. You can return to these docs by saying `"cursorless docs"` or `"cursorless help"` within VS Code. To change any spoken forms, see [Customization](./customization.md). diff --git a/packages/app-web-docs/src/docs/user/custom-ide-actions.md b/packages/app-web-docs/src/docs/user/custom-ide-actions.md new file mode 100644 index 0000000000..493029fe8d --- /dev/null +++ b/packages/app-web-docs/src/docs/user/custom-ide-actions.md @@ -0,0 +1,36 @@ +# Custom IDE actions + +You can use Cursorless to run any built-in IDE command on a specific target. + +Just add your custom commands to `user/cursorless-settings/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 VS Code command `editor.action.moveLinesDownAction`, and then restore your original selection. + +See this [video on finding VS Code command IDs 🎬](https://youtu.be/oWUJyDgz63k?si=mw-KPhjFoqbcgGOp) for commands you use. + +## Examples + +```csv +Spoken form, VSCode command +join, editor.action.joinLines +git revert, git.revertSelectedRanges +git stage, git.stageSelectedRanges +git unstage, git.unstageSelectedRanges +bubble, editor.action.moveLinesUpAction +sink, editor.action.moveLinesDownAction +accept, merge-conflict.accept.selection +accept both, merge-conflict.accept.both +reflow, rewrap.rewrapComment +``` + +### Calva `"slurp"` / `"barf"` + +```csv +slurp,paredit.slurpSexpForward +barf,paredit.barfSexpForward +``` diff --git a/packages/app-web-docs/src/docs/user/custom-regex-scopes.md b/packages/app-web-docs/src/docs/user/custom-regex-scopes.md new file mode 100644 index 0000000000..de38a94859 --- /dev/null +++ b/packages/app-web-docs/src/docs/user/custom-regex-scopes.md @@ -0,0 +1,39 @@ +# 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.]+"`: + +
+ ![visualization of a custom regex scope](./images/custom-regex-scopes.png) +
+ +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 916615b5c2..0aa192f80c 100644 --- a/packages/app-web-docs/src/docs/user/customization.md +++ b/packages/app-web-docs/src/docs/user/customization.md @@ -2,14 +2,14 @@ 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 @@ -57,53 +57,6 @@ 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 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.]+"`: - -
- ![visualization of a custom regex scope](./images/custom-regex-scopes.png) -
- -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 0000000000..4acc45fa52 --- /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/README.md b/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md index f3fd9699cb..1cf39fd674 100644 --- a/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md +++ b/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md @@ -28,7 +28,7 @@ The keys used for actions, targets, and modifiers are context-sensitive. For exa ### `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 { @@ -73,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": { 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 163ffeb83a..3ae59254cd 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 f64d064bb9..77bff0e512 100644 --- a/packages/app-web-docs/src/docs/user/installation.md +++ b/packages/app-web-docs/src/docs/user/installation.md @@ -4,9 +4,9 @@ - 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) +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/local-command-history.md b/packages/app-web-docs/src/docs/user/local-command-history.md index cea882d585..f892d58459 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/public-talon-api.md b/packages/app-web-docs/src/docs/user/public-talon-api.md new file mode 100644 index 0000000000..c9e75a09aa --- /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 0000000000..f9ccaeb4f5 --- /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 6829814604..181f396c6c 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 @@ -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 (🤫): ![cursorless sidebar](sidebar-sneak-preview.png) 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 (🤫): ![cursorless sidebar](sidebar-sneak-preview.png) 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 aafaf1adfb..ef7243e27c 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. @@ -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/2022-year-in-review.md b/packages/app-web-docs/src/docs/user/release-notes/2022-year-in-review.md index 7cfd03dfaf..6cbdd69824 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 bc9bfd963b..4eb465f8fb 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/targets.md b/packages/app-web-docs/src/docs/user/targets.md index 07e53a6a6b..d9df804bcc 100644 --- a/packages/app-web-docs/src/docs/user/targets.md +++ b/packages/app-web-docs/src/docs/user/targets.md @@ -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,7 +73,7 @@ The following shapes are supported. Note that to target the default (dot) shape | `"cross"` | ![Crosshairs](../../../../../resources/images/hats/crosshairs.svg) | `crosshairs` | ❌ | | `"eye"` | ![Eye](../../../../../resources/images/hats/eye.svg) | `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 @@ -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"` diff --git a/packages/app-web-docs/src/docs/user/updating.md b/packages/app-web-docs/src/docs/user/updating.md index 71aafdaca1..d478c3a809 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-vscode-tutorial-webview/README.md b/packages/lib-vscode-tutorial-webview/README.md index 5be2e3d9a9..f24f909f2e 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 4c41a3ca2d..8a255f376b 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. From a0651af875c7141d6e5aafe793750cfcdea6d446 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 13:27:16 +0200 Subject: [PATCH 6/8] Capital C --- .../src/docs/contributing/CONTRIBUTING.mdx | 2 +- .../src/docs/contributing/adding-a-new-language.md | 4 ++-- .../docs/contributing/architecture/hat-snapshots.md | 2 +- .../src/docs/contributing/cursorless-in-neovim.md | 4 ++-- .../src/docs/contributing/test-case-recorder.md | 8 ++++---- packages/app-web-docs/src/docs/user/customization.md | 12 ++++++------ .../src/docs/user/experimental/keyboard/README.md | 2 +- packages/app-web-docs/src/docs/user/installation.md | 2 +- .../src/docs/user/release-notes/0.28.0.md | 2 +- packages/app-web-docs/src/docs/user/targets.md | 10 +++++----- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx b/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx index 84235f7955..ebb46d6cb0 100644 --- a/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx +++ b/packages/app-web-docs/src/docs/contributing/CONTRIBUTING.mdx @@ -206,7 +206,7 @@ cli](https://cli.github.com/). For example: pnpm -F @cursorless/app-vscode install-from-pr 1281 ``` -To uninstall the local build and revert to production cursorless, run the following command: +To uninstall the local build and revert to production Cursorless, run the following command: ```bash pnpm -F @cursorless/app-vscode uninstall-local diff --git a/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md b/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md index d3b2144f86..4134296c86 100644 --- a/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md +++ b/packages/app-web-docs/src/docs/contributing/adding-a-new-language.md @@ -1,6 +1,6 @@ # Adding a new programming language -So you want cursorless to support a new language? Great! Here's how to do it: +So you want Cursorless to support a new language? Great! Here's how to do it: ## 1. Add support to the [vscode-parse-tree](https://github.com/pokey/vscode-parse-tree) extension @@ -11,7 +11,7 @@ for how to add support for a new parser ## 2. Ensure file type is supported by VS Code -If you are adding support for a new language that isn't natively detected by VS Code, you will need to add the appropriate extension to the list of dependencies. The list of languages officially supported by VS Code is listed [in the VS Code docs](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers). If your language is in that list, you can skip this step and proceed to step 3. If your language is not in that list, you need to find a VS Code extension that adds support for your language, and add the id of the given extension to [`packages/lib-common/src/extensionDependencies.ts`](../../../../../packages/lib-common/src/extensionDependencies.ts) and then re-run `pnpm init-vscode-sandbox` to ensure it is installed. If you do not do this you will encounter errors when attempting to execute cursorless commands in the next step. See [#1895](https://github.com/cursorless-dev/cursorless/issues/1895) for more info. +If you are adding support for a new language that isn't natively detected by VS Code, you will need to add the appropriate extension to the list of dependencies. The list of languages officially supported by VS Code is listed [in the VS Code docs](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers). If your language is in that list, you can skip this step and proceed to step 3. If your language is not in that list, you need to find a VS Code extension that adds support for your language, and add the id of the given extension to [`packages/lib-common/src/extensionDependencies.ts`](../../../../../packages/lib-common/src/extensionDependencies.ts) and then re-run `pnpm init-vscode-sandbox` to ensure it is installed. If you do not do this you will encounter errors when attempting to execute Cursorless commands in the next step. See [#1895](https://github.com/cursorless-dev/cursorless/issues/1895) for more info. ## 3. Register your language with Cursorless diff --git a/packages/app-web-docs/src/docs/contributing/architecture/hat-snapshots.md b/packages/app-web-docs/src/docs/contributing/architecture/hat-snapshots.md index de4c33c4f3..9c420c43d9 100644 --- a/packages/app-web-docs/src/docs/contributing/architecture/hat-snapshots.md +++ b/packages/app-web-docs/src/docs/contributing/architecture/hat-snapshots.md @@ -2,7 +2,7 @@ In order to allow long chained command phrases, we take a snapshot of the hat token map at the start of a phrase and continue to use this map during the course of the entire phrase. This way you can be sure that any commands issued during the course of a single phrase that refer to a decorated token will continue to refer to the same logical token no matter what happens in the document during phrase execution. Note that the ranges of tokens will be kept current as the document changes so that they refer to the same logical range, but the same logical token will keep the same key in the hat token map over the course of a phrase. -To make this work, first the voice engine [touches](https://github.com/talonhub/community/blob/e373780af16256ab8fd5638af32d97fa23c4c0fc/apps/vscode/command_client/command_client.py#L398) a file within the signals subdirectory of the command server communication directory after the phrase has been parsed but right before execution begins. Then cursorless will check the version of the signal file before it [reads](https://github.com/cursorless-dev/cursorless/blob/2a624888369d41b0531e472d001d63d09912c8aa/src/core/HatTokenMap.ts#L88) or [updates](https://github.com/cursorless-dev/cursorless/blob/0d1004bafc6764734bee62afbfbb02500630a264/src/core/HatTokenMap.ts#L70) the hat token map via the command server [signal API](https://github.com/pokey/command-server/blob/2b9f9ea2a38b6e95aa60ff9553a804165e527308/src/extension.ts#L29). If the signal has been emitted since the last time cursorless took a snapshot of the hat token map, it will take a new snapshot and continue to use that snapshot of the hats until the next time the signal is emitted. Note that the signal transmission is asynchronous so cursorless just needs to make sure to check the version of the signal before it either updates or reads the map. +To make this work, first the voice engine [touches](https://github.com/talonhub/community/blob/e373780af16256ab8fd5638af32d97fa23c4c0fc/apps/vscode/command_client/command_client.py#L398) a file within the signals subdirectory of the command server communication directory after the phrase has been parsed but right before execution begins. Then Cursorless will check the version of the signal file before it [reads](https://github.com/cursorless-dev/cursorless/blob/2a624888369d41b0531e472d001d63d09912c8aa/src/core/HatTokenMap.ts#L88) or [updates](https://github.com/cursorless-dev/cursorless/blob/0d1004bafc6764734bee62afbfbb02500630a264/src/core/HatTokenMap.ts#L70) the hat token map via the command server [signal API](https://github.com/pokey/command-server/blob/2b9f9ea2a38b6e95aa60ff9553a804165e527308/src/extension.ts#L29). If the signal has been emitted since the last time Cursorless took a snapshot of the hat token map, it will take a new snapshot and continue to use that snapshot of the hats until the next time the signal is emitted. Note that the signal transmission is asynchronous so Cursorless just needs to make sure to check the version of the signal before it either updates or reads the map. In the diagram below, we document the flow of a couple different cases. Dotted lines represent asynchronous / fire-and-forget communication: diff --git a/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md b/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md index 022bfcc2e1..0965d0a57f 100644 --- a/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md +++ b/packages/app-web-docs/src/docs/contributing/cursorless-in-neovim.md @@ -33,7 +33,7 @@ mklink /D C:\path\to\cursorless\packages\app-neovim\cursorless.nvim\node\cursorl mklink /D C:\path\to\cursorless\packages\app-neovim\cursorless.nvim\node\test-runner C:\path\to\cursorless\packages\test-runner ``` -Note that the `C:\path\to\cursorless` path above should match your cloned cursorless repository. +Note that the `C:\path\to\cursorless` path above should match your cloned Cursorless repository. ## Running / testing extension locally @@ -49,7 +49,7 @@ If you don't have the `cursorless-talon-dev` files in your Talon user directory ### Running lua tests -Their are separate cursorless and lua tests. You can run the lua tests by entering the `packages/app-neovim/cursorless.nvim` folder and +Their are separate Cursorless and lua tests. You can run the lua tests by entering the `packages/app-neovim/cursorless.nvim` folder and running: `busted --run unit`. These tests currently only work on Linux. ## Sending pull requests diff --git a/packages/app-web-docs/src/docs/contributing/test-case-recorder.md b/packages/app-web-docs/src/docs/contributing/test-case-recorder.md index 726303890f..700a09c8eb 100644 --- a/packages/app-web-docs/src/docs/contributing/test-case-recorder.md +++ b/packages/app-web-docs/src/docs/contributing/test-case-recorder.md @@ -2,8 +2,8 @@ We use an automated test case recorder to generate test cases. To use it, you set up a file the way you'd like (usually a minimal file containing something -like `hello world`), positioning your cursor where you want, tell cursorless to -start recording, and then issue one or more cursorless commands. It works by +like `hello world`), positioning your cursor where you want, tell Cursorless to +start recording, and then issue one or more Cursorless commands. It works by recording the initial state of the file including cursor position(s), the command run, and the final state, all in the form of a yaml document. See [existing test cases](../../../../../resources/fixtures/recorded) for example outputs. @@ -20,11 +20,11 @@ command run, and the final state, all in the form of a yaml document. See commands listed in [Test case recorder options](#test-case-recorder-options). 1. Pick a target directory, or create a new one by just typing the name of the new directory. Using `/` will create nested subdirectories. -1. Issue any cursorless voice command, eg `"take air"`. This will result in a +1. Issue any Cursorless voice command, eg `"take air"`. This will result in a new test case being generated in the Cursorless directory. You can verify by returning to the main VS Code window and looking at the source control sidebar to see the new yaml file. -1. Repeat as many cursorless voice commands as you want recorded. Each command +1. Repeat as many Cursorless voice commands as you want recorded. Each command you issue will generate a test case in the form of a new yaml file. 1. Issue `"cursorless record"` command again to stop recording diff --git a/packages/app-web-docs/src/docs/user/customization.md b/packages/app-web-docs/src/docs/user/customization.md index 0aa192f80c..b6877b64fd 100644 --- a/packages/app-web-docs/src/docs/user/customization.md +++ b/packages/app-web-docs/src/docs/user/customization.md @@ -13,10 +13,10 @@ The IDE settings can be accessed by saying `"cursorless settings"` with your IDE ## 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,7 +54,7 @@ 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. ## Toggling "hat" display diff --git a/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md b/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md index 1cf39fd674..31a867803d 100644 --- a/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md +++ b/packages/app-web-docs/src/docs/user/experimental/keyboard/README.md @@ -2,7 +2,7 @@ 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. ![Delete demo](images/keyboardDelete.gif) ![Bring demo](images/keyboardBring.gif) diff --git a/packages/app-web-docs/src/docs/user/installation.md b/packages/app-web-docs/src/docs/user/installation.md index 77bff0e512..7e8da1d81d 100644 --- a/packages/app-web-docs/src/docs/user/installation.md +++ b/packages/app-web-docs/src/docs/user/installation.md @@ -3,7 +3,7 @@ 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.)_ + _(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) 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 181f396c6c..bdb9d6736c 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 @@ -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 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 (🤫): ![cursorless sidebar](sidebar-sneak-preview.png) 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 (🤫): ![Cursorless sidebar](sidebar-sneak-preview.png) 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 🙄 💅) diff --git a/packages/app-web-docs/src/docs/user/targets.md b/packages/app-web-docs/src/docs/user/targets.md index d9df804bcc..b9ce2dfcda 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"` @@ -77,9 +77,9 @@ You can enable or disable shapes in your VS Code settings, by searching for [`cu 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"` @@ -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"`) From 4b2739ba33dbf15fe65e2a09184c8a3a3114e4b1 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 13:31:00 +0200 Subject: [PATCH 7/8] Fix broken links --- packages/app-web-docs/src/docs/user/release-notes/0.28.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 bdb9d6736c..5b440248e1 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 👒.![Big hats](big-hats.png) 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. From 3d6219d869c17d39d1b203f4be92f8b26d93c5f2 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 2 Sep 2026 13:42:11 +0200 Subject: [PATCH 8/8] Use relative links --- CHANGELOG.md | 2 +- .../app-web-docs/src/docs/contributing/test-case-recorder.md | 2 +- packages/app-web-docs/src/docs/user/release-notes/0.29.0.md | 2 +- packages/app-web-docs/src/docs/user/release-notes/1.0.0.md | 2 +- packages/app-web-docs/src/docs/user/release-notes/1.1.0.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 967c7b03bd..ac7392ffa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,7 @@ - 2024-08-12: Updated `drop`, `float`, and `puff` so they behave like `drink` and `pour` for non-line targets, including inserting spaces or delimiters as needed. ([#2646](https://github.com/cursorless-dev/cursorless/pull/2646)) - 2024-08-11: Updated `head` and `tail` so that inside a surrounding pair they expand only to the pair interior instead of the whole line. Use `"head line"` or `"tail line"` for the old behavior. ([#2652](https://github.com/cursorless-dev/cursorless/pull/2652)) - 2024-08-11: Updated `join token` so `"join two tokens air"` removes the whitespace between the tokens instead of joining their lines. ([#2651](https://github.com/cursorless-dev/cursorless/pull/2651)) -- 2024-06-14: Added `user.cursorless_create_destination` to the public API. See the [Talon-side API docs](https://www.cursorless.org/docs/user/customization#public-talon-actions) for details. ([#2402](https://github.com/cursorless-dev/cursorless/pull/2402)) +- 2024-06-14: Added `user.cursorless_create_destination` to the public API. See the [Talon-side API docs](https://www.cursorless.org/docs/user/public-talon-api#public-talon-actions) for details. ([#2402](https://github.com/cursorless-dev/cursorless/pull/2402)) - 2024-05-25: Added the public `user.cursorless_reformat` action to the Cursorless API. Example: `user.cursorless_reformat(cursorless_target, "ALL_CAPS")`. ([#2358](https://github.com/cursorless-dev/cursorless/pull/2358)) - 2024-04-21: Added support for using community snippets for wrapping and Cursorless insertion instead of snippets defined in Cursorless. ([#1998](https://github.com/cursorless-dev/cursorless/pull/1998)) - 2024-03-25: Added the `every` / spread ordinal and relative modifier, which turns ordinal and relative range modifiers into multiple target selections instead of a contiguous range. ([#2254](https://github.com/cursorless-dev/cursorless/pull/2254)) diff --git a/packages/app-web-docs/src/docs/contributing/test-case-recorder.md b/packages/app-web-docs/src/docs/contributing/test-case-recorder.md index 700a09c8eb..f6627b3133 100644 --- a/packages/app-web-docs/src/docs/contributing/test-case-recorder.md +++ b/packages/app-web-docs/src/docs/contributing/test-case-recorder.md @@ -12,7 +12,7 @@ command run, and the final state, all in the form of a yaml document. See 1. Run the extension locally by saying `"debug extension"` (as described [in the inital setup - documentation](https://www.cursorless.org/docs/contributing/#running--testing-extension-locally)). + documentation](./CONTRIBUTING.mdx#running--testing-extension-locally)). 1. Open an editor and fill it out with the content on which you'd like to operate. You can just use an untitled document, or open a real file; it doesn't matter. Please try to keep the file as small as possible, though. 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 ef7243e27c..bb524205e3 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 @@ -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. 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 9fff968cb2..82b92cc89d 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 9960c7f1d7..044cd89e48 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)) ![Scope visualizer](./sidebar-containment-icons.png)