Allow words to be ignored by the spell checker (session only)
This commit is contained in:
@@ -125,21 +125,16 @@ class NWSpellEnchant:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def addWord(self, word: str) -> bool:
|
def addWord(self, word: str, save: bool = True) -> None:
|
||||||
"""Add a word to the project dictionary."""
|
"""Add a word to the project dictionary."""
|
||||||
word = word.strip()
|
if word := word.strip():
|
||||||
if not word:
|
try:
|
||||||
return False
|
self._enchant.add_to_session(word)
|
||||||
try:
|
except Exception:
|
||||||
self._enchant.add_to_session(word)
|
return
|
||||||
except Exception:
|
if save and self._userDict.add(word):
|
||||||
return False
|
self._userDict.save()
|
||||||
|
return
|
||||||
added = self._userDict.add(word)
|
|
||||||
if added:
|
|
||||||
self._userDict.save()
|
|
||||||
|
|
||||||
return added
|
|
||||||
|
|
||||||
def listDictionaries(self) -> list[tuple[str, str]]:
|
def listDictionaries(self) -> list[tuple[str, str]]:
|
||||||
"""List available dictionaries."""
|
"""List available dictionaries."""
|
||||||
|
|||||||
@@ -1164,8 +1164,10 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
ctxMenu.addAction(f"{nwUnicode.U_ENDASH} {trNone}")
|
ctxMenu.addAction(f"{nwUnicode.U_ENDASH} {trNone}")
|
||||||
|
|
||||||
ctxMenu.addSeparator()
|
ctxMenu.addSeparator()
|
||||||
|
action = ctxMenu.addAction(self.tr("Ignore Word"))
|
||||||
|
action.triggered.connect(lambda: self._addWord(word, block, False))
|
||||||
action = ctxMenu.addAction(self.tr("Add Word to Dictionary"))
|
action = ctxMenu.addAction(self.tr("Add Word to Dictionary"))
|
||||||
action.triggered.connect(lambda: self._addWord(word, block))
|
action.triggered.connect(lambda: self._addWord(word, block, True))
|
||||||
|
|
||||||
# Execute the context menu
|
# Execute the context menu
|
||||||
ctxMenu.exec(self.viewport().mapToGlobal(pos))
|
ctxMenu.exec(self.viewport().mapToGlobal(pos))
|
||||||
@@ -1173,30 +1175,6 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot("QTextCursor", str)
|
|
||||||
def _correctWord(self, cursor: QTextCursor, word: str) -> None:
|
|
||||||
"""Slot for the spell check context menu triggering the
|
|
||||||
replacement of a word with the word from the dictionary.
|
|
||||||
"""
|
|
||||||
pos = cursor.selectionStart()
|
|
||||||
cursor.beginEditBlock()
|
|
||||||
cursor.removeSelectedText()
|
|
||||||
cursor.insertText(word)
|
|
||||||
cursor.endEditBlock()
|
|
||||||
cursor.setPosition(pos)
|
|
||||||
self.setTextCursor(cursor)
|
|
||||||
return
|
|
||||||
|
|
||||||
@pyqtSlot(str, "QTextBlock")
|
|
||||||
def _addWord(self, word: str, block: QTextBlock) -> None:
|
|
||||||
"""Slot for the spell check context menu triggered when the user
|
|
||||||
wants to add a word to the project dictionary.
|
|
||||||
"""
|
|
||||||
logger.debug("Added '%s' to project dictionary", word)
|
|
||||||
SHARED.spelling.addWord(word)
|
|
||||||
self._qDocument.syntaxHighlighter.rehighlightBlock(block)
|
|
||||||
return
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def _runDocumentTasks(self) -> None:
|
def _runDocumentTasks(self) -> None:
|
||||||
"""Run timer document tasks."""
|
"""Run timer document tasks."""
|
||||||
@@ -1875,6 +1853,28 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
# Internal Functions
|
# Internal Functions
|
||||||
##
|
##
|
||||||
|
|
||||||
|
def _correctWord(self, cursor: QTextCursor, word: str) -> None:
|
||||||
|
"""Slot for the spell check context menu triggering the
|
||||||
|
replacement of a word with the word from the dictionary.
|
||||||
|
"""
|
||||||
|
pos = cursor.selectionStart()
|
||||||
|
cursor.beginEditBlock()
|
||||||
|
cursor.removeSelectedText()
|
||||||
|
cursor.insertText(word)
|
||||||
|
cursor.endEditBlock()
|
||||||
|
cursor.setPosition(pos)
|
||||||
|
self.setTextCursor(cursor)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _addWord(self, word: str, block: QTextBlock, save: bool) -> None:
|
||||||
|
"""Slot for the spell check context menu triggered when the user
|
||||||
|
wants to add a word to the project dictionary.
|
||||||
|
"""
|
||||||
|
logger.debug("Added '%s' to project dictionary, %s", word, "saved" if save else "unsaved")
|
||||||
|
SHARED.spelling.addWord(word, save=save)
|
||||||
|
self._qDocument.syntaxHighlighter.rehighlightBlock(block)
|
||||||
|
return
|
||||||
|
|
||||||
def _processTag(self, cursor: QTextCursor | None = None,
|
def _processTag(self, cursor: QTextCursor | None = None,
|
||||||
follow: bool = True, create: bool = False) -> nwTrinary:
|
follow: bool = True, create: bool = False) -> nwTrinary:
|
||||||
"""Activated by Ctrl+Enter. Checks that we're in a block
|
"""Activated by Ctrl+Enter. Checks that we're in a block
|
||||||
|
|||||||
@@ -158,15 +158,21 @@ def testCoreSpell_Enchant(monkeypatch, mockGUI, fncPath):
|
|||||||
assert isinstance(spChk._enchant, FakeEnchant)
|
assert isinstance(spChk._enchant, FakeEnchant)
|
||||||
assert spChk.checkWord("word") is True
|
assert spChk.checkWord("word") is True
|
||||||
assert spChk.suggestWords("word") == []
|
assert spChk.suggestWords("word") == []
|
||||||
assert spChk.addWord("word") is True
|
spChk.addWord("word")
|
||||||
|
assert "word" in spChk._userDict
|
||||||
|
|
||||||
# Set the dict to None, and check enchant error handling
|
# Set the dict to None, and check enchant error handling
|
||||||
spChk = NWSpellEnchant(project)
|
spChk = NWSpellEnchant(project)
|
||||||
spChk._enchant = None # type: ignore
|
spChk._enchant = None # type: ignore
|
||||||
assert spChk.checkWord("word") is True
|
assert spChk.checkWord("word") is True
|
||||||
assert spChk.suggestWords("word") == []
|
assert spChk.suggestWords("word") == []
|
||||||
assert spChk.addWord("word") is False
|
|
||||||
assert spChk.addWord("\n\t ") is False
|
spChk.addWord("word")
|
||||||
|
assert "word" not in spChk._userDict
|
||||||
|
|
||||||
|
spChk.addWord("\n\t ")
|
||||||
|
assert "\n\t " not in spChk._userDict
|
||||||
|
|
||||||
assert spChk.describeDict() == ("", "")
|
assert spChk.describeDict() == ("", "")
|
||||||
|
|
||||||
# Load the proper enchant package (twice)
|
# Load the proper enchant package (twice)
|
||||||
|
|||||||
@@ -453,9 +453,13 @@ def testGuiEditor_SpellChecking(qtbot, monkeypatch, nwGUI, projPath, ipsumText,
|
|||||||
ctxMenu = getMenuForPos(docEditor, 16)
|
ctxMenu = getMenuForPos(docEditor, 16)
|
||||||
assert ctxMenu is not None
|
assert ctxMenu is not None
|
||||||
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||||
|
assert "Ignore Word" in actions
|
||||||
assert "Add Word to Dictionary" in actions
|
assert "Add Word to Dictionary" in actions
|
||||||
|
|
||||||
assert "Lorax" not in SHARED.spelling._userDict
|
assert "Lorax" not in SHARED.spelling._userDict
|
||||||
ctxMenu.actions()[7].trigger()
|
ctxMenu.actions()[7].trigger() # Ignore
|
||||||
|
assert "Lorax" not in SHARED.spelling._userDict
|
||||||
|
ctxMenu.actions()[8].trigger() # Add
|
||||||
assert "Lorax" in SHARED.spelling._userDict
|
assert "Lorax" in SHARED.spelling._userDict
|
||||||
ctxMenu.setObjectName("")
|
ctxMenu.setObjectName("")
|
||||||
ctxMenu.deleteLater()
|
ctxMenu.deleteLater()
|
||||||
|
|||||||
Reference in New Issue
Block a user