PluginSplitMergeCamelCase.py

branch
eric7
changeset 48
4f0e000eab79
parent 45
e12f7ab5f6c0
child 51
f862797030d1
diff -r 0780a9985266 -r 4f0e000eab79 PluginSplitMergeCamelCase.py
--- a/PluginSplitMergeCamelCase.py	Fri May 28 19:09:47 2021 +0200
+++ b/PluginSplitMergeCamelCase.py	Fri May 28 19:37:46 2021 +0200
@@ -11,25 +11,26 @@
 import os
 import re
 
-from PyQt5.QtCore import QObject, QTranslator
-from PyQt5.QtWidgets import QMenu
+from PyQt6.QtCore import QObject, QTranslator
+from PyQt6.QtWidgets import QMenu
 
-from E5Gui.E5Application import e5App
+from EricWidgets.EricApplication import ericApp
 
 # Start-Of-Header
 name = "Camel Case Handling Plug-in"
 author = "Detlev Offenbach <detlev@die-offenbachs.de>"
 autoactivate = True
 deactivateable = True
-version = "3.1.0"
+version = "1.0.0"
 className = "SplitMergeCamelCasePlugin"
 packageName = "SplitMergeCamelCase"
-shortDescription = "Split, merge or convert camel case text"
+shortDescription = "Split, merge or convert camel/snake case text"
 longDescription = (
-    """This plug-in implements a tool to split, merge or convert"""
-    """ camel case text. It works with the text of the current"""
-    """ editor. The menu entries will only be selectable, if the"""
-    """ current editor has some selected text."""
+    """This plug-in implements a tool to split or merge camel case """
+    """or snake case text. It also offers the capability to convert"""
+    """ text between these case variants. It works with the text of"""
+    """ the current editor. The menu entries will only be enabled,"""
+    """ if the current editor has some selected text."""
 )
 needsRestart = False
 pyqtApi = 2
@@ -46,7 +47,8 @@
         """
         Constructor
         
-        @param ui reference to the user interface object (UI.UserInterface)
+        @param ui reference to the user interface object
+        @type UserInterface
         """
         super().__init__(ui)
         self.__ui = ui
@@ -63,7 +65,8 @@
         """
         Public method to activate this plugin.
         
-        @return tuple of None and activation status (boolean)
+        @return tuple of None and activation status
+        @rtype tuple of (None, bool)
         """
         global error
         error = ""     # clear previous error
@@ -78,12 +81,12 @@
             act = menu.addMenu(self.__menu)
             self.__mainActions.append(act)
         
-        e5App().getObject("ViewManager").editorOpenedEd.connect(
+        ericApp().getObject("ViewManager").editorOpenedEd.connect(
             self.__editorOpened)
-        e5App().getObject("ViewManager").editorClosedEd.connect(
+        ericApp().getObject("ViewManager").editorClosedEd.connect(
             self.__editorClosed)
         
-        for editor in e5App().getObject("ViewManager").getOpenEditors():
+        for editor in ericApp().getObject("ViewManager").getOpenEditors():
             self.__editorOpened(editor)
         
         return None, True
@@ -100,9 +103,9 @@
                 menu.removeAction(act)
         self.__mainActions = []
 
-        e5App().getObject("ViewManager").editorOpenedEd.disconnect(
+        ericApp().getObject("ViewManager").editorOpenedEd.disconnect(
             self.__editorOpened)
-        e5App().getObject("ViewManager").editorClosedEd.disconnect(
+        ericApp().getObject("ViewManager").editorClosedEd.disconnect(
             self.__editorClosed)
         
         for editor, acts in self.__editors.items():
@@ -127,7 +130,7 @@
                 loaded = translator.load(translation, locale_dir)
                 if loaded:
                     self.__translator = translator
-                    e5App().installTranslator(self.__translator)
+                    ericApp().installTranslator(self.__translator)
                 else:
                     print("Warning: translation file '{0}' could not be"
                           " loaded.".format(translation))
@@ -137,30 +140,47 @@
         """
         Private method to initialize the camel case handling menu.
         """
-        self.__menu = QMenu(self.tr("CamelCase Handling"))
-        self.__menu.addAction(self.tr("Split from CamelCase"),
-                              self.__splitCamelCase)
-        self.__menu.addAction(self.tr("Merge to CamelCase"),
-                              self.__mergeCamelCase)
-        self.__menu.addAction(self.tr("CamelCase to under_score"),
-                              self.__camelCaseToUnderscore)
-        self.__menu.addAction(self.tr("under_score to CamelCase"),
-                              self.__underscoreToCamelCase)
+        self.__menu = QMenu(self.tr("Camel/Snake Case Handling"))
+        self.__menu.addAction(
+            self.tr("Split from Camel Case"),
+            self.__splitCamelCase)
+        self.__menu.addAction(
+            self.tr("Merge to Camel Case"),
+            self.__mergeCamelCase)
+        self.__menu.addAction(
+            self.tr("Merge to Camel Case (upper case first)"),
+            self.__mergeCamelCaseUppercaseFirst)
+        self.__menu.addSeparator()
         self.__menu.addAction(
-            self.tr("under_score to CamelCase (upper case first)"),
-            self.__underscoreToCamelCaseUppercaseFirst)
+            self.tr("Split from Snake Case"),
+            self.__splitSnakeCase)
+        self.__menu.addAction(
+            self.tr("Merge to Snake Case"),
+            self.__mergeSnakeCase)
+        self.__menu.addSeparator()
+        self.__menu.addAction(
+            self.tr("Camel Case to Snake Case"),
+            self.__camelCaseToSnakeCase)
+        self.__menu.addAction(
+            self.tr("Snake Case to Camel Case"),
+            self.__snakeCaseToCamelCase)
+        self.__menu.addAction(
+            self.tr("Snake Case to Camel Case (upper case first)"),
+            self.__snakeCaseToCamelCaseUppercaseFirst)
     
     def __populateMenu(self, name, menu):
         """
         Private slot to populate the tools menu with our entries.
         
-        @param name name of the menu (string)
-        @param menu reference to the menu to be populated (QMenu)
+        @param name name of the menu
+        @type str
+        @param menu reference to the menu to be populated
+        @type QMenu
         """
         if name not in ["Tools", "PluginTools"]:
             return
         
-        editor = e5App().getObject("ViewManager").activeWindow()
+        editor = ericApp().getObject("ViewManager").activeWindow()
         
         if name == "Tools":
             if not menu.isEmpty():
@@ -175,7 +195,8 @@
         """
         Private slot called, when a new editor was opened.
         
-        @param editor reference to the new editor (QScintilla.Editor)
+        @param editor reference to the new editor
+        @type Editor
         """
         menu = editor.getMenu("Tools")
         if menu is not None:
@@ -191,7 +212,8 @@
         """
         Private slot called, when an editor was closed.
         
-        @param editor reference to the editor (QScintilla.Editor)
+        @param editor reference to the editor
+        @type Editor
         """
         with contextlib.suppress(KeyError):
             del self.__editors[editor]
@@ -201,9 +223,12 @@
         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 (string)
-        @param menu reference to the menu (QMenu)
+        @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 == "Tools":
             if self.__menu.menuAction() not in menu.actions():
@@ -221,9 +246,11 @@
         """
         Private method to change the selected text.
         
-        @param newText new (converted) text (string)
+        @param newText new (converted) text
+        @type str
         @param editor reference to the editor to apply the text
-            change to (Editor)
+            change to
+        @type Editor
         """
         editor.beginUndoAction()
         editor.replaceSelectedText(newText)
@@ -233,73 +260,119 @@
         """
         Private slot to split the selected camel case text.
         """
-        editor = e5App().getObject("ViewManager").activeWindow()
+        editor = ericApp().getObject("ViewManager").activeWindow()
         if editor is None:
             return
         
         text = editor.selectedText()
         if text:
-            newText = re.sub(r"([A-Z])", r" \1", text)
-            if newText.startswith(" "):
-                newText = newText[1:]
+            newText = re.sub(r"([A-Z])", r" \1", text).lstrip(" ")
             if newText != text:
                 self.__applyChange(newText, editor)
     
-    def __mergeCamelCase(self):
+    def __mergeCamelCase(self, uppercaseFirst=False):
         """
         Private slot to merge the selected text to camel case.
+        
+        @param uppercaseFirst flag indicating to upper case the
+            first character
+        @type bool
         """
-        editor = e5App().getObject("ViewManager").activeWindow()
+        editor = ericApp().getObject("ViewManager").activeWindow()
+        if editor is None:
+            return
+        
+        text = editor.selectedText()
+        if text:
+            newText = "".join(w[0].upper() + w[1:] for w in text.split())
+            if not uppercaseFirst:
+                newText = newText[0].lower() + newText[1:]
+            if newText != text:
+                self.__applyChange(newText, editor)
+    
+    def __mergeCamelCaseUppercaseFirst(self):
+        """
+        Private slot to merge the selected text to camel case upper casing
+        the first character.
+        """
+        self.__mergeCamelCase(True)
+    
+    def __splitSnakeCase(self):
+        """
+        Private slot to split the selected snake case text.
+        """
+        editor = ericApp().getObject("ViewManager").activeWindow()
         if editor is None:
             return
         
         text = editor.selectedText()
         if text:
-            newText = "".join(text.split())
+            newText = text.replace("_", " ").lstrip(" ")
             if newText != text:
                 self.__applyChange(newText, editor)
     
-    def __camelCaseToUnderscore(self):
+    def __mergeSnakeCase(self):
+        """
+        Private slot to merge the selected text to snake case.
+        """
+        editor = ericApp().getObject("ViewManager").activeWindow()
+        if editor is None:
+            return
+        
+        text = editor.selectedText()
+        if text:
+            newText = "_".join(w.lower() for w in text.split())
+            if newText != text:
+                self.__applyChange(newText, editor)
+    
+    def __camelCaseToSnakeCase(self):
         """
         Private slot to convert camel case text to underscore separated text.
         """
-        editor = e5App().getObject("ViewManager").activeWindow()
+        editor = ericApp().getObject("ViewManager").activeWindow()
         if editor is None:
             return
         
         text = editor.selectedText()
         if text:
-            newText = re.sub(r"([A-Z])", r"_\1", text).lower()
-            if newText.startswith("_"):
-                newText = newText[1:]
+            newText = re.sub(r"([A-Z])", r"_\1", text).lower().lstrip("_")
+            if text.startswith("__"):
+                newText = "__" + newText
+            elif text.startswith("_"):
+                newText = "_" + newText
             if newText != text:
                 self.__applyChange(newText, editor)
     
-    def __underscoreToCamelCase(self, uppercaseFirst=False):
+    def __snakeCaseToCamelCase(self, uppercaseFirst=False):
         """
         Private slot to convert underscore separated text to camel case.
         
         @param uppercaseFirst flag indicating to upper case the
-            first character (boolean)
+            first character
+        @type bool
         """
-        editor = e5App().getObject("ViewManager").activeWindow()
+        editor = ericApp().getObject("ViewManager").activeWindow()
         if editor is None:
             return
         
         text = editor.selectedText()
         if text:
-            newText = "".join([s.capitalize() for s in text.split("_")])
+            newText = "".join(s.capitalize() for s in text.split("_"))
             if not uppercaseFirst:
                 newText = newText[0].lower() + newText[1:]
+            if text.startswith("__"):
+                newText = "__" + newText
+            elif text.startswith("_"):
+                newText = "_" + newText
             if newText != text:
                 self.__applyChange(newText, editor)
     
-    def __underscoreToCamelCaseUppercaseFirst(self):
+    def __snakeCaseToCamelCaseUppercaseFirst(self):
         """
         Private slot to convert underscore separated text to camel case
         upper casing the first character.
         """
-        self.__underscoreToCamelCase(True)
+        self.__snakeCaseToCamelCase(True)
 
 #
 # eflag: noqa = M801

eric ide

mercurial