mirror of
https://github.com/tiennm99/serena.git
synced 2026-09-04 02:18:39 +00:00
Fix Windows compatibility of TypeScriptLanguageServer (pwd not available)
This commit is contained in:
@@ -34,8 +34,8 @@ With Serena, we provide
|
||||
* direct, out-of-the-box support for:
|
||||
* Python
|
||||
* Java (_Note_: startup is slow, initial startup especially so)
|
||||
* TypeScript
|
||||
* indirect support (requiring separate language server installation) for:
|
||||
* TypeScript (untested)
|
||||
* Ruby (untested)
|
||||
* Go (untested)
|
||||
* C# (untested)
|
||||
|
||||
+36
-21
@@ -7,7 +7,6 @@ import json
|
||||
import shutil
|
||||
import logging
|
||||
import os
|
||||
import pwd
|
||||
import subprocess
|
||||
import pathlib
|
||||
from contextlib import asynccontextmanager
|
||||
@@ -20,6 +19,16 @@ from multilspy.lsp_protocol_handler.lsp_types import InitializeParams
|
||||
from multilspy.multilspy_config import MultilspyConfig
|
||||
from multilspy.multilspy_utils import PlatformUtils, PlatformId
|
||||
|
||||
# Platform-specific imports
|
||||
if os.name != 'nt': # Unix-like systems
|
||||
import pwd
|
||||
else:
|
||||
# Dummy pwd module for Windows
|
||||
class pwd:
|
||||
@staticmethod
|
||||
def getpwuid(uid):
|
||||
return type('obj', (), {'pw_name': os.environ.get('USERNAME', 'unknown')})()
|
||||
|
||||
|
||||
class TypeScriptLanguageServer(LanguageServer):
|
||||
"""
|
||||
@@ -47,14 +56,14 @@ class TypeScriptLanguageServer(LanguageServer):
|
||||
platform_id = PlatformUtils.get_platform_id()
|
||||
|
||||
valid_platforms = [
|
||||
PlatformId.LINUX_x64,
|
||||
PlatformId.LINUX_x64,
|
||||
PlatformId.LINUX_arm64,
|
||||
PlatformId.OSX,
|
||||
PlatformId.OSX,
|
||||
PlatformId.OSX_x64,
|
||||
PlatformId.OSX_arm64,
|
||||
PlatformId.WIN_x64,
|
||||
PlatformId.WIN_arm64,
|
||||
]
|
||||
PlatformId.WIN_x64,
|
||||
PlatformId.WIN_arm64,
|
||||
]
|
||||
assert platform_id in valid_platforms, f"Platform {platform_id} is not supported for multilspy javascript/typescript at the moment"
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), "runtime_dependencies.json"), "r") as f:
|
||||
@@ -71,22 +80,28 @@ class TypeScriptLanguageServer(LanguageServer):
|
||||
is_npm_installed = shutil.which('npm') is not None
|
||||
assert is_npm_installed, "npm is not installed or isn't in PATH. Please install npm and try again."
|
||||
|
||||
# Install typescript and typescript-language-server if not already installed, as a non-root user
|
||||
# Install typescript and typescript-language-server if not already installed
|
||||
if not os.path.exists(tsserver_ls_dir):
|
||||
os.makedirs(tsserver_ls_dir, exist_ok=True)
|
||||
for dependency in runtime_dependencies:
|
||||
user = pwd.getpwuid(os.getuid()).pw_name
|
||||
subprocess.run(
|
||||
dependency["command"],
|
||||
shell=True,
|
||||
check=True,
|
||||
user=user,
|
||||
cwd=tsserver_ls_dir,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
|
||||
# Handle platform-specific user settings
|
||||
subprocess_kwargs = {
|
||||
'shell': True,
|
||||
'check': True,
|
||||
'cwd': tsserver_ls_dir,
|
||||
'stdout': subprocess.DEVNULL,
|
||||
'stderr': subprocess.DEVNULL
|
||||
}
|
||||
|
||||
# Only add user parameter on Unix-like systems
|
||||
if os.name != 'nt': # Not Windows
|
||||
user = pwd.getpwuid(os.getuid()).pw_name
|
||||
subprocess_kwargs['user'] = user
|
||||
|
||||
subprocess.run(dependency["command"], **subprocess_kwargs)
|
||||
|
||||
tsserver_executable_path = os.path.join(tsserver_ls_dir, "node_modules", ".bin", "typescript-language-server")
|
||||
|
||||
assert os.path.exists(tsserver_executable_path), "typescript-language-server executable not found. Please install typescript-language-server and try again."
|
||||
return f"{tsserver_executable_path} --stdio"
|
||||
|
||||
@@ -113,7 +128,7 @@ class TypeScriptLanguageServer(LanguageServer):
|
||||
d["workspaceFolders"][0]["name"] = os.path.basename(repository_absolute_path)
|
||||
|
||||
return d
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def start_server(self) -> AsyncIterator["TypeScriptLanguageServer"]:
|
||||
"""
|
||||
@@ -164,7 +179,7 @@ class TypeScriptLanguageServer(LanguageServer):
|
||||
logging.INFO,
|
||||
)
|
||||
init_response = await self.server.send.initialize(initialize_params)
|
||||
|
||||
|
||||
# TypeScript-specific capability checks
|
||||
assert init_response["capabilities"]["textDocumentSync"] == 2
|
||||
assert "completionProvider" in init_response["capabilities"]
|
||||
@@ -172,7 +187,7 @@ class TypeScriptLanguageServer(LanguageServer):
|
||||
"triggerCharacters": ['.', '"', "'", '/', '@', '<'],
|
||||
"resolveProvider": True
|
||||
}
|
||||
|
||||
|
||||
self.server.notify.initialized({})
|
||||
self.completions_available.set()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user