Skip to content

Commit e1bf423

Browse files
committed
update
1 parent 0850a6f commit e1bf423

23 files changed

+309
-377
lines changed

python/docs/locate_design.md

Lines changed: 0 additions & 163 deletions
This file was deleted.

python/src/lsap/definition.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import asyncer
77
from attrs import define
88
from lsap_schema.definition import DefinitionRequest, DefinitionResponse
9-
from lsap_schema.types import SymbolInfo
9+
from lsap_schema.types import SymbolCodeInfo
1010
from lsp_client.capability.request import (
1111
WithRequestDeclaration,
1212
WithRequestDefinition,
@@ -73,18 +73,16 @@ async def __call__(self, req: DefinitionRequest) -> DefinitionResponse | None:
7373
infos = []
7474
async with asyncer.create_task_group() as tg:
7575

76-
async def resolve_item(loc: Location) -> SymbolInfo | None:
76+
async def resolve_item(loc: Location) -> SymbolCodeInfo | None:
7777
target_file_path = self.client.from_uri(loc.uri)
7878
if symbol_info := await self.symbol.resolve(
7979
target_file_path,
8080
loc.range.start,
81-
include_hover=req.include_hover,
82-
include_code=req.include_code,
8381
):
8482
return symbol_info
8583

8684
infos = [tg.soonify(resolve_item)(loc) for loc in locations]
87-
items: list[SymbolInfo] = [
85+
items: list[SymbolCodeInfo] = [
8886
value for info in infos if (value := info.value) is not None
8987
]
9088

python/src/lsap/draft/completion.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from functools import cached_property
2-
from typing import Protocol, cast, override, runtime_checkable
2+
from typing import Protocol, override, runtime_checkable
33

44
from attrs import Factory, define
55
from lsap_schema.draft.completion import (
@@ -57,7 +57,14 @@ async def fetcher() -> list[CompletionItem] | None:
5757
for lsp_item in lsp_items:
5858
kind = "Unknown"
5959
if lsp_item.kind is not None:
60-
kind = cast(CompletionItemKind, lsp_item.kind).name
60+
if isinstance(lsp_item.kind, CompletionItemKind):
61+
kind = lsp_item.kind.name
62+
else:
63+
# Handle case where it might be a raw integer
64+
try:
65+
kind = CompletionItemKind(lsp_item.kind).name
66+
except ValueError:
67+
kind = str(lsp_item.kind)
6168

6269
documentation = None
6370
if lsp_item.documentation:
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from __future__ import annotations
2+
3+
from typing import Literal, Protocol, override, runtime_checkable
4+
5+
from attrs import Factory, define
6+
from lsap_schema.draft.diagnostics import (
7+
Diagnostic,
8+
FileDiagnosticsRequest,
9+
FileDiagnosticsResponse,
10+
)
11+
from lsap_schema.types import Position, Range
12+
from lsp_client.capability.request import WithDocumentDiagnostic
13+
from lsp_client.protocol import CapabilityClientProtocol
14+
from lsprotocol.types import DiagnosticSeverity
15+
16+
from lsap.abc import Capability
17+
from lsap.utils.cache import PaginationCache
18+
from lsap.utils.pagination import paginate
19+
20+
21+
@runtime_checkable
22+
class DiagnosticsClient(WithDocumentDiagnostic, CapabilityClientProtocol, Protocol): ...
23+
24+
25+
@define
26+
class FileDiagnosticsCapability(
27+
Capability[DiagnosticsClient, FileDiagnosticsRequest, FileDiagnosticsResponse]
28+
):
29+
_cache: PaginationCache[Diagnostic] = Factory(PaginationCache)
30+
31+
@override
32+
async def __call__(
33+
self, req: FileDiagnosticsRequest
34+
) -> FileDiagnosticsResponse | None:
35+
async def fetcher() -> list[Diagnostic] | None:
36+
lsp_diagnostics = await self.client.request_diagnostics(req.file_path)
37+
if lsp_diagnostics is None:
38+
return None
39+
40+
severity_map: dict[
41+
DiagnosticSeverity, Literal["Error", "Warning", "Information", "Hint"]
42+
] = {
43+
DiagnosticSeverity.Error: "Error",
44+
DiagnosticSeverity.Warning: "Warning",
45+
DiagnosticSeverity.Information: "Information",
46+
DiagnosticSeverity.Hint: "Hint",
47+
}
48+
49+
items = []
50+
for d in lsp_diagnostics:
51+
severity: Literal["Error", "Warning", "Information", "Hint"] = (
52+
"Information"
53+
)
54+
if d.severity is not None:
55+
try:
56+
severity = severity_map[DiagnosticSeverity(d.severity)]
57+
except (KeyError, ValueError):
58+
pass
59+
60+
items.append(
61+
Diagnostic(
62+
range=Range(
63+
start=Position.from_lsp(d.range.start),
64+
end=Position.from_lsp(d.range.end),
65+
),
66+
severity=severity,
67+
message=d.message,
68+
source=d.source,
69+
code=d.code,
70+
)
71+
)
72+
73+
# Filter by min_severity
74+
severity_order = ["Hint", "Information", "Warning", "Error"]
75+
min_idx = severity_order.index(req.min_severity)
76+
items = [i for i in items if severity_order.index(i.severity) >= min_idx]
77+
78+
return items
79+
80+
result = await paginate(req, self._cache, fetcher)
81+
if result is None:
82+
return None
83+
84+
return FileDiagnosticsResponse(
85+
file_path=req.file_path,
86+
diagnostics=result.items,
87+
start_index=req.start_index,
88+
max_items=req.max_items,
89+
total=result.total,
90+
has_more=result.has_more,
91+
pagination_id=result.pagination_id,
92+
)

python/src/lsap/hover.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from functools import cached_property
4-
from typing import Protocol, override, runtime_checkable
4+
from typing import Protocol, runtime_checkable
55

66
from attrs import define
77
from lsap_schema.hover import HoverRequest, HoverResponse
@@ -26,7 +26,6 @@ class HoverCapability(Capability[HoverClient, HoverRequest, HoverResponse]):
2626
def locate(self) -> LocateCapability:
2727
return LocateCapability(self.client)
2828

29-
@override
3029
async def __call__(self, req: HoverRequest) -> HoverResponse | None:
3130
if not (loc_resp := await self.locate(req)):
3231
return None
@@ -37,16 +36,4 @@ async def __call__(self, req: HoverRequest) -> HoverResponse | None:
3736
if hover is None:
3837
return None
3938

40-
contents = ""
41-
if isinstance(hover.value, str):
42-
contents = hover.contents
43-
elif isinstance(hover.contents, list):
44-
contents = "\n".join(
45-
c if isinstance(c, str) else c.value for c in hover.contents
46-
)
47-
else:
48-
contents = hover.contents.value
49-
50-
return HoverResponse(
51-
contents=contents,
52-
)
39+
return HoverResponse(content=hover.value)

python/src/lsap/reference.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import asyncer
55
from attrs import Factory, define
66
from lsap_schema.reference import ReferenceItem, ReferenceRequest, ReferenceResponse
7-
from lsap_schema.types import SymbolInfo, SymbolKind
7+
from lsap_schema.types import Position, Range, SymbolDetailInfo, SymbolKind
88
from lsp_client.capability.request import (
99
WithRequestDocumentSymbol,
1010
WithRequestHover,
@@ -116,19 +116,26 @@ async def _process_reference(
116116
if not (snippet := reader.read(context_range)):
117117
return
118118

119-
symbol: SymbolInfo | None = None
119+
symbol: SymbolDetailInfo | None = None
120120
if symbols := await self.client.request_document_symbol_list(file_path):
121121
if match := symbol_at(symbols, range_.start):
122122
path, sym = match
123123
kind = SymbolKind.from_lsp(sym.kind)
124124

125-
symbol = SymbolInfo(
125+
symbol = SymbolDetailInfo(
126126
file_path=file_path,
127127
name=sym.name,
128128
path=path,
129129
kind=kind,
130-
detail=sym.detail,
130+
detail=sym.detail or "",
131+
hover="",
132+
range=Range(
133+
start=Position.from_lsp(sym.range.start),
134+
end=Position.from_lsp(sym.range.end),
135+
),
131136
)
137+
if hover := await self.client.request_hover(file_path, range_.start):
138+
symbol.hover = hover.value
132139

133140
items.append(
134141
ReferenceItem(

0 commit comments

Comments
 (0)