Extend completer for editor to also support comments

This commit is contained in:
Veronica Berglyd Olsen
2025-05-18 21:56:58 +02:00
parent 779026408e
commit f2f2e6cb46
+50 -11
View File
@@ -12,6 +12,7 @@ Created: 2020-06-27 [0.10] GuiDocEditFooter
Rewritten: 2020-10-07 [1.0b3] BackgroundWordCounter
Created: 2023-11-06 [2.2b1] MetaCompleter
Created: 2023-11-07 [2.2b1] GuiDocToolBar
Extended: 2025-05-18 [2.7rc1] CommandCompleter
This file is a part of novelWriter
Copyright (C) 2018 Veronica Berglyd Olsen and novelWriter contributors
@@ -149,7 +150,7 @@ class GuiDocEditor(QPlainTextEdit):
self._autoReplace = TextAutoReplace()
# Completer
self._completer = MetaCompleter(self)
self._completer = CommandCompleter(self)
self._completer.complete.connect(self._insertCompletion)
# Create Custom Document
@@ -1079,13 +1080,16 @@ class GuiDocEditor(QPlainTextEdit):
if (block := self._qDocument.findBlock(pos)).isValid():
text = block.text()
if text.startswith("@") and added + removed == 1:
if text and text[0] in "@%" and added + removed == 1:
# Only run on single character changes, or it will trigger
# at unwanted times when other changes are made to the document
cursor = self.textCursor()
bPos = cursor.positionInBlock()
if bPos > 0 and (viewport := self.viewport()):
show = self._completer.updateText(text, bPos)
if text[0] == "@":
show = self._completer.updateMetaText(text, bPos)
else:
show = self._completer.updateCommentText(text, bPos)
point = self.cursorRect().bottomRight()
self._completer.move(viewport.mapToGlobal(point))
self._completer.setVisible(show)
@@ -2073,13 +2077,13 @@ class GuiDocEditor(QPlainTextEdit):
return
class MetaCompleter(QMenu):
"""GuiWidget: Meta Completer Menu
class CommandCompleter(QMenu):
"""GuiWidget: Command Completer Menu
This is a context menu with options populated from the user's
defined tags. It also helps to type the meta data keyword on a new
line starting with an @. The updateText function should be called on
every keystroke on a line starting with @.
defined tags and keys. It also helps to type the meta data keyword
on a new line starting with @ or %. The update functions should be
called on every keystroke on a line starting with @ or %.
"""
complete = pyqtSignal(int, int, str)
@@ -2088,7 +2092,7 @@ class MetaCompleter(QMenu):
super().__init__(parent=parent)
return
def updateText(self, text: str, pos: int) -> bool:
def updateMetaText(self, text: str, pos: int) -> bool:
"""Update the menu options based on the line of text."""
self.clear()
kw, sep, _ = text.partition(":")
@@ -2108,7 +2112,7 @@ class MetaCompleter(QMenu):
offset = tPos[index] if lookup else pos
length = len(lookup)
suffix = ""
options = list(filter(
options = sorted(filter(
lambda x: lookup in x.lower(), SHARED.project.index.getClassTags(
nwKeyWords.KEY_CLASS.get(kw.strip())
)
@@ -2117,13 +2121,48 @@ class MetaCompleter(QMenu):
if not options:
return False
for value in sorted(options):
for value in options:
rep = value + suffix
action = qtAddAction(self, value)
action.triggered.connect(qtLambda(self._emitComplete, offset, length, rep))
return True
def updateCommentText(self, text: str, pos: int) -> bool:
"""Update the menu options based on the line of text."""
self.clear()
cmd, sep, _ = text.partition(":")
if pos <= len(cmd):
clean = text[1:].lstrip()[:6].lower()
if clean[:6] == "story.":
pre, _, key = cmd.partition(".")
offset = len(pre) + 1
length = len(key)
suffix = "" if sep else ": "
options = sorted(filter(
lambda x: x.startswith(key.rstrip()),
SHARED.project.index.getStoryKeys(),
))
elif pos < 12:
offset = 0
length = len(cmd.rstrip())
suffix = ""
options = list(filter(
lambda x: x.startswith(cmd.rstrip()),
["%Synopsis: ", "%Short: ", "%Story", "%Note"],
))
else:
return False
if options:
for value in options:
rep = value + suffix
action = qtAddAction(self, rep.rstrip(":. "))
action.triggered.connect(qtLambda(self._emitComplete, offset, length, rep))
return True
return False
##
# Events
##