--- a/eric7/JediInterface/JediServer.py Sun Oct 03 18:36:41 2021 +0200 +++ b/eric7/JediInterface/JediServer.py Mon Oct 04 19:59:06 2021 +0200 @@ -12,8 +12,10 @@ import uuid from PyQt6.QtCore import pyqtSlot, QCoreApplication, QTimer +from PyQt6.QtWidgets import QInputDialog, QLineEdit, QDialog from EricWidgets.EricApplication import ericApp +from EricWidgets import EricMessageBox from EricNetwork.EricJsonServer import EricJsonServer @@ -22,6 +24,8 @@ import Preferences import Globals +from .RefactoringPreviewDialog import RefactoringPreviewDialog + class JediServer(EricJsonServer): """ @@ -86,6 +90,9 @@ "GotoDefinitionResult": self.__processGotoDefinitionResult, "GotoReferencesResult": self.__processGotoReferencesResult, + "RenameVariableDiff": self.__showRenameVariableDiff, + "RefactoringApplyResult": self.__checkRefactoringResult, + "ClientException": self.__processClientException, } @@ -480,6 +487,114 @@ del self.__editors[euuid] ####################################################################### + ## Refactoring methods below + ####################################################################### + + @pyqtSlot() + def refactoringRenameVariable(self): + """ + Public slot to rename the selected variable. + """ + editor = self.__vm.activeWindow() + if editor: + idString = self.__idString(editor) + if not idString: + return + + newName, ok = QInputDialog.getText( + None, + self.tr("Rename Variable"), + self.tr("Enter the new name for the variable:"), + QLineEdit.EchoMode.Normal + ) + + if ok and newName: + filename = editor.getFileName() + line, index = editor.getCursorPosition() + line += 1 # jedi line numbers are 1 based + source = editor.text() + + self.__ensureActive(idString) + + euuid = str(uuid.uuid4()) + self.__editors[euuid] = editor + + self.sendJson("renameVariable", { + "FileName": filename, + "Source": source, + "Line": line, + "Index": index, + "Uuid": euuid, + "NewName": newName, + }, idString=idString) + + def __showRenameVariableDiff(self, result): + """ + Private method to show the diff of the Rename Variable refactoring. + + @param result dictionary containing the result data + @type dict + """ + if "Error" not in result: + # ignore errors silently + euuid = result["Uuid"] + diff = result["Diff"] + dlg = RefactoringPreviewDialog(self.tr("Rename Variable"), diff) + if dlg.exec() == QDialog.DialogCode.Accepted: + self.__applyRefactoring(euuid) + else: + self.__cancelRefactoring(euuid) + + def __applyRefactoring(self, uid): + """ + Private method to apply a given refactoring. + + @param uid UID of the calculated refactoring + @type str + """ + with contextlib.suppress(KeyError): + editor = self.__editors[uid] + idString = self.__idString(editor) + + self.sendJson("applyRefactoring", { + "Uuid": uid, + }, idString=idString) + + del self.__editors[uid] + + def __cancelRefactoring(self, uid): + """ + Private method to cancel a given refactoring. + + @param uid UID of the calculated refactoring + @type str + """ + with contextlib.suppress(KeyError): + editor = self.__editors[uid] + idString = self.__idString(editor) + + self.sendJson("cancelRefactoring", { + "Uuid": uid, + }, idString=idString) + + del self.__editors[uid] + + def __checkRefactoringResult(self, result): + """ + Private method to check the refactoring result for errors. + + @param result dictionary containing the result data + @type dict + """ + if "Error" in result: + EricMessageBox.critical( + self, + self.tr("Apply Refactoring"), + self.tr("<p>The refactoring could not be applied.</p>" + "<p>Reason: {0}</p>").format(result["ErrorString"]) + ) + + ####################################################################### ## Methods below handle the network connection #######################################################################