Skip to content

Commit c9a7f97

Browse files
author
fidgetingbits
committed
Fix '' strings and add related tests
1 parent ee4052d commit c9a7f97

File tree

9 files changed

+170
-5
lines changed

9 files changed

+170
-5
lines changed

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ export function findSurroundingPairParseTreeBased(
6666
) {
6767
const document: TextDocument = editor.document;
6868

69-
const individualDelimiters = getIndividualDelimiters(delimiters);
69+
const individualDelimiters = getIndividualDelimiters(
70+
document.languageId,
71+
delimiters,
72+
);
7073

7174
const delimiterTextToDelimiterInfoMap = Object.fromEntries(
7275
individualDelimiters.map((individualDelimiter) => [

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairTextBased.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ export function findSurroundingPairTextBased(
7474
const document: TextDocument = editor.document;
7575
const fullRange = allowableRange ?? document.range;
7676

77-
const individualDelimiters = getIndividualDelimiters(delimiters);
77+
const individualDelimiters = getIndividualDelimiters(
78+
editor.document.languageId,
79+
delimiters,
80+
);
7881

7982
const delimiterTextToDelimiterInfoMap = Object.fromEntries(
8083
individualDelimiters.map((individualDelimiter) => [

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/delimiterMaps.ts renamed to packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/getDelimiterMaps.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55

66
type IndividualDelimiterText = string | string[];
77

8-
export const delimiterToText: Record<
8+
const delimiterToText: Record<
99
SimpleSurroundingPairName,
1010
[IndividualDelimiterText, IndividualDelimiterText]
1111
> = {
@@ -25,6 +25,26 @@ export const delimiterToText: Record<
2525
squareBrackets: ["[", "]"],
2626
};
2727

28+
const delimiterToTextNix: Record<
29+
SimpleSurroundingPairName,
30+
[IndividualDelimiterText, IndividualDelimiterText]
31+
> = {
32+
angleBrackets: [
33+
["</", "<"],
34+
[">", "/>"],
35+
],
36+
backtickQuotes: ["`", "`"],
37+
curlyBrackets: [["{", "${"], "}"],
38+
doubleQuotes: ['"', '"'],
39+
escapedDoubleQuotes: ['\\"', '\\"'],
40+
escapedParentheses: ["\\(", "\\)"],
41+
escapedSquareBrackets: ["\\[", "\\]"],
42+
escapedSingleQuotes: ["\\'", "\\'"],
43+
parentheses: [["(", "$("], ")"],
44+
singleQuotes: ["''", "''"],
45+
squareBrackets: ["[", "]"],
46+
};
47+
2848
export const leftToRightMap: Record<string, string> = Object.fromEntries(
2949
Object.values(delimiterToText),
3050
);
@@ -46,3 +66,22 @@ export const complexDelimiterMap: Record<
4666
"angleBrackets",
4767
],
4868
};
69+
70+
/**
71+
* Given a language id, returns a list of all possible delimiters
72+
* for that language.
73+
* @param languageId The language id
74+
* @returns A list of all possible delimiters for that language
75+
*/
76+
export function getSimpleDelimiterMap(
77+
languageId: string,
78+
): Record<
79+
SimpleSurroundingPairName,
80+
[IndividualDelimiterText, IndividualDelimiterText]
81+
> {
82+
if (languageId == "nix") {
83+
return delimiterToTextNix;
84+
} else {
85+
return delimiterToText;
86+
}
87+
}

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/getIndividualDelimiters.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SimpleSurroundingPairName } from "@cursorless/common";
22
import { IndividualDelimiter } from "./types";
3-
import { delimiterToText } from "./delimiterMaps";
3+
import { getSimpleDelimiterMap } from "./getDelimiterMaps";
44
import { concat, uniq } from "lodash";
55
import { isString } from "../../../util/type";
66

@@ -13,8 +13,10 @@ import { isString } from "../../../util/type";
1313
* @returns A list of information about all possible left / right delimiter instances
1414
*/
1515
export function getIndividualDelimiters(
16+
languageId: string,
1617
delimiters: SimpleSurroundingPairName[],
1718
): IndividualDelimiter[] {
19+
const delimiterToText = getSimpleDelimiterMap(languageId);
1820
return delimiters.flatMap((delimiter) => {
1921
const [leftDelimiter, rightDelimiter] = delimiterToText[delimiter];
2022

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import getTextFragmentExtractor from "../../../languages/getTextFragmentExtracto
99
import { Target } from "../../../typings/target.types";
1010
import { SurroundingPairTarget } from "../../targets";
1111
import { getContainingScopeTarget } from "../getContainingScopeTarget";
12-
import { complexDelimiterMap } from "./delimiterMaps";
12+
import { complexDelimiterMap } from "./getDelimiterMaps";
1313
import { SurroundingPairInfo } from "./extractSelectionFromSurroundingPairOffsets";
1414
import { findSurroundingPairParseTreeBased } from "./findSurroundingPairParseTreeBased";
1515
import { findSurroundingPairTextBased } from "./findSurroundingPairTextBased";
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
languageId: nix
2+
command:
3+
version: 6
4+
spokenForm: change round
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: surroundingPair, delimiter: parentheses}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |
15+
{
16+
b = ''two single (quote) string'';
17+
}
18+
selections:
19+
- anchor: {line: 1, character: 22}
20+
active: {line: 1, character: 22}
21+
marks: {}
22+
finalState:
23+
documentContents: |
24+
{
25+
b = ''two single string'';
26+
}
27+
selections:
28+
- anchor: {line: 1, character: 19}
29+
active: {line: 1, character: 19}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
languageId: nix
2+
command:
3+
version: 6
4+
spokenForm: change string
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: surroundingPair, delimiter: string}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |
15+
{
16+
a = "double quoted string";
17+
}
18+
selections:
19+
- anchor: {line: 1, character: 25}
20+
active: {line: 1, character: 25}
21+
marks: {}
22+
finalState:
23+
documentContents: |
24+
{
25+
a = ;
26+
}
27+
selections:
28+
- anchor: {line: 1, character: 6}
29+
active: {line: 1, character: 6}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
languageId: nix
2+
command:
3+
version: 6
4+
spokenForm: change string
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: surroundingPair, delimiter: string}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |
15+
{
16+
b = ''two single (quote) string'';
17+
}
18+
selections:
19+
- anchor: {line: 1, character: 16}
20+
active: {line: 1, character: 16}
21+
marks: {}
22+
finalState:
23+
documentContents: |
24+
{
25+
b = ;
26+
}
27+
selections:
28+
- anchor: {line: 1, character: 6}
29+
active: {line: 1, character: 6}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
languageId: nix
2+
command:
3+
version: 6
4+
spokenForm: change string
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: surroundingPair, delimiter: string}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |
15+
{
16+
c = ''
17+
multi-line
18+
quote string'';
19+
}
20+
selections:
21+
- anchor: {line: 3, character: 4}
22+
active: {line: 3, character: 4}
23+
marks: {}
24+
finalState:
25+
documentContents: |
26+
{
27+
c = ;
28+
}
29+
selections:
30+
- anchor: {line: 1, character: 6}
31+
active: {line: 1, character: 6}

0 commit comments

Comments
 (0)