ZedScripts 0.0.2__tar.gz → 0.0.3__tar.gz
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-0.0.2/src/ZedScripts.egg-info → zedscripts-0.0.3}/PKG-INFO +33 -6
- {zedscripts-0.0.2 → zedscripts-0.0.3}/README.md +32 -5
- {zedscripts-0.0.2 → zedscripts-0.0.3}/pyproject.toml +8 -1
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/enums/Diagnostic.py +1 -1
- zedscripts-0.0.3/src/ZedScripts/environment/config.py +179 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/environment/document.py +10 -14
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/environment/workspace.py +46 -18
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/diagnostics.py +38 -11
- zedscripts-0.0.3/src/ZedScripts/providers/notifications.py +57 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/scripts/block.py +2 -1
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/scripts/value.py +1 -1
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/server.py +30 -10
- {zedscripts-0.0.2 → zedscripts-0.0.3/src/ZedScripts.egg-info}/PKG-INFO +33 -6
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts.egg-info/SOURCES.txt +0 -1
- zedscripts-0.0.2/src/ZedScripts/environment/config.py +0 -82
- zedscripts-0.0.2/src/ZedScripts/providers/configuration.py +0 -26
- zedscripts-0.0.2/src/ZedScripts/providers/notifications.py +0 -45
- {zedscripts-0.0.2 → zedscripts-0.0.3}/LICENSE +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/setup.cfg +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/__about__.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/__init__.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/enums/SyntaxErrorType.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/environment/__init__.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/environment/mod.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/environment/version.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/locale/en.json +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/main.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/actions.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/capabilities.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/debug.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/hover.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/http.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/locale.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/providers/semantic_tokens.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/scripts/__init__.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/scripts/dataset.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/scripts/version.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/structure/ast.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/structure/lexer.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/structure/parser.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts/utils.py +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts.egg-info/dependency_links.txt +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts.egg-info/requires.txt +0 -0
- {zedscripts-0.0.2 → zedscripts-0.0.3}/src/ZedScripts.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ZedScripts
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Author: SimKDT
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.12.3
|
|
@@ -19,11 +19,11 @@ Dynamic: license-file
|
|
|
19
19
|
|
|
20
20
|
# ZedScripts LSP
|
|
21
21
|
|
|
22
|
-
](LICENSE)
|
|
23
|
+

|
|
24
|
+
[](https://pypi.org/project/ZedScripts/)
|
|
25
|
+
[](https://pypi.org/project/ZedScripts/)
|
|
26
|
+

|
|
27
27
|
|
|
28
28
|
> [!IMPORTANT]
|
|
29
29
|
> Work In Progress, this is a BETA release
|
|
@@ -101,5 +101,32 @@ Example configuration:
|
|
|
101
101
|
|
|
102
102
|
WIP: proper documentation will come soon
|
|
103
103
|
|
|
104
|
+
## IDE configuration
|
|
105
|
+
Based on the IDE you use, you may need to install the ZedScripts LSP application for your OS in the [releases](https://github.com/PZ-Wiki-Modding/ZedScripts-LSP/releases) (Linux, Windows).
|
|
106
|
+
|
|
107
|
+
### Visual Studio Code
|
|
108
|
+
|
|
109
|
+
Install the [ZedScripts extension](https://marketplace.visualstudio.com/items?itemName=SimKDT.ZedScripts) from the Visual Studio Code marketplace. The extension will handle the downloading and setup of the ZedScripts LSP server for you.
|
|
110
|
+
|
|
111
|
+
### VIM
|
|
112
|
+
|
|
113
|
+
Using [yegappan/lsp](https://github.com/yegappan/lsp), setup the ZedScripts LSP server as follows:
|
|
114
|
+
|
|
115
|
+
```vim
|
|
116
|
+
let lspServers = [
|
|
117
|
+
\ #{
|
|
118
|
+
\ name: 'zedscripts',
|
|
119
|
+
\ filetype: ['text', 'zedscripts'],
|
|
120
|
+
\ path: 'path/to/ZedScripts',
|
|
121
|
+
\ args: []
|
|
122
|
+
\ }
|
|
123
|
+
\ ]
|
|
124
|
+
|
|
125
|
+
autocmd User LspSetup call LspAddServer(lspServers)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
> [!NOTE]
|
|
129
|
+
> You can see [this video](https://www.youtube.com/watch?v=-5lb_jLQmKc) which explains how to set up VIM, and notably setup a LSP server.
|
|
130
|
+
|
|
104
131
|
## License
|
|
105
132
|
See [LICENSE](LICENSE) for details.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# ZedScripts LSP
|
|
2
2
|
|
|
3
|
-
](LICENSE)
|
|
4
|
+

|
|
5
|
+
[](https://pypi.org/project/ZedScripts/)
|
|
6
|
+
[](https://pypi.org/project/ZedScripts/)
|
|
7
|
+

|
|
8
8
|
|
|
9
9
|
> [!IMPORTANT]
|
|
10
10
|
> Work In Progress, this is a BETA release
|
|
@@ -82,5 +82,32 @@ Example configuration:
|
|
|
82
82
|
|
|
83
83
|
WIP: proper documentation will come soon
|
|
84
84
|
|
|
85
|
+
## IDE configuration
|
|
86
|
+
Based on the IDE you use, you may need to install the ZedScripts LSP application for your OS in the [releases](https://github.com/PZ-Wiki-Modding/ZedScripts-LSP/releases) (Linux, Windows).
|
|
87
|
+
|
|
88
|
+
### Visual Studio Code
|
|
89
|
+
|
|
90
|
+
Install the [ZedScripts extension](https://marketplace.visualstudio.com/items?itemName=SimKDT.ZedScripts) from the Visual Studio Code marketplace. The extension will handle the downloading and setup of the ZedScripts LSP server for you.
|
|
91
|
+
|
|
92
|
+
### VIM
|
|
93
|
+
|
|
94
|
+
Using [yegappan/lsp](https://github.com/yegappan/lsp), setup the ZedScripts LSP server as follows:
|
|
95
|
+
|
|
96
|
+
```vim
|
|
97
|
+
let lspServers = [
|
|
98
|
+
\ #{
|
|
99
|
+
\ name: 'zedscripts',
|
|
100
|
+
\ filetype: ['text', 'zedscripts'],
|
|
101
|
+
\ path: 'path/to/ZedScripts',
|
|
102
|
+
\ args: []
|
|
103
|
+
\ }
|
|
104
|
+
\ ]
|
|
105
|
+
|
|
106
|
+
autocmd User LspSetup call LspAddServer(lspServers)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> [!NOTE]
|
|
110
|
+
> You can see [this video](https://www.youtube.com/watch?v=-5lb_jLQmKc) which explains how to set up VIM, and notably setup a LSP server.
|
|
111
|
+
|
|
85
112
|
## License
|
|
86
113
|
See [LICENSE](LICENSE) for details.
|
|
@@ -3,7 +3,7 @@ name = "ZedScripts"
|
|
|
3
3
|
description = ""
|
|
4
4
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
5
5
|
requires-python = ">=3.12.3"
|
|
6
|
-
version = "0.0.
|
|
6
|
+
version = "0.0.3"
|
|
7
7
|
license = "MIT"
|
|
8
8
|
license-files = ["LICENSE"]
|
|
9
9
|
authors = [
|
|
@@ -34,3 +34,10 @@ build-backend = "setuptools.build_meta"
|
|
|
34
34
|
ZedScripts = [
|
|
35
35
|
"locale/*.json"
|
|
36
36
|
]
|
|
37
|
+
|
|
38
|
+
# uv configs
|
|
39
|
+
[[tool.uv.index]]
|
|
40
|
+
name = "testpypi"
|
|
41
|
+
url = "https://test.pypi.org/simple/"
|
|
42
|
+
publish-url = "https://test.pypi.org/legacy/"
|
|
43
|
+
explicit = true
|
|
@@ -7,7 +7,7 @@ from ..enums.SyntaxErrorType import SyntaxErrorType
|
|
|
7
7
|
from ..providers.diagnostics import DiagnosticDefinition
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class DiagnosticType(enum.
|
|
10
|
+
class DiagnosticType(enum.StrEnum):
|
|
11
11
|
@classmethod
|
|
12
12
|
def _missing_(cls, value: Any) -> 'DiagnosticType | None':
|
|
13
13
|
if isinstance(value, SyntaxErrorType):
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import enum
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated, Optional
|
|
5
|
+
from pydantic import BaseModel, BeforeValidator, Field, WithJsonSchema
|
|
6
|
+
|
|
7
|
+
from lsprotocol.types import DiagnosticSeverity, DiagnosticTag
|
|
8
|
+
|
|
9
|
+
from ..scripts.version import DataVersion
|
|
10
|
+
from ..enums.Diagnostic import DiagnosticType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# the auto enum of DiagnosticType makes them lowercase, but we'll want to use
|
|
15
|
+
# uppercase, that is the member's name
|
|
16
|
+
|
|
17
|
+
def _parse_diagnostic_type_name(value: object) -> object:
|
|
18
|
+
if isinstance(value, DiagnosticType):
|
|
19
|
+
return value
|
|
20
|
+
if isinstance(value, str):
|
|
21
|
+
try:
|
|
22
|
+
return DiagnosticType[value]
|
|
23
|
+
except KeyError:
|
|
24
|
+
raise ValueError("type must be a DiagnosticType member name") from None
|
|
25
|
+
return value
|
|
26
|
+
DiagnosticTypeName = Annotated[
|
|
27
|
+
DiagnosticType,
|
|
28
|
+
BeforeValidator(_parse_diagnostic_type_name),
|
|
29
|
+
WithJsonSchema({
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": [member.name for member in DiagnosticType],
|
|
32
|
+
}),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
def _parse_diagnostic_severity_name(value: object) -> object:
|
|
36
|
+
if isinstance(value, DiagnosticSeverity):
|
|
37
|
+
return value
|
|
38
|
+
if isinstance(value, str):
|
|
39
|
+
try:
|
|
40
|
+
return DiagnosticSeverity[value]
|
|
41
|
+
except KeyError:
|
|
42
|
+
raise ValueError("severity must be a DiagnosticSeverity member name") from None
|
|
43
|
+
return value
|
|
44
|
+
DiagnosticSeverityName = Annotated[
|
|
45
|
+
DiagnosticSeverity,
|
|
46
|
+
BeforeValidator(_parse_diagnostic_severity_name),
|
|
47
|
+
WithJsonSchema({
|
|
48
|
+
"type": "string",
|
|
49
|
+
"enum": [member.name for member in DiagnosticSeverity],
|
|
50
|
+
}),
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
def _parse_diagnostic_tag_name(value: object) -> object:
|
|
54
|
+
if isinstance(value, DiagnosticTag):
|
|
55
|
+
return value
|
|
56
|
+
if isinstance(value, str):
|
|
57
|
+
try:
|
|
58
|
+
return DiagnosticTag[value]
|
|
59
|
+
except KeyError:
|
|
60
|
+
raise ValueError("tag must be a DiagnosticTag member name") from None
|
|
61
|
+
return value
|
|
62
|
+
DiagnosticTagName = Annotated[
|
|
63
|
+
DiagnosticTag,
|
|
64
|
+
BeforeValidator(_parse_diagnostic_tag_name),
|
|
65
|
+
WithJsonSchema({
|
|
66
|
+
"type": "string",
|
|
67
|
+
"enum": [member.name for member in DiagnosticTag],
|
|
68
|
+
}),
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# define the models
|
|
74
|
+
|
|
75
|
+
class DatasetTag(enum.StrEnum):
|
|
76
|
+
LATEST = "latest"
|
|
77
|
+
STABLE = "stable"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ReleaseModel(BaseModel):
|
|
82
|
+
major: int = Field(
|
|
83
|
+
description="Build game version number.",
|
|
84
|
+
ge=42,
|
|
85
|
+
)
|
|
86
|
+
minor: int = Field(
|
|
87
|
+
description="Minor game version number.",
|
|
88
|
+
ge=0,
|
|
89
|
+
)
|
|
90
|
+
patch: int = Field(
|
|
91
|
+
description="Patch game version number.",
|
|
92
|
+
ge=0,
|
|
93
|
+
)
|
|
94
|
+
version: Optional[int] = Field(
|
|
95
|
+
description="Dataset version number for the provided Build release (major.minor.patch). This is incremented whenever the dataset for a specific version is updated.",
|
|
96
|
+
default=None,
|
|
97
|
+
ge=0,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
class DatasetModel(BaseModel):
|
|
101
|
+
release: Optional[ReleaseModel] = Field(
|
|
102
|
+
description="Provides a configuration for the dataset version to use for validation. This overrides the `latest` and `stable` fields if set.",
|
|
103
|
+
default=None,
|
|
104
|
+
)
|
|
105
|
+
latest: Optional[bool] = Field(
|
|
106
|
+
description="Indicates whether to use the latest dataset version for validation. This is ignored if `release` is set. Overrides the `stable` field if set.",
|
|
107
|
+
default=False,
|
|
108
|
+
)
|
|
109
|
+
stable: Optional[bool] = Field(
|
|
110
|
+
description="Provides a configuration for the stable dataset version to use for validation. Ignored if `release` or `latest` is set.",
|
|
111
|
+
default=True,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def to_data_version(self) -> DataVersion | DatasetTag:
|
|
115
|
+
if self.release is None:
|
|
116
|
+
if self.latest:
|
|
117
|
+
return DatasetTag.LATEST
|
|
118
|
+
if self.stable:
|
|
119
|
+
return DatasetTag.STABLE
|
|
120
|
+
logging.warning("No dataset version specified, defaulting to 'stable'.")
|
|
121
|
+
return DatasetTag.STABLE
|
|
122
|
+
from ..scripts.dataset import Manifest
|
|
123
|
+
try:
|
|
124
|
+
return Manifest.from_release_model(self.release)
|
|
125
|
+
except Exception as e:
|
|
126
|
+
logging.error(f"Failed to get data version from release model: {e}. Defaulting to 'stable'.")
|
|
127
|
+
return DatasetTag.STABLE
|
|
128
|
+
|
|
129
|
+
class DiagnosticsModel(BaseModel):
|
|
130
|
+
"""Represents the diagnostics configuration for the workspace environment."""
|
|
131
|
+
type: DiagnosticTypeName = Field(
|
|
132
|
+
description="Specifies the diagnostic member name to enable.",
|
|
133
|
+
)
|
|
134
|
+
enable: Optional[bool] = Field(
|
|
135
|
+
description="Indicates whether diagnostics are enabled.",
|
|
136
|
+
default=True,
|
|
137
|
+
)
|
|
138
|
+
severity: Optional[DiagnosticSeverityName] = Field(
|
|
139
|
+
description="Specifies the severity level of the diagnostics.",
|
|
140
|
+
default=None,
|
|
141
|
+
)
|
|
142
|
+
tags: Optional[list[DiagnosticTagName]] = Field(
|
|
143
|
+
description="Specifies the tags associated with the diagnostics.",
|
|
144
|
+
default=None,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
class ConfigurationModel(BaseModel):
|
|
148
|
+
"""Represents the content of the configuration files for workspace environments."""
|
|
149
|
+
dataset: DatasetModel = Field(
|
|
150
|
+
description="Provides configuration for the dataset version to use for diagnostics.",
|
|
151
|
+
default_factory=DatasetModel,
|
|
152
|
+
)
|
|
153
|
+
libraries: set[Path] = Field(
|
|
154
|
+
description="Set of library folders to reference. Usually this should contain the base game folder.",
|
|
155
|
+
default_factory=set,
|
|
156
|
+
)
|
|
157
|
+
ignored: set[str] = Field(
|
|
158
|
+
description="Regex patterns for files and folders to ignore in the workspace.",
|
|
159
|
+
default=set([
|
|
160
|
+
r"tileGeometry\.txt",
|
|
161
|
+
r"tileDepthTextureAssignments\.txt",
|
|
162
|
+
r".+\.tiles\.txt"
|
|
163
|
+
]),
|
|
164
|
+
)
|
|
165
|
+
diagnostics: list[DiagnosticsModel] = Field(
|
|
166
|
+
description="List of diagnostics configurations for the workspace environment.",
|
|
167
|
+
default_factory=list,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
def find_diagnostic(self, type: DiagnosticType) -> DiagnosticsModel | None:
|
|
171
|
+
for diagnostic in self.diagnostics:
|
|
172
|
+
if diagnostic.type == type:
|
|
173
|
+
return diagnostic
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
if __name__ == "__main__":
|
|
177
|
+
import json
|
|
178
|
+
config = ConfigurationModel()
|
|
179
|
+
print(json.dumps(config.model_json_schema(), indent=4))
|
|
@@ -10,8 +10,8 @@ from ..utils import path_to_uri, position_to_texposition
|
|
|
10
10
|
from ..enums.Diagnostic import DiagnosticType
|
|
11
11
|
from ..structure.lexer import Lexer, TokenCollection
|
|
12
12
|
from ..structure.parser import parse_tokens, chunk_to_root
|
|
13
|
+
from ..providers import notifications
|
|
13
14
|
from ..providers.diagnostics import DiagnosticReport, WorkspaceDiagnosticReport, DiagnosticCollection
|
|
14
|
-
from ..providers.notifications import ZedNotification, SetZedScriptsNotificationParams
|
|
15
15
|
from ..providers.semantic_tokens import SemanticTokenCollection, build_syntactic_tokens
|
|
16
16
|
from ..providers.actions import make_linked_editing_ranges
|
|
17
17
|
|
|
@@ -21,8 +21,7 @@ if TYPE_CHECKING:
|
|
|
21
21
|
|
|
22
22
|
from .workspace import Workspace
|
|
23
23
|
from .mod import Mod
|
|
24
|
-
from ..
|
|
25
|
-
from ..scripts.block import Block, Root
|
|
24
|
+
from ..scripts.block import Root
|
|
26
25
|
from ..scripts.dataset import Dataset
|
|
27
26
|
|
|
28
27
|
class Document:
|
|
@@ -85,16 +84,10 @@ class Document:
|
|
|
85
84
|
self.mod = mod
|
|
86
85
|
|
|
87
86
|
def make_zedscripts(self) -> None:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
server.send_notification(
|
|
93
|
-
ZedNotification.SET_ZEDSCRIPTS,
|
|
94
|
-
SetZedScriptsNotificationParams(
|
|
95
|
-
uri=path_to_uri(self.path)
|
|
96
|
-
)
|
|
97
|
-
)
|
|
87
|
+
notifications.send_notification(
|
|
88
|
+
notifications.ZedNotification.SET_ZEDSCRIPTS,
|
|
89
|
+
uri=self.get_uri()
|
|
90
|
+
)
|
|
98
91
|
|
|
99
92
|
def get_text(self) -> str:
|
|
100
93
|
if self.text is None:
|
|
@@ -111,7 +104,8 @@ class Document:
|
|
|
111
104
|
return path_to_uri(self.path)
|
|
112
105
|
|
|
113
106
|
def get_lsp_diagnostics(self) -> list[types.Diagnostic]:
|
|
114
|
-
|
|
107
|
+
config = self.workspace.get_configuration()
|
|
108
|
+
lsp_diagnostics = self.diagnostics.to_lsp(config) + self.syntactic_diagnostics.to_lsp(config)
|
|
115
109
|
logging.debug(f"LSP Diagnostics for {self.get_uri()}: {len(lsp_diagnostics)}")
|
|
116
110
|
return lsp_diagnostics
|
|
117
111
|
|
|
@@ -267,8 +261,10 @@ class Document:
|
|
|
267
261
|
# set new syntactic diagnostics
|
|
268
262
|
syntactic_diagnostics = self.syntactic_diagnostics
|
|
269
263
|
syntactic_diagnostics.clear() # reset previous syntactic diagnostics
|
|
264
|
+
config = self.workspace.configuration
|
|
270
265
|
for error in result.errors:
|
|
271
266
|
syntactic_diagnostics.add(
|
|
267
|
+
config,
|
|
272
268
|
type=DiagnosticType(error.type),
|
|
273
269
|
location=error.location
|
|
274
270
|
)
|
|
@@ -12,8 +12,8 @@ from .document import Document
|
|
|
12
12
|
from .mod import Mod, ModCollection
|
|
13
13
|
from .version import Version
|
|
14
14
|
from .config import ConfigurationModel
|
|
15
|
-
from ..providers
|
|
16
|
-
from ..utils import merge_pydantic_models
|
|
15
|
+
from ..providers import notifications
|
|
16
|
+
from ..utils import merge_pydantic_models, path_to_uri
|
|
17
17
|
from ..scripts.dataset import Dataset
|
|
18
18
|
|
|
19
19
|
if TYPE_CHECKING:
|
|
@@ -43,19 +43,20 @@ class Workspace:
|
|
|
43
43
|
def __repr__(self) -> str:
|
|
44
44
|
return f"Workspace(type={self.workspace_type}, folder={self.folder})"
|
|
45
45
|
|
|
46
|
-
def load(self) ->
|
|
46
|
+
def load(self) -> tuple[int, int]:
|
|
47
47
|
"""
|
|
48
48
|
Retrieve every script files and cache them as Document instances.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
tuple[int, int]: A tuple containing the number of loaded mods and the number of loaded documents.
|
|
49
52
|
"""
|
|
50
53
|
logging.info(f"Loading workspace: {self.folder}")
|
|
51
|
-
self.load_mods()
|
|
54
|
+
loaded_mod_count = self.load_mods()
|
|
52
55
|
# self.load_documents()
|
|
53
|
-
self.load_documents()
|
|
54
|
-
|
|
55
|
-
def load_documents(self) -> None:
|
|
56
|
-
send_progress_notification(ZedNotification.LOADING_DOCUMENTS,
|
|
57
|
-
self.folder, 0.0, self.workspace_type)
|
|
56
|
+
loaded_document_count = self.load_documents()
|
|
57
|
+
return loaded_mod_count, loaded_document_count
|
|
58
58
|
|
|
59
|
+
def load_documents(self) -> int:
|
|
59
60
|
# inside the workspace folder, find every txt files, and try to load them
|
|
60
61
|
# as documents
|
|
61
62
|
files = list(self.folder.rglob("*.txt"))
|
|
@@ -63,39 +64,51 @@ class Workspace:
|
|
|
63
64
|
last_progress = 0
|
|
64
65
|
step = 10
|
|
65
66
|
step_count = step * total_files / 100
|
|
67
|
+
loaded_file_count = 0
|
|
66
68
|
for progress, path in enumerate(files):
|
|
67
|
-
self.load_document(path)
|
|
69
|
+
document = self.load_document(path)
|
|
70
|
+
if document is not None:
|
|
71
|
+
loaded_file_count += 1
|
|
68
72
|
|
|
69
73
|
# send update notification to client
|
|
70
74
|
if progress - last_progress >= step_count:
|
|
71
75
|
logging.info(f"Loading progress: {progress}/{total_files}")
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
notifications.send_notification(
|
|
77
|
+
notifications.ZedNotification.SET_PROGRESS,
|
|
78
|
+
progress=progress / total_files * 100,
|
|
79
|
+
)
|
|
74
80
|
last_progress = progress
|
|
75
81
|
|
|
76
82
|
# send final progress notification
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
notifications.send_notification(
|
|
84
|
+
notifications.ZedNotification.SET_PROGRESS,
|
|
85
|
+
progress=100
|
|
86
|
+
)
|
|
87
|
+
return loaded_file_count
|
|
79
88
|
|
|
80
|
-
def load_mods(self) ->
|
|
89
|
+
def load_mods(self) -> int:
|
|
81
90
|
logging.info(f"Loading mods for workspace: {self.folder}")
|
|
82
91
|
# look for mod.info files
|
|
83
92
|
# one or more of these files are associated to a specific mod
|
|
93
|
+
mod_count = 0
|
|
84
94
|
for file in self.folder.rglob("mod.info"):
|
|
85
95
|
# only consider versioning and common folders
|
|
86
96
|
version = Version.find_or_make_version(file)
|
|
87
97
|
if version.type in {VersionType.VERSIONING, VersionType.COMMON}:
|
|
88
|
-
mod_folder = file.parent.parent
|
|
98
|
+
mod_folder = file.parent.parent # the folder containing the 42 / common folders
|
|
89
99
|
mod = Mod.find_or_make_mod(mod_folder, self)
|
|
90
100
|
mod.add_mod_info_file(file, version)
|
|
91
101
|
self.mods[mod_folder] = mod
|
|
102
|
+
mod_count += 1
|
|
92
103
|
continue
|
|
93
104
|
|
|
94
105
|
# if it's OTHER, then it's probably not a mod file
|
|
95
106
|
# TODO: should we handle those ?
|
|
96
107
|
|
|
108
|
+
return mod_count
|
|
109
|
+
|
|
97
110
|
@staticmethod
|
|
98
|
-
def load_libraries() ->
|
|
111
|
+
def load_libraries() -> int:
|
|
99
112
|
logging.info("Loading libraries for all workspaces.")
|
|
100
113
|
|
|
101
114
|
# gather libraries from configs
|
|
@@ -111,10 +124,25 @@ class Workspace:
|
|
|
111
124
|
libraries = Workspace.filter_out_projects(libraries)
|
|
112
125
|
|
|
113
126
|
Workspace.workspace_cache[WorkspaceType.LIBRARY] = {}
|
|
127
|
+
libraries_count = 0
|
|
114
128
|
for library in libraries:
|
|
115
129
|
Workspace.workspace_cache[WorkspaceType.LIBRARY][library] = Workspace(library, WorkspaceType.LIBRARY)
|
|
116
|
-
|
|
130
|
+
libraries_count += 1
|
|
131
|
+
|
|
132
|
+
notifications.send_notification(
|
|
133
|
+
notifications.ZedNotification.SET_LIBRARIES_COUNT,
|
|
134
|
+
count=libraries_count
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
for i, library in enumerate(Workspace.workspace_cache[WorkspaceType.LIBRARY].values()):
|
|
138
|
+
notifications.send_notification(
|
|
139
|
+
notifications.ZedNotification.LOADING_DOCUMENTS,
|
|
140
|
+
uri=str(library.folder),
|
|
141
|
+
workspace_type=library.workspace_type,
|
|
142
|
+
index=i
|
|
143
|
+
)
|
|
117
144
|
library.load()
|
|
145
|
+
return libraries_count
|
|
118
146
|
|
|
119
147
|
def should_ignore(self, path: Path) -> bool:
|
|
120
148
|
for pattern in self.ignored_patterns:
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from lsprotocol
|
|
3
|
+
from lsprotocol import types
|
|
4
4
|
|
|
5
5
|
import enum
|
|
6
6
|
from typing import TYPE_CHECKING, ClassVar, Any
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
|
|
9
|
-
from lsprotocol import types
|
|
10
9
|
|
|
11
10
|
import ZedScripts
|
|
12
11
|
from ..utils import textrange_to_lsp
|
|
13
|
-
from ..enums.SyntaxErrorType import SyntaxErrorType
|
|
14
12
|
from ..structure.lexer import TextRange
|
|
15
13
|
from ..providers.locale import zedlocalizer
|
|
16
14
|
|
|
17
15
|
if TYPE_CHECKING:
|
|
16
|
+
from ..environment.config import ConfigurationModel
|
|
18
17
|
from ..enums.Diagnostic import DiagnosticType
|
|
19
18
|
|
|
20
19
|
type DiagnosticReport = (
|
|
@@ -37,19 +36,30 @@ class DiagnosticDefinition:
|
|
|
37
36
|
type: DiagnosticType,
|
|
38
37
|
severity: types.DiagnosticSeverity,
|
|
39
38
|
args: dict[str, Any] = {},
|
|
40
|
-
tags: list[DiagnosticTag] = [],
|
|
39
|
+
tags: list[types.DiagnosticTag] = [],
|
|
41
40
|
) -> None:
|
|
42
41
|
self.type: DiagnosticType = type
|
|
43
42
|
self.severity: types.DiagnosticSeverity = severity
|
|
44
43
|
self.args: dict[str, Any] = args
|
|
45
|
-
self.tags: list[DiagnosticTag] = tags
|
|
44
|
+
self.tags: list[types.DiagnosticTag] = tags
|
|
46
45
|
|
|
47
46
|
DiagnosticDefinition.by_type[type] = self
|
|
48
47
|
|
|
48
|
+
@staticmethod
|
|
49
|
+
def get(type: DiagnosticType) -> DiagnosticDefinition:
|
|
50
|
+
assert type in DiagnosticDefinition.by_type, f"WEIRD: Diagnostic type '{type}' is not registered, but this is verified earlier"
|
|
51
|
+
return DiagnosticDefinition.by_type[type]
|
|
52
|
+
|
|
49
53
|
def get_name(self) -> str:
|
|
50
54
|
"""Provides an identifier for the diagnostic type."""
|
|
51
55
|
return self.type.name
|
|
52
56
|
|
|
57
|
+
def get_severity(self) -> types.DiagnosticSeverity:
|
|
58
|
+
return self.severity
|
|
59
|
+
|
|
60
|
+
def get_tags(self) -> list[types.DiagnosticTag]:
|
|
61
|
+
return self.tags
|
|
62
|
+
|
|
53
63
|
|
|
54
64
|
@dataclass
|
|
55
65
|
class DiagnosticInfo:
|
|
@@ -59,7 +69,7 @@ class DiagnosticInfo:
|
|
|
59
69
|
|
|
60
70
|
|
|
61
71
|
class DiagnosticCollection(list[DiagnosticInfo]):
|
|
62
|
-
def to_lsp(self) -> list[types.Diagnostic]:
|
|
72
|
+
def to_lsp(self, config: ConfigurationModel) -> list[types.Diagnostic]:
|
|
63
73
|
"""
|
|
64
74
|
Converts the different diagnostic information into LSP-compatible diagnostics.
|
|
65
75
|
|
|
@@ -67,8 +77,19 @@ class DiagnosticCollection(list[DiagnosticInfo]):
|
|
|
67
77
|
list[types.Diagnostic]: A list of LSP-compatible diagnostic objects.
|
|
68
78
|
"""
|
|
69
79
|
lsp_diagnostics: list[types.Diagnostic] = []
|
|
70
|
-
for diagnostic in self:
|
|
71
|
-
definition = DiagnosticDefinition.
|
|
80
|
+
for i, diagnostic in enumerate(reversed(self)):
|
|
81
|
+
definition = DiagnosticDefinition.get(diagnostic.type)
|
|
82
|
+
severity = definition.get_severity()
|
|
83
|
+
tags = definition.get_tags()
|
|
84
|
+
|
|
85
|
+
config_def = config.find_diagnostic(diagnostic.type)
|
|
86
|
+
if config_def is not None:
|
|
87
|
+
config_severity = config_def.severity
|
|
88
|
+
if config_severity is not None:
|
|
89
|
+
severity = config_severity
|
|
90
|
+
config_tags = config_def.tags
|
|
91
|
+
if config_tags is not None:
|
|
92
|
+
tags = config_tags
|
|
72
93
|
|
|
73
94
|
# ensure that the correct arguments are always passed
|
|
74
95
|
for name, arg_type in definition.args.items():
|
|
@@ -80,22 +101,28 @@ class DiagnosticCollection(list[DiagnosticInfo]):
|
|
|
80
101
|
range=textrange_to_lsp(diagnostic.location),
|
|
81
102
|
message=zedlocalizer.localize_string(definition.type, definition,
|
|
82
103
|
args=diagnostic.args),
|
|
83
|
-
severity=
|
|
104
|
+
severity=severity,
|
|
84
105
|
source=ZedScripts.SOURCE,
|
|
85
106
|
code=definition.get_name(),
|
|
86
|
-
tags=
|
|
107
|
+
tags=tags
|
|
87
108
|
)
|
|
88
109
|
)
|
|
89
110
|
return lsp_diagnostics
|
|
90
111
|
|
|
91
|
-
def add(self, type: DiagnosticType, location: TextRange, args: dict[str, Any] = {}) -> None:
|
|
112
|
+
def add(self, config: ConfigurationModel, type: DiagnosticType, location: TextRange, args: dict[str, Any] = {}) -> None:
|
|
92
113
|
"""
|
|
93
114
|
Adds a new diagnostic to the collection.
|
|
94
115
|
|
|
95
116
|
Args:
|
|
117
|
+
config (ConfigurationModel): The configuration model to use for the diagnostic.
|
|
96
118
|
type (DiagnosticType): The type of the diagnostic.
|
|
97
119
|
location (TextRange): The location in the text where the diagnostic applies.
|
|
98
120
|
args (dict[str, Any], optional): Additional arguments for the diagnostic. Defaults to {}.
|
|
99
121
|
"""
|
|
122
|
+
config_def = config.find_diagnostic(type)
|
|
123
|
+
if config_def is not None:
|
|
124
|
+
enabled = config_def.enable
|
|
125
|
+
if not enabled:
|
|
126
|
+
return
|
|
100
127
|
self.append(DiagnosticInfo(type=type, location=location, args=args))
|
|
101
128
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Literal, overload
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from ..environment import WorkspaceType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ZedNotification(enum.StrEnum):
|
|
9
|
+
SET_ZEDSCRIPTS = "zedscripts/setZedScripts"
|
|
10
|
+
|
|
11
|
+
SET_PROGRESS = "zedscripts/setProgress"
|
|
12
|
+
SET_WORKSPACE_COUNT = "zedscripts/setWorkspaceCount"
|
|
13
|
+
SET_LIBRARIES_COUNT = "zedscripts/setLibrariesCount"
|
|
14
|
+
|
|
15
|
+
LOADING_DOCUMENTS = "zedscripts/loadingDocuments"
|
|
16
|
+
LOADING_DOCUMENTS_DONE = "zedscripts/loadingDocumentsDone"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@overload
|
|
20
|
+
def send_notification(
|
|
21
|
+
notification: Literal[ZedNotification.SET_ZEDSCRIPTS],
|
|
22
|
+
*, uri: str) -> None: ...
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@overload
|
|
26
|
+
def send_notification(
|
|
27
|
+
notification: Literal[ZedNotification.SET_PROGRESS],
|
|
28
|
+
*, progress: float) -> None: ...
|
|
29
|
+
@overload
|
|
30
|
+
def send_notification(
|
|
31
|
+
notification: Literal[ZedNotification.SET_WORKSPACE_COUNT],
|
|
32
|
+
*, count: int) -> None: ...
|
|
33
|
+
@overload
|
|
34
|
+
def send_notification(
|
|
35
|
+
notification: Literal[ZedNotification.SET_LIBRARIES_COUNT],
|
|
36
|
+
*, count: int) -> None: ...
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@overload
|
|
40
|
+
def send_notification(
|
|
41
|
+
notification: Literal[ZedNotification.LOADING_DOCUMENTS],
|
|
42
|
+
*, uri: str, workspace_type: 'WorkspaceType', index: int) -> None: ...
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def send_notification(notification: ZedNotification, **kargs) -> None:
|
|
46
|
+
"""
|
|
47
|
+
Sends a notification to the Zed server.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
notification (ZedNotification): The type of notification to send.
|
|
51
|
+
**kargs: Additional keyword arguments specific to the notification type.
|
|
52
|
+
"""
|
|
53
|
+
from ..server import ZedServer
|
|
54
|
+
server = ZedServer.instance
|
|
55
|
+
if server is None:
|
|
56
|
+
return
|
|
57
|
+
server.send_notification(notification, kargs)
|
|
@@ -116,7 +116,8 @@ class Block:
|
|
|
116
116
|
return duplicate_count > 1 # > 1 bcs there's itself in the list
|
|
117
117
|
|
|
118
118
|
def add_diagnostic(self, type: DiagnosticType, location: TextRange, args: dict[str, Any] = {}) -> None:
|
|
119
|
-
self.document.
|
|
119
|
+
config = self.document.workspace.configuration
|
|
120
|
+
self.document.diagnostics.add(config, type=type, location=location, args=args)
|
|
120
121
|
|
|
121
122
|
def add_semantic_token(self, type: SemanticTokenType, location: TextRange, modifiers: list[SemanticTokenModifier] = []) -> None:
|
|
122
123
|
self.document.semantic_tokens.add(type=type, location=location, modifiers=modifiers)
|
|
@@ -280,7 +280,7 @@ class Value(Element["ValueNode"]):
|
|
|
280
280
|
|
|
281
281
|
if IS_DEBUG:
|
|
282
282
|
txt += "(debug)\n\n"
|
|
283
|
-
txt += f"- Refs: {[
|
|
283
|
+
txt += f"- Refs: {[f"{ref.document.path}:{ref.get_ref_id_range()}" for ref in self.refs]}"
|
|
284
284
|
|
|
285
285
|
return make_hover_information(txt, value_node.to_range())
|
|
286
286
|
|
|
@@ -7,15 +7,14 @@ from pygls.lsp.server import LanguageServer
|
|
|
7
7
|
from pygls.protocol.language_server import LanguageServerProtocol
|
|
8
8
|
|
|
9
9
|
from .__about__ import __version__
|
|
10
|
-
from .utils import uri_to_path
|
|
10
|
+
from .utils import uri_to_path, path_to_uri
|
|
11
11
|
from .environment import WorkspaceType
|
|
12
12
|
from .environment.workspace import Workspace
|
|
13
13
|
from .environment.document import Document
|
|
14
14
|
from .providers.diagnostics import DiagnosticReport
|
|
15
15
|
from .providers.semantic_tokens import get_tokens
|
|
16
16
|
from .providers.locale import zedlocalizer
|
|
17
|
-
from .providers import capabilities
|
|
18
|
-
from .providers.notifications import ZedNotification, NotificationParams
|
|
17
|
+
from .providers import capabilities, notifications
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
|
|
@@ -32,7 +31,7 @@ class ZedServer(LanguageServer):
|
|
|
32
31
|
zedlocalizer.load_locale_files()
|
|
33
32
|
ZedServer.instance = self
|
|
34
33
|
|
|
35
|
-
def send_notification(self, method: ZedNotification, params:
|
|
34
|
+
def send_notification(self, method: notifications.ZedNotification, params: dict | None = None) -> None:
|
|
36
35
|
logging.debug("Sending notification: %s with params: %s", method, params)
|
|
37
36
|
self.protocol.notify(
|
|
38
37
|
method,
|
|
@@ -186,16 +185,37 @@ def initialized(server: ZedServer, params: types.InitializedParams) -> None:
|
|
|
186
185
|
# load the global dataset
|
|
187
186
|
Workspace.global_dataset.load()
|
|
188
187
|
|
|
188
|
+
# load workspaces
|
|
189
189
|
logging.debug("Server workspace folders")
|
|
190
190
|
logging.debug(server.workspace.folders)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
191
|
+
should_load_libraries = False
|
|
192
|
+
folders = server.workspace.folders.values()
|
|
193
|
+
|
|
194
|
+
notifications.send_notification(
|
|
195
|
+
notifications.ZedNotification.SET_WORKSPACE_COUNT,
|
|
196
|
+
count=len(folders)
|
|
197
197
|
)
|
|
198
198
|
|
|
199
|
+
for i, workspace_folder in enumerate(folders):
|
|
200
|
+
ws = Workspace(uri_to_path(workspace_folder.uri), WorkspaceType.PROJECT)
|
|
201
|
+
|
|
202
|
+
notifications.send_notification(
|
|
203
|
+
notifications.ZedNotification.LOADING_DOCUMENTS,
|
|
204
|
+
uri=path_to_uri(ws.folder),
|
|
205
|
+
workspace_type=ws.workspace_type,
|
|
206
|
+
index=i+1
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
_, file_count = ws.load()
|
|
210
|
+
if file_count != 0:
|
|
211
|
+
should_load_libraries = True
|
|
212
|
+
|
|
213
|
+
# load libraries if any ZedScripts files were found
|
|
214
|
+
if should_load_libraries:
|
|
215
|
+
Workspace.load_libraries()
|
|
216
|
+
|
|
217
|
+
server.send_notification(notifications.ZedNotification.LOADING_DOCUMENTS_DONE)
|
|
218
|
+
|
|
199
219
|
|
|
200
220
|
@zedserver.feature(types.TEXT_DOCUMENT_DID_OPEN)
|
|
201
221
|
def did_open(server: ZedServer, params: types.DidOpenTextDocumentParams) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ZedScripts
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Author: SimKDT
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.12.3
|
|
@@ -19,11 +19,11 @@ Dynamic: license-file
|
|
|
19
19
|
|
|
20
20
|
# ZedScripts LSP
|
|
21
21
|
|
|
22
|
-
](LICENSE)
|
|
23
|
+

|
|
24
|
+
[](https://pypi.org/project/ZedScripts/)
|
|
25
|
+
[](https://pypi.org/project/ZedScripts/)
|
|
26
|
+

|
|
27
27
|
|
|
28
28
|
> [!IMPORTANT]
|
|
29
29
|
> Work In Progress, this is a BETA release
|
|
@@ -101,5 +101,32 @@ Example configuration:
|
|
|
101
101
|
|
|
102
102
|
WIP: proper documentation will come soon
|
|
103
103
|
|
|
104
|
+
## IDE configuration
|
|
105
|
+
Based on the IDE you use, you may need to install the ZedScripts LSP application for your OS in the [releases](https://github.com/PZ-Wiki-Modding/ZedScripts-LSP/releases) (Linux, Windows).
|
|
106
|
+
|
|
107
|
+
### Visual Studio Code
|
|
108
|
+
|
|
109
|
+
Install the [ZedScripts extension](https://marketplace.visualstudio.com/items?itemName=SimKDT.ZedScripts) from the Visual Studio Code marketplace. The extension will handle the downloading and setup of the ZedScripts LSP server for you.
|
|
110
|
+
|
|
111
|
+
### VIM
|
|
112
|
+
|
|
113
|
+
Using [yegappan/lsp](https://github.com/yegappan/lsp), setup the ZedScripts LSP server as follows:
|
|
114
|
+
|
|
115
|
+
```vim
|
|
116
|
+
let lspServers = [
|
|
117
|
+
\ #{
|
|
118
|
+
\ name: 'zedscripts',
|
|
119
|
+
\ filetype: ['text', 'zedscripts'],
|
|
120
|
+
\ path: 'path/to/ZedScripts',
|
|
121
|
+
\ args: []
|
|
122
|
+
\ }
|
|
123
|
+
\ ]
|
|
124
|
+
|
|
125
|
+
autocmd User LspSetup call LspAddServer(lspServers)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
> [!NOTE]
|
|
129
|
+
> You can see [this video](https://www.youtube.com/watch?v=-5lb_jLQmKc) which explains how to set up VIM, and notably setup a LSP server.
|
|
130
|
+
|
|
104
131
|
## License
|
|
105
132
|
See [LICENSE](LICENSE) for details.
|
|
@@ -22,7 +22,6 @@ src/ZedScripts/environment/workspace.py
|
|
|
22
22
|
src/ZedScripts/locale/en.json
|
|
23
23
|
src/ZedScripts/providers/actions.py
|
|
24
24
|
src/ZedScripts/providers/capabilities.py
|
|
25
|
-
src/ZedScripts/providers/configuration.py
|
|
26
25
|
src/ZedScripts/providers/debug.py
|
|
27
26
|
src/ZedScripts/providers/diagnostics.py
|
|
28
27
|
src/ZedScripts/providers/hover.py
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import enum
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
6
|
-
|
|
7
|
-
from ..scripts.version import DataVersion
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class DatasetTag(enum.Enum):
|
|
11
|
-
LATEST = "latest"
|
|
12
|
-
STABLE = "stable"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class ReleaseModel(BaseModel):
|
|
17
|
-
major: int = Field(
|
|
18
|
-
description="Build game version number.",
|
|
19
|
-
ge=42,
|
|
20
|
-
)
|
|
21
|
-
minor: int = Field(
|
|
22
|
-
description="Minor game version number.",
|
|
23
|
-
ge=0,
|
|
24
|
-
)
|
|
25
|
-
patch: int = Field(
|
|
26
|
-
description="Patch game version number.",
|
|
27
|
-
ge=0,
|
|
28
|
-
)
|
|
29
|
-
version: Optional[int] = Field(
|
|
30
|
-
description="Dataset version number for the provided Build release (major.minor.patch). This is incremented whenever the dataset for a specific version is updated.",
|
|
31
|
-
default=None,
|
|
32
|
-
ge=0,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
class DatasetModel(BaseModel):
|
|
36
|
-
release: Optional[ReleaseModel] = Field(
|
|
37
|
-
description="Provides a configuration for the dataset version to use for validation. This overrides the `latest` and `stable` fields if set.",
|
|
38
|
-
default=None,
|
|
39
|
-
)
|
|
40
|
-
latest: Optional[bool] = Field(
|
|
41
|
-
description="Indicates whether to use the latest dataset version for validation. This is ignored if `release` is set. Overrides the `stable` field if set.",
|
|
42
|
-
default=False,
|
|
43
|
-
)
|
|
44
|
-
stable: Optional[bool] = Field(
|
|
45
|
-
description="Provides a configuration for the stable dataset version to use for validation. Ignored if `release` or `latest` is set.",
|
|
46
|
-
default=True,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
def to_data_version(self) -> DataVersion | DatasetTag:
|
|
50
|
-
if self.release is None:
|
|
51
|
-
if self.latest:
|
|
52
|
-
return DatasetTag.LATEST
|
|
53
|
-
if self.stable:
|
|
54
|
-
return DatasetTag.STABLE
|
|
55
|
-
logging.warning("No dataset version specified, defaulting to 'stable'.")
|
|
56
|
-
return DatasetTag.STABLE
|
|
57
|
-
from ..scripts.dataset import Manifest
|
|
58
|
-
try:
|
|
59
|
-
return Manifest.from_release_model(self.release)
|
|
60
|
-
except Exception as e:
|
|
61
|
-
logging.error(f"Failed to get data version from release model: {e}. Defaulting to 'stable'.")
|
|
62
|
-
return DatasetTag.STABLE
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class ConfigurationModel(BaseModel):
|
|
66
|
-
"""Represents the content of the configuration files for workspace environments."""
|
|
67
|
-
dataset: DatasetModel = Field(
|
|
68
|
-
description="Provides configuration for the dataset version to use for diagnostics.",
|
|
69
|
-
default_factory=DatasetModel,
|
|
70
|
-
)
|
|
71
|
-
libraries: set[Path] = Field(
|
|
72
|
-
description="Set of library folders to reference. Usually this should contain the base game folder.",
|
|
73
|
-
default_factory=set,
|
|
74
|
-
)
|
|
75
|
-
ignored: set[str] = Field(
|
|
76
|
-
description="Regex patterns for files and folders to ignore in the workspace.",
|
|
77
|
-
default=set([
|
|
78
|
-
r"tileGeometry\.txt",
|
|
79
|
-
r"tileDepthTextureAssignments\.txt",
|
|
80
|
-
r".+\.tiles\.txt"
|
|
81
|
-
]),
|
|
82
|
-
)
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
from typing import Any, TypedDict
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ConfigurationType(enum.IntEnum):
|
|
6
|
-
DATA_SOURCE = enum.auto()
|
|
7
|
-
|
|
8
|
-
# TODO: implement fixed configuration values
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
default_configuration: dict[ConfigurationType, Any] = {
|
|
12
|
-
ConfigurationType.DATA_SOURCE: "latest"
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Configuration:
|
|
18
|
-
def __init__(self):
|
|
19
|
-
self.settings: dict[ConfigurationType, Any] = {}
|
|
20
|
-
|
|
21
|
-
def get(self, key: ConfigurationType, default=None):
|
|
22
|
-
return self.settings.get(key, default)
|
|
23
|
-
|
|
24
|
-
def set(self, key: ConfigurationType, value):
|
|
25
|
-
self.settings[key] = value
|
|
26
|
-
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
from typing import TypedDict
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from ..utils import path_to_uri
|
|
6
|
-
|
|
7
|
-
from typing import TYPE_CHECKING
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from ..environment import WorkspaceType
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ZedNotification(enum.StrEnum):
|
|
13
|
-
SET_ZEDSCRIPTS = "zedscripts/setZedScripts"
|
|
14
|
-
|
|
15
|
-
LOADING_DOCUMENTS = "zedscripts/loadingDocuments"
|
|
16
|
-
LOADING_DOCUMENTS_DONE = "zedscripts/loadingDocumentsDone"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class NotificationParams(TypedDict): ...
|
|
21
|
-
|
|
22
|
-
class SetZedScriptsNotificationParams(NotificationParams):
|
|
23
|
-
uri: str
|
|
24
|
-
|
|
25
|
-
class LoadingDocumentsNotificationParams(NotificationParams):
|
|
26
|
-
uri: str
|
|
27
|
-
progress: float
|
|
28
|
-
workspace_type: 'WorkspaceType'
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def send_progress_notification(type: ZedNotification, folder: Path, progress: float, workspace_type: 'WorkspaceType'):
|
|
34
|
-
from ..server import ZedServer
|
|
35
|
-
server = ZedServer.instance
|
|
36
|
-
if server is None:
|
|
37
|
-
return
|
|
38
|
-
server.send_notification(
|
|
39
|
-
type,
|
|
40
|
-
LoadingDocumentsNotificationParams(
|
|
41
|
-
uri=path_to_uri(folder),
|
|
42
|
-
progress=progress,
|
|
43
|
-
workspace_type=workspace_type
|
|
44
|
-
)
|
|
45
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|