Search for sub-string matches.

        This method is triggered by Qt whenever the text changes,
        ie. whenever the user has altered the input. Extract the
        new input, find all matches, and highlight them accordingly.

def qteTextChanged(self):
        """
        Search for sub-string matches.

        This method is triggered by Qt whenever the text changes,
        ie. whenever the user has altered the input. Extract the
        new input, find all matches, and highlight them accordingly.
        """
        # Remove any previous highlighting.
        self.clearHighlighting()
        SCI = self.qteWidget

        # Compile a list of spans that contain the specified string.
        self.compileMatchList()

        # Return if the substring does not exist in the text.
        if len(self.matchList) == 0:
            return

        # ------------------------------------------------------------
        # Make a copy of the style bits of the document, overwrite
        # those parts containing a substring, and then write them
        # back all at once. This is much faster than calling the
        # styling methods repeatedly.
        # ------------------------------------------------------------

        # Make a copy of the document style bits and determine the
        # cursor position in the document.
        style = bytearray(self.styleOrig)
        cur = SCI.positionFromLineIndex(*self.cursorPosOrig)

        # Style all matches.
        self.selMatchIdx = 0
        for start, stop in self.matchList:
            if start < cur:
                self.selMatchIdx += 1
            style[start:stop] = bytes(b'\x1e') * (stop - start)

        # If the cursor is after the last possible match (eg. always
        # the case when the cursor is at the end of the file) then
        # self.selMatchIdx will point beyond the list.
        if self.selMatchIdx == len(self.matchList):
            self.selMatchIdx = 0

        # Style the first match after the current cursor position
        # differently to indicate that it is the currently
        # selected one.
        start, stop = self.matchList[self.selMatchIdx]
        style[start:stop] = bytes(b'\x1f') * (stop - start)

        # Place the cursor at the start of the currently selected match.
        line, col = SCI.lineIndexFromPosition(start)
        SCI.setCursorPosition(line, col)
        self.selMatchIdx += 1

        # Apply the modified style array to the document.
        self.qteWidget.SCISetStylingEx(0, 0, style)