Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ tags: [enhancement, talon]
pullRequest: 1879
---

- Added `destination: CursorlessDestination` and `scope_type: Optional[Union[str, list[str]]]` arguments to the public Talon api action `user.cursorless_insert_snippet`. See the [talon-side api docs](https://www.cursorless.org/docs/user/customization/#public-talon-actions) for more.
- Added `destination: CursorlessDestination` and `scope_type: Optional[Union[str, list[str]]]` arguments to the public Talon api action `user.cursorless_insert_snippet`. See the [talon-side api docs](https://www.cursorless.org/docs/user/customization#public-talon-actions) for more.
2 changes: 1 addition & 1 deletion changelog/2023-09-addedInsertPythonAction.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ pullRequest: 1875
mergeDate: 2023-09-10
---

- Added `cursorless_insert` action to the public Talon api. This api enables you to define custom grammars for Cursorless text insertion. See the [talon-side api docs](https://www.cursorless.org/docs/user/customization/#public-talon-actions) for more
- Added `cursorless_insert` action to the public Talon api. This api enables you to define custom grammars for Cursorless text insertion. See the [talon-side api docs](https://www.cursorless.org/docs/user/customization#public-talon-actions) for more
2 changes: 1 addition & 1 deletion cursorless-talon/docs/customization.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Cursorless is now monorepo 🙌. This document now lives at https://www.cursorless.org/docs/user/customization/.
Cursorless is now monorepo 🙌. This document now lives at https://www.cursorless.org/docs/user/customization.
2 changes: 1 addition & 1 deletion cursorless-talon/src/marks/lines_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CustomizableTerm:


# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
# See https://www.cursorless.org/docs/user/customization
directions = [
CustomizableTerm("lineNumberModulo100", "modulo100", lambda number: number - 1),
CustomizableTerm("lineNumberRelativeUp", "relative", lambda number: -number),
Expand Down
2 changes: 1 addition & 1 deletion data/fixtures/recorded/customRegex/clearWhite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id \p{Zs}+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: "\" \""
selections:
Expand Down
2 changes: 1 addition & 1 deletion data/fixtures/recorded/ordinalScopes/clearFirstPaint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id [^\s"'`]+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: aaa-bbb ccc-ddd eee-fff ggg-hhh
selections:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id [^\s"'`]+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: aaa-bbb ccc-ddd eee-fff ggg-hhh
selections:
Expand Down
2 changes: 1 addition & 1 deletion data/fixtures/recorded/ordinalScopes/clearLastPaint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id [^\s"'`]+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: aaa-bbb ccc-ddd eee-fff ggg-hhh
selections:
Expand Down
2 changes: 1 addition & 1 deletion data/fixtures/recorded/ordinalScopes/clearLastPaint2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id [^\s"'`]+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: aaa-bbb ccc-ddd eee-fff ggg-hhh
selections:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id [\w/_.]+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: aa.bb/cc_dd123( )
selections:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ command:
usePrePhraseSnapshot: true
spokenFormError: >-
custom regex with id [\w/_.]+; please see
https://www.cursorless.org/docs/user/customization/ for more information
https://www.cursorless.org/docs/user/customization for more information
initialState:
documentContents: aa.bb/cc_dd123 aa.bb/cc_dd123( )
selections:
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const CURSORLESS_ORG_URL = "https://www.cursorless.org";
export const DOCS_URL = `${CURSORLESS_ORG_URL}/docs`;
export const GITHUB_URL = "https://github.com/cursorless-dev/cursorless";
4 changes: 3 additions & 1 deletion packages/common/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { DOCS_URL } from "./constants";

export class UnsupportedLanguageError extends Error {
constructor(languageId: string) {
super(
`Language '${languageId}' is not implemented yet; See https://www.cursorless.org/docs/contributing/adding-a-new-language/`,
`Language '${languageId}' is not implemented yet; See ${DOCS_URL}/contributing/adding-a-new-language`,
);
this.name = "UnsupportedLanguageError";
}
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./constants";
export * from "./cursorlessCommandIds";
export * from "./cursorlessSideBarIds";
export * from "./Debouncer";
Expand Down Expand Up @@ -92,8 +93,6 @@ export * from "./types/Token";
export * from "./types/TreeSitter";
export * from "./types/tutorial.types";
export * from "./util";
export * from "./util/camelCaseToAllDown";
export * from "./util/capitalize";
export * from "./util/clientSupportsFallback";
export * from "./util/CompositeKeyDefaultMap";
export * from "./util/CompositeKeyMap";
Expand All @@ -111,6 +110,7 @@ export * from "./util/selectionsEqual";
export * from "./util/serializedMarksToTokenHats";
export * from "./util/serializeScopeType";
export * from "./util/splitKey";
export * from "./util/stringUtils";
export * from "./util/toPlainObject";
export * from "./util/type";
export * from "./util/typeUtils";
Expand Down
19 changes: 19 additions & 0 deletions packages/common/src/types/Position.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ export class Position {
*/
public readonly character: number;

/**
* Create a position from a concise string representation.
* The string should be in the format `line:character`, where both line and character
* are zero-based.
*
* @param concise A concise string representation of a position.
* @return A position with the given line and character values.
*/
static fromConcise(concise: string): Position {
const parts = concise.split(":");
if (parts.length !== 2) {
throw new Error(
`Invalid concise position format: "${concise}". Expected "line:character" format.`,
);
}
const [line, character] = parts.map((s) => parseInt(s, 10));
return new Position(line, character);
}

/**
* @param line A zero-based line value.
* @param character A zero-based character value.
Expand Down
19 changes: 19 additions & 0 deletions packages/common/src/types/Range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ export class Range {
*/
readonly end: Position;

/**
* Create a new range from a concise string representation.
* The string should be in the format `start-end`, where both start and end
* are in the format `line:character`, where both line and character are zero-based.
*
* @param concise A concise string representation of a range.
* @return A range with the given start and end positions.
*/
static fromConcise(concise: string): Range {
const parts = concise.split("-");
if (parts.length !== 2) {
throw new Error(
`Invalid concise range format: "${concise}". Expected "start-end" format.`,
);
}
const [start, end] = parts.map((s) => Position.fromConcise(s));
return new Range(start, end);
}

/**
* Create a new range from two positions.
* The earlier of `p1` and `p2` will be used as the start position.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ export interface SimpleScopeType {
type: SimpleScopeTypeType;
}

export type ScopeTypeType = SimpleScopeTypeType | ScopeType["type"];

export interface CustomRegexScopeType {
type: "customRegex";
regex: string;
Expand Down
17 changes: 0 additions & 17 deletions packages/common/src/util/camelCaseToAllDown.ts

This file was deleted.

3 changes: 0 additions & 3 deletions packages/common/src/util/capitalize.ts

This file was deleted.

3 changes: 2 additions & 1 deletion packages/common/src/util/serializeScopeType.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type {
ScopeType,
ScopeTypeType,
SimpleScopeTypeType,
} from "../types/command/PartialTargetDescriptor.types";

export function serializeScopeType(
scopeType: SimpleScopeTypeType | ScopeType,
): string {
): ScopeTypeType {
if (typeof scopeType === "string") {
return scopeType;
}
Expand Down
44 changes: 44 additions & 0 deletions packages/common/src/util/stringUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Converts a camelCase string to a string with spaces between each word, and
* all words in lowercase.
*
* Example: `camelCaseToAllDown("fooBarBaz")` returns `"foo bar baz"`.
*
* @param input A camelCase string
* @returns The same string, but with spaces between each word, and all words
* in lowercase
*/
export function camelCaseToAllDown(input: string): string {
return input
.replace(/([A-Z])/g, " $1")
.split(" ")
.map((word) => word.toLowerCase())
.join(" ");
}

/**
* Capitalizes string
*
* @param input A string
* @returns The same string, but with the first character capitalized
*/
export function capitalize(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}

/**
* Converts a string to a URL-friendly hash ID.
*
* This function takes an input string, converts it to lowercase, replaces spaces
* with hyphens, and removes any characters that are not lowercase letters,
* digits, or hyphens. The result is a string that can be used as a
* URL-friendly hash ID.
*
* @param text The input string to be converted
* @returns A URL-friendly hash ID
*/
export function uriEncodeHashId(text: string): string {
return camelCaseToAllDown(text)
.replaceAll(" ", "-")
.replace(/[^a-z0-9-]/g, "");
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
SpokenFormMapKeyTypes,
SpokenFormType,
} from "@cursorless/common";
import { camelCaseToAllDown } from "@cursorless/common";
import { camelCaseToAllDown, DOCS_URL } from "@cursorless/common";
import type { SpokenFormMap } from "../spokenForms/SpokenFormMap";
import { NoSpokenFormError } from "./NoSpokenFormError";
import type { SpokenFormComponent } from "./SpokenFormComponent";
Expand Down Expand Up @@ -310,11 +310,9 @@ function constructSpokenForms(component: SpokenFormComponent): string[] {
helpInfo =
"this is a private spoken form currently only for internal experimentation";
} else if (component.spokenForms.requiresTalonUpdate) {
helpInfo =
"please update talon to the latest version (see https://www.cursorless.org/docs/user/updating/)";
helpInfo = `please update talon to the latest version (see ${DOCS_URL}/user/updating)`;
} else {
helpInfo =
"please see https://www.cursorless.org/docs/user/customization/ for more information";
helpInfo = `please see ${DOCS_URL}/user/customization for more information`;
}

throw new NoSpokenFormError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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](https://www.cursorless.org/docs/user/customization#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.

Expand Down
1 change: 1 addition & 0 deletions packages/cursorless-org/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
},
"dependencies": {
"@cursorless/cheatsheet": "workspace:*",
"@cursorless/common": "workspace:*",
"@mdx-js/loader": "3.1.0",
"@mdx-js/react": "3.1.0",
"@next/mdx": "15.3.3",
Expand Down
4 changes: 2 additions & 2 deletions packages/cursorless-org/src/components/BaseSocial.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CURSORLESS_ORG_URL } from "@cursorless/common";
import {
BASE_URL,
VIDEO_SHARE_THUMBNAIL_HEIGHT,
VIDEO_SHARE_THUMBNAIL_URL,
VIDEO_SHARE_THUMBNAIL_WIDTH,
Expand All @@ -24,7 +24,7 @@ export default function BaseSocial({
thumbnailWidth = VIDEO_SHARE_THUMBNAIL_WIDTH,
thumbnailHeight = VIDEO_SHARE_THUMBNAIL_HEIGHT,
}: Props) {
const url = `${BASE_URL}/${relativeUrl}`;
const url = `${CURSORLESS_ORG_URL}/${relativeUrl}`;

return (
<>
Expand Down
5 changes: 3 additions & 2 deletions packages/cursorless-org/src/components/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { CURSORLESS_ORG_URL } from "@cursorless/common";

export const DESCRIPTION = "Voice coding at the speed of thought";
export const TITLE = `Cursorless: ${DESCRIPTION}`;
export const BASE_URL = "https://cursorless.org/";
export const VIDEO_SHARE_THUMBNAIL_URL = `${BASE_URL}video-share-thumbnail.jpg`;
export const VIDEO_SHARE_THUMBNAIL_URL = `${CURSORLESS_ORG_URL}/video-share-thumbnail.jpg`;
export const VIDEO_SHARE_THUMBNAIL_WIDTH = "1280";
export const VIDEO_SHARE_THUMBNAIL_HEIGHT = "720";
export const YOUTUBE_SLUG = "5mAzHGM2M0k";
3 changes: 3 additions & 0 deletions packages/cursorless-org/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
"references": [
{
"path": "../cheatsheet"
},
{
"path": "../common"
}
],
"exclude": ["node_modules"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getCursorlessApi } from "@cursorless/vscode-common";
import type { ScopeTypeInfo } from "@cursorless/common";
import { sleep } from "@cursorless/common";
import { DOCS_URL, sleep } from "@cursorless/common";
import { getCursorlessApi } from "@cursorless/vscode-common";
import { stat, unlink, writeFile } from "fs/promises";
import * as sinon from "sinon";
import { assertCalledWithScopeInfo } from "./assertCalledWithScopeInfo";
import { stat, unlink, writeFile } from "fs/promises";

/**
* Tests that the scope provider correctly reports custom spoken forms
Expand Down Expand Up @@ -152,8 +152,7 @@ const squareMissing: ScopeTypeInfo = {
scopeType: { type: "surroundingPair", delimiter: "squareBrackets" },
spokenForm: {
isPrivate: false,
reason:
"paired delimiter with id squareBrackets; please update talon to the latest version (see https://www.cursorless.org/docs/user/updating/)",
reason: `paired delimiter with id squareBrackets; please update talon to the latest version (see ${DOCS_URL}/user/updating)`,
requiresTalonUpdate: true,
type: "error",
},
Expand Down Expand Up @@ -195,8 +194,7 @@ const lambdaCustom: ScopeTypeInfo = {
scopeType: { type: "anonymousFunction" },
spokenForm: {
isPrivate: false,
reason:
"simple scope type type with id anonymousFunction; please see https://www.cursorless.org/docs/user/customization/ for more information",
reason: `simple scope type type with id anonymousFunction; please see ${DOCS_URL}/user/customization for more information`,
requiresTalonUpdate: false,
type: "error",
},
Expand All @@ -218,8 +216,7 @@ const statementMissing: ScopeTypeInfo = {
scopeType: { type: "statement" },
spokenForm: {
isPrivate: false,
reason:
"simple scope type type with id statement; please update talon to the latest version (see https://www.cursorless.org/docs/user/updating/)",
reason: `simple scope type type with id statement; please update talon to the latest version (see ${DOCS_URL}/user/updating)`,
requiresTalonUpdate: true,
type: "error",
},
Expand Down
Loading
Loading