Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
phillco committed Aug 28, 2022
2 parents 9c86595 + 7823b4b commit 3c7080e
Show file tree
Hide file tree
Showing 45 changed files with 1,237 additions and 7 deletions.
8 changes: 8 additions & 0 deletions cursorless-talon/src/modifiers/containing_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@
"short paint": "boundedNonWhitespaceSequence",
"link": "url",
"token": "token",
# LaTeX
"part": "part",
"chapter": "chapter",
"subsection": "subSection",
"subsubsection": "subSubSection",
"paragraph": "namedParagraph",
"subparagraph": "subParagraph",
"environment": "environment",
}


Expand Down
1 change: 1 addition & 0 deletions src/languages/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const supportedLanguageIds = [
"javascriptreact",
"json",
"jsonc",
"latex",
"markdown",
"php",
"python",
Expand Down
2 changes: 2 additions & 0 deletions src/languages/getNodeMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import markdown from "./markdown";
import scala from "./scala";
import { patternMatchers as scss } from "./scss";
import go from "./go";
import latex from "./latex";
import { patternMatchers as ruby } from "./ruby";
import rust from "./rust";
import { UnsupportedLanguageError } from "../errors";
Expand Down Expand Up @@ -65,6 +66,7 @@ const languageMatchers: Record<
javascriptreact: typescript,
json,
jsonc: json,
latex,
markdown,
php,
python,
Expand Down
1 change: 1 addition & 0 deletions src/languages/getTextFragmentExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ const textFragmentExtractors: Record<
"json",
jsonStringTextFragmentExtractor
),
latex: fullDocumentTextFragmentExtractor,
markdown: fullDocumentTextFragmentExtractor,
php: constructDefaultTextFragmentExtractor(
"php",
Expand Down
196 changes: 196 additions & 0 deletions src/languages/latex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { Range, Selection, TextEditor } from "vscode";
import { SyntaxNode } from "web-tree-sitter";
import { SimpleScopeTypeType } from "../typings/targetDescriptor.types";
import { NodeMatcherAlternative, SelectionWithContext } from "../typings/Types";
import { patternFinder } from "../util/nodeFinders";
import {
ancestorChainNodeMatcher,
cascadingMatcher,
createPatternMatchers,
matcher,
} from "../util/nodeMatchers";

const COMMANDS = [
"command",
"displayed_equation",
"inline_formula",
"math_set",
"block_comment",
"package_include",
"class_include",
"latex_include",
"biblatex_include",
"bibtex_include",
"graphics_include",
"svg_include",
"inkscape_include",
"verbatim_include",
"import_include",
"caption",
"citation",
"label_definition",
"label_reference",
"label_reference_range",
"label_number",
"new_command_definition",
"old_command_definition",
"let_command_definition",
"environment_definition",
"glossary_entry_definition",
"glossary_entry_reference",
"acronym_definition",
"acronym_reference",
"theorem_definition",
"color_definition",
"color_set_definition",
"color_reference",
"tikz_library_import",
];

const GROUPS = [
"curly_group",
"curly_group_text",
"curly_group_text_list",
"curly_group_path",
"curly_group_path_list",
"curly_group_command_name",
"curly_group_key_value",
"curly_group_glob_pattern",
"curly_group_impl",
"brack_group",
"brack_group_text",
"brack_group_argc",
"brack_group_key_value",
"mixed_group",
];

const SECTIONING = [
"subparagraph",
"paragraph",
"subsubsection",
"subsection",
"section",
"chapter",
"part",
];

const ENVIRONMENTS = [
"generic_environment",
"comment_environment",
"verbatim_environment",
"listing_environment",
"minted_environment",
"pycode_environment",
];

const sectioningText = SECTIONING.map((s) => `${s}[text]`);
const sectioningCommand = SECTIONING.map((s) => `${s}[command]`);

function unwrapGroupParens(
editor: TextEditor,
node: SyntaxNode
): SelectionWithContext {
return {
selection: new Selection(
editor.document.positionAt(node.startIndex + 1),
editor.document.positionAt(node.endIndex - 1)
),
context: {
removalRange: new Selection(
editor.document.positionAt(node.startIndex),
editor.document.positionAt(node.endIndex)
),
},
};
}

function extendToNamedSiblingIfExists(
editor: TextEditor,
node: SyntaxNode
): SelectionWithContext {
const startIndex = node.startIndex;
let endIndex = node.endIndex;
const sibling = node.nextNamedSibling;

if (sibling != null && sibling.isNamed()) {
endIndex = sibling.endIndex;
}

return {
selection: new Selection(
editor.document.positionAt(startIndex),
editor.document.positionAt(endIndex)
),
context: {},
};
}

function extractItemContent(
editor: TextEditor,
node: SyntaxNode
): SelectionWithContext {
let contentStartIndex = node.startIndex;

const label = node.childForFieldName("label");
if (label == null) {
const command = node.childForFieldName("command");
if (command != null) {
contentStartIndex = command.endIndex + 1;
}
} else {
contentStartIndex = label.endIndex + 1;
}

return {
selection: new Selection(
editor.document.positionAt(contentStartIndex),
editor.document.positionAt(node.endIndex)
),
context: {
leadingDelimiterRange: new Range(
editor.document.positionAt(node.startIndex),
editor.document.positionAt(contentStartIndex - 1)
),
},
};
}

const nodeMatchers: Partial<
Record<SimpleScopeTypeType, NodeMatcherAlternative>
> = {
argumentOrParameter: cascadingMatcher(
ancestorChainNodeMatcher(
[patternFinder(...COMMANDS), patternFinder(...GROUPS)],
1,
unwrapGroupParens
),
matcher(
patternFinder("begin[name]", "end[name]", ...sectioningText),
unwrapGroupParens
)
),

functionCall: cascadingMatcher(
matcher(patternFinder(...COMMANDS, "begin", "end")),
matcher(patternFinder(...sectioningCommand), extendToNamedSiblingIfExists)
),

name: matcher(patternFinder(...sectioningText), unwrapGroupParens),
functionCallee: "command_name",

collectionItem: matcher(patternFinder("enum_item"), extractItemContent),

comment: ["block_comment", "line_comment"],

part: "part",
chapter: "chapter",
section: "section",
subSection: "subsection",
subSubSection: "subsubsection",
namedParagraph: "paragraph",
subParagraph: "subparagraph",

environment: ENVIRONMENTS,
};

export default createPatternMatchers(nodeMatchers);
25 changes: 19 additions & 6 deletions src/languages/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,21 @@ export const getTypeNode = (node: SyntaxNode) =>
const dictionaryTypes = ["dictionary", "dictionary_comprehension"];
const listTypes = ["list", "list_comprehension", "set"];

function importNodeFinder(): NodeFinder {
const finder = argumentNodeFinder("import_from_statement");
function itemNodeFinder(
parentType: string,
childType: string,
excludeFirstChild: boolean = false
): NodeFinder {
const finder = argumentNodeFinder(parentType);
return (node: SyntaxNode, selection?: Selection) => {
const childNode = finder(node, selection);
if (
childNode?.type === "dotted_name" &&
childNode.id !== childNode.parent?.firstNamedChild?.id
childNode?.type === childType &&
(!excludeFirstChild ||
childNode.id !== childNode.parent?.firstNamedChild?.id)
) {
return childNode;
}

return null;
};
}
Expand All @@ -75,7 +79,16 @@ const nodeMatchers: Partial<
list: listTypes,
statement: STATEMENT_TYPES,
string: "string",
collectionItem: matcher(importNodeFinder(), argumentSelectionExtractor()),
collectionItem: cascadingMatcher(
matcher(
itemNodeFinder("import_from_statement", "dotted_name", true),
argumentSelectionExtractor()
),
matcher(
itemNodeFinder("global_statement", "identifier"),
argumentSelectionExtractor()
)
),
collectionKey: trailingMatcher(["pair[key]"], [":"]),
ifStatement: "if_statement",
anonymousFunction: "lambda?.lambda",
Expand Down
27 changes: 27 additions & 0 deletions src/test/suite/fixtures/recorded/languages/latex/changeArg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
languageId: latex
command:
version: 1
spokenForm: change arg
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: |
\begin{itemize}
\end{itemize}
selections:
- anchor: {line: 0, character: 11}
active: {line: 0, character: 11}
marks: {}
finalState:
documentContents: |
\begin{}
\end{itemize}
selections:
- anchor: {line: 0, character: 7}
active: {line: 0, character: 7}
thatMark:
- anchor: {line: 0, character: 7}
active: {line: 0, character: 7}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}, isImplicit: false}]
25 changes: 25 additions & 0 deletions src/test/suite/fixtures/recorded/languages/latex/changeArg2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
languageId: latex
command:
version: 1
spokenForm: change arg
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: |
\section{some section}
selections:
- anchor: {line: 0, character: 16}
active: {line: 0, character: 16}
marks: {}
finalState:
documentContents: |
\section{}
selections:
- anchor: {line: 0, character: 9}
active: {line: 0, character: 9}
thatMark:
- anchor: {line: 0, character: 9}
active: {line: 0, character: 9}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}, isImplicit: false}]
25 changes: 25 additions & 0 deletions src/test/suite/fixtures/recorded/languages/latex/changeArg3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
languageId: latex
command:
version: 1
spokenForm: change arg
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: |
\href{https://some.url}{some text}
selections:
- anchor: {line: 0, character: 14}
active: {line: 0, character: 14}
marks: {}
finalState:
documentContents: |
\href{}{some text}
selections:
- anchor: {line: 0, character: 6}
active: {line: 0, character: 6}
thatMark:
- anchor: {line: 0, character: 6}
active: {line: 0, character: 6}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}, isImplicit: false}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/latex/changeArg4.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: latex
command:
version: 1
spokenForm: change arg
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: \usepackage[utf8]{inputenc}
selections:
- anchor: {line: 0, character: 14}
active: {line: 0, character: 14}
marks: {}
finalState:
documentContents: \usepackage[]{inputenc}
selections:
- anchor: {line: 0, character: 12}
active: {line: 0, character: 12}
thatMark:
- anchor: {line: 0, character: 12}
active: {line: 0, character: 12}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}, isImplicit: false}]
Loading

0 comments on commit 3c7080e

Please sign in to comment.