ZedScripts 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ZedScripts/__about__.py +1 -0
- ZedScripts/__init__.py +38 -0
- ZedScripts/enums/Diagnostic.py +165 -0
- ZedScripts/enums/SyntaxErrorType.py +7 -0
- ZedScripts/environment/__init__.py +33 -0
- ZedScripts/environment/config.py +82 -0
- ZedScripts/environment/document.py +374 -0
- ZedScripts/environment/mod.py +62 -0
- ZedScripts/environment/version.py +202 -0
- ZedScripts/environment/workspace.py +320 -0
- ZedScripts/locale/en.json +38 -0
- ZedScripts/main.py +7 -0
- ZedScripts/providers/actions.py +13 -0
- ZedScripts/providers/capabilities.py +107 -0
- ZedScripts/providers/configuration.py +26 -0
- ZedScripts/providers/debug.py +59 -0
- ZedScripts/providers/diagnostics.py +101 -0
- ZedScripts/providers/hover.py +37 -0
- ZedScripts/providers/http.py +49 -0
- ZedScripts/providers/locale.py +80 -0
- ZedScripts/providers/notifications.py +45 -0
- ZedScripts/providers/semantic_tokens.py +189 -0
- ZedScripts/scripts/__init__.py +160 -0
- ZedScripts/scripts/block.py +547 -0
- ZedScripts/scripts/dataset.py +355 -0
- ZedScripts/scripts/value.py +706 -0
- ZedScripts/scripts/version.py +75 -0
- ZedScripts/server.py +288 -0
- ZedScripts/structure/ast.py +143 -0
- ZedScripts/structure/lexer.py +482 -0
- ZedScripts/structure/parser.py +243 -0
- ZedScripts/utils.py +85 -0
- zedscripts-0.0.2.dist-info/METADATA +105 -0
- zedscripts-0.0.2.dist-info/RECORD +37 -0
- zedscripts-0.0.2.dist-info/WHEEL +5 -0
- zedscripts-0.0.2.dist-info/licenses/LICENSE +21 -0
- zedscripts-0.0.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from ..enums.SyntaxErrorType import SyntaxErrorType
|
|
5
|
+
from .lexer import (
|
|
6
|
+
Lexer,
|
|
7
|
+
TokenType, Token, TokenCollection,
|
|
8
|
+
TextRange, TextPosition,
|
|
9
|
+
ELEMENTS_DELIMITERS
|
|
10
|
+
)
|
|
11
|
+
from .ast import Node, Chunk, BlockNode, ValueNode
|
|
12
|
+
from ..scripts.block import Block, ScriptBlock, Root
|
|
13
|
+
from ..scripts.value import Value
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ..environment.document import Document
|
|
17
|
+
|
|
18
|
+
class SyntaxError:
|
|
19
|
+
def __init__(self, type: SyntaxErrorType, location: TextRange) -> None:
|
|
20
|
+
self.type: SyntaxErrorType = type
|
|
21
|
+
self.location: TextRange = location
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ParseResult:
|
|
25
|
+
def __init__(self, chunk: Chunk) -> None:
|
|
26
|
+
self.chunk: Chunk = chunk
|
|
27
|
+
self.errors: list[SyntaxError] = []
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Parser:
|
|
31
|
+
def __init__(self) -> None:
|
|
32
|
+
self.chunk: Chunk = Chunk()
|
|
33
|
+
"""Root of the chunk being parsed."""
|
|
34
|
+
self.block_stack: list[BlockNode] = []
|
|
35
|
+
"""Stack of the currently parsing blocks."""
|
|
36
|
+
|
|
37
|
+
def add_block(self, block: BlockNode) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Adds a block to the top of the stack.
|
|
40
|
+
:return: The block that was added.
|
|
41
|
+
"""
|
|
42
|
+
if len(self.block_stack) > 0:
|
|
43
|
+
self.block_stack[-1].children.append(block)
|
|
44
|
+
else:
|
|
45
|
+
self.chunk.children.append(block)
|
|
46
|
+
self.block_stack.append(block)
|
|
47
|
+
|
|
48
|
+
def add_value(self, value: ValueNode) -> None:
|
|
49
|
+
"""
|
|
50
|
+
Adds a value to the block at the top of the stack, or the root if the stack is empty.
|
|
51
|
+
:param value: The value to push.
|
|
52
|
+
:return:
|
|
53
|
+
"""
|
|
54
|
+
if len(self.block_stack) > 0:
|
|
55
|
+
self.block_stack[-1].children.append(value)
|
|
56
|
+
else:
|
|
57
|
+
self.chunk.children.append(value)
|
|
58
|
+
|
|
59
|
+
def pop_block(self) -> BlockNode:
|
|
60
|
+
"""
|
|
61
|
+
Removes the block at the top of the stack.
|
|
62
|
+
:return: The block that was at the top of the stack.
|
|
63
|
+
"""
|
|
64
|
+
assert len(self.block_stack) > 0, "Attempted to pop from empty stack"
|
|
65
|
+
return self.block_stack.pop()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def parse_type_id(tokens: list[Token]) -> tuple[TokenCollection | None, TokenCollection | None]:
|
|
69
|
+
type_token = TokenCollection()
|
|
70
|
+
id_token = TokenCollection()
|
|
71
|
+
hit_whitespace = False
|
|
72
|
+
for unparsed_token in tokens:
|
|
73
|
+
if unparsed_token.type is TokenType.TEXT:
|
|
74
|
+
# all tokens before the first whitespace are the type
|
|
75
|
+
if not hit_whitespace:
|
|
76
|
+
type_token.append(unparsed_token)
|
|
77
|
+
# all tokens between the first and second are the id
|
|
78
|
+
else:
|
|
79
|
+
id_token.append(unparsed_token)
|
|
80
|
+
elif len(type_token) > 0 and unparsed_token.type is TokenType.WHITESPACE:
|
|
81
|
+
if not hit_whitespace:
|
|
82
|
+
hit_whitespace = True
|
|
83
|
+
else:
|
|
84
|
+
# after we hit whitespace for a second time, break
|
|
85
|
+
# FIXME: whitespace -> comment -> whitespace should not break
|
|
86
|
+
break
|
|
87
|
+
|
|
88
|
+
if len(type_token) < 1:
|
|
89
|
+
type_token = None
|
|
90
|
+
if len(id_token) < 1:
|
|
91
|
+
id_token = None
|
|
92
|
+
|
|
93
|
+
return type_token, id_token
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def parse(text: str) -> ParseResult:
|
|
97
|
+
return parse_tokens(Lexer.tokenize(text))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def parse_tokens(tokens: TokenCollection) -> ParseResult:
|
|
101
|
+
parser = Parser()
|
|
102
|
+
unparsed_tokens: list[Token] = []
|
|
103
|
+
result: ParseResult = ParseResult(parser.chunk)
|
|
104
|
+
unassigned_comments: list[Token] = []
|
|
105
|
+
|
|
106
|
+
for token in tokens:
|
|
107
|
+
match token.type:
|
|
108
|
+
case TokenType.ELEMENT_DELIMITER:
|
|
109
|
+
match token.text:
|
|
110
|
+
case "}":
|
|
111
|
+
if len(parser.block_stack) == 0:
|
|
112
|
+
result.errors.append(
|
|
113
|
+
SyntaxError(SyntaxErrorType.TOO_MANY_CLOSING_BRACKETS,
|
|
114
|
+
TextRange(token.pos, token.end))
|
|
115
|
+
)
|
|
116
|
+
break
|
|
117
|
+
if len(unparsed_tokens) > 1:
|
|
118
|
+
# necessary when when writing between two block end }
|
|
119
|
+
# should be -1 when after a key-value def
|
|
120
|
+
start = 1
|
|
121
|
+
end = -2 if len(unparsed_tokens) > 2 else -1
|
|
122
|
+
result.errors.append(
|
|
123
|
+
SyntaxError(SyntaxErrorType.UNPARSED_TOKENS,
|
|
124
|
+
TextRange(unparsed_tokens[start].pos, unparsed_tokens[end].end))
|
|
125
|
+
)
|
|
126
|
+
top_block = parser.pop_block()
|
|
127
|
+
top_block.close_bracket = token
|
|
128
|
+
case "{":
|
|
129
|
+
type_token, id_token = parse_type_id(unparsed_tokens)
|
|
130
|
+
|
|
131
|
+
if type_token is None:
|
|
132
|
+
result.errors.append(
|
|
133
|
+
SyntaxError(SyntaxErrorType.BLOCK_MISSING_TYPE,
|
|
134
|
+
TextRange(token.pos, token.end))
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
parser.add_block(
|
|
138
|
+
BlockNode(
|
|
139
|
+
type_token, id_token, token, None,
|
|
140
|
+
comments=unassigned_comments
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
case ",":
|
|
144
|
+
value = ValueNode(
|
|
145
|
+
TokenCollection(unparsed_tokens),
|
|
146
|
+
token, # comma token
|
|
147
|
+
comments=unassigned_comments
|
|
148
|
+
)
|
|
149
|
+
parser.add_value(value)
|
|
150
|
+
case _:
|
|
151
|
+
raise RuntimeError("Unknown punctuator " + token.text)
|
|
152
|
+
unparsed_tokens = []
|
|
153
|
+
unassigned_comments = []
|
|
154
|
+
case TokenType.COMMENT:
|
|
155
|
+
unassigned_comments.append(token)
|
|
156
|
+
case _:
|
|
157
|
+
unparsed_tokens.append(token)
|
|
158
|
+
|
|
159
|
+
if len(parser.block_stack) > 0:
|
|
160
|
+
result.errors.append(
|
|
161
|
+
SyntaxError(SyntaxErrorType.BLOCK_NOT_CLOSED,
|
|
162
|
+
TextRange(parser.block_stack[0].open_bracket.pos, tokens[-1].end))
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
return result
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def ast_to_comment(node: Node, start: TextPosition) -> str:
|
|
169
|
+
"""
|
|
170
|
+
Parses comment tokens from a node into a single string.
|
|
171
|
+
:param node: The node to parse comments from.
|
|
172
|
+
:param start: The start position of the actual object represented by the node.
|
|
173
|
+
:return: The comments merged into a string.
|
|
174
|
+
"""
|
|
175
|
+
comment: str = ""
|
|
176
|
+
|
|
177
|
+
# we loop backwards to easily ignore comment tokens separated by a non-comment line
|
|
178
|
+
for token in reversed(node.comments):
|
|
179
|
+
if token.end.line < start.line - 1:
|
|
180
|
+
continue
|
|
181
|
+
|
|
182
|
+
comment = str(token)[2:-2] + comment
|
|
183
|
+
|
|
184
|
+
if token.pos < start:
|
|
185
|
+
start = token.pos
|
|
186
|
+
|
|
187
|
+
# remove leading whitespace from each line
|
|
188
|
+
comment = re.sub(r'\n\s+', '\n', comment)
|
|
189
|
+
# remove leading/trailing newlines
|
|
190
|
+
comment = re.sub(r'^\n+', '', comment)
|
|
191
|
+
comment = re.sub(r'\n+$', '', comment)
|
|
192
|
+
|
|
193
|
+
return comment
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def ast_to_value(node: ValueNode, parent: Block) -> Value:
|
|
197
|
+
tokens = node.tokens.strip()
|
|
198
|
+
if len(tokens) > 0:
|
|
199
|
+
comment = ast_to_comment(node, tokens[0].pos)
|
|
200
|
+
else:
|
|
201
|
+
comment = ""
|
|
202
|
+
|
|
203
|
+
value = Value(
|
|
204
|
+
str(node.tokens).strip(),
|
|
205
|
+
node,
|
|
206
|
+
parent,
|
|
207
|
+
comment
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return value
|
|
211
|
+
|
|
212
|
+
def ast_to_block(document: 'Document', node: BlockNode, parent: Block) -> ScriptBlock:
|
|
213
|
+
if node.type is None:
|
|
214
|
+
type = ""
|
|
215
|
+
else:
|
|
216
|
+
type = str(node.type)
|
|
217
|
+
|
|
218
|
+
if node.id is None:
|
|
219
|
+
id = None
|
|
220
|
+
else:
|
|
221
|
+
id = str(node.id)
|
|
222
|
+
|
|
223
|
+
comment = ast_to_comment(node, node.open_bracket.pos)
|
|
224
|
+
block = ScriptBlock(document, type, id, node, parent, comment)
|
|
225
|
+
ast_to_any(document, block)
|
|
226
|
+
|
|
227
|
+
return block
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def ast_to_any(document, parent: ScriptBlock | Root):
|
|
231
|
+
if parent.node is None:
|
|
232
|
+
raise RuntimeError("Parent block has no associated AST node.")
|
|
233
|
+
for child in parent.node.children:
|
|
234
|
+
if isinstance(child, ValueNode):
|
|
235
|
+
parent.values.append(ast_to_value(child, parent))
|
|
236
|
+
elif isinstance(child, BlockNode):
|
|
237
|
+
parent.children.append(ast_to_block(document, child, parent))
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def chunk_to_root(document: 'Document', chunk: Chunk, rootType: str) -> Root:
|
|
241
|
+
root = Root(document, rootType, chunk, "")
|
|
242
|
+
ast_to_any(document, root)
|
|
243
|
+
return root
|
ZedScripts/utils.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Iterable, TypeVar
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
from deepmerge import always_merger
|
|
5
|
+
|
|
6
|
+
from lsprotocol import types
|
|
7
|
+
from pygls.uris import from_fs_path, to_fs_path
|
|
8
|
+
|
|
9
|
+
from .structure.lexer import TextRange, TextPosition
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def textrange_to_lsp(range: TextRange) -> types.Range:
|
|
13
|
+
return types.Range(
|
|
14
|
+
types.Position(range.start.line, range.start.offset),
|
|
15
|
+
types.Position(range.end.line, range.end.offset)
|
|
16
|
+
)
|
|
17
|
+
def position_to_texposition(position: types.Position) -> TextPosition:
|
|
18
|
+
return TextPosition(position.line, position.character)
|
|
19
|
+
|
|
20
|
+
def uri_to_path(uri: str) -> Path:
|
|
21
|
+
fs_path = to_fs_path(uri)
|
|
22
|
+
if fs_path is None:
|
|
23
|
+
raise ValueError(f"Cannot convert URI to file path: {uri}")
|
|
24
|
+
return Path(fs_path)
|
|
25
|
+
|
|
26
|
+
def path_to_uri(path: Path | str) -> str:
|
|
27
|
+
uri = from_fs_path(str(path))
|
|
28
|
+
if uri is None:
|
|
29
|
+
raise ValueError(f"Cannot convert file path to URI: {path}")
|
|
30
|
+
return uri
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def sort_by_load_order(files: Iterable[Path]) -> Iterable[Path]:
|
|
35
|
+
"""
|
|
36
|
+
Sorts an iterable of script paths into the order that the game would load them.
|
|
37
|
+
:param files: List of script filepaths.
|
|
38
|
+
:return: Sorted list of filepaths.
|
|
39
|
+
"""
|
|
40
|
+
templates: list[Path] = []
|
|
41
|
+
other: list[Path] = []
|
|
42
|
+
|
|
43
|
+
for path in files:
|
|
44
|
+
if path.name.startswith("template_"):
|
|
45
|
+
templates.append(path)
|
|
46
|
+
else:
|
|
47
|
+
other.append(path)
|
|
48
|
+
|
|
49
|
+
templates.sort()
|
|
50
|
+
other.sort()
|
|
51
|
+
|
|
52
|
+
return templates + other
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def glob_files_by_extensions(folder: Path, extensions: set[str]) -> Iterable[Path]:
|
|
57
|
+
"""
|
|
58
|
+
Glob all files in the given folder and its subfolders
|
|
59
|
+
that have one of the specified extensions.
|
|
60
|
+
https://stackoverflow.com/a/57054058/33113221
|
|
61
|
+
"""
|
|
62
|
+
files = (p.resolve() for p in Path(folder).rglob("*") if p.suffix in extensions)
|
|
63
|
+
return files
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
T = TypeVar("T", bound=BaseModel)
|
|
67
|
+
|
|
68
|
+
def merge_pydantic_models(base: T, *models: T) -> T:
|
|
69
|
+
"""Merge multiple Pydantic model instances.
|
|
70
|
+
|
|
71
|
+
The attributes of 'base' and all subsequent models that weren't explicitly set are dumped into dicts
|
|
72
|
+
using '.model_dump(exclude_unset=True)', which are then merged using 'deepmerge',
|
|
73
|
+
and the merged result is turned into a model instance using '.model_validate'.
|
|
74
|
+
|
|
75
|
+
For attributes set on both 'base' and the subsequent models, the value from the last model in the arguments will be used in
|
|
76
|
+
the output result.
|
|
77
|
+
|
|
78
|
+
Modified from:
|
|
79
|
+
@source: https://github.com/pydantic/pydantic/discussions/3416#discussioncomment-12267413
|
|
80
|
+
"""
|
|
81
|
+
base_dict = base.model_dump(exclude_unset=True)
|
|
82
|
+
for nxt in models:
|
|
83
|
+
nxt_dict = nxt.model_dump(exclude_unset=True)
|
|
84
|
+
base_dict = always_merger.merge(base_dict, nxt_dict)
|
|
85
|
+
return base.model_validate(base_dict)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ZedScripts
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Author: SimKDT
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.12.3
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: lsprotocol
|
|
10
|
+
Requires-Dist: pygls
|
|
11
|
+
Requires-Dist: requests-cache
|
|
12
|
+
Requires-Dist: pydantic
|
|
13
|
+
Requires-Dist: deepmerge
|
|
14
|
+
Provides-Extra: build
|
|
15
|
+
Requires-Dist: pyinstaller; extra == "build"
|
|
16
|
+
Provides-Extra: debug
|
|
17
|
+
Requires-Dist: debugpy; extra == "debug"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# ZedScripts LSP
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
[](LICENSE)
|
|
24
|
+

|
|
25
|
+
[](https://pypi.org/project/ZedScripts-LSP/)
|
|
26
|
+
[](https://pypi.org/project/ZedScripts-LSP/)
|
|
27
|
+
|
|
28
|
+
> [!IMPORTANT]
|
|
29
|
+
> Work In Progress, this is a BETA release
|
|
30
|
+
|
|
31
|
+
ZedScripts LSP is a language server protocol implementation in Python for the [scripting format]() of Project Zomboid. Previously a VSCode extension, it is now reimplemented as a standalone LSP.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
### Releases
|
|
35
|
+
|
|
36
|
+
### Python package
|
|
37
|
+
|
|
38
|
+
<!-- <details open>
|
|
39
|
+
<summary>PyPi</summary>
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install ZedScripts-LSP
|
|
43
|
+
```
|
|
44
|
+
</details> -->
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Git</summary>
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install git+https://github.com/PZ-Wiki-Modding/ZedScripts-LSP.git
|
|
51
|
+
```
|
|
52
|
+
</details>
|
|
53
|
+
|
|
54
|
+
<details>
|
|
55
|
+
<summary>Local</summary>
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install .
|
|
59
|
+
```
|
|
60
|
+
</details>
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
You can either launch the LSP from Python or you can launch the software as is.
|
|
65
|
+
|
|
66
|
+
### LSP cache directory
|
|
67
|
+
|
|
68
|
+
The LSP uses a cache directory on your system to store temporary files and logs as well as configuration files. You can find it here:
|
|
69
|
+
|
|
70
|
+
<details>
|
|
71
|
+
<summary>Linux</summary>
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
~/.zedscripts
|
|
75
|
+
```
|
|
76
|
+
</details>
|
|
77
|
+
|
|
78
|
+
<details>
|
|
79
|
+
<summary>Windows</summary>
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
%USERPROFILE%\.zedscripts
|
|
83
|
+
```
|
|
84
|
+
</details>
|
|
85
|
+
|
|
86
|
+
### Configuration
|
|
87
|
+
|
|
88
|
+
The LSP uses configurations files which provide information to the LSP about various settings. You have access to a global configuration file
|
|
89
|
+
|
|
90
|
+
Example configuration:
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"dataset": {
|
|
94
|
+
"latest": true
|
|
95
|
+
},
|
|
96
|
+
"libraries": [
|
|
97
|
+
"/home/simon/.steam/debian-installation/steamapps/common/ProjectZomboid/projectzomboid/media",
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
WIP: proper documentation will come soon
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
ZedScripts/__about__.py,sha256=ry5O5SW74ugwOUMKSV2_LbWjYa8B0IEvUm7S-lHPA2c,23
|
|
2
|
+
ZedScripts/__init__.py,sha256=FhE0ANZpYH8YyjZXQGzplZ9VrqEXFsD8S0wx9Q-E-As,1282
|
|
3
|
+
ZedScripts/main.py,sha256=hoa-oRPmUy0mmIkUyoAWLh8wCwo1jCgvtEQOKw-HSf8,124
|
|
4
|
+
ZedScripts/server.py,sha256=4b4C5hLG5Dw2tdcptd2uo655dI0QFw3H5wvWdGPM0xk,11047
|
|
5
|
+
ZedScripts/utils.py,sha256=eQFqgWKMO0riKeb_IzHTY6tj2lPUT3NATqW5Pk6_EVA,2852
|
|
6
|
+
ZedScripts/enums/Diagnostic.py,sha256=a2PANTKDy1PZd1flAVQXJy1L5QpTTbwAHwbK_PgR7Qo,8075
|
|
7
|
+
ZedScripts/enums/SyntaxErrorType.py,sha256=MC9VWpoxfwPaPGRGwi-jpKISiHJaO63DFvUg_nBsPQ4,196
|
|
8
|
+
ZedScripts/environment/__init__.py,sha256=uv-ez4lW8KkpvZMNZlq5npKJVzAO72YF6Vot4Dz6MZU,1107
|
|
9
|
+
ZedScripts/environment/config.py,sha256=7YsQHkUvPfbySShRIHoZJtnUdstHk1gC5693KqQwtco,2896
|
|
10
|
+
ZedScripts/environment/document.py,sha256=2Mx1ZSin6fiBoKaww15YSDbRrcfAu80GzJ5UZHyTObU,14552
|
|
11
|
+
ZedScripts/environment/mod.py,sha256=wlfnIU5LmTesrFsD5Ynh64qRRms6ua6y5Si0cxMp1Yg,2434
|
|
12
|
+
ZedScripts/environment/version.py,sha256=0gmsqIyWIO1Ctk0FTddAR2SrMacUdlFjzUn2VyqAANw,7441
|
|
13
|
+
ZedScripts/environment/workspace.py,sha256=ghrNQ0Um93-vvpsZAOIVDOhD1YX8ss9057BuvwP1L3I,12877
|
|
14
|
+
ZedScripts/locale/en.json,sha256=82CWRO9_G2y5-fr-3aM-6laEI67FI7YNQUW0EXSukqk,3580
|
|
15
|
+
ZedScripts/providers/actions.py,sha256=WyWOtlw_YOO4J-Hn0OkTA9NZFFeaB4wyXpKPPBFi02o,411
|
|
16
|
+
ZedScripts/providers/capabilities.py,sha256=_cMMuFTucqa-UDobOcTQ-6bkiGE23K8cQ-fFAetBq7s,3485
|
|
17
|
+
ZedScripts/providers/configuration.py,sha256=dCr1EwuHjvqOKZVMpl7P-JVyMkSMHYyG3Blkzn3Z0SQ,564
|
|
18
|
+
ZedScripts/providers/debug.py,sha256=_uAA-78y4k4Qe1yvsIHSPVhZNOVHnP6vZ_iEepwfCBU,2204
|
|
19
|
+
ZedScripts/providers/diagnostics.py,sha256=DHkG4WOjaFQlK5wa4DAHSxqCkgdGK4_EFKS5VtQ7hno,3739
|
|
20
|
+
ZedScripts/providers/hover.py,sha256=Mju1hfdKODThE_DH7BXc6Bfkiel5HM5czX5LGCjW-Us,1051
|
|
21
|
+
ZedScripts/providers/http.py,sha256=DwQ1qMPJSOB2tUAOcQXy5WU3Yd2uvoejG2g7pWeS-Wo,1648
|
|
22
|
+
ZedScripts/providers/locale.py,sha256=eEOdPZ8FKYPdmshB7kvpCFLD5AjNrZIO3DeT45Jukyo,3042
|
|
23
|
+
ZedScripts/providers/notifications.py,sha256=xfUb4HDs5LoR0by_l4PQs9xIQmr7h0CsD77LugKtkPk,1090
|
|
24
|
+
ZedScripts/providers/semantic_tokens.py,sha256=6HI3ixWz8uahjSBehD00c3K9RmEXR5FZoSKXET3lERw,6431
|
|
25
|
+
ZedScripts/scripts/__init__.py,sha256=3En0FJDKn1gR49T0NzV6rhie-ZvU3s59v47t8paH0Xc,4638
|
|
26
|
+
ZedScripts/scripts/block.py,sha256=TEtSiGjXASIRKT6g0S_Dk5lvCRWtpM-ObsqmQd31KYI,18947
|
|
27
|
+
ZedScripts/scripts/dataset.py,sha256=YnsMHfxE75cQC4dBgFAPN9eqcaOfpWqX0KTjhMXs0Xs,13062
|
|
28
|
+
ZedScripts/scripts/value.py,sha256=HTgoae5dCUCCwPFO6oOEyOH1B3JXW_IqesMVPfzOlKs,28001
|
|
29
|
+
ZedScripts/scripts/version.py,sha256=-R7VofQyJrOqqq86JnmukWTv2P6RmqDX6O4vDIXmJbw,2897
|
|
30
|
+
ZedScripts/structure/ast.py,sha256=ukRATCVenrKjwsUHKUYR4wP9LBOwFhV3enjwBNNmtB4,4624
|
|
31
|
+
ZedScripts/structure/lexer.py,sha256=2cp5eYIyGPond1W-41ALlut8wDitxHDJcpjdSSPEv7c,16339
|
|
32
|
+
ZedScripts/structure/parser.py,sha256=bK4taAONQOpoEW6fZ222GSd-EDOpsBFtHIRmmZXOJW0,8577
|
|
33
|
+
zedscripts-0.0.2.dist-info/licenses/LICENSE,sha256=U4VZ5OLZttGqVxQfLdbpLIvMEDpj5KRXLqltyHwWxsA,1072
|
|
34
|
+
zedscripts-0.0.2.dist-info/METADATA,sha256=dPXVBMQS35QFRzhuerYjQlOfIpNAX32ID1TECHmT4PI,2474
|
|
35
|
+
zedscripts-0.0.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
36
|
+
zedscripts-0.0.2.dist-info/top_level.txt,sha256=FkHjeVoFW1B97gPjIPEMXwVDyWr_9RoNYnOlWfDnYTg,11
|
|
37
|
+
zedscripts-0.0.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PZ Wiki Modding
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ZedScripts
|