forked from mrob95/mathfly-talon
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcursorless_vscode.py
124 lines (93 loc) · 3.54 KB
/
cursorless_vscode.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from typing import Callable, Optional
from talon import Module, Context, actions, app
mod = Module()
ctx = Context()
ctx.matches = r"""
app: vscode
tag: user.cursorless
title: /\.tex/
"""
mod.list("math_big_operator", "Big operators such as sum, product, integral, etc.")
ctx.lists["user.math_big_operator"] = {
"summation": "sum",
"product": "prod",
"integral": "int",
"double integral": "iint",
"triple integral": "iiint",
}
@mod.capture(rule="[short | nude] {user.math_big_operator}")
def big_operator_snippet(m) -> str:
name = m.math_big_operator
if m[0] == "short":
return f"\\{name}_{{$lower}} $body"
if m[0] == "nude":
return f"\\{name} $body"
return f"\\{name}_{{$lower}}^{{$upper}} $body"
def get_environment_snippet(name: str):
indentation = "" if name == "document" else "\t"
return f"\\begin{{{name}}}\n{indentation}$body\n\\end{{{name}}}"
@mod.action_class
class Actions:
def latex_wrap_with_environment(name: str, target: dict):
"""Insert a latex environment"""
actions.user.cursorless_wrap_with_snippet(
get_environment_snippet(name), target, "body"
)
def fraction_snippet() -> str:
"""Get the fraction snippet"""
return "\\frac{$numerator}{$denominator}"
def matrix_snippet(
rows: int, columns: int, bracket_type: str, matrix_type: str
) -> str:
"""Get the identity matrix snippet"""
return get_matrix_snippet(
rows, columns, bracket_type, cell_content_getter[matrix_type]
)
@ctx.action_class("user")
class Actions:
def latex_insert_environment(name: str):
actions.user.cursorless_insert_snippet(get_environment_snippet(name))
def maths_matrix(rows: int, columns: int, bracket_type: str, matrix_type: str):
matrix_snippet = actions.user.matrix_snippet(
rows, columns, bracket_type, matrix_type
)
actions.user.cursorless_insert_snippet(matrix_snippet)
def maths_fraction():
actions.user.cursorless_insert_snippet(actions.user.fraction_snippet())
def identity_matrix_get_cell_content(row_idx: int, column_idx: int) -> str:
return "1" if row_idx == column_idx else "0"
def scalar_matrix_get_cell_content(row_idx: int, column_idx: int) -> str:
return "$constant" if row_idx == column_idx else "0"
def diagonal_matrix_get_cell_content(row_idx: int, column_idx: int) -> str:
return f"$cell_{row_idx}_{column_idx}" if row_idx == column_idx else "0"
def default_get_cell_content(row_idx: int, column_idx: int) -> str:
return f"$cell_{row_idx}_{column_idx}"
cell_content_getter = {
"identity": identity_matrix_get_cell_content,
"scalar": scalar_matrix_get_cell_content,
"diagonal": diagonal_matrix_get_cell_content,
"full": default_get_cell_content,
}
def get_matrix_snippet(
rows: int,
columns: int,
bracket_type: str,
get_cell_content: Callable[[int, int], str],
):
matrix_snippet = f"\\begin{{{bracket_type}}}\n"
# NB: We need 8 backslashes here because we want 2, and we need to escape in
# Python, and also for our snippet parser
matrix_snippet += " \\\\\\\\\n".join(
[get_matrix_row(row_idx, columns, get_cell_content) for row_idx in range(rows)]
)
matrix_snippet += f"\n\\end{{{bracket_type}}}"
return matrix_snippet
def get_matrix_row(
row_idx: int,
columns: int,
get_cell_content: Callable[[int, int], str],
):
content = " & ".join(
[get_cell_content(row_idx, column_idx) for column_idx in range(columns)]
)
return f"\t{content}"