Skip to content

Commit 95c6d1c

Browse files
Copilotobserverw
andauthored
Add typescript-language-server support (#3)
* Initial plan * Add support for typescript-language-server Co-authored-by: observerw <[email protected]> * Remove unused attributes from TsserverClient Co-authored-by: observerw <[email protected]> * Remove WithRequestCallHierarchy capability from TsserverClient Co-authored-by: observerw <[email protected]> * Improve error message and add missing Position import to example Co-authored-by: observerw <[email protected]> * Rename TsserverClient to TypescriptClient and TsserverLocalServer to TypescriptServer Co-authored-by: observerw <[email protected]> * Add documentation references for initialization options and TypeScript dependency Co-authored-by: observerw <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: observerw <[email protected]>
1 parent eee7ba6 commit 95c6d1c

File tree

4 files changed

+159
-6
lines changed

4 files changed

+159
-6
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,13 @@ if __name__ == "__main__":
8888

8989
The library includes pre-configured clients for popular language servers:
9090

91-
| Language Server | Module Path | Language |
92-
| --------------- | ---------------------------------- | --------------------- |
93-
| Pyright | `lsp_client.clients.pyright` | Python |
94-
| Pyrefly | `lsp_client.clients.pyrefly` | Python |
95-
| Rust Analyzer | `lsp_client.clients.rust_analyzer` | Rust |
96-
| Deno | `lsp_client.clients.deno` | TypeScript/JavaScript |
91+
| Language Server | Module Path | Language |
92+
| ---------------------------- | ------------------------------------ | --------------------- |
93+
| Pyright | `lsp_client.clients.pyright` | Python |
94+
| Pyrefly | `lsp_client.clients.pyrefly` | Python |
95+
| Rust Analyzer | `lsp_client.clients.rust_analyzer` | Rust |
96+
| Deno | `lsp_client.clients.deno` | TypeScript/JavaScript |
97+
| TypeScript Language Server | `lsp_client.clients.typescript` | TypeScript/JavaScript |
9798

9899
## Contributing
99100

examples/typescript.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Example: Using TypeScript Language Server for TypeScript code analysis
2+
#
3+
# This example demonstrates how to use the TypeScript Language Server
4+
# to find definition locations in TypeScript code. The typescript-language-server
5+
# provides powerful static analysis for TypeScript and JavaScript projects.
6+
7+
from __future__ import annotations
8+
9+
from pathlib import Path
10+
11+
import anyio
12+
13+
from lsp_client import Position # noqa: F401 - Used in commented example code
14+
from lsp_client.clients.typescript import TypescriptClient, TypescriptServer
15+
16+
17+
async def main():
18+
# Set up workspace directory
19+
workspace = Path.cwd()
20+
async with TypescriptClient(
21+
server=TypescriptServer(),
22+
workspace=workspace,
23+
) as client:
24+
# Example: Find definition of TypescriptClient at line 13, column 28
25+
# This demonstrates the definition lookup capability
26+
print(f"Using language server for: {client.get_language_id()}")
27+
28+
# In a real scenario, you would provide a TypeScript file path
29+
# refs = await client.request_definition_locations(
30+
# file_path="src/index.ts",
31+
# position=Position(10, 15),
32+
# )
33+
#
34+
# if not refs:
35+
# print("No definition locations found.")
36+
# return
37+
#
38+
# # Display all definition locations found
39+
# for ref in refs:
40+
# print(f"Definition location found at {ref.uri} - Range: {ref.range}")
41+
42+
43+
if __name__ == "__main__":
44+
anyio.run(main) # Run the async example

src/lsp_client/clients/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
from .pyrefly import PyreflyClient
77
from .pyright import PyrightClient
88
from .rust_analyzer import RustAnalyzerClient
9+
from .typescript import TypescriptClient
910

1011
clients: Final = (
1112
DenoClient,
1213
PyreflyClient,
1314
PyrightClient,
1415
RustAnalyzerClient,
16+
TypescriptClient,
1517
)
1618

1719
PythonClient = PyrightClient
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from __future__ import annotations
2+
3+
import shutil
4+
from functools import partial
5+
from subprocess import CalledProcessError
6+
from typing import Any, override
7+
8+
import anyio
9+
from attrs import define
10+
from loguru import logger
11+
12+
from lsp_client.capability.request import (
13+
WithRequestDefinition,
14+
WithRequestDocumentSymbol,
15+
WithRequestHover,
16+
WithRequestImplementation,
17+
WithRequestReferences,
18+
WithRequestTypeDefinition,
19+
WithRequestWorkspaceSymbol,
20+
)
21+
from lsp_client.capability.server_notification import (
22+
WithReceivePublishDiagnostics,
23+
)
24+
from lsp_client.capability.server_notification.log_message import WithReceiveLogMessage
25+
from lsp_client.client.abc import LSPClient
26+
from lsp_client.server.docker import DockerServer
27+
from lsp_client.server.local import LocalServer
28+
from lsp_client.utils.types import lsp_type
29+
30+
TypescriptServer = partial(
31+
LocalServer, command=["typescript-language-server", "--stdio"]
32+
)
33+
TypescriptDockerServer = partial(DockerServer, image="docker.io/lspcontainers/tsserver")
34+
35+
36+
@define
37+
class TypescriptClient(
38+
LSPClient,
39+
WithRequestHover,
40+
WithRequestDefinition,
41+
WithRequestReferences,
42+
WithRequestImplementation,
43+
WithRequestTypeDefinition,
44+
WithRequestDocumentSymbol,
45+
WithRequestWorkspaceSymbol,
46+
WithReceiveLogMessage,
47+
WithReceivePublishDiagnostics,
48+
):
49+
"""
50+
- Language: TypeScript, JavaScript
51+
- Homepage: https://github.com/typescript-language-server/typescript-language-server
52+
- Doc: https://github.com/typescript-language-server/typescript-language-server#readme
53+
- Github: https://github.com/typescript-language-server/typescript-language-server
54+
- VSCode Extension: Built-in TypeScript support in VS Code
55+
"""
56+
57+
# Preferences for TypeScript/JavaScript language features
58+
# Reference: https://github.com/typescript-language-server/typescript-language-server#initializationoptions
59+
suggest_complete_function_calls: bool = True
60+
include_automatic_optional_chain_completions: bool = True
61+
include_completions_for_module_exports: bool = True
62+
include_completions_with_insert_text: bool = True
63+
64+
@override
65+
def get_language_id(self) -> lsp_type.LanguageKind:
66+
return lsp_type.LanguageKind.TypeScript
67+
68+
@override
69+
def create_initialization_options(self) -> dict[str, Any]:
70+
return {
71+
"preferences": {
72+
"includeCompletionsForModuleExports": self.include_completions_for_module_exports,
73+
"includeAutomaticOptionalChainCompletions": self.include_automatic_optional_chain_completions,
74+
"includeCompletionsWithInsertText": self.include_completions_with_insert_text,
75+
},
76+
"suggest": {
77+
"completeFunctionCalls": self.suggest_complete_function_calls,
78+
},
79+
}
80+
81+
@override
82+
def check_server_compatibility(self, info: lsp_type.ServerInfo | None) -> None:
83+
return
84+
85+
@override
86+
async def ensure_installed(self) -> None:
87+
if shutil.which("typescript-language-server"):
88+
return
89+
90+
logger.warning(
91+
"typescript-language-server not found, attempting to install via npm..."
92+
)
93+
94+
try:
95+
# typescript-language-server requires the TypeScript compiler as a peer dependency
96+
# Reference: https://github.com/typescript-language-server/typescript-language-server#installing
97+
await anyio.run_process(
98+
["npm", "install", "-g", "typescript-language-server", "typescript"]
99+
)
100+
logger.info("Successfully installed typescript-language-server via npm")
101+
return
102+
except CalledProcessError as e:
103+
raise RuntimeError(
104+
"Could not install typescript-language-server and typescript. Please install them manually with 'npm install -g typescript-language-server typescript'. "
105+
"See https://github.com/typescript-language-server/typescript-language-server for more information."
106+
) from e

0 commit comments

Comments
 (0)