diff --git a/src/serena/code_editor.py b/src/serena/code_editor.py index 5aaba834..6fb1e668 100644 --- a/src/serena/code_editor.py +++ b/src/serena/code_editor.py @@ -218,14 +218,14 @@ class CodeEditor(Generic[TSymbol], ABC): edited_file.delete_text_between_positions(start_pos, end_pos) @abstractmethod - def rename_symbol(self, name_path: str, relative_file_path: str, new_name: str) -> list[str]: + def rename_symbol(self, name_path: str, relative_file_path: str, new_name: str) -> str: """ Renames the symbol with the given name throughout the codebase. :param name_path: the name path of the symbol to rename :param relative_file_path: the relative path of the file containing the symbol :param new_name: the new name for the symbol - :return: list of files that were modified + :return: a status message """ @@ -296,14 +296,7 @@ class LanguageServerCodeEditor(CodeEditor[LanguageServerSymbol]): edited_file.apply_text_edits(edits) return modified_relative_paths - def rename_symbol(self, name_path: str, relative_file_path: str, new_name: str) -> list[str]: - """ - Renames the symbol with the given name throughout the codebase. - :param name_path: - :param relative_file_path: - :param new_name: - :return: list of files that were modified - """ + def rename_symbol(self, name_path: str, relative_file_path: str, new_name: str) -> str: symbol = self._find_unique_symbol(name_path, relative_file_path) if not symbol.location.has_position_in_file(): raise ValueError(f"Symbol '{name_path}' does not have a valid position in file for renaming") @@ -320,7 +313,9 @@ class LanguageServerCodeEditor(CodeEditor[LanguageServerSymbol]): f"Language server for {self._lang_server.language_id} returned no rename edits for symbol '{name_path}'. " f"The symbol might not support renaming." ) - return self._apply_workspace_edit(rename_result) + modified_files = self._apply_workspace_edit(rename_result) + msg = f"Successfully renamed '{name_path}' to '{new_name}' in {len(modified_files)} file(s)" + return msg class JetBrainsCodeEditor(CodeEditor[JetBrainsSymbol]): @@ -363,9 +358,13 @@ class JetBrainsCodeEditor(CodeEditor[JetBrainsSymbol]): ) return JetBrainsSymbol(symbols[0], self._project) - def rename_symbol(self, name_path: str, relative_file_path: str, new_name: str) -> list[str]: - """ - Renames the symbol with the given name throughout the codebase. - Not yet implemented for JetBrains code editor. - """ - raise NotImplementedError("Symbol renaming is not yet supported for JetBrains code editor") + def rename_symbol(self, name_path: str, relative_file_path: str, new_name: str) -> str: + with JetBrainsPluginClient.from_project(self._project) as client: + client.rename_symbol( + name_path=name_path, + relative_path=relative_file_path, + new_name=new_name, + rename_in_comments=False, + rename_in_text_occurrences=False, + ) + return "Success" diff --git a/src/serena/tools/jetbrains_plugin_client.py b/src/serena/tools/jetbrains_plugin_client.py index 5a845a6e..47efb30a 100644 --- a/src/serena/tools/jetbrains_plugin_client.py +++ b/src/serena/tools/jetbrains_plugin_client.py @@ -136,7 +136,7 @@ class JetBrainsPluginClient(ToStringMixin): self, name_path: str, relative_path: str | None = None, include_body: bool = False, depth: int = 0, include_location: bool = False ) -> dict[str, Any]: """ - Find symbols by name. + Finds symbols by name. :param name_path: the name path to match :param relative_path: the relative path to which to restrict the search @@ -156,7 +156,7 @@ class JetBrainsPluginClient(ToStringMixin): def find_references(self, name_path: str, relative_path: str) -> dict[str, Any]: """ - Find references to a symbol. + Finds references to a symbol. :param name_path: the name path of the symbol :param relative_path: the relative path @@ -172,6 +172,27 @@ class JetBrainsPluginClient(ToStringMixin): request_data = {"relativePath": relative_path} return self._make_request("POST", "/getSymbolsOverview", request_data) + def rename_symbol( + self, name_path: str, relative_path: str, new_name: str, rename_in_comments: bool, rename_in_text_occurrences: bool + ) -> None: + """ + Renames a symbol. + + :param name_path: the name path of the symbol + :param relative_path: the relative path + :param new_name: the new name for the symbol + :param rename_in_comments: whether to rename in comments + :param rename_in_text_occurrences: whether to rename in text occurrences + """ + request_data = { + "namePath": name_path, + "relativePath": relative_path, + "newName": new_name, + "renameInComments": rename_in_comments, + "renameInTextOccurrences": rename_in_text_occurrences, + } + self._make_request("POST", "/renameSymbol", request_data) + def is_service_available(self) -> bool: try: self.project_root() diff --git a/src/serena/tools/symbol_tools.py b/src/serena/tools/symbol_tools.py index 7526d20e..1f8cbf58 100644 --- a/src/serena/tools/symbol_tools.py +++ b/src/serena/tools/symbol_tools.py @@ -319,5 +319,5 @@ class RenameSymbolTool(Tool, ToolMarkerSymbolicEdit): :return: result summary indicating success or failure """ code_editor = self.create_code_editor() - modified_files = code_editor.rename_symbol(name_path, relative_file_path=relative_path, new_name=new_name) - return f"Successfully renamed '{name_path}' to '{new_name}' in {len(modified_files)} file(s)" + status_message = code_editor.rename_symbol(name_path, relative_file_path=relative_path, new_name=new_name) + return status_message