From 29dda22c8d7d4e9dbaab88b185597b24416cfbe0 Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Mon, 9 Dec 2024 17:17:00 +0000 Subject: [PATCH] Fixed FG text color if background is not null in the pygments integration --- TermTk/TTkGui/textcursor.py | 8 +++++ TermTk/TTkGui/textdocument.py | 16 +++++++++ TermTk/TTkGui/textdocument_highlight.py | 2 -- .../TTkGui/textdocument_highlight_pygments.py | 33 ++++++++++++++----- tools/check.import.sh | 2 +- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/TermTk/TTkGui/textcursor.py b/TermTk/TTkGui/textcursor.py index e4b31edd..255990ee 100644 --- a/TermTk/TTkGui/textcursor.py +++ b/TermTk/TTkGui/textcursor.py @@ -348,6 +348,7 @@ class TTkTextCursor(): def replaceText(self, text:TTkString, moveCursor:bool=False) -> None: # if there is no selection, just select the next n chars till the end of the line # the newline is not replaced + self._document._acquire() for p in self._properties: if not p.hasSelection(): line = p.position.line @@ -358,9 +359,11 @@ class TTkTextCursor(): pos = self._document._dataLines[line].nextPos(pos) pos = min(size,pos) p.anchor.set(line,pos) + self._document._release() return self.insertText(text, moveCursor) def insertText(self, text:TTkString, moveCursor:bool=False) -> None: + self._document._acquire() _lineFirst = -1 if self.hasSelection(): _lineFirst, _lineRem, _lineAdd = self._removeSelectedText() @@ -446,6 +449,7 @@ class TTkTextCursor(): pp.anchor.line += diffLine self._autoChanged = True self._document.setChanged(True) + self._document._release() self._document.contentsChanged.emit() self._document.contentsChange.emit(lineFirst, lineRem, lineAdd) self._autoChanged = False @@ -552,14 +556,17 @@ class TTkTextCursor(): def removeSelectedText(self) -> None: if not self.hasSelection(): return + self._document._acquire() a,b,c = self._removeSelectedText() self._autoChanged = True self._document.setChanged(True) + self._document._release() self._document.contentsChanged.emit() self._document.contentsChange.emit(a,b,c) self._autoChanged = False def applyColor(self, color:TTkColor) -> None: + self._document._acquire() for p in self._properties: selSt = p.selectionStart() selEn = p.selectionEnd() @@ -570,6 +577,7 @@ class TTkTextCursor(): self._document._dataLines[l] = line.setColor(color=color, posFrom=pf, posTo=pt) self._autoChanged = True self._document.setChanged(True) + self._document._acquire() self._document.contentsChanged.emit() # self._document.contentsChange.emit(0,0,0) self._autoChanged = True diff --git a/TermTk/TTkGui/textdocument.py b/TermTk/TTkGui/textdocument.py index 8064e751..39a91849 100644 --- a/TermTk/TTkGui/textdocument.py +++ b/TermTk/TTkGui/textdocument.py @@ -22,6 +22,8 @@ __all__ = ['TTkTextDocument'] +from threading import Lock + from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot from TermTk.TTkCore.string import TTkString @@ -124,6 +126,7 @@ class TTkTextDocument(): '_snap', '_snapChanged', '_lastSnap', '_lastCursor', '_backgroundColor', + '_docMutex', # Signals 'contentsChange', 'contentsChanged', 'formatChanged', @@ -133,6 +136,7 @@ class TTkTextDocument(): ) def __init__(self, *, text:TTkString=" ") -> None: from TermTk.TTkGui.textcursor import TTkTextCursor + self._docMutex = Lock() self.cursorPositionChanged = pyTTkSignal(TTkTextCursor) self.contentsChange = pyTTkSignal(int,int,int) # int line, int linesRemoved, int linesAdded self.contentsChanged = pyTTkSignal() @@ -175,6 +179,12 @@ class TTkTextDocument(): # z1 = l1+a1 + (a2-r2) # z2 = l2+a2 + def _acquire(self) -> None: + self._docMutex.acquire() + + def _release(self) -> None: + self._docMutex.release() + @staticmethod def _mergeChangesSlices(ch1,ch2): l1,r1,a1 = ch1 @@ -226,10 +236,12 @@ class TTkTextDocument(): remLines = len(self._dataLines) if not isinstance(text, str) and not isinstance(text,TTkString): text=str(text) + self._acquire() self._dataLines = [TTkString(t) for t in text.split('\n')] self._modified = False self._lastSnap = self._dataLines.copy() self._snap = TTkTextDocument._snapshot(self._lastCursor, None, None) + self._release() self.contentsChanged.emit() self.contentsChange.emit(0,remLines,len(self._dataLines)) self._snapChanged = None @@ -237,11 +249,13 @@ class TTkTextDocument(): def appendText(self, text): if type(text) == str: text = TTkString() + text + self._acquire() oldLines = len(self._dataLines) self._dataLines += text.split('\n') self._modified = False self._lastSnap = self._dataLines.copy() self._snap = TTkTextDocument._snapshot(self._lastCursor, None, None) + self._release() self.contentsChanged.emit() self.contentsChange.emit(oldLines,0,len(self._dataLines)-oldLines) self._snapChanged = None @@ -297,10 +311,12 @@ class TTkTextDocument(): (not next and not self._snap._prevDiff) ): return None + self._acquire() if next: self._snap = self._snap.getNextSnap(self._dataLines) else: self._snap = self._snap.getPrevSnap(self._dataLines) + self._release() self._lastSnap = self._dataLines.copy() self._lastCursor = self._snap._cursor.copy() diff --git a/TermTk/TTkGui/textdocument_highlight.py b/TermTk/TTkGui/textdocument_highlight.py index 28b331af..98296d27 100644 --- a/TermTk/TTkGui/textdocument_highlight.py +++ b/TermTk/TTkGui/textdocument_highlight.py @@ -22,8 +22,6 @@ __all__ = ['TextDocumentHighlight'] -# from threading import Lock - from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkGui import TTkTextDocument diff --git a/TermTk/TTkGui/textdocument_highlight_pygments.py b/TermTk/TTkGui/textdocument_highlight_pygments.py index 2a12d598..e1f4cc28 100644 --- a/TermTk/TTkGui/textdocument_highlight_pygments.py +++ b/TermTk/TTkGui/textdocument_highlight_pygments.py @@ -22,8 +22,6 @@ __all__ = ['TextDocumentHighlight'] -from threading import Lock - from pygments import highlight from pygments.util import ClassNotFound from pygments.styles import get_all_styles @@ -50,8 +48,9 @@ class _TTkFormatter(Formatter): self.error = None self.multiline = False - __slots__ = ('_dl', '_blockNum', '_highlightStyles') + __slots__ = ('_dl', '_blockNum', '_highlightStyles', '_defaultColor') def __init__(self, *args, **kwargs): + self._defaultColor = TTkColor.RST super().__init__(*args, **kwargs) self._highlightStyles = {} self._blockNum = 1 @@ -82,6 +81,9 @@ class _TTkFormatter(Formatter): def setDl(self,dl): self._dl = dl + def setDefaultColor(self, color:TTkColor) -> None: + self._defaultColor = color + def format(self, tokensource, _): multiline = False multilineId = 0 @@ -95,7 +97,9 @@ class _TTkFormatter(Formatter): ttype = ttype.parent # TTkLog.debug (f"{ttype=}") # TTkLog.debug (f"{value=}") - color = self._highlightStyles[ttype] + color:TTkColor = self._highlightStyles[ttype] + if not color.hasForeground(): + color += self._defaultColor values = value.split('\n') @@ -124,16 +128,16 @@ class TextDocumentHighlight(TTkTextDocument): _linesRefreshed:int = 30 __slots__ = ( '_timerRefresh', - '_highlightDocMutex', '_blocks', '_changedContent', '_refreshContent', '_lexer', '_formatter', + '_defaultForegroundColor', #Signals 'highlightUpdate') def __init__(self, **kwargs): self.highlightUpdate = pyTTkSignal() - self._highlightDocMutex = Lock() self._lexer = None self._blocks = [] + self._defaultForegroundColor = TTkColor.RST # self._formatter = _TTkFormatter(style='dracula') self._formatter = _TTkFormatter(style='gruvbox-dark') super().__init__(**kwargs) @@ -141,7 +145,7 @@ class TextDocumentHighlight(TTkTextDocument): self._timerRefresh.timeout.connect(self._refreshEvent) self._changedContent = (0,0,len(self._dataLines)) self._refreshContent = (0,TextDocumentHighlight._linesRefreshed) - self.contentsChange.connect(lambda a,b,c: TTkLog.debug(f"{a=} {b=} {c=}")) + # self.contentsChange.connect(lambda a,b,c: TTkLog.debug(f"{a=} {b=} {c=}")) self.contentsChange.connect(self._saveChangedContent) try: @@ -167,6 +171,16 @@ class TextDocumentHighlight(TTkTextDocument): self._backgroundColor = TTkColor.bg(color) else: self._backgroundColor = TTkColor.RST + + if self._backgroundColor == TTkColor.RST: + self._defaultForegroundColor = TTkColor.RST + else: + r,g,b = self._backgroundColor.bgToRGB() + if r+g+b < 127*3: + self._defaultForegroundColor = TTkColor.WHITE + else: + self._defaultForegroundColor = TTkColor.BLACK + TTkLog.debug(f"{color=} {alias=} {formatter.style}") self._changedContent = (0,0,len(self._dataLines)) self._refreshContent = (0,TextDocumentHighlight._linesRefreshed) @@ -206,7 +220,7 @@ class TextDocumentHighlight(TTkTextDocument): @pyTTkSlot() def _refreshEvent(self): if not self._refreshContent: return - self._highlightDocMutex.acquire() + self._acquire() ra,rb = self._refreshContent @@ -251,6 +265,7 @@ class TextDocumentHighlight(TTkTextDocument): kfd = _TTkFormatter.Data(tsl1, block) self._formatter.setDl(kfd) + self._formatter.setDefaultColor(self._defaultForegroundColor) rawl = [l._text for l in tsl[offset:]] rawt = '\n'.join(rawl) @@ -283,6 +298,6 @@ class TextDocumentHighlight(TTkTextDocument): else: TTkLog.debug(f"Refresh {self._lexer.name} DONE!!!") - self._highlightDocMutex.release() + self._release() self.highlightUpdate.emit() self.formatChanged.emit() diff --git a/tools/check.import.sh b/tools/check.import.sh index 79f2c17c..934e56be 100755 --- a/tools/check.import.sh +++ b/tools/check.import.sh @@ -50,7 +50,7 @@ __check(){ -e "TTkTerm/input.py:from .input_thread import *" | grep -v \ -e "TTkGui/__init__.py:import importlib.util" \ - -e "TTkGui/textdocument_highlight_pygments.py:from threading import Lock" \ + -e "TTkGui/textdocument.py:from threading import Lock" \ -e "TTkGui/textdocument_highlight_pygments.py:from pygments" | grep -v \ -e "TTkTerm/term.py:from ..drivers import *" \