diff --git a/.vscode/settings.json b/.vscode/settings.json index d98e4514..5d3ef653 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "cSpell.words": [ + "langsrv", "multilspy", "pixi" ] diff --git a/src/multilspy/language_server.py b/src/multilspy/language_server.py index 7f6e11be..c26091e1 100644 --- a/src/multilspy/language_server.py +++ b/src/multilspy/language_server.py @@ -833,7 +833,7 @@ class LanguageServer: start_path = start_dir_relative_path or self.repository_root_path return await process_directory(start_path) - async def request_dir_overview(self, relative_dir_path: str) -> dict[str, list[tuple[str, int, int]]]: + async def request_dir_overview(self, relative_dir_path: str) -> dict[str, list[tuple[str, multilspy_types.SymbolKind, int]]]: """ An overview of the given directory. @@ -851,7 +851,7 @@ class LanguageServer: symbol_tree = await self.request_full_symbol_tree(relative_dir_path) # Initialize result dictionary - result: dict[str, list[tuple[str, int, int]]] = defaultdict(list) + result: dict[str, list[tuple[str, multilspy_types.SymbolKind, int]]] = defaultdict(list) # Helper function to process a symbol and its children def process_symbol(symbol: multilspy_types.UnifiedSymbolInformation): @@ -1511,7 +1511,7 @@ class SyncLanguageServer: ).result() return result - def request_dir_overview(self, relative_dir_path: str) -> dict[str, list[tuple[str, int, int]]]: + def request_dir_overview(self, relative_dir_path: str) -> dict[str, list[tuple[str, multilspy_types.SymbolKind, int]]]: """ An overview of the given directory. diff --git a/src/multilspy/lsp_protocol_handler/lsp_types.py b/src/multilspy/lsp_protocol_handler/lsp_types.py index a6476164..b90c9271 100644 --- a/src/multilspy/lsp_protocol_handler/lsp_types.py +++ b/src/multilspy/lsp_protocol_handler/lsp_types.py @@ -188,6 +188,13 @@ class SymbolKind(IntEnum): Event = 24 Operator = 25 TypeParameter = 26 + + @classmethod + def from_int(cls, value: int) -> "SymbolKind": + for symbol_kind in cls: + if symbol_kind.value == value: + return symbol_kind + raise ValueError(f"Invalid symbol kind: {value}") class SymbolTag(IntEnum): diff --git a/src/serena/mcp.py b/src/serena/mcp.py index 9cf3aad8..ad2e8c9d 100644 --- a/src/serena/mcp.py +++ b/src/serena/mcp.py @@ -185,6 +185,25 @@ def list_dir(ctx: Context, relative_path: str, recursive: bool) -> str: return ListDirTool(ctx).execute() +@mcp.tool() +def get_dir_overview(ctx: Context, relative_path: str) -> str: + """ + Get an overview of the given directory. + For each file in the directory, we list the top-level symbols in the file (name, kind, line). + + :param ctx: the context object, which will be created and provided automatically + :param relative_path: the relative path to the directory to get the overview of + :return: a JSON object mapping relative paths of all contained files to info about top-level symbols in the file (name, kind, line). + """ + log.info(f"get_dir_overview: {relative_path=}") + + class GetDirOverviewTool(Tool): + def _execute(self) -> str: + return json.dumps(self.langsrv.request_dir_overview(relative_path)) + + return GetDirOverviewTool(ctx).execute() + + @mcp.tool() def onboarding(ctx: Context) -> str: """