diff --git a/data/fixtures/recorded/languages/markdown/changePair.yml b/data/fixtures/recorded/languages/markdown/changePair.yml new file mode 100644 index 0000000000..0fab148589 --- /dev/null +++ b/data/fixtures/recorded/languages/markdown/changePair.yml @@ -0,0 +1,26 @@ +languageId: markdown +command: + version: 7 + spokenForm: change pair + action: + name: clearAndSetSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: surroundingPair, delimiter: any} + usePrePhraseSnapshot: false +initialState: + documentContents: |- + ```python + a = 2 + ``` + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/common/src/types/command/PartialTargetDescriptor.types.ts b/packages/common/src/types/command/PartialTargetDescriptor.types.ts index e09d94d230..97de296c5d 100644 --- a/packages/common/src/types/command/PartialTargetDescriptor.types.ts +++ b/packages/common/src/types/command/PartialTargetDescriptor.types.ts @@ -118,6 +118,7 @@ export const simpleSurroundingPairNames = [ "parentheses", "singleQuotes", "squareBrackets", + "tripleBacktickQuotes", "tripleDoubleQuotes", "tripleSingleQuotes", ] as const; diff --git a/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/surroundingPairsDelimiters.ts b/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/surroundingPairsDelimiters.ts index 900e3a5034..51d7fe7c66 100644 --- a/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/surroundingPairsDelimiters.ts +++ b/packages/cursorless-engine/src/generateSpokenForm/defaultSpokenForms/surroundingPairsDelimiters.ts @@ -15,6 +15,7 @@ export const surroundingPairsDelimiters: Record< backtickQuotes: ["`", "`"], squareBrackets: ["[", "]"], singleQuotes: ["'", "'"], + tripleBacktickQuotes: ["```", "```"], tripleDoubleQuotes: ['"""', '"""'], tripleSingleQuotes: ["'''", "'''"], whitespace: [" ", " "], diff --git a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts index d82149625f..b91b10517f 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts @@ -22,13 +22,15 @@ type DelimiterMap = Record< | [IndividualDelimiterText, IndividualDelimiterText, Options] >; +// Note that the order here is important since we are creating a regex from the key order. +// For example triple quotes need to come before single quotes. const delimiterToText: DelimiterMap = Object.freeze({ angleBrackets: [ ["", "/>"], ], - backtickQuotes: ["`", "`"], curlyBrackets: [["{", "${"], "}"], + tripleBacktickQuotes: [[], []], tripleDoubleQuotes: [[], []], tripleSingleQuotes: [[], []], doubleQuotes: ['"', '"', { isSingleLine: true }], @@ -37,6 +39,7 @@ const delimiterToText: DelimiterMap = Object.freeze({ escapedSquareBrackets: ["\\[", "\\]"], escapedSingleQuotes: ["\\'", "\\'", { isSingleLine: true }], parentheses: [["(", "$("], ")"], + backtickQuotes: ["`", "`"], singleQuotes: ["'", "'", { isSingleLine: true }], squareBrackets: ["[", "]"], }); @@ -63,6 +66,10 @@ const delimiterToTextOverrides: Record> = { tripleDoubleQuotes: ['"""', '"""'], }, + markdown: { + tripleBacktickQuotes: ["```", "```"], + }, + ruby: { tripleDoubleQuotes: ["%Q(", ")"], }, @@ -84,6 +91,7 @@ export const complexDelimiterMap: Record< string: [ "tripleDoubleQuotes", "tripleSingleQuotes", + "tripleBacktickQuotes", "doubleQuotes", "singleQuotes", "backtickQuotes", diff --git a/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts b/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts index c9a2661173..96b224f5ff 100644 --- a/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts +++ b/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts @@ -30,6 +30,7 @@ export const defaultSpokenFormMapCore: DefaultSpokenFormMapDefinition = { singleQuotes: "twin", tripleDoubleQuotes: isPrivate("triple quad"), tripleSingleQuotes: isPrivate("triple twin"), + tripleBacktickQuotes: isPrivate("triple skis"), any: "pair", string: "string", whitespace: "void",