Skip to content

Commit 5f35c86

Browse files
committed
Initial Perl support and some tests
1 parent 3f81c5b commit 5f35c86

24 files changed

+666
-0
lines changed

packages/cursorless-engine/src/languages/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const supportedLanguageIds = [
1414
"jsonc",
1515
"latex",
1616
"markdown",
17+
"perl",
1718
"php",
1819
"python",
1920
"ruby",

packages/cursorless-engine/src/languages/getNodeMatcher.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import java from "./java";
1818
import { patternMatchers as json } from "./json";
1919
import latex from "./latex";
2020
import markdown from "./markdown";
21+
import { patternMatchers as perl } from "./perl";
2122
import php from "./php";
2223
import python from "./python";
2324
import { patternMatchers as ruby } from "./ruby";
@@ -68,6 +69,7 @@ const languageMatchers: Record<
6869
jsonc: json,
6970
latex,
7071
markdown,
72+
perl,
7173
php,
7274
python,
7375
ruby,

packages/cursorless-engine/src/languages/getTextFragmentExtractor.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { SupportedLanguageId } from "./constants";
77
import { getNodeMatcher } from "./getNodeMatcher";
88
import { stringTextFragmentExtractor as htmlStringTextFragmentExtractor } from "./html";
99
import { stringTextFragmentExtractor as jsonStringTextFragmentExtractor } from "./json";
10+
import { stringTextFragmentExtractor as perlStringTextFragmentExtractor } from "./perl";
1011
import { stringTextFragmentExtractor as phpStringTextFragmentExtractor } from "./php";
1112
import { stringTextFragmentExtractor as rubyStringTextFragmentExtractor } from "./ruby";
1213
import { stringTextFragmentExtractor as scssStringTextFragmentExtractor } from "./scss";
@@ -162,6 +163,10 @@ const textFragmentExtractors: Record<
162163
),
163164
latex: fullDocumentTextFragmentExtractor,
164165
markdown: fullDocumentTextFragmentExtractor,
166+
perl: constructDefaultTextFragmentExtractor(
167+
"perl",
168+
perlStringTextFragmentExtractor,
169+
),
165170
php: constructDefaultTextFragmentExtractor(
166171
"php",
167172
phpStringTextFragmentExtractor,
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import {
2+
createPatternMatchers,
3+
matcher,
4+
} from "../util/nodeMatchers";
5+
import { NodeMatcherAlternative, SelectionWithEditor } from "../typings/Types";
6+
import { SimpleScopeTypeType } from "@cursorless/common";
7+
import { SyntaxNode } from "web-tree-sitter";
8+
import { getNodeRange, unwrapSelectionExtractor } from "../util/nodeSelectors";
9+
import { patternFinder } from "../util/nodeFinders";
10+
11+
// Generated by the following command:
12+
// curl https://raw.githubusercontent.com/ganezdragon/tree-sitter-perl/ee1001210af5f32ba14d2ced834636548e1b6485/src/node-types.json \
13+
// | jq '[.[] | select(.type|match("_statement")) | .type ]'
14+
const STATEMENT_TYPES = [
15+
"ellipsis_statement",
16+
"for_simple_statement",
17+
"for_statement_1",
18+
"for_statement_2",
19+
"foreach_simple_statement",
20+
"foreach_statement",
21+
"if_simple_statement",
22+
"if_statement",
23+
"loop_control_statement",
24+
"loop_control_statement",
25+
"named_block_statement",
26+
"package_statement",
27+
"pod_statement",
28+
"require_statement",
29+
"single_line_statement",
30+
"unless_simple_statement",
31+
"unless_statement",
32+
"until_simple_statement",
33+
"until_statement",
34+
"use_constant_statement",
35+
"use_no_feature_statement",
36+
"use_no_if_statement",
37+
"use_no_statement",
38+
"use_no_subs_statement",
39+
"use_parent_statement",
40+
"when_simple_statement",
41+
"while_simple_statement",
42+
"while_statement",
43+
];
44+
45+
const EXPRESSION_TYPES = [
46+
"array",
47+
"assignment",
48+
"begin",
49+
// MANY MORE TODO ...
50+
];
51+
52+
const EXPRESSION_STATEMENT_PARENT_TYPES = [
53+
"begin",
54+
"block",
55+
"do",
56+
"do_block",
57+
"else",
58+
"lambda",
59+
"method",
60+
"then",
61+
];
62+
63+
const assignmentOperators = [
64+
"=",
65+
"+=",
66+
"-=",
67+
"*=",
68+
"/=",
69+
"||=",
70+
"//=",
71+
"|=",
72+
"&&=",
73+
"&=",
74+
"%=",
75+
">>=",
76+
"<<=",
77+
"^=",
78+
];
79+
80+
const mapKeyValueSeparators = [",", "=>"];
81+
82+
const nodeMatchers: Partial<
83+
Record<SimpleScopeTypeType, NodeMatcherAlternative>
84+
> = {
85+
map: "hash",
86+
list: "array",
87+
condition: matcher(
88+
patternFinder("while_statement[condition]"),
89+
unwrapSelectionExtractor,
90+
),
91+
string: [
92+
"string_single_quoted",
93+
"string_double_quoted",
94+
"string_q_quoted",
95+
"string_qq_quoted",
96+
],
97+
ifStatement: "if_statement",
98+
functionCall: [
99+
"call_expression",
100+
"call_expression_with_just_name",
101+
"method_invocation",
102+
],
103+
comment: "comments",
104+
namedFunction: ["function_definition"],
105+
anonymousFunction: "anonymous_function",
106+
regularExpression: ["regex_pattern", "regex_pattern_qr"],
107+
collectionKey: "*[key]", // TODO: child of "value: hash?"
108+
collectionItem: "*[value]", // TODO: child of "value: hash?"
109+
argumentOrParameter: [
110+
"empty_parenthesized_argument",
111+
"parenthesized_argument",
112+
"argument",
113+
],
114+
className: "package_name",
115+
};
116+
117+
export const patternMatchers = createPatternMatchers(nodeMatchers);
118+
119+
export function stringTextFragmentExtractor(
120+
node: SyntaxNode,
121+
_selection: SelectionWithEditor,
122+
) {
123+
// heredoc_content does not seem to supported by tree-sitter-perl,
124+
// leaving it anyway since it won't hurt
125+
if (node.type === "string_content" || node.type === "heredoc_content") {
126+
return getNodeRange(node);
127+
}
128+
129+
return null;
130+
}
131+
132+
// EOF
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: perl
2+
command:
3+
version: 4
4+
spokenForm: change arg
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: argumentOrParameter}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: some_funky_func( "and", "three", "args" )
14+
selections:
15+
- anchor: {line: 0, character: 36}
16+
active: {line: 0, character: 36}
17+
marks: {}
18+
finalState:
19+
documentContents: some_funky_func( )
20+
selections:
21+
- anchor: {line: 0, character: 17}
22+
active: {line: 0, character: 17}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
languageId: perl
2+
command:
3+
version: 4
4+
spokenForm: change call
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: functionCall}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: |-
14+
my $var = 1;
15+
$var = func();
16+
$var = 2;
17+
selections:
18+
- anchor: {line: 1, character: 12}
19+
active: {line: 1, character: 12}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
my $var = 1;
24+
$var = ;
25+
$var = 2;
26+
selections:
27+
- anchor: {line: 1, character: 7}
28+
active: {line: 1, character: 7}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
languageId: perl
2+
command:
3+
version: 4
4+
spokenForm: change call
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: functionCall}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: |-
14+
my $var = 1;
15+
$var = func_with_params( $var );
16+
$var = 2;
17+
selections:
18+
- anchor: {line: 1, character: 27}
19+
active: {line: 1, character: 27}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
my $var = 1;
24+
$var = ;
25+
$var = 2;
26+
selections:
27+
- anchor: {line: 1, character: 7}
28+
active: {line: 1, character: 7}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
languageId: perl
2+
command:
3+
version: 4
4+
spokenForm: change call
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: functionCall}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: |-
14+
my $var = 1;
15+
$var = $object->method( );
16+
$var = 2;
17+
selections:
18+
- anchor: {line: 1, character: 24}
19+
active: {line: 1, character: 24}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
my $var = 1;
24+
$var = ;
25+
$var = 2;
26+
selections:
27+
- anchor: {line: 1, character: 7}
28+
active: {line: 1, character: 7}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
languageId: perl
2+
command:
3+
version: 4
4+
spokenForm: change call
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: functionCall}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: |-
14+
my $var = 1;
15+
$var = Other::Package::func();
16+
$var = 2;
17+
selections:
18+
- anchor: {line: 1, character: 24}
19+
active: {line: 1, character: 24}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
my $var = 1;
24+
$var = ;
25+
$var = 2;
26+
selections:
27+
- anchor: {line: 1, character: 7}
28+
active: {line: 1, character: 7}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: perl
2+
command:
3+
version: 4
4+
spokenForm: change class name
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: className}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: $var = Some::Package::func()
14+
selections:
15+
- anchor: {line: 0, character: 17}
16+
active: {line: 0, character: 17}
17+
marks: {}
18+
finalState:
19+
documentContents: $var = ::func()
20+
selections:
21+
- anchor: {line: 0, character: 7}
22+
active: {line: 0, character: 7}

0 commit comments

Comments
 (0)