pyxle-langkit 0.2.0__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.
- pyxle_langkit-0.2.0/.gitignore +32 -0
- pyxle_langkit-0.2.0/CLAUDE.md +163 -0
- pyxle_langkit-0.2.0/LICENSE +21 -0
- pyxle_langkit-0.2.0/PKG-INFO +69 -0
- pyxle_langkit-0.2.0/README.md +35 -0
- pyxle_langkit-0.2.0/editors/vscode/.vscodeignore +10 -0
- pyxle_langkit-0.2.0/editors/vscode/LICENSE +21 -0
- pyxle_langkit-0.2.0/editors/vscode/icons/pyx.svg +11 -0
- pyxle_langkit-0.2.0/editors/vscode/language-configuration.json +51 -0
- pyxle_langkit-0.2.0/editors/vscode/package.json +106 -0
- pyxle_langkit-0.2.0/editors/vscode/src/extension.ts +135 -0
- pyxle_langkit-0.2.0/editors/vscode/src/status.ts +59 -0
- pyxle_langkit-0.2.0/editors/vscode/syntaxes/pyx.tmLanguage.json +27 -0
- pyxle_langkit-0.2.0/editors/vscode/tsconfig.json +20 -0
- pyxle_langkit-0.2.0/package.json +8 -0
- pyxle_langkit-0.2.0/pyproject.toml +71 -0
- pyxle_langkit-0.2.0/pyxle_langkit/__init__.py +18 -0
- pyxle_langkit-0.2.0/pyxle_langkit/cli.py +206 -0
- pyxle_langkit-0.2.0/pyxle_langkit/completions.py +397 -0
- pyxle_langkit-0.2.0/pyxle_langkit/definitions.py +273 -0
- pyxle_langkit-0.2.0/pyxle_langkit/diagnostics.py +142 -0
- pyxle_langkit-0.2.0/pyxle_langkit/document.py +187 -0
- pyxle_langkit-0.2.0/pyxle_langkit/formatting.py +292 -0
- pyxle_langkit-0.2.0/pyxle_langkit/hover.py +407 -0
- pyxle_langkit-0.2.0/pyxle_langkit/js/jsx_component_extractor.mjs +193 -0
- pyxle_langkit-0.2.0/pyxle_langkit/js/react_parser_runner.mjs +116 -0
- pyxle_langkit-0.2.0/pyxle_langkit/js/ts_service.mjs +338 -0
- pyxle_langkit-0.2.0/pyxle_langkit/linter.py +850 -0
- pyxle_langkit-0.2.0/pyxle_langkit/parser_adapter.py +123 -0
- pyxle_langkit-0.2.0/pyxle_langkit/react_checker.py +248 -0
- pyxle_langkit-0.2.0/pyxle_langkit/semantic_tokens.py +363 -0
- pyxle_langkit-0.2.0/pyxle_langkit/server.py +639 -0
- pyxle_langkit-0.2.0/pyxle_langkit/symbols.py +253 -0
- pyxle_langkit-0.2.0/pyxle_langkit/ts_bridge.py +319 -0
- pyxle_langkit-0.2.0/pyxle_langkit/workspace.py +193 -0
- pyxle_langkit-0.2.0/tests/__init__.py +0 -0
- pyxle_langkit-0.2.0/tests/conftest.py +123 -0
- pyxle_langkit-0.2.0/tests/test_cli.py +318 -0
- pyxle_langkit-0.2.0/tests/test_completions.py +447 -0
- pyxle_langkit-0.2.0/tests/test_definitions.py +491 -0
- pyxle_langkit-0.2.0/tests/test_diagnostics.py +224 -0
- pyxle_langkit-0.2.0/tests/test_document.py +258 -0
- pyxle_langkit-0.2.0/tests/test_formatting.py +460 -0
- pyxle_langkit-0.2.0/tests/test_hover.py +464 -0
- pyxle_langkit-0.2.0/tests/test_linter.py +1879 -0
- pyxle_langkit-0.2.0/tests/test_parser_adapter.py +219 -0
- pyxle_langkit-0.2.0/tests/test_react_checker.py +311 -0
- pyxle_langkit-0.2.0/tests/test_semantic_tokens.py +439 -0
- pyxle_langkit-0.2.0/tests/test_server.py +1184 -0
- pyxle_langkit-0.2.0/tests/test_symbols.py +366 -0
- pyxle_langkit-0.2.0/tests/test_workspace.py +259 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.eggs/
|
|
8
|
+
|
|
9
|
+
# Coverage
|
|
10
|
+
.coverage
|
|
11
|
+
htmlcov/
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
|
|
14
|
+
# Node
|
|
15
|
+
node_modules/
|
|
16
|
+
package-lock.json
|
|
17
|
+
|
|
18
|
+
# VS Code extension build
|
|
19
|
+
editors/vscode/out/
|
|
20
|
+
editors/vscode/node_modules/
|
|
21
|
+
editors/vscode/*.vsix
|
|
22
|
+
|
|
23
|
+
# Ruff
|
|
24
|
+
.ruff_cache/
|
|
25
|
+
|
|
26
|
+
# IDE
|
|
27
|
+
.vscode/
|
|
28
|
+
.idea/
|
|
29
|
+
|
|
30
|
+
# OS
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# CLAUDE.md — Pyxle Langkit v2
|
|
2
|
+
|
|
3
|
+
Language tooling suite for Pyxle — powers IDE support for `.pyx` files.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Project Overview
|
|
8
|
+
|
|
9
|
+
Pyxle Langkit provides IDE support for `.pyx` files — the hybrid Python/JSX format
|
|
10
|
+
used by the Pyxle framework. The architecture is **server-driven**: all intelligence
|
|
11
|
+
lives in the Python LSP server, and the VS Code extension is a thin LSP client.
|
|
12
|
+
|
|
13
|
+
**Key architecture decisions:**
|
|
14
|
+
- **jedi** for Python completions, definitions, hover, references
|
|
15
|
+
- **pyflakes** for Python static analysis
|
|
16
|
+
- **Babel** (Node.js subprocess) for JSX validation
|
|
17
|
+
- **pygls** for the LSP server framework
|
|
18
|
+
- **TypeScript** for the VS Code extension
|
|
19
|
+
- **No virtual files on disk** — jedi analyzes in-memory, no SegmentManager
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Module Map
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
pyxle_langkit/
|
|
27
|
+
|-- __init__.py # Public API exports
|
|
28
|
+
|-- server.py # PyxleLanguageServer (pygls) — main LSP orchestrator
|
|
29
|
+
|-- parser_adapter.py # Tolerant parser wrapper (never raises)
|
|
30
|
+
|-- document.py # PyxDocument — parsed .pyx with line mapping
|
|
31
|
+
|-- workspace.py # WorkspaceIndex — tracks all .pyx files
|
|
32
|
+
|-- linter.py # Static analysis: pyflakes, Pyxle rules, React rules
|
|
33
|
+
|-- react_checker.py # Babel-based JSX validation via Node.js
|
|
34
|
+
|-- completions.py # jedi + Pyxle-specific completions
|
|
35
|
+
|-- hover.py # jedi + Pyxle-specific hover docs
|
|
36
|
+
|-- definitions.py # jedi + cross-section go-to-definition
|
|
37
|
+
|-- diagnostics.py # Diagnostic aggregation + position mapping
|
|
38
|
+
|-- symbols.py # Document + workspace symbols
|
|
39
|
+
|-- formatting.py # ruff (Python) + prettier (JSX) coordinator
|
|
40
|
+
|-- semantic_tokens.py # AST-based semantic tokens
|
|
41
|
+
|-- cli.py # CLI: parse, lint, outline, format
|
|
42
|
+
+-- js/ # Node.js helpers
|
|
43
|
+
|-- react_parser_runner.mjs
|
|
44
|
+
+-- jsx_component_extractor.mjs
|
|
45
|
+
|
|
46
|
+
editors/vscode/ # VS Code extension (TypeScript, thin client)
|
|
47
|
+
|-- src/
|
|
48
|
+
| |-- extension.ts # Activation + LSP client lifecycle
|
|
49
|
+
| +-- status.ts # Status bar management
|
|
50
|
+
|-- syntaxes/
|
|
51
|
+
| +-- pyx.tmLanguage.json
|
|
52
|
+
|-- test/
|
|
53
|
+
| |-- suite/
|
|
54
|
+
| | +-- extension.test.ts
|
|
55
|
+
| +-- runTest.ts
|
|
56
|
+
|-- package.json
|
|
57
|
+
|-- tsconfig.json
|
|
58
|
+
+-- language-configuration.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Setup
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Install core framework (editable)
|
|
67
|
+
pip install -e /path/to/pyxle[dev]
|
|
68
|
+
|
|
69
|
+
# Install langkit
|
|
70
|
+
pip install -e .[dev]
|
|
71
|
+
|
|
72
|
+
# Install Babel helpers
|
|
73
|
+
npm install
|
|
74
|
+
|
|
75
|
+
# Build VS Code extension
|
|
76
|
+
cd editors/vscode && npm install && npm run compile
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Mandatory Rules
|
|
82
|
+
|
|
83
|
+
### 1. Run Tests After Every Change
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pytest # Full suite with coverage
|
|
87
|
+
pytest tests/ -x # Stop on first failure
|
|
88
|
+
pytest --no-cov # Skip coverage for faster iteration
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
All tests must pass. Coverage threshold is 95%.
|
|
92
|
+
|
|
93
|
+
### 2. Test File Convention
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
pyxle_langkit/parser_adapter.py -> tests/test_parser_adapter.py
|
|
97
|
+
pyxle_langkit/document.py -> tests/test_document.py
|
|
98
|
+
pyxle_langkit/linter.py -> tests/test_linter.py
|
|
99
|
+
pyxle_langkit/completions.py -> tests/test_completions.py
|
|
100
|
+
pyxle_langkit/hover.py -> tests/test_hover.py
|
|
101
|
+
pyxle_langkit/definitions.py -> tests/test_definitions.py
|
|
102
|
+
pyxle_langkit/server.py -> tests/test_server.py
|
|
103
|
+
pyxle_langkit/workspace.py -> tests/test_workspace.py
|
|
104
|
+
pyxle_langkit/diagnostics.py -> tests/test_diagnostics.py
|
|
105
|
+
pyxle_langkit/symbols.py -> tests/test_symbols.py
|
|
106
|
+
pyxle_langkit/formatting.py -> tests/test_formatting.py
|
|
107
|
+
pyxle_langkit/semantic_tokens.py -> tests/test_semantic_tokens.py
|
|
108
|
+
pyxle_langkit/cli.py -> tests/test_cli.py
|
|
109
|
+
editors/vscode/ -> editors/vscode/test/
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 3. Lint Before Committing
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
ruff check pyxle_langkit/ tests/
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 4. Commit Scope Convention
|
|
119
|
+
|
|
120
|
+
Scope examples: `linter`, `server`, `completions`, `hover`, `definitions`,
|
|
121
|
+
`formatting`, `vscode`, `parser`, `cli`, `workspace`.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Module Rules
|
|
126
|
+
|
|
127
|
+
### Parser Adapter
|
|
128
|
+
- Must tolerate incomplete/malformed code — IDE users type incomplete code constantly
|
|
129
|
+
- Never raise exceptions for parse failures — return PyxDocument with diagnostics
|
|
130
|
+
|
|
131
|
+
### Linter
|
|
132
|
+
- Python issues use pyflakes — don't reinvent its checks
|
|
133
|
+
- `server` and `action` are whitelisted as globals (injected by Pyxle runtime)
|
|
134
|
+
- JSX issues delegate to Node.js/Babel
|
|
135
|
+
- All issues must have accurate line/column mapped to the original `.pyx` file
|
|
136
|
+
|
|
137
|
+
### Completions / Hover / Definitions
|
|
138
|
+
- Use jedi for Python intelligence — import safely with try/except
|
|
139
|
+
- If jedi is not available, return Pyxle-specific results only (never crash)
|
|
140
|
+
- Map all positions: .pyx → virtual Python → jedi → virtual Python → .pyx
|
|
141
|
+
|
|
142
|
+
### LSP Server
|
|
143
|
+
- Never block the event loop with synchronous I/O
|
|
144
|
+
- Use asyncio.to_thread() for jedi calls (jedi is synchronous)
|
|
145
|
+
- Diagnostics published on didOpen, didChange, didSave
|
|
146
|
+
|
|
147
|
+
### VS Code Extension
|
|
148
|
+
- TypeScript — compiled to out/ directory
|
|
149
|
+
- Thin LSP client only — no SegmentManager, no virtual files
|
|
150
|
+
- All intelligence comes from the LSP server
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## DO NOT List
|
|
155
|
+
|
|
156
|
+
- **DO NOT** import anything from `pyxle` other than `pyxle.compiler`
|
|
157
|
+
- **DO NOT** add `print()` — use `logging`
|
|
158
|
+
- **DO NOT** write virtual files to disk for language analysis
|
|
159
|
+
- **DO NOT** use mutable dataclasses for data-carrying types
|
|
160
|
+
- **DO NOT** block the async event loop with synchronous I/O
|
|
161
|
+
- **DO NOT** grow caches without eviction policies
|
|
162
|
+
- **DO NOT** hardcode file paths or OS-specific assumptions
|
|
163
|
+
- **DO NOT** commit `.vsix` build artifacts or `node_modules/`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shivam Saini
|
|
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,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyxle-langkit
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Language tools for Pyxle: LSP server, linter, and editor integrations.
|
|
5
|
+
Project-URL: Homepage, https://pyxle.dev
|
|
6
|
+
Project-URL: Repository, https://github.com/pyxle-framework/pyxle-langkit
|
|
7
|
+
Author-email: Shivam Saini <dev@pyxle.dev>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: language-server,linter,lsp,pyxle,vscode
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE)
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: jedi<0.20,>=0.19
|
|
24
|
+
Requires-Dist: lsprotocol>=2023.0.0
|
|
25
|
+
Requires-Dist: pyflakes<3.3,>=3.2
|
|
26
|
+
Requires-Dist: pygls<2.0,>=1.3
|
|
27
|
+
Requires-Dist: pyxle-framework>=0.1.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: coverage<8.0,>=7.4; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov<5.0,>=4.1; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest<9.0,>=8.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff<0.7,>=0.6; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# Pyxle Language Toolkit
|
|
36
|
+
|
|
37
|
+
Language tools for [Pyxle](https://pyxle.dev) `.pyx` files — LSP server, linter, and VS Code extension.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **Syntax highlighting** via TextMate grammar (Python + JSX sections)
|
|
42
|
+
- **Diagnostics** from pyflakes, Babel, and Pyxle-specific rules
|
|
43
|
+
- **Completions** via Jedi (Python) + Pyxle component completions (JSX)
|
|
44
|
+
- **Hover documentation** for Python symbols and Pyxle decorators/components
|
|
45
|
+
- **Go-to-definition** via Jedi with cross-section navigation
|
|
46
|
+
- **Document symbols** and **workspace symbols**
|
|
47
|
+
- **Formatting** with ruff (Python) and prettier (JSX)
|
|
48
|
+
- **Semantic tokens** via AST analysis
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install pyxle-langkit
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The VS Code extension is available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=pyxle.pyxle-language-tools).
|
|
57
|
+
|
|
58
|
+
## Architecture
|
|
59
|
+
|
|
60
|
+
All intelligence lives in the Python LSP server. The VS Code extension is a thin LSP client (~100 LOC).
|
|
61
|
+
|
|
62
|
+
- **Python analysis**: [Jedi](https://jedi.readthedocs.io/) for completions, definitions, hover
|
|
63
|
+
- **JSX analysis**: Pyxle-specific completions + [Babel](https://babeljs.io/) for validation
|
|
64
|
+
- **Static analysis**: [pyflakes](https://pypi.org/project/pyflakes/) + Pyxle rules
|
|
65
|
+
- **LSP framework**: [pygls](https://pygls.readthedocs.io/)
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Pyxle Language Toolkit
|
|
2
|
+
|
|
3
|
+
Language tools for [Pyxle](https://pyxle.dev) `.pyx` files — LSP server, linter, and VS Code extension.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Syntax highlighting** via TextMate grammar (Python + JSX sections)
|
|
8
|
+
- **Diagnostics** from pyflakes, Babel, and Pyxle-specific rules
|
|
9
|
+
- **Completions** via Jedi (Python) + Pyxle component completions (JSX)
|
|
10
|
+
- **Hover documentation** for Python symbols and Pyxle decorators/components
|
|
11
|
+
- **Go-to-definition** via Jedi with cross-section navigation
|
|
12
|
+
- **Document symbols** and **workspace symbols**
|
|
13
|
+
- **Formatting** with ruff (Python) and prettier (JSX)
|
|
14
|
+
- **Semantic tokens** via AST analysis
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install pyxle-langkit
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The VS Code extension is available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=pyxle.pyxle-language-tools).
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
All intelligence lives in the Python LSP server. The VS Code extension is a thin LSP client (~100 LOC).
|
|
27
|
+
|
|
28
|
+
- **Python analysis**: [Jedi](https://jedi.readthedocs.io/) for completions, definitions, hover
|
|
29
|
+
- **JSX analysis**: Pyxle-specific completions + [Babel](https://babeljs.io/) for validation
|
|
30
|
+
- **Static analysis**: [pyflakes](https://pypi.org/project/pyflakes/) + Pyxle rules
|
|
31
|
+
- **LSP framework**: [pygls](https://pygls.readthedocs.io/)
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
MIT
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shivam Saini
|
|
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,11 @@
|
|
|
1
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="g" x1="2" y1="1" x2="14" y2="15" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#6ee7b7" />
|
|
5
|
+
<stop offset="0.5" stop-color="#34d399" />
|
|
6
|
+
<stop offset="1" stop-color="#059669" />
|
|
7
|
+
</linearGradient>
|
|
8
|
+
</defs>
|
|
9
|
+
<path d="M4.5 13 V3 H9 Q12.5 3 12.5 6.5 Q12.5 10 9 10 H4.5" stroke="url(#g)" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none" />
|
|
10
|
+
<circle cx="9" cy="6.5" r="1.2" fill="#6ee7b7" />
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comments": {
|
|
3
|
+
"lineComment": "//",
|
|
4
|
+
"blockComment": ["/*", "*/"]
|
|
5
|
+
},
|
|
6
|
+
"brackets": [
|
|
7
|
+
["{", "}"],
|
|
8
|
+
["[", "]"],
|
|
9
|
+
["(", ")"],
|
|
10
|
+
["<", ">"]
|
|
11
|
+
],
|
|
12
|
+
"autoClosingPairs": [
|
|
13
|
+
{ "open": "{", "close": "}" },
|
|
14
|
+
{ "open": "[", "close": "]" },
|
|
15
|
+
{ "open": "(", "close": ")" },
|
|
16
|
+
{ "open": "'", "close": "'", "notIn": ["string", "comment"] },
|
|
17
|
+
{ "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
|
|
18
|
+
{ "open": "`", "close": "`", "notIn": ["string", "comment"] },
|
|
19
|
+
{ "open": "<", "close": ">", "notIn": ["string", "comment"] }
|
|
20
|
+
],
|
|
21
|
+
"surroundingPairs": [
|
|
22
|
+
["{", "}"],
|
|
23
|
+
["[", "]"],
|
|
24
|
+
["(", ")"],
|
|
25
|
+
["'", "'"],
|
|
26
|
+
["\"", "\""],
|
|
27
|
+
["`", "`"],
|
|
28
|
+
["<", ">"]
|
|
29
|
+
],
|
|
30
|
+
"folding": {
|
|
31
|
+
"markers": {
|
|
32
|
+
"start": "^\\s*(?:#\\s*---\\s*(?:python|server|javascript|client)|(?:def|class|async\\s+def|if|for|while|with|try|export\\s+default\\s+function|function|const)\\b)",
|
|
33
|
+
"end": "^\\s*$"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"indentationRules": {
|
|
37
|
+
"increaseIndentPattern": "^\\s*(?:def\\b|class\\b|if\\b|elif\\b|else:|for\\b|while\\b|with\\b|try:|except\\b|finally:|async\\s+def\\b|function\\b|=>\\s*\\{|\\{).*$",
|
|
38
|
+
"decreaseIndentPattern": "^\\s*(?:elif\\b|else:|except\\b|finally:|\\}|\\)|\\])"
|
|
39
|
+
},
|
|
40
|
+
"onEnterRules": [
|
|
41
|
+
{
|
|
42
|
+
"beforeText": ":\\s*$",
|
|
43
|
+
"action": { "indent": "indent" }
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"beforeText": "\\{\\s*$",
|
|
47
|
+
"afterText": "^\\s*\\}",
|
|
48
|
+
"action": { "indent": "indent" }
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pyxle-language-tools",
|
|
3
|
+
"displayName": "Pyxle Language Tools",
|
|
4
|
+
"publisher": "pyxle",
|
|
5
|
+
"version": "0.1.0-beta",
|
|
6
|
+
"description": "Language support for Pyxle .pyx files — syntax highlighting, diagnostics, completions, hover, go-to-definition, and formatting.",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/pyxle-framework/pyxle-langkit"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/pyxle-framework/pyxle-langkit/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://pyxle.dev",
|
|
16
|
+
"keywords": ["pyxle", "pyx", "python", "react", "jsx", "lsp"],
|
|
17
|
+
"engines": {
|
|
18
|
+
"vscode": "^1.85.0"
|
|
19
|
+
},
|
|
20
|
+
"categories": ["Programming Languages"],
|
|
21
|
+
"activationEvents": ["onLanguage:pyxle"],
|
|
22
|
+
"main": "./out/extension.js",
|
|
23
|
+
"scripts": {
|
|
24
|
+
"compile": "tsc -p ./",
|
|
25
|
+
"watch": "tsc -watch -p ./",
|
|
26
|
+
"lint": "tsc --noEmit",
|
|
27
|
+
"pretest": "npm run compile",
|
|
28
|
+
"test": "node ./out/test/runTest.js",
|
|
29
|
+
"package": "npx @vscode/vsce package --no-dependencies"
|
|
30
|
+
},
|
|
31
|
+
"contributes": {
|
|
32
|
+
"languages": [
|
|
33
|
+
{
|
|
34
|
+
"id": "pyxle",
|
|
35
|
+
"aliases": ["Pyxle", "pyxle"],
|
|
36
|
+
"extensions": [".pyx"],
|
|
37
|
+
"configuration": "./language-configuration.json",
|
|
38
|
+
"icon": {
|
|
39
|
+
"light": "./icons/pyx.svg",
|
|
40
|
+
"dark": "./icons/pyx.svg"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"grammars": [
|
|
45
|
+
{
|
|
46
|
+
"language": "pyxle",
|
|
47
|
+
"scopeName": "source.pyxle",
|
|
48
|
+
"path": "./syntaxes/pyx.tmLanguage.json",
|
|
49
|
+
"embeddedLanguages": {
|
|
50
|
+
"source.python": "python",
|
|
51
|
+
"source.js.jsx": "javascriptreact"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"configuration": [
|
|
56
|
+
{
|
|
57
|
+
"title": "Pyxle",
|
|
58
|
+
"properties": {
|
|
59
|
+
"pyxle.langserver.command": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"default": "pyxle-langserver",
|
|
62
|
+
"description": "Command to launch the Pyxle language server. Install via: pip install pyxle-langkit"
|
|
63
|
+
},
|
|
64
|
+
"pyxle.langserver.args": {
|
|
65
|
+
"type": "array",
|
|
66
|
+
"items": { "type": "string" },
|
|
67
|
+
"default": ["--stdio"],
|
|
68
|
+
"description": "Arguments forwarded to the language server command."
|
|
69
|
+
},
|
|
70
|
+
"pyxle.formatting.python": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"default": "ruff",
|
|
73
|
+
"enum": ["ruff", "black", "none"],
|
|
74
|
+
"description": "Python formatter for .pyx files."
|
|
75
|
+
},
|
|
76
|
+
"pyxle.formatting.jsx": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"default": "prettier",
|
|
79
|
+
"enum": ["prettier", "none"],
|
|
80
|
+
"description": "JSX formatter for .pyx files."
|
|
81
|
+
},
|
|
82
|
+
"pyxle.diagnostics.pyflakes": {
|
|
83
|
+
"type": "boolean",
|
|
84
|
+
"default": true,
|
|
85
|
+
"description": "Enable pyflakes diagnostics for Python sections."
|
|
86
|
+
},
|
|
87
|
+
"pyxle.diagnostics.react": {
|
|
88
|
+
"type": "boolean",
|
|
89
|
+
"default": true,
|
|
90
|
+
"description": "Enable React/JSX analysis via Babel."
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"vscode-languageclient": "^9.0.1"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"typescript": "^5.3.0",
|
|
101
|
+
"@types/vscode": "^1.85.0",
|
|
102
|
+
"@types/node": "^20.0.0",
|
|
103
|
+
"@vscode/test-electron": "^2.3.0",
|
|
104
|
+
"@vscode/vsce": "^2.22.0"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pyxle Language Tools — VS Code extension.
|
|
3
|
+
*
|
|
4
|
+
* This is a thin LSP client. All language intelligence (completions, hover,
|
|
5
|
+
* diagnostics, formatting, semantic tokens, go-to-definition) is provided by
|
|
6
|
+
* the ``pyxle-langserver`` Python process. The extension's only job is to
|
|
7
|
+
* launch that process, wire up the Language Client, and manage the status bar.
|
|
8
|
+
*
|
|
9
|
+
* JSX intelligence comes from two sources:
|
|
10
|
+
* 1. The LSP server provides Pyxle-specific completions (components, props)
|
|
11
|
+
* 2. The ``embeddedLanguages`` mapping in the grammar contribution tells
|
|
12
|
+
* VS Code that ``source.js.jsx`` regions are ``javascriptreact``, which
|
|
13
|
+
* enables basic word-based completions and bracket matching from VS Code's
|
|
14
|
+
* built-in TypeScript/JavaScript extension.
|
|
15
|
+
*
|
|
16
|
+
* Full semantic JSX intelligence (type-aware completions, go-to-definition
|
|
17
|
+
* into React types) requires embedding TypeScript's language service in the
|
|
18
|
+
* LSP server — planned for a future release.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import * as vscode from "vscode";
|
|
22
|
+
import {
|
|
23
|
+
LanguageClient,
|
|
24
|
+
LanguageClientOptions,
|
|
25
|
+
ServerOptions,
|
|
26
|
+
} from "vscode-languageclient/node";
|
|
27
|
+
import { createStatusBar, updateStatus, StatusState } from "./status";
|
|
28
|
+
|
|
29
|
+
const LANGUAGE_ID = "pyxle";
|
|
30
|
+
const MAX_RETRIES = 3;
|
|
31
|
+
const RETRY_DELAY_MS = 2_000;
|
|
32
|
+
|
|
33
|
+
let client: LanguageClient | undefined;
|
|
34
|
+
let outputChannel: vscode.OutputChannel;
|
|
35
|
+
let statusBar: vscode.StatusBarItem;
|
|
36
|
+
|
|
37
|
+
/* ------------------------------------------------------------------ */
|
|
38
|
+
/* Activation */
|
|
39
|
+
/* ------------------------------------------------------------------ */
|
|
40
|
+
|
|
41
|
+
export function activate(context: vscode.ExtensionContext): void {
|
|
42
|
+
outputChannel = vscode.window.createOutputChannel("Pyxle Language Server");
|
|
43
|
+
context.subscriptions.push(outputChannel);
|
|
44
|
+
|
|
45
|
+
statusBar = createStatusBar(context);
|
|
46
|
+
updateStatus(statusBar, StatusState.Starting);
|
|
47
|
+
|
|
48
|
+
startClient(context, 0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* ------------------------------------------------------------------ */
|
|
52
|
+
/* Deactivation */
|
|
53
|
+
/* ------------------------------------------------------------------ */
|
|
54
|
+
|
|
55
|
+
export function deactivate(): Thenable<void> | undefined {
|
|
56
|
+
return client?.stop();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* ------------------------------------------------------------------ */
|
|
60
|
+
/* Client lifecycle */
|
|
61
|
+
/* ------------------------------------------------------------------ */
|
|
62
|
+
|
|
63
|
+
function startClient(
|
|
64
|
+
context: vscode.ExtensionContext,
|
|
65
|
+
attempt: number,
|
|
66
|
+
): void {
|
|
67
|
+
const config = vscode.workspace.getConfiguration("pyxle.langserver");
|
|
68
|
+
const command = config.get<string>("command", "pyxle-langserver");
|
|
69
|
+
const args = config.get<string[]>("args", ["--stdio"]);
|
|
70
|
+
|
|
71
|
+
const serverOptions: ServerOptions = {
|
|
72
|
+
run: { command, args },
|
|
73
|
+
debug: { command, args },
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const clientOptions: LanguageClientOptions = {
|
|
77
|
+
documentSelector: [{ scheme: "file", language: LANGUAGE_ID }],
|
|
78
|
+
synchronize: {
|
|
79
|
+
fileEvents: vscode.workspace.createFileSystemWatcher("**/*.pyx"),
|
|
80
|
+
},
|
|
81
|
+
outputChannel,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
client = new LanguageClient(
|
|
85
|
+
"pyxle",
|
|
86
|
+
"Pyxle Language Server",
|
|
87
|
+
serverOptions,
|
|
88
|
+
clientOptions,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const startPromise = client.start();
|
|
92
|
+
|
|
93
|
+
client.onDidChangeState((event) => {
|
|
94
|
+
if (event.newState === 2 /* Running */) {
|
|
95
|
+
updateStatus(statusBar, StatusState.Running);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const onReady = (): void => {
|
|
100
|
+
updateStatus(statusBar, StatusState.Running);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const onError = (error: unknown): void => {
|
|
104
|
+
const message =
|
|
105
|
+
error instanceof Error ? error.message : String(error);
|
|
106
|
+
outputChannel.appendLine(
|
|
107
|
+
`Language server failed to start: ${message}`,
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
if (attempt < MAX_RETRIES) {
|
|
111
|
+
const next = attempt + 1;
|
|
112
|
+
updateStatus(statusBar, StatusState.Retrying, next, MAX_RETRIES);
|
|
113
|
+
outputChannel.appendLine(
|
|
114
|
+
`Retrying in ${RETRY_DELAY_MS}ms (attempt ${next}/${MAX_RETRIES})...`,
|
|
115
|
+
);
|
|
116
|
+
setTimeout(() => startClient(context, next), RETRY_DELAY_MS);
|
|
117
|
+
} else {
|
|
118
|
+
updateStatus(statusBar, StatusState.Failed);
|
|
119
|
+
vscode.window
|
|
120
|
+
.showErrorMessage(
|
|
121
|
+
`Pyxle Language Server failed after ${MAX_RETRIES} attempts. Is pyxle-langserver installed?`,
|
|
122
|
+
"Show Output",
|
|
123
|
+
)
|
|
124
|
+
.then((choice) => {
|
|
125
|
+
if (choice === "Show Output") {
|
|
126
|
+
outputChannel.show();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
startPromise.then(onReady, onError);
|
|
133
|
+
|
|
134
|
+
context.subscriptions.push({ dispose: () => { client?.stop(); } });
|
|
135
|
+
}
|