Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@ Requires py3.8 and up.

## Setup

Use UV to manage virtual environment and run scripts.

Install dependecies:
```sh
pip install -r requirements.txt
uv venv
```

## Update types

Download the latest json schema:
```sh
python ./download_schemas.py
uv run download_schemas.py
```

Generate the types:
Generate the types and fix some issues by triggering formatting:
```sh
python ./generate.py
uv run generate.py
uv run ruff format
```

Copy the `lsp_types.py` file to your project.

NOTE: Do not import types that begin with `__`. These types are internal types and are not meant to be used.
63 changes: 54 additions & 9 deletions generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from operator import itemgetter
from pathlib import Path
from typing import cast
from typing import Literal
Expand Down Expand Up @@ -42,7 +43,7 @@
ALIAS_OVERRIDES: dict[str, str] = {'LSPArray': "Sequence['LSPAny']", 'LSPObject': 'Mapping[str, Any]'}


def generate(output: str) -> None:
def generate_protocol(output: str) -> None:
reset_new_literal_structures()

schema = Path('./lsprotocol/lsp.json').read_text(encoding='utf-8')
Expand All @@ -54,10 +55,20 @@ def generate(output: str) -> None:
'# ruff: noqa: E501, UP006, UP007',
'# Code generated. DO NOT EDIT.',
f'# LSP v{specification_version}\n',
'from __future__ import annotations',
'from enum import IntEnum, IntFlag, StrEnum',
'from typing import Any, Dict, List, Literal, Mapping, Sequence, TypedDict, Union',
'from typing_extensions import NotRequired, TypeAlias\n\n',
'from __future__ import annotations\n',
'from enum import IntEnum',
'from enum import IntFlag',
'from enum import StrEnum',
'from typing import Any',
'from typing import Dict',
'from typing import List',
'from typing import Literal',
'from typing import Mapping',
'from typing import Sequence',
'from typing import TypedDict',
'from typing import Union',
'from typing_extensions import NotRequired',
'from typing_extensions import TypeAlias\n',
'URI = str',
'DocumentUri = str',
'Uint = int',
Expand All @@ -71,12 +82,45 @@ def generate(output: str) -> None:
content += '\n'.join(generate_type_aliases(lsp_json['typeAliases'], ALIAS_OVERRIDES))
content += '\n\n\n'
content += '\n\n\n'.join(generate_structures(lsp_json['structures']))
content += '\n'
content += '\n'.join(get_new_literal_structures())

# Remove trailing spaces.
lines = content.split('\n')
lines = [line.rstrip() for line in lines]
content = '\n'.join(lines)

Path(output).write_text(content, encoding='utf-8')


def generate_custom(output: str) -> None:
reset_new_literal_structures()

schema = Path('./lsprotocol/lsp.json').read_text(encoding='utf-8')
lsp_json = cast('MetaModel', json.loads(schema))

content = '\n'.join( # noqa: FLY002
[
'# ruff: noqa: UP006, UP007',
'from __future__ import annotations\n',
'from .lsp_types import *',
'from typing import List',
'from typing import Literal',
'from typing import TypedDict',
'from typing import Union',
'from typing_extensions import TypeAlias',
]
)

# Sort by method name to avoid unstable order.
requests = sorted(lsp_json['requests'], key=itemgetter('typeName'))
notifications = sorted(lsp_json['notifications'], key=itemgetter('typeName'))

content += '\n\n\n'
content += '\n\n\n'.join(generate_requests_and_responses(lsp_json['requests']))
content += '\n\n\n'.join(generate_requests_and_responses(requests))
content += '\n\n\n'
content += '\n\n\n'.join(generate_notifications(lsp_json['notifications']))
content += '\n\n\n'.join(generate_notifications(notifications))
content += '\n'
content += '\n'.join(get_new_literal_structures())

# Remove trailing spaces.
lines = content.split('\n')
Expand All @@ -86,4 +130,5 @@ def generate(output: str) -> None:
Path(output).write_text(content, encoding='utf-8')


generate(output='./generated/lsp_types.py')
generate_protocol(output='./generated/lsp_types.py')
generate_custom(output='./generated/custom.py')
Loading