diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py index 6c749007..edea8f71 100644 --- a/novelwriter/core/index.py +++ b/novelwriter/core/index.py @@ -32,7 +32,7 @@ import json import logging from time import time -from typing import TYPE_CHECKING, ItemsView, Iterable, Iterator, Literal +from typing import TYPE_CHECKING, ItemsView, Iterable, Iterator from pathlib import Path from novelwriter import SHARED @@ -472,41 +472,33 @@ class NWIndex: return True, tBits, tPos - def checkThese(self, tBits: list[str], nwItem: NWItem) -> list[Literal[0, 1, 2, 3]]: + def checkThese(self, tBits: list[str], nwItem: NWItem) -> list[bool]: """Check the tags against the index to see if they are valid - tags. This is needed for syntax highlighting. The return values - for each item are: - 0: Invalid - 1: Valid and a keyword - 2: Valid and a value - 3: Valid and an optional value + tags. This is needed for syntax highlighting. """ nBits = len(tBits) + isGood = [False]*nBits if nBits == 0: return [] # Check that the key is valid - isGood: list[Literal[0, 1, 2, 3]] = [0]*nBits - isGood[0] = 1 if tBits[0] in nwKeyWords.VALID_KEYS else 0 - if isGood[0] == 0 or nBits == 1: + isGood[0] = tBits[0] in nwKeyWords.VALID_KEYS + if not isGood[0] or nBits == 1: return isGood - # For a tag, the first value is the tag, and the second is - # optional and is the display name + # For a tag, only the first value is accepted, the rest are ignored if tBits[0] == nwKeyWords.TAG_KEY and nBits > 1: if tBits[1] in self._tagsIndex: - isGood[1] = 2 if self._tagsIndex.tagHandle(tBits[1]) == nwItem.itemHandle else 0 + isGood[1] = self._tagsIndex.tagHandle(tBits[1]) == nwItem.itemHandle else: - isGood[1] = 2 - if nBits > 2: - isGood[2] = 3 + isGood[1] = True return isGood # If we're still here, we check that the references exist refKey = nwKeyWords.KEY_CLASS[tBits[0]].name for n in range(1, nBits): if tBits[n] in self._tagsIndex: - isGood[n] = 2 if self._tagsIndex.tagClass(tBits[n]) == refKey else 0 + isGood[n] = self._tagsIndex.tagClass(tBits[n]) == refKey return isGood diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 6e353687..6baddf67 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -1842,7 +1842,7 @@ class GuiDocEditor(QPlainTextEdit): return nwTrinary.NEUTRAL tag = "" - exist = 0 + exist = False cPos = cursor.selectionStart() - block.position() tExist = SHARED.project.index.checkThese(tBits, self._nwItem) for sTag, sPos, sExist in zip(reversed(tBits), reversed(tPos), reversed(tExist)): @@ -1854,14 +1854,14 @@ class GuiDocEditor(QPlainTextEdit): exist = sExist break - if exist in (1, 3) or not tag: - # Ignore keywords, optionals and empty tags + if not tag or tag.startswith("@"): + # The keyword cannot be looked up, so we ignore that return nwTrinary.NEUTRAL - if follow and exist == 2: + if follow and exist: logger.debug("Attempting to follow tag '%s'", tag) self.loadDocumentTagRequest.emit(tag, nwDocMode.VIEW) - elif create and exist == 0: + elif create and not exist: if SHARED.question(self.tr( "Do you want to create a new project note for the tag '{0}'?" ).format(tag)): @@ -1874,7 +1874,7 @@ class GuiDocEditor(QPlainTextEdit): "If one doesn't exist, you must create one first." ).format(trConst(nwLabels.CLASS_NAME[itemClass]))) - return nwTrinary.POSITIVE if exist == 2 else nwTrinary.NEGATIVE + return nwTrinary.POSITIVE if exist else nwTrinary.NEGATIVE return nwTrinary.NEUTRAL diff --git a/novelwriter/gui/dochighlight.py b/novelwriter/gui/dochighlight.py index 8ce2f462..01accfda 100644 --- a/novelwriter/gui/dochighlight.py +++ b/novelwriter/gui/dochighlight.py @@ -287,14 +287,15 @@ class GuiDocHighlighter(QSyntaxHighlighter): for n, bit in enumerate(bits): xPos = pos[n] xLen = len(bit) - if isGood[n] == 1: - self.setFormat(xPos, xLen, self._hStyles["keyword"]) - elif isGood[n] == 2: - self.setFormat(xPos, xLen, self._hStyles["value"]) - elif isGood[n] == 3: - self.setFormat(xPos, xLen, self._hStyles["optional"]) + if isGood[n]: + if n == 0: + self.setFormat(xPos, xLen, self._hStyles["keyword"]) + else: + self.setFormat(xPos, xLen, self._hStyles["value"]) else: - self.setFormat(xPos, xLen, self._hStyles["codeinval"]) + kwFmt = self.format(xPos) + kwFmt.merge(self._hStyles["codeinval"]) + self.setFormat(xPos, xLen, kwFmt) # We never want to run the spell checker on keyword/values, # so we force a return here diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py index c0053ff4..34ca97ed 100644 --- a/tests/test_core/test_core_index.py +++ b/tests/test_core/test_core_index.py @@ -269,33 +269,26 @@ def testCoreIndex_CheckThese(mockGUI, fncPath, mockRnd): assert nItem.mainHeading == "H1" # Zero Items - assert index.checkThese([], cItem) == [] + assert index.checkThese([], cHandle) == [] # One Item - assert index.checkThese(["@tag"], cItem) == [1] - assert index.checkThese(["@who"], cItem) == [0] + assert index.checkThese(["@tag"], cItem) == [True] + assert index.checkThese(["@who"], cItem) == [False] # Two Items - assert index.checkThese(["@tag", "Jane"], cItem) == [1, 2] - assert index.checkThese(["@tag", "John"], cItem) == [1, 2] - assert index.checkThese(["@tag", "Jane"], nItem) == [1, 0] - assert index.checkThese(["@tag", "John"], nItem) == [1, 2] - assert index.checkThese(["@pov", "John"], nItem) == [1, 0] - assert index.checkThese(["@pov", "Jane"], nItem) == [1, 2] - assert index.checkThese(["@ pov", "Jane"], nItem) == [0, 0] - assert index.checkThese(["@what", "Jane"], nItem) == [0, 0] + assert index.checkThese(["@tag", "Jane"], cItem) == [True, True] + assert index.checkThese(["@tag", "John"], cItem) == [True, True] + assert index.checkThese(["@tag", "Jane"], nItem) == [True, False] + assert index.checkThese(["@tag", "John"], nItem) == [True, True] + assert index.checkThese(["@pov", "John"], nItem) == [True, False] + assert index.checkThese(["@pov", "Jane"], nItem) == [True, True] + assert index.checkThese(["@ pov", "Jane"], nItem) == [False, False] + assert index.checkThese(["@what", "Jane"], nItem) == [False, False] # Three Items - assert index.checkThese(["@tag", "Jane", "Jany"], cItem) == [1, 2, 3] - assert index.checkThese(["@who", "Jane", "John"], cItem) == [0, 0, 0] - assert index.checkThese(["@pov", "Jane", "John"], nItem) == [1, 2, 0] - assert index.checkThese(["@pov", "Jane", "Jane"], nItem) == [1, 2, 2] - - # Four Items - assert index.checkThese(["@tag", "Jane", "Jany", "John"], cItem) == [1, 2, 3, 0] - assert index.checkThese(["@who", "Jane", "Jane", "Jane"], cItem) == [0, 0, 0, 0] - assert index.checkThese(["@pov", "Jane", "John", "Jane"], nItem) == [1, 2, 0, 2] - assert index.checkThese(["@pov", "Jane", "Jane", "Jane"], nItem) == [1, 2, 2, 2] + assert index.checkThese(["@tag", "Jane", "John"], cItem) == [True, True, False] + assert index.checkThese(["@who", "Jane", "John"], cItem) == [False, False, False] + assert index.checkThese(["@pov", "Jane", "John"], nItem) == [True, True, False] project.closeProject()