src/eric7/QScintilla/TypingCompleters/CompleterToml.py

branch
eric7
changeset 10201
5beaa25bdfbe
parent 10162
e7040c88b39e
child 10439
21c28b0f9e41
diff -r 7c282bf19646 -r 5beaa25bdfbe src/eric7/QScintilla/TypingCompleters/CompleterToml.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/QScintilla/TypingCompleters/CompleterToml.py	Sun Sep 10 18:04:28 2023 +0200
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2019 - 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a typing completer for TOML.
+"""
+
+import re
+
+from PyQt6.Qsci import QsciScintilla
+
+from eric7 import Preferences
+
+from .CompleterBase import CompleterBase
+
+
+class CompleterYaml(CompleterBase):
+    """
+    Class implementing typing completer for TOML.
+    """
+
+    def __init__(self, editor, parent=None):
+        """
+        Constructor
+
+        @param editor reference to the editor object
+        @type QScintilla.Editor
+        @param parent reference to the parent object
+        @type QObject
+        """
+        super().__init__(editor, parent)
+
+        self.__autoIndentationRe = re.compile(r"(?:\(|\[|{)(\s*)\r?\n")
+        self.__trailingBlankRe = re.compile(r"(?:[=:,])(\s*)\r?\n")
+
+        self.readSettings()
+
+    def readSettings(self):
+        """
+        Public slot called to reread the configuration parameters.
+        """
+        self.setEnabled(Preferences.getEditorTyping("Toml/EnabledTypingAids"))
+        self.__insertClosingBrace = Preferences.getEditorTyping(
+            "Toml/InsertClosingBrace"
+        )
+        self.__skipBrace = Preferences.getEditorTyping("Toml/SkipBrace")
+        self.__insertQuote = Preferences.getEditorTyping("Toml/InsertQuote")
+        self.__autoIndentation = Preferences.getEditorTyping("Toml/AutoIndentation")
+        self.__colonDetection = Preferences.getEditorTyping("Toml/ColonDetection")
+        self.__insertBlankEqual = Preferences.getEditorTyping("Toml/InsertBlankEqual")
+        self.__insertBlankColon = Preferences.getEditorTyping("Toml/InsertBlankColon")
+        self.__insertBlankComma = Preferences.getEditorTyping("Toml/InsertBlankComma")
+
+    def charAdded(self, charNumber):
+        """
+        Public slot called to handle the user entering a character.
+
+        @param charNumber value of the character entered
+        @type int
+        """
+        char = chr(charNumber)
+        if char not in ["{", "}", "[", "]", "(", ")", "'", '"', "=", ":", ",", "\n"]:
+            return  # take the short route
+
+        line, col = self.editor.getCursorPosition()
+
+        if self.__inComment(line, col):
+            return
+
+        # open parenthesis
+        # insert closing parenthesis
+        if char == "(" and self.__insertClosingBrace:
+            self.editor.insert(")")
+
+        # open curly bracket
+        # insert closing bracket
+        if char == "{" and self.__insertClosingBrace:
+            self.editor.insert("}")
+
+        # open bracket
+        # insert closing bracket
+        elif char == "[" and self.__insertClosingBrace:
+            self.editor.insert("]")
+
+        # closing parenthesis
+        # skip matching closing parenthesis
+        elif char in [")", "}", "]"]:
+            txt = self.editor.text(line)
+            if col < len(txt) and char == txt[col] and self.__skipBrace:
+                self.editor.setSelection(line, col, line, col + 1)
+                self.editor.removeSelectedText()
+
+        # colon
+        # 1. skip colon if not last character
+        # 2. insert blank if last character
+        elif char == ":":
+            text = self.editor.text(line)
+            if col < len(text) and char == text[col]:
+                if self.__colonDetection:
+                    self.editor.setSelection(line, col, line, col + 1)
+                    self.editor.removeSelectedText()
+            elif self.__insertBlankColon and col == len(text.rstrip()):
+                self.editor.insert(" ")
+                self.editor.setCursorPosition(line, col + 1)
+
+        # equal sign or comma
+        # insert blank
+        elif (char == "=" and self.__insertBlankEqual) or (
+            char == "," and self.__insertBlankComma
+        ):
+            self.editor.insert(" ")
+            self.editor.setCursorPosition(line, col + 1)
+
+        # double quote
+        # insert double quote
+        elif char == '"' and self.__insertQuote:
+            self.editor.insert('"')
+
+        # single quote
+        # insert single quote
+        elif char == "'" and self.__insertQuote:
+            self.editor.insert("'")
+
+        # new line
+        elif char == "\n":
+            txt = self.editor.text(line - 1)
+            if self.__autoIndentation and self.__autoIndentationRe.search(txt):
+                # indent after line ending with auto indentation character
+                match = self.__autoIndentationRe.search(txt)
+                if match is not None:
+                    startBlanks = match.start(1)
+                    endBlanks = match.end(1)
+                    if startBlanks != -1 and startBlanks != endBlanks:
+                        # previous line ends with whitespace, e.g. caused by
+                        # blank insertion above
+                        self.editor.setSelection(
+                            line - 1, startBlanks, line - 1, endBlanks
+                        )
+                        self.editor.removeSelectedText()
+
+                    self.editor.indent(line)
+                    self.editor.setCursorPosition(line, 0)
+                    self.editor.editorCommand(QsciScintilla.SCI_VCHOME)
+
+            elif (
+                self.__insertBlankColon
+                or self.__insertBlankComma
+                or self.__insertBlankEqual
+            ) and self.__trailingBlankRe.search(txt):
+                # remove blank at end of line inserted by blank insertion above
+                match = self.__trailingBlankRe.search(txt)
+                if match is not None:
+                    startBlanks = match.start(1)
+                    endBlanks = match.end(1)
+                    if startBlanks != -1 and startBlanks != endBlanks:
+                        self.editor.setSelection(
+                            line - 1, startBlanks, line - 1, endBlanks
+                        )
+                        self.editor.removeSelectedText()
+
+                    self.editor.setCursorPosition(line, 0)
+                    self.editor.editorCommand(QsciScintilla.SCI_VCHOME)
+
+    def __inComment(self, line, col):
+        """
+        Private method to check, if the cursor is inside a comment.
+
+        @param line current line
+        @type int
+        @param col current position within line
+        @type int
+        @return flag indicating, if the cursor is inside a comment
+        @rtype bool
+        """
+        txt = self.editor.text(line)
+        if col == len(txt):
+            col -= 1
+        while col >= 0:
+            if txt[col] == "#":
+                return True
+            col -= 1
+        return False
+
+
+def createCompleter(editor, parent=None):
+    """
+    Function to instantiate a typing completer object.
+
+    @param editor reference to the editor object
+    @type QScintilla.Editor
+    @param parent reference to the parent object (defaults to None)
+    @type QObject (optional)
+    @return reference to the instantiated typing completer object
+    @rtype CompleterYaml
+    """
+    return CompleterYaml(editor, parent=parent)

eric ide

mercurial