| 494 | |
| 495 | |
| 496 | class LSPCodeServer(ToolBase): |
| 497 | |
| 498 | skip_files = [ |
| 499 | 'vite.config.ts', 'vite.config.js', 'webpack.config.js', |
| 500 | 'webpack.config.ts', 'rollup.config.js', 'rollup.config.ts', |
| 501 | 'next.config.js', 'next.config.ts', 'tsconfig.json', 'jsconfig.json', |
| 502 | 'package.json', 'pom.xml', 'build.gradle' |
| 503 | ] |
| 504 | |
| 505 | language_mapping = { |
| 506 | 'typescript': ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'], |
| 507 | 'python': ['.py'], |
| 508 | 'java': ['.java'], |
| 509 | } |
| 510 | |
| 511 | skip_prefixes = ['.', '..', '__pycache__', 'node_modules'] |
| 512 | |
| 513 | def __init__(self, config): |
| 514 | super().__init__(config) |
| 515 | self.servers: Dict[str, LSPServer] = {} |
| 516 | self.file_versions: Dict[str, int] = {} |
| 517 | self.opened_documents: Dict[str, str] = { |
| 518 | } # Track opened documents: file_path -> language |
| 519 | self.output_dir = getattr(self.config, 'output_dir', |
| 520 | DEFAULT_OUTPUT_DIR) |
| 521 | self.workspace_dir = self.output_dir |
| 522 | self.index_dir = os.path.join(self.output_dir, DEFAULT_INDEX_DIR) |
| 523 | self.lock_dir = os.path.join(self.output_dir, DEFAULT_LOCK_DIR) |
| 524 | self.cleanup_lsp_index_dirs() |
| 525 | |
| 526 | async def connect(self) -> None: |
| 527 | """Initialize LSP servers""" |
| 528 | logger.info('LSP Code Server connecting...') |
| 529 | |
| 530 | def cleanup_lsp_index_dirs(self): |
| 531 | cleanup_dirs = [ |
| 532 | os.path.join(self.output_dir, '.jdtls_workspace'), # Java LSP |
| 533 | os.path.join(self.output_dir, |
| 534 | '.pyright'), # Python LSP (if exists) |
| 535 | os.path.join(self.output_dir, 'node_modules', |
| 536 | '.cache'), # TypeScript LSP cache |
| 537 | ] |
| 538 | |
| 539 | for dir_path in cleanup_dirs: |
| 540 | if os.path.exists(dir_path): |
| 541 | try: |
| 542 | shutil.rmtree(dir_path, ignore_errors=True) |
| 543 | except Exception as e: # noqa |
| 544 | logger.warning( |
| 545 | f'Failed to cleanup LSP index directory {dir_path}: {e}' |
| 546 | ) |
| 547 | |
| 548 | async def cleanup(self) -> None: |
| 549 | """Stop all LSP servers and clear indexes""" |
| 550 | # Close all open documents first |
| 551 | for file_path, language in list(self.opened_documents.items()): |
| 552 | server = self.servers.get(language) |
| 553 | if server: |
no outgoing calls