src/eric7/JediInterface/AssistantJedi.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8949
bab82fd15a6b
child 9214
bd28e56047d7
diff -r 3fc8dfeb6ebe -r b99e7fd55fd3 src/eric7/JediInterface/AssistantJedi.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/JediInterface/AssistantJedi.py	Thu Jul 07 11:23:56 2022 +0200
@@ -0,0 +1,253 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2015 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Jedi assistant plug-in.
+"""
+
+import contextlib
+
+from PyQt6.QtCore import pyqtSlot, QObject
+from PyQt6.QtWidgets import QMenu
+
+import Preferences
+
+
+class AssistantJedi(QObject):
+    """
+    Class implementing the Jedi assistant interface.
+    """
+    def __init__(self, ui, viewManager, project):
+        """
+        Constructor
+        
+        @param ui reference to the user interface object
+        @type UserInterface
+        @param viewManager reference to the viewmanager object
+        @type ViewManager
+        @param project reference to the project object
+        @type Project
+        """
+        super().__init__(ui)
+        self.__ui = ui
+        self.__vm = viewManager
+        
+        self.__jediServer = None
+        self.__editors = []
+        self.__menuActions = {}
+        
+        from .JediServer import JediServer
+        self.__jediServer = JediServer(self.__vm, project, self.__ui)
+        self.__jediServer.activate()
+        
+        self.__ui.preferencesChanged.connect(self.__preferencesChanged)
+        
+        self.__initRefactoringMenu()
+        
+        self.__vm.editorOpenedEd.connect(self.__editorOpened)
+        self.__vm.editorClosedEd.connect(self.__editorClosed)
+    
+    @pyqtSlot()
+    def __preferencesChanged(self):
+        """
+        Private slot handling changes of the Disassembly viewer settings.
+        """
+        for editor in self.__editors:
+            self.__disconnectMouseClickHandler(editor)
+            self.__connectMouseClickHandler(editor)
+    
+    def __determineLanguage(self):
+        """
+        Private method to determine the valid language strings.
+        
+        @return list of valid language strings
+        @rtype list of str
+        """
+        return ["Python3", "MicroPython",
+                "Pygments|Python", "Pygments|Python 2.x",
+                "Cython"]
+    
+    def __editorOpened(self, editor):
+        """
+        Private slot called, when a new editor was opened.
+        
+        @param editor reference to the new editor
+        @type Editor
+        """
+        languages = self.__determineLanguage()
+        
+        if editor.getLanguage() in languages:
+            self.__connectEditor(editor)
+        
+        editor.languageChanged.connect(self.__editorLanguageChanged)
+        self.__editors.append(editor)
+    
+    def __editorClosed(self, editor):
+        """
+        Private slot called, when an editor was closed.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        if editor in self.__editors:
+            editor.languageChanged.disconnect(self.__editorLanguageChanged)
+            self.__disconnectEditor(editor)
+            self.__editors.remove(editor)
+    
+    def __editorLanguageChanged(self, language):
+        """
+        Private slot to handle the language change of an editor.
+        
+        @param language programming language of the editor
+        @type str
+        """
+        editor = self.sender()
+        languages = self.__determineLanguage()
+        
+        self.__disconnectEditor(editor)
+        if language in languages:
+            self.__connectEditor(editor)
+    
+    def __connectEditor(self, editor):
+        """
+        Private method to connect an editor.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        self.__setAutoCompletionHook(editor)
+        self.__setCalltipsHook(editor)
+        
+        self.__connectMouseClickHandler(editor)
+        
+        editor.registerMouseHoverHelpFunction(
+            self.__jediServer.hoverHelp)
+        
+        menu = editor.getMenu("Main")
+        if menu is not None:
+            checkAction = editor.getMenu("Checks").menuAction()
+            act = menu.insertMenu(checkAction, self.__menu)
+            sep = menu.insertSeparator(checkAction)
+            self.__menuActions[editor] = [act, sep]
+        editor.showMenu.connect(self.__editorShowMenu)
+    
+    def __disconnectEditor(self, editor):
+        """
+        Private method to disconnect an editor.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        self.__unsetAutoCompletionHook(editor)
+        self.__unsetCalltipsHook(editor)
+        
+        self.__disconnectMouseClickHandler(editor)
+        
+        editor.unregisterMouseHoverHelpFunction(
+            self.__jediServer.hoverHelp)
+        
+        with contextlib.suppress(TypeError):
+            editor.showMenu.disconnect(self.__editorShowMenu)
+        menu = editor.getMenu("Main")
+        if menu is not None and editor in self.__menuActions:
+            for act in self.__menuActions[editor]:
+                with contextlib.suppress(RuntimeError):
+                    menu.removeAction(act)
+            del self.__menuActions[editor]
+    
+    def __connectMouseClickHandler(self, editor):
+        """
+        Private method to connect the mouse click handler to an editor.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        if Preferences.getJedi("MouseClickGotoButton"):
+            editor.setMouseClickHandler(
+                "jedi",
+                Preferences.getJedi("MouseClickGotoModifiers"),
+                Preferences.getJedi("MouseClickGotoButton"),
+                self.__jediServer.gotoDefinition
+            )
+    
+    def __disconnectMouseClickHandler(self, editor):
+        """
+        Private method to disconnect the mouse click handler from an editor.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        editor.removeMouseClickHandlers("jedi")
+    
+    def __setAutoCompletionHook(self, editor):
+        """
+        Private method to set the autocompletion hook.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        editor.addCompletionListHook(
+            "jedi", self.__jediServer.requestCompletions, True)
+    
+    def __unsetAutoCompletionHook(self, editor):
+        """
+        Private method to unset the autocompletion hook.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        editor.removeCompletionListHook("jedi")
+    
+    def __setCalltipsHook(self, editor):
+        """
+        Private method to set the calltip hook.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        editor.addCallTipHook("jedi", self.__jediServer.getCallTips)
+    
+    def __unsetCalltipsHook(self, editor):
+        """
+        Private method to unset the calltip hook.
+        
+        @param editor reference to the editor
+        @type Editor
+        """
+        editor.removeCallTipHook("jedi")
+    
+    def __initRefactoringMenu(self):
+        """
+        Private method to initialize the Refactoring menu.
+        """
+        self.__menu = QMenu(self.tr("Refactoring"))
+        self.__menu.addAction(
+            self.tr("Rename Variable"),
+            self.__jediServer.refactoringRenameVariable)
+        self.__menu.addAction(
+            self.tr("Extract Variable"),
+            self.__jediServer.refactoringExtractNewVariable)
+        self.__menu.addAction(
+            self.tr("Inline Variable"),
+            self.__jediServer.refactoringInlineVariable)
+        self.__menu.addSeparator()
+        self.__menu.addAction(
+            self.tr("Extract Function"),
+            self.__jediServer.refactoringExtractFunction)
+    
+    def __editorShowMenu(self, menuName, menu, editor):
+        """
+        Private slot called, when the the editor context menu or a submenu is
+        about to be shown.
+        
+        @param menuName name of the menu to be shown
+        @type str
+        @param menu reference to the menu
+        @type QMenu
+        @param editor reference to the editor
+        @type Editor
+        """
+        if menuName == "Main":
+            self.__menu.setEnabled(editor.hasSelectedText())

eric ide

mercurial