class Editor(QPlainTextEdit): def __init__(self, parent): super().__init__(parent) self.lineNumberArea = QLineNumberArea(self) self.blockCountChanged.connect(self.updateLineNumberAreaWidth) self.updateRequest.connect(self.updateLineNumberArea) self.cursorPositionChanged.connect(self.highlightCurrentLine) self.updateLineNumberAreaWidth(0) self.parent = parent self.font = QFont() self.size = 12 self.dialog = MessageBox(self) self.menu_font = QFont() self.menu_font.setFamily("Iosevka") self.menu_font.setPointSize(10) self.font.setFamily(editor["editorFont"]) self.font.setPointSize(editor["editorFontSize"]) self.focused = None self.text = None self.replace_tabs = 4 self.setWordWrapMode(4) self.setFont(self.font) self.l = 0 self.highlightingRules = [] self.indexes = None self.setTabStopWidth(editor["TabWidth"]) self.createStandardContextMenu() self.setWordWrapMode(QTextOption.NoWrap) def getTextCursor(self): textCursor = self.textCursor() textCursorPos = textCursor.position() return textCursor, textCursorPos def get_linenumbers(self): return self.blockCount() def check(self): cursor = self.textCursor() b = cursor.block() extraSelections = [] if len(b.text()) > 120: selection = QTextEdit.ExtraSelection() # TODO: implement something using flake8 selection.format.setFontUnderline(True) selection.format.setUnderlineColor(QColor("#FF0000")) selection.format.setUnderlineStyle( QTextCharFormat.SpellCheckUnderline) selection.format.setProperty(QTextFormat.FullWidthSelection, True) selection.cursor = self.textCursor() selection.cursor.clearSelection() extraSelections.append(selection) self.setExtraSelections(extraSelections) font = QFont() font.setFamily("Iosevka") font.setPointSize(10) QToolTip.setFont(font) cursor = self.textCursor() current_line = cursor.positionInBlock() QToolTip.showText( QCursor.pos(), "Line too long (" + str(current_line) + "> 120) | violation on line: " + str(b.blockNumber() + 1)) def newFile(self): """This is a wrapper for the function defined in Main""" self.new_action = QAction("New") self.new_action.triggered.connect(self.parent.parent.newFile) def lineNumberAreaWidth(self): digits = 1 max_value = max(1, self.blockCount()) while max_value >= 10: max_value /= 10 digits += 1 space = 10 + self.fontMetrics().width('9') * digits return space def updateLineNumberAreaWidth(self, _): self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0) def updateLineNumberArea(self, rect, dy): if dy: self.lineNumberArea.scroll(0, dy) else: self.lineNumberArea.update(0, rect.y(), self.lineNumberArea.width(), rect.height()) if rect.contains(self.viewport().rect()): self.updateLineNumberAreaWidth(0) def resizeEvent(self, event): super().resizeEvent(event) cr = self.contentsRect() self.lineNumberArea.setGeometry( QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height())) def highlightCurrentLine(self): extraSelections = [] if not self.isReadOnly(): selection = QTextEdit.ExtraSelection() lineColor = QColor("#434343") selection.format.setBackground(lineColor) selection.format.setProperty(QTextFormat.FullWidthSelection, True) selection.cursor = self.textCursor() selection.cursor.clearSelection() extraSelections.append(selection) self.setExtraSelections(extraSelections) self.check() def lineNumberAreaPaintEvent(self, event): painter = QPainter(self.lineNumberArea) painter.fillRect(event.rect(), QColor("#303030")) block = self.firstVisibleBlock() blockNumber = block.blockNumber() top = self.blockBoundingGeometry(block).translated( self.contentOffset()).top() bottom = top + self.blockBoundingRect(block).height() # Just to make sure I use the right font height = self.fontMetrics().height() while block.isValid() and (top <= event.rect().bottom()): if block.isVisible() and (bottom >= event.rect().top()): number = str(blockNumber + 1) painter.setPen(Qt.white) painter.drawText(0, top, self.lineNumberArea.width(), height, Qt.AlignCenter, number) block = block.next() top = bottom bottom = top + self.blockBoundingRect(block).height() blockNumber += 1 def openFile(self): self.open_action = QAction("Open") self.open_action.triggered.connect(self.parent.parent.openFileFromMenu) def runFile(self): self.run_action = QAction("Run") self.run_action.triggered.connect(self.parent.parent.terminal) def textUnderCursor(self): textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) return textCursor.selectedText() def contextMenuEvent(self, event): menu = QMenu() """Initializing actions""" self.newFile() self.openFile() self.runFile() menu.addAction(self.new_action) menu.addAction(self.open_action) menu.addAction(self.run_action) menu.setFont(self.menu_font) menu.exec(event.globalPos()) del menu def moveCursorPosBack(self): textCursor = self.textCursor() textCursorPos = textCursor.position() textCursor.setPosition(textCursorPos - 1) self.setTextCursor(textCursor) def mousePressEvent(self, e): self.check() if QApplication.queryKeyboardModifiers() == Qt.ControlModifier: if self.text is not None: self.check_func("lol") url = "https://docs.python.org/3/library/functions.html#" + self.text word = self.text self.parent.parent.showBrowser(url, word) QApplication.restoreOverrideCursor() super().mousePressEvent(e) def check_func(self, word): funcs = [ "abs", "all", "any", "ascii", "bin", "bool", "breakpoint", "bytearray", "bytes", "callable", "chr", "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod", "enumerate", "eval", "exec", "filter", "float", "format", "frozenset", "getattr", "globals", "hasattr", "hash", "help", "hex", "id", "input", "int", "isinstance", "issubclass", "iter", "len", "list", "locals", "map", "max", "memoryview", "min", "next", "object", "oct", "open", "ord", "pow", "print", "property", "range", "repr", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum", "super", "tuple", "type", "vars", "zip", "__import__" ] word_array = list(word) for wo in word_array: if wo in ["{", "}", "'", '"', "[", "]", "(", ")"]: word_array.remove(wo) for w in funcs: if w == "".join(word_array): print("".join(word_array)) return True def mouseReleaseEvent(self, e): self.check() super().mouseReleaseEvent(e) def keyPressEvent(self, e): textCursor = self.textCursor() key = e.key() if key == Qt.Key_H: # self.parent.completer.wordList # TODO: implement dynamic completion pass if e.modifiers( ) == Qt.ControlModifier and key == 16777217: # that key code stands for tab self.parent.parent.switchTabs() isSearch = (e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_F) if isSearch: try: currentWidget = self.parent currentFile = currentWidget.fileName currentEditor = currentWidget.editor textCursor = currentEditor.textCursor() textCursorPos = textCursor.position() except (AttributeError, UnboundLocalError) as E: print(E, " on line 228 in the file Editor.py") if currentWidget is not None: text, okPressed = QInputDialog.getText(self, 'Find', 'Find what: ') if okPressed: if text == "": text = " " self.dialog.noMatch(text) self.searchtext = text try: with open(currentFile, 'r') as file: contents = file.read() self.indexes = list(find_all(contents, text)) if len(self.indexes) == 0: self.dialog.noMatch(text) except FileNotFoundError as E: print(E, " on line 245 in the file Editor.py") if key == Qt.Key_QuoteDbl: self.insertPlainText('"') self.moveCursorPosBack() if key == 16777249: # This code stands for CTRL if self.check_func(self.textUnderCursor()): extraSelections = [] selection = QTextEdit.ExtraSelection() selection.format.setFontUnderline(True) selection.format.setUnderlineColor(QColor("#00d2ff")) selection.format.setBackground(QColor("#00d2ff")) selection.format.setProperty(QTextFormat.FullWidthSelection, True) selection.cursor = self.textCursor() selection.cursor.clearSelection() selection.cursor.select(QTextCursor.WordUnderCursor) extraSelections.append(selection) self.setExtraSelections(extraSelections) self.text = self.textUnderCursor() QApplication.setOverrideCursor(Qt.PointingHandCursor) else: self.text = None if e.modifiers() == Qt.ControlModifier and e.key( ) == 61: # Press Ctrl+Equal key to make font bigger self.font.setPointSize(self.size + 1) self.font.setFamily(editor["editorFont"]) self.setFont(self.font) self.size += 1 if e.modifiers() == Qt.ControlModifier and e.key() == 16777217: return if e.modifiers() == Qt.ControlModifier and e.key( ) == 45: # Press Ctrl+Minus key to make font smaller self.font.setPointSize(self.size - 1) self.font.setFamily(editor["editorFont"]) self.setFont(self.font) self.size -= 1 if key == Qt.Key_F3: try: index = self.indexes[0 + self.l] currentWidget = self.parent currentFile = currentWidget.fileName currentEditor = currentWidget.editor textCursor.setPosition(index) textCursor.movePosition(textCursor.Right, textCursor.KeepAnchor, len(self.searchtext)) currentEditor.setTextCursor(textCursor) self.l += 1 except IndexError: self.l = 0 if key == 39: self.insertPlainText("'") self.moveCursorPosBack() if key == Qt.Key_BraceLeft: self.insertPlainText("}") self.moveCursorPosBack() if key == Qt.Key_BracketLeft: self.insertPlainText("]") self.moveCursorPosBack() if key == Qt.Key_ParenLeft: self.insertPlainText(")") self.moveCursorPosBack() if key == Qt.Key_ParenRight: textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) if textCursor.selectedText( ) == "()" or "()" in textCursor.selectedText(): return if key == Qt.Key_BraceRight: textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) if textCursor.selectedText == "": return if key == 16777219: if self.textUnderCursor() in ['""', '()', '[]', "''", "{}"]: textCursor = self.textCursor() textCursorPos = textCursor.position() textCursor.setPosition(textCursorPos + 1) textCursor.deletePreviousChar() self.setTextCursor(textCursor) if key not in [16777217, 16777219, 16777220]: super().keyPressEvent(e) return e.accept() cursor = self.textCursor() if key == 16777217: # and self.replace_tabs: amount = 4 - self.textCursor().positionInBlock() % 4 self.insertPlainText(' ' * amount) elif key == 16777219 and cursor.selectionStart() == cursor.selectionEnd() and self.replace_tabs and \ cursor.positionInBlock(): position = cursor.positionInBlock() end = cursor.position() start = end - (position % 4) if start == end and position >= 4: start -= 4 string = self.toPlainText()[start:end] if not len(string.strip() ): # if length is 0 which is binary for false for i in range(end - start): cursor.deletePreviousChar() else: super().keyPressEvent(e) elif key == 16777220: end = cursor.position() start = end - cursor.positionInBlock() line = self.toPlainText()[start:end] indentation = len(line) - len(line.lstrip()) chars = '\t' if self.replace_tabs: chars = ' ' indentation /= self.replace_tabs if line.endswith(':'): if self.replace_tabs: indentation += 1 super().keyPressEvent(e) self.insertPlainText(chars * int(indentation)) else: super().keyPressEvent(e)
class Editor(QPlainTextEdit): def __init__(self, parent): super().__init__(parent) self.lineNumberArea = QLineNumberArea(self) self.blockCountChanged.connect(self.updateLineNumberAreaWidth) self.updateRequest.connect(self.updateLineNumberArea) self.textChanged.connect(self.check) self.cursorPositionChanged.connect(self.highlightCurrentLine) self.updateLineNumberAreaWidth(0) self.parent = parent self.font = QFont() self.size = 12 self.dialog = MessageBox() self.menu_font = QFont() self.menu_font.setFamily("Iosevka") self.menu_font.setPointSize(10) self.font.setFamily(editor["editorFont"]) self.font.setPointSize(editor["editorFontSize"]) self.focused = None self.replace_tabs = 4 self.setWordWrapMode(4) self.setFont(self.font) self.l = 0 self.highlightingRules = [] self.indexes = None self.setTabStopWidth(editor["TabWidth"]) self.createStandardContextMenu() self.setWordWrapMode(QTextOption.NoWrap) def get_linenumbers(self): return self.blockCount() def check(self): cursor = self.textCursor() b = cursor.block() if len(b.text()) >= 79: print("pep 8 violation on line: " + str(b.blockNumber() + 1)) def newFile(self): """This and most of the functions below will just be wrappers for the functions defined in Main""" self.new_action = QAction("New") self.new_action.triggered.connect(self.parent.parent.newFile) def lineNumberAreaWidth(self): digits = 1 max_value = max(1, self.blockCount()) while max_value >= 10: max_value /= 10 digits += 1 space = 10 + self.fontMetrics().width('9') * digits return space def updateLineNumberAreaWidth(self, _): self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0) def updateLineNumberArea(self, rect, dy): if dy: self.lineNumberArea.scroll(0, dy) else: self.lineNumberArea.update(0, rect.y(), self.lineNumberArea.width(), rect.height()) if rect.contains(self.viewport().rect()): self.updateLineNumberAreaWidth(0) def resizeEvent(self, event): super().resizeEvent(event) cr = self.contentsRect() self.lineNumberArea.setGeometry( QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height())) def highlightCurrentLine(self): extraSelections = [] if not self.isReadOnly(): selection = QTextEdit.ExtraSelection() lineColor = QColor("#434343") selection.format.setBackground(lineColor) selection.format.setProperty(QTextFormat.FullWidthSelection, True) selection.cursor = self.textCursor() selection.cursor.clearSelection() extraSelections.append(selection) self.setExtraSelections(extraSelections) def lineNumberAreaPaintEvent(self, event): painter = QPainter(self.lineNumberArea) painter.fillRect(event.rect(), QColor("#303030")) block = self.firstVisibleBlock() blockNumber = block.blockNumber() top = self.blockBoundingGeometry(block).translated( self.contentOffset()).top() bottom = top + self.blockBoundingRect(block).height() # Just to make sure I use the right font height = self.fontMetrics().height() while block.isValid() and (top <= event.rect().bottom()): if block.isVisible() and (bottom >= event.rect().top()): number = str(blockNumber + 1) painter.setPen(Qt.white) painter.drawText(0, top, self.lineNumberArea.width(), height, Qt.AlignCenter, number) block = block.next() top = bottom bottom = top + self.blockBoundingRect(block).height() blockNumber += 1 def openFile(self): self.open_action = QAction("Open") self.open_action.triggered.connect(self.parent.parent.openFileFromMenu) def runFile(self): self.run_action = QAction("Run") self.run_action.triggered.connect(self.parent.parent.terminal) def contextMenuEvent(self, event): menu = QMenu() """Initializing actions""" self.newFile() self.openFile() self.runFile() print("aa") menu.addAction(self.new_action) menu.addAction(self.open_action) menu.addAction(self.run_action) menu.setFont(self.menu_font) menu.exec(event.globalPos()) del menu def moveCursorPosBack(self): textCursor = self.textCursor() textCursorPos = textCursor.position() textCursor.setPosition(textCursorPos - 1) self.setTextCursor(textCursor) def keyPressEvent(self, e): textCursor = self.textCursor() key = e.key() if key == Qt.Key_H: # self.parent.completer.wordList # TODO: implement dynamic completion pass textCursorPos = textCursor.position() isSearch = (e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_F) if isSearch: try: currentWidget = self.parent currentFile = currentWidget.fileName currentEditor = currentWidget.editor textCursor = currentEditor.textCursor() textCursorPos = textCursor.position() except (AttributeError, UnboundLocalError) as E: print(E) if currentWidget is not None: text, okPressed = QInputDialog.getText(self, 'Find', 'Find what: ') if okPressed: if text == "": text = " " self.dialog.noMatch(text) self.searchtext = text try: with open(currentFile, 'r') as file: contents = file.read() self.indexes = list(find_all(contents, text)) if len(self.indexes) == 0: self.dialog.noMatch(text) except FileNotFoundError as E: print(E) if key == Qt.Key_QuoteDbl: self.insertPlainText('"') self.moveCursorPosBack() if e.modifiers() == Qt.ControlModifier and e.key( ) == 61: # Press Ctrl+Equal key to make font bigger self.font.setPointSize(self.size + 1) self.font.setFamily(editor["editorFont"]) self.setFont(self.font) self.size += 1 if e.modifiers() == Qt.ControlModifier and e.key() == 16777217: return if e.modifiers() == Qt.ControlModifier and e.key( ) == 45: # Press Ctrl+Minus key to make font smaller self.font.setPointSize(self.size - 1) self.font.setFamily(editor["editorFont"]) self.setFont(self.font) self.size -= 1 if key == Qt.Key_F3: try: index = self.indexes[0 + self.l] currentWidget = self.parent currentFile = currentWidget.fileName currentEditor = currentWidget.editor textCursor.setPosition(index) textCursor.movePosition(textCursor.Right, textCursor.KeepAnchor, len(self.searchtext)) currentEditor.setTextCursor(textCursor) self.l += 1 except IndexError: self.l = 0 if key == 39: self.insertPlainText("'") self.moveCursorPosBack() if key == Qt.Key_BraceLeft: self.insertPlainText("}") self.moveCursorPosBack() if key == Qt.Key_BracketLeft: self.insertPlainText("]") self.moveCursorPosBack() if key == Qt.Key_ParenLeft: self.insertPlainText(")") self.moveCursorPosBack() if key == Qt.Key_ParenRight: textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) if textCursor.selectedText( ) == "()" or "()" in textCursor.selectedText(): return if key == Qt.Key_BraceRight: textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) if textCursor.selectedText == "": return if key not in [16777217, 16777219, 16777220]: super().keyPressEvent(e) return e.accept() cursor = self.textCursor() if key == 16777217: # and self.replace_tabs: amount = 4 - self.textCursor().positionInBlock() % 4 self.insertPlainText(' ' * amount) elif key == 16777219 and cursor.selectionStart() == cursor.selectionEnd() and self.replace_tabs and \ cursor.positionInBlock(): position = cursor.positionInBlock() end = cursor.position() start = end - (position % 4) if start == end and position >= 4: start -= 4 string = self.toPlainText()[start:end] if not len(string.strip() ): # if length is 0 which is binary for false for i in range(end - start): cursor.deletePreviousChar() else: super().keyPressEvent(e) elif key == 16777220: end = cursor.position() start = end - cursor.positionInBlock() line = self.toPlainText()[start:end] indentation = len(line) - len(line.lstrip()) chars = '\t' if self.replace_tabs: chars = ' ' indentation /= self.replace_tabs if line.endswith(':'): if self.replace_tabs: indentation += 1 super().keyPressEvent(e) self.insertPlainText(chars * int(indentation)) else: super().keyPressEvent(e)
class Editor(QPlainTextEdit): def __init__(self, parent): super().__init__(parent) self.parent = parent self.font = QFont() self.size = 12 self.dialog = MessageBox() self.menu_font = QFont() self.menu_font.setFamily("Iosevka") self.menu_font.setPointSize(10) self.font.setFamily(editor["editorFont"]) self.font.setPointSize(editor["editorFontSize"]) self.focused = None self.replace_tabs = 4 self.setWordWrapMode(4) self.setFont(self.font) self.l = 0 self.highlightingRules = [] self.indexes = None self.setTabStopWidth(editor["TabWidth"]) self.createStandardContextMenu() self.setWordWrapMode(QTextOption.NoWrap) def newFile(self): """This and most of the functions below will just be wrappers for the functions defined in Main""" self.new_action = QAction("New") self.new_action.triggered.connect(self.parent.parent.newFile) def openFile(self): self.open_action = QAction("Open") self.open_action.triggered.connect(self.parent.parent.openFileFromMenu) def runFile(self): self.run_action = QAction("Run") self.run_action.triggered.connect(self.parent.parent.Terminal) def contextMenuEvent(self, event): menu = QMenu() """Initializing actions""" self.newFile() self.openFile() self.runFile() menu.addAction(self.new_action) menu.addAction(self.open_action) menu.addAction(self.run_action) menu.setFont(self.menu_font) menu.exec(event.globalPos()) del menu def moveCursorPosBack(self): textCursor = self.textCursor() textCursorPos = textCursor.position() textCursor.setPosition(textCursorPos - 1) self.setTextCursor(textCursor) def keyPressEvent(self, e): textCursor = self.textCursor() key = e.key() if key == Qt.Key_H: # self.parent.completer.wordList # TODO: implement dynamic completion pass textCursorPos = textCursor.position() isSearch = (e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_F) if isSearch: try: currentWidget = self.parent currentFile = currentWidget.fileName currentEditor = currentWidget.editor textCursor = currentEditor.textCursor() textCursorPos = textCursor.position() except (AttributeError, UnboundLocalError) as E: print(E) if currentWidget is not None: text, okPressed = QInputDialog.getText(self, 'Find', 'Find what: ') if okPressed: if text == "": text = " " self.dialog.noMatch(text) self.searchtext = text try: with open(currentFile, 'r') as file: contents = file.read() self.indexes = list(find_all(contents, text)) if len(self.indexes) == 0: self.dialog.noMatch(text) except FileNotFoundError as E: print(E) if key == Qt.Key_QuoteDbl: self.insertPlainText('"') self.moveCursorPosBack() if (e.modifiers() == Qt.ControlModifier and e.key() == 61): # Press Ctrl+Equal key to make font bigger self.font.setPointSize(self.size + 1) self.font.setFamily(editor["editorFont"]) self.setFont(self.font) self.size += 1 if (e.modifiers() == Qt.ControlModifier and e.key() == 45): # Press Ctrl+Minus key to make font smaller self.font.setPointSize(self.size - 1) self.font.setFamily(editor["editorFont"]) self.setFont(self.font) self.size -= 1 if key == Qt.Key_F3: try: index = self.indexes[0 + self.l] currentWidget = self.parent currentFile = currentWidget.fileName currentEditor = currentWidget.editor textCursor.setPosition(index) textCursor.movePosition(textCursor.Right, textCursor.KeepAnchor, len(self.searchtext)) currentEditor.setTextCursor(textCursor) self.l += 1 except IndexError: self.l = 0 if key == 39: self.insertPlainText("'") self.moveCursorPosBack() if key == Qt.Key_BraceLeft: self.insertPlainText("}") self.moveCursorPosBack() if key == Qt.Key_BracketLeft: self.insertPlainText("]") self.moveCursorPosBack() if key == Qt.Key_ParenLeft: self.insertPlainText(")") self.moveCursorPosBack() if key == Qt.Key_ParenRight: textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) if textCursor.selectedText() == "()" or "()" in textCursor.selectedText(): return if key == Qt.Key_BraceRight: textCursor = self.textCursor() textCursor.select(QTextCursor.WordUnderCursor) if textCursor.selectedText == "": return if key not in [16777217, 16777219, 16777220]: super().keyPressEvent(e) return e.accept() cursor = self.textCursor() if key == 16777217: # and self.replace_tabs: amount = 4 - self.textCursor().positionInBlock() % 4 self.insertPlainText(' ' * amount) elif key == 16777219 and cursor.selectionStart() == cursor.selectionEnd() and self.replace_tabs and \ cursor.positionInBlock(): position = cursor.positionInBlock() end = cursor.position() start = end - (position % 4) if start == end and position >= 4: start -= 4 string = self.toPlainText()[start:end] if not len(string.strip()): # if length is 0 which is binary for false for i in range(end - start): cursor.deletePreviousChar() else: super().keyPressEvent(e) elif key == 16777220: end = cursor.position() start = end - cursor.positionInBlock() line = self.toPlainText()[start:end] indentation = len(line) - len(line.lstrip()) chars = '\t' if self.replace_tabs: chars = ' ' indentation /= self.replace_tabs if line.endswith(':'): if self.replace_tabs: indentation += 1 super().keyPressEvent(e) self.insertPlainText(chars * int(indentation)) else: super().keyPressEvent(e)
class Editor(QsciScintilla): def __init__(self, parent=None): super().__init__(parent) self.fileName = None self.parent = parent self.debugging = False self.line = None self.column = None self.wordlist = [] self.searchtext = None self.font = QFont() self.font.setFamily("Inconsolata") self.pointSize = 12 # TODO: Make this customizable self.tabWidth = 4 # TODO: Make this customizable self.font.setPointSize(self.pointSize) self.dialog = MessageBox(self) self.verticalScrollBar().setStyleSheet(""" background-color: transparent; """) self.horizontalScrollBar().setStyleSheet(""" background-color: transparent; """) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setCaretForegroundColor(QColor("#FFFFFF")) self.setEdgeColumn(121) self.setEdgeMode(1) self.setEdgeColor(QColor("#8c8c8c")) self.setFont(self.font) self.setMarginSensitivity(1, True) self.markerDefine(QsciScintilla.RightArrow, 8) self.setMarkerBackgroundColor(QColor('#FF0000'), 8) self.indicator_number = 0 self.indicator_value = 222 self.indicator_color = QColor("#FF0000") self.draw_under_text = True # Initializing some stuff self.set_brace_colors(QColor("#98b4f9"), QColor("#edf40e"), QColor("#98b4f9"), QColor("red")) self.cursorPositionChanged.connect(self.change_col) self.textChanged.connect(self.check_lines) self.set_linenumbers(QFontMetrics(self.font)) self.setFoldMarginColors(QColor("#212121"), QColor("#212121")) self.set_indentation_settings(self.tabWidth) def set_up_tooltips(self): self.setCallTipsStyle(QsciScintilla.CallTipsNoContext) self.setCallTipsVisible(0) self.setCallTipsPosition(QsciScintilla.CallTipsAboveText) self.setCallTipsBackgroundColor(QColor("#FF0000")) self.setCallTipsForegroundColor(QColor("#FF0000")) self.setCallTipsHighlightColor(QColor("#FF0000")) def set_brace_colors(self, matched_B=None, matched_F=None, unmatched_B=None, unmatched_F=None): self.setMatchedBraceBackgroundColor(matched_B) self.setMatchedBraceForegroundColor(matched_F) self.setUnmatchedBraceBackgroundColor(unmatched_B) self.setUnmatchedBraceForegroundColor(unmatched_F) self.setBraceMatching(QsciScintilla.SloppyBraceMatch) def set_linenumbers(self, fontmetrics): self.setMarginsFont(self.font) self.setMarginWidth(0, fontmetrics.width("00000")) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#212121")) self.setMarginsForegroundColor(QColor("#FFFFFF")) def set_indentation_settings(self, tab_width): self.setIndentationsUseTabs(False) self.setTabWidth(tab_width) self.SendScintilla(QsciScintilla.SCI_SETUSETABS, False) self.setAutoIndent(True) self.setTabIndents(True) def check_lines(self): line_n = self.lines() for i in range(line_n): if self.lineLength(i) > 121: # TODO: Make a character format or something pass # print("Line over 121 characters on line", str(i+1)) # self.setCursorPosition(i, 120) def python_highlighter(self): self.lexer = PythonLexer() self.lexer.setFoldComments(True) self.setCaretLineVisible(True) self.setDefaultSettings(self.lexer) self.setPythonAutocomplete() self.setFold() def json_highlighter(self): lexer = QsciLexerJSON() self.setDefaultSettings(lexer) def c_highlighter(self): lexer = QsciLexerCPP() self.setDefaultSettings(lexer) def setDefaultSettings(self, lexer): self.setAutoIndent(True) lexer.setFont(self.font) lexer.setColor(QColor('white'), 0) # default lexer.setColor(QColor('#6B6E6C'), PythonLexer.Comment) # = 1 lexer.setColor(QColor('#ADD4FF'), 2) # Number = 2 lexer.setColor(QColor('#38ef7d'), 3) # DoubleQuotedString lexer.setColor(QColor('#38ef7d'), 4) # SingleQuotedString lexer.setColor(QColor('#F6DC74'), 5) # Keyword lexer.setColor(QColor('#38ef7d'), 6) # TripleSingleQuotedString lexer.setColor(QColor('#38ef7d'), 7) # TripleDoubleQuotedString lexer.setColor(QColor('#74F6C3'), 8) # ClassName lexer.setColor(QColor('#FF6666'), 9) # FunctionMethodName lexer.setColor(QColor('magenta'), 10) # Operator lexer.setColor(QColor('white'), 11) # Identifier lexer.setColor(QColor('gray'), 12) # CommentBlock lexer.setColor(QColor('#a8ff78'), 13) # UnclosedString lexer.setColor(QColor('gray'), 14) # HighlightedIdentifier lexer.setColor(QColor('#FF00E7'), 15) # Decorator lexer.setFont(QFont("Iosevka", weight=QFont.Bold), 5) self.setCaretLineBackgroundColor(QColor("#3C3B3F")) self.setLexer(lexer) def setPythonAutocomplete(self): self.autocomplete = QsciAPIs(self.lexer) self.keywords = wordList for word in self.keywords: self.autocomplete.add(word) self.setAutoCompletionThreshold(2) self.setAutoCompletionSource(QsciScintilla.AcsAPIs) self.updateAutoComplete(self.parent.fileName) self.autocomplete.prepare() def setFold(self): # setup Fold Styles for classes and functions ... x = self.FoldStyle(self.FoldStyle(5)) # self.textPad.folding() if not x: self.foldAll(False) self.setFolding(x) # self.textPad.folding() def unsetFold(self): self.setFolding(0) def updateAutoComplete(self, file_path=None): for i in tokenize(file_path): for j in i: if j not in self.wordlist: self.wordlist.append(j) for word in self.wordlist: self.autocomplete.add(word) self.autocomplete.prepare() def change_col(self, line, column): # Responsible for changing the column bar. self.line = line self.column = column def check_if_func(self, word): # Checks if a word is a built in function word_array = list(word) for wo in word_array: if wo in ["{", "}", "'", '"', "[", "]", "(", ")"]: word_array.remove(wo) for w in funcList: if w == "".join(word_array): return True def check_if_error(self, word): if word in errorList: # This is the list where all possible errors are defined return True def keyReleaseEvent(self, e): if e.key() == Qt.Key_Return: try: self.updateAutoComplete(self.parent.fileName) except AttributeError as E: print(E, "on line 210 in TextEditor.py") if e.key() == Qt.Key_Backspace: pass def mousePressEvent(self, e): super().mousePressEvent(e) if QGuiApplication.queryKeyboardModifiers() == Qt.ControlModifier: word = self.wordAtLineIndex(self.getCursorPosition()[0], self.getCursorPosition()[1]) print(word) if self.check_if_func(word): url = "https://docs.python.org/3/library/functions.html#" + word self.parent.parent.openBrowser( url, word) # Runs the openBrowser function in Main class elif self.check_if_error(word): url = "https://docs.python.org/3/library/exceptions.html#" + word print(url) self.parent.parent.openBrowser(url, word) def keyPressEvent(self, e): if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_F: text, okPressed = QInputDialog.getText(self, 'Find', 'Find what: ') self.setSelectionBackgroundColor(QColor("#6be585")) if okPressed: if text == "": text = " " self.dialog.noMatch(text) self.searchtext = text """ This is the way to implement a search function using QScintilla http://pyqt.sourceforge.net/Docs/QScintilla2/classQsciScintilla.html#a37ac2bea94eafcfa639173557a821200 """ if self.findFirst(self.searchtext, False, True, False, True, True, -1, -1, True, False): pass else: self.dialog.noMatch(self.searchtext) if e.key() == Qt.Key_F3: self.findNext() self.setSelectionBackgroundColor(QColor("#6be585")) if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_L: self.setCursorPosition(self.line, self.column + 1) return if e.modifiers() == Qt.ControlModifier and e.key() == 77: self.setCursorPosition(self.line + 1, self.column) return if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_J: self.setCursorPosition(self.line, self.column - 1) if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_I: self.setCursorPosition(self.line - 1, self.column) if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_T: self.parent.parent.realterminal() return super().keyPressEvent(e)