Skip to content

Commit 423ef1b

Browse files
committed
Update style for complex types
1 parent deca679 commit 423ef1b

1 file changed

Lines changed: 101 additions & 30 deletions

File tree

src/build.py

Lines changed: 101 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,94 @@
44
import json
55
import re
66
import yaml
7-
from yaml.representer import SafeRepresenter
87

9-
CompletionItem: dict[str, str | list[str]]
10-
CompletionMetadata: dict[str, str | list[str]]
11-
CompletionSet: dict[str, CompletionItem | CompletionMetadata]
12-
CryptoSet: dict[str, str | list[str]]
8+
from typing import Callable, Literal, NotRequired, TypedDict
9+
from yaml.representer import SafeRepresenter
1310

1411
SYNTAX_STEM = 'Packages/SSH Config/syntax/'
1512
TEST_STEM = '../test/generated/syntax_test_'
1613
SUPPORT_STEM = '../support/generated/'
1714

1815

16+
class CompletionMetadata(TypedDict):
17+
scope: str
18+
kind: list[str]
19+
annotation: str
20+
21+
22+
class CompletionItem(TypedDict):
23+
kind: list[str] | Literal['snippet']
24+
annotation: str
25+
trigger: str
26+
contents: str
27+
details: NotRequired[str]
28+
29+
30+
class CompletionFillins(TypedDict):
31+
details: str
32+
values: str | list[str]
33+
34+
35+
class CompletionSet(TypedDict):
36+
completions: CompletionMetadata
37+
items: dict[str,CompletionFillins]
38+
39+
40+
class CompletionYaml(TypedDict):
41+
scope: str
42+
completions: list[CompletionItem]
43+
44+
45+
class CryptoFillins(TypedDict):
46+
scope: str
47+
items: list[str]
48+
49+
50+
class CryptoSet(TypedDict):
51+
completions: CompletionMetadata
52+
active: CryptoFillins
53+
deprecated: CryptoFillins
54+
55+
56+
class SyntaxContext(TypedDict):
57+
include: NotRequired[str]
58+
match: NotRequired[str]
59+
scope: NotRequired[str]
60+
captures: NotRequired[dict[int,str]]
61+
pop: NotRequired[bool | int]
62+
push: NotRequired[str | list[str] | list[SyntaxContext]]
63+
64+
65+
class SyntaxYaml(TypedDict):
66+
scope: str
67+
name: NotRequired[str]
68+
hidden: NotRequired[bool]
69+
file_extensions: NotRequired[list[str]]
70+
hidden_file_extensions: NotRequired[list[str]]
71+
extends: NotRequired[str | list[str]]
72+
version: NotRequired[int]
73+
variables: NotRequired[dict[str, str]]
74+
contexts: dict[str, list[SyntaxContext]]
75+
76+
1977
def build_ssh_options():
2078
with open('options.yaml', 'r') as stream:
21-
ssh_options_input: dict[str, CompletionSet] = yaml.load(
79+
ssh_options_input: dict[str, CompletionSet] = yaml.load( # pyright: ignore[reportAssignmentType]
2280
stream, Loader=yaml.BaseLoader)
2381

2482
for domain, settings in ssh_options_input.items():
25-
completions = {
83+
completions_yaml: CompletionYaml = {
2684
'scope': settings['completions']['scope'],
2785
'completions': [],
2886
}
87+
completions: list[CompletionItem] = []
2988
snippet_spacer: str = settings['completions'].get('snippet_spacer', ' ')
3089
default_kind: list[str] = settings['completions']['kind']
3190
annotation: str = settings['completions']['annotation']
3291

3392
for keyword, options in settings['items'].items():
3493
details: str = options.get('details', '') if options else ''
35-
_ = completions['completions'].append({
94+
_ = completions.append({
3695
'trigger': keyword,
3796
'contents': keyword,
3897
'annotation': annotation,
@@ -47,21 +106,23 @@ def build_ssh_options():
47106
value_string = values
48107
else:
49108
value_string = f'${{0:{{ {" | ".join(values)} \\}}}}'
50-
_ = completions['completions'].append({
109+
_ = completions.append({
51110
'trigger': keyword.lower(),
52111
'contents': f'{keyword}{snippet_spacer}{value_string}',
53112
'annotation': annotation,
54113
'kind': 'snippet',
55114
'details': details,
56115
})
57116

117+
completions_yaml['completions'] = completions
118+
58119
with open(f'{SUPPORT_STEM}{domain}.sublime-completions', 'w') as f:
59-
json.dump(completions, f, indent=4)
120+
json.dump(completions_yaml, f, indent=4)
60121

61122

62123
def build_sshd_index_test():
63124
with open('options.yaml', 'r') as stream:
64-
ssh_options_input: dict[str, CompletionSet] = yaml.load(
125+
ssh_options_input: dict[str, CompletionSet] = yaml.load( # pyright: ignore[reportAssignmentType]
65126
stream, Loader=yaml.BaseLoader)
66127

67128
test_content = [
@@ -91,8 +152,9 @@ def build_crypto():
91152
# Set up YAML dump style
92153
class literal_str(str): pass
93154

94-
def change_style(style, representer):
95-
def new_representer(dumper, data):
155+
def change_style(style: Literal['"', '|', '>'],
156+
representer: Callable['...', yaml.ScalarNode]):
157+
def new_representer(dumper: yaml.Dumper, data: str) -> yaml.ScalarNode:
96158
scalar = representer(dumper, data)
97159
scalar.style = style
98160
return scalar
@@ -103,12 +165,13 @@ def new_representer(dumper, data):
103165

104166
# Process
105167
with open('crypto.yaml', 'r') as stream:
106-
crypto_input = yaml.load(stream, Loader=yaml.BaseLoader)
168+
crypto_input: dict[str, CryptoSet] = yaml.load( # pyright: ignore[reportAssignmentType]
169+
stream, Loader=yaml.BaseLoader)
107170

108-
test_content = [
171+
test_content: list[str] = [
109172
f'# SYNTAX TEST "{SYNTAX_STEM}SSH Crypto.sublime-syntax"\n',
110173
]
111-
syntax_content = {
174+
syntax_content: SyntaxYaml = {
112175
'name': 'SSH Crypto',
113176
'hidden': True,
114177
'scope': 'text.ssh.crypto',
@@ -117,19 +180,22 @@ def new_representer(dumper, data):
117180
'hidden_file_extensions': [
118181
'syntax_test_crypto',
119182
],
120-
'contexts': {
121-
'main': [
122-
{'include': 'comments'},
123-
],
124-
},
183+
'contexts': {},
125184
'variables': {},
126185
}
186+
syntax_contexts: dict[str, list[SyntaxContext]] = {
187+
'main': [
188+
{'include': 'comments'},
189+
],
190+
}
191+
syntax_variables: dict[str, str] = {}
127192

128193
for domain, settings in crypto_input.items():
129-
completions = {
194+
completions_yaml: CompletionYaml = {
130195
'scope': settings['completions']['scope'].strip(),
131196
'completions': [],
132197
}
198+
completions: list[CompletionItem] = []
133199
default_kind: list[str] = settings['completions']['kind']
134200
annotation: str = settings['completions']['annotation']
135201
active_scope: str = settings['active']['scope']
@@ -138,14 +204,14 @@ def new_representer(dumper, data):
138204
domain_ = domain.replace('-', '_')
139205

140206
test_content.append(f'\n###[ {domain + " ]":#<74}\n')
141-
_ = syntax_content['contexts']['main'].append({
207+
_ = syntax_contexts['main'].append({
142208
'match': fr'^{annotation}:',
143209
'push': [
144210
{'include': 'pop-before-nl'},
145211
{'include': f'ssh-{domain}'}
146212
]
147213
})
148-
syntax_content['contexts'][f'ssh-{domain}'] = [
214+
syntax_contexts[f'ssh-{domain}'] = [
149215
{
150216
'match': fr'\b{{{{{domain_}_active}}}}(?=[,\s\"])',
151217
'scope': active_scope,
@@ -155,21 +221,21 @@ def new_representer(dumper, data):
155221
'scope': deprec_scope,
156222
},
157223
]
158-
syntax_content['variables'][f'{domain_}_active'] = literal_str(
224+
syntax_variables[f'{domain_}_active'] = literal_str(
159225
fr"""(?x:{'\n '}{'\n| '.join(
160226
re.escape(i) for i in
161227
sorted(settings['active']['items'], reverse=True)
162228
)}{'\n'})"""
163229
)
164-
syntax_content['variables'][f'{domain_}_deprec'] = literal_str(
230+
syntax_variables[f'{domain_}_deprec'] = literal_str(
165231
fr"""(?x:{'\n '}{'\n| '.join(
166232
re.escape(i) for i in
167233
sorted(settings['deprecated']['items'], reverse=True)
168234
)}{'\n'})"""
169235
)
170236

171237
for item in settings['active']['items']:
172-
_ = completions['completions'].append({
238+
_ = completions.append({
173239
'trigger': item,
174240
'contents': item,
175241
'annotation': annotation,
@@ -180,7 +246,7 @@ def new_representer(dumper, data):
180246
f'#{" " * len(annotation)} {"^" * len(item)} {active_scope}')
181247

182248
for item in settings['deprecated']['items']:
183-
_ = completions['completions'].append({
249+
_ = completions.append({
184250
'trigger': item,
185251
'contents': item,
186252
'annotation': f'deprecated {annotation}',
@@ -191,12 +257,17 @@ def new_representer(dumper, data):
191257
test_content.append(
192258
f'#{" " * len(annotation)} {"^" * len(item)} {deprec_scope}')
193259

260+
completions_yaml['completions'] = completions
261+
194262
with open(f'{SUPPORT_STEM}{domain}.sublime-completions', 'w') as f:
195-
json.dump(completions, f, indent=4)
263+
json.dump(completions_yaml, f, indent=4)
264+
265+
syntax_content['contexts'] = syntax_contexts
266+
syntax_content['variables'] = syntax_variables
196267

197268
with open('../syntax/SSH Crypto.sublime-syntax', 'w') as syntax_file:
198269
_ = syntax_file.write('%YAML 1.2\n---\n')
199-
yaml.dump(syntax_content, syntax_file)
270+
_ = yaml.dump(syntax_content, syntax_file)
200271

201272
with open(f'{TEST_STEM}crypto', 'w') as test_file:
202273
_ = test_file.write('\n'.join(test_content))

0 commit comments

Comments
 (0)