summaryrefslogtreecommitdiffstats
path: root/ui/frontmatter_editor.py
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-05-03 16:09:26 +0200
committerDanilo M. <danix@danix.xyz>2026-05-03 16:09:26 +0200
commit365b911ba1288ccfb428602ba765750ad9d0a139 (patch)
tree42467975cbb2208b576088e24d504077183bb0e3 /ui/frontmatter_editor.py
parent86fd963587ce87b56f208daf07714c0f87a8cb08 (diff)
downloadpublisher-365b911ba1288ccfb428602ba765750ad9d0a139.tar.gz
publisher-365b911ba1288ccfb428602ba765750ad9d0a139.zip
feat: multi-token tag autocomplete in FrontmatterEditor
Replace single-token QCompleter with MultiTokenCompleter that completes each comma-separated tag independently. Activating a suggestion inserts the completed tag and positions cursor after a trailing ", " separator for immediate next-tag input. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'ui/frontmatter_editor.py')
-rw-r--r--ui/frontmatter_editor.py39
1 files changed, 36 insertions, 3 deletions
diff --git a/ui/frontmatter_editor.py b/ui/frontmatter_editor.py
index 3b4b690..ce70355 100644
--- a/ui/frontmatter_editor.py
+++ b/ui/frontmatter_editor.py
@@ -10,6 +10,41 @@ from core.models import Article, ARTICLE_TYPES
from core.frontmatter import write_frontmatter
from core.taxonomy import load_taxonomy
+class MultiTokenCompleter(QCompleter):
+ """QCompleter that completes only the last comma-separated token."""
+
+ def __init__(self, tags: list[str], parent=None):
+ super().__init__(tags, parent)
+ self.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
+
+ def attach(self, line_edit):
+ self.setWidget(line_edit)
+ line_edit.textEdited.connect(self._on_text_edited)
+ self.activated[str].connect(self._on_activated)
+
+ def _on_text_edited(self, text: str):
+ token = text.split(",")[-1].lstrip()
+ if token:
+ self.setCompletionPrefix(token)
+ self.complete()
+ else:
+ self.popup().hide()
+
+ def _on_activated(self, completion: str):
+ widget = self.widget()
+ if widget is None:
+ return
+ current = widget.text()
+ if "," in current:
+ prefix = current.rsplit(",", 1)[0]
+ new_text = prefix + ", " + completion + ", "
+ else:
+ new_text = completion + ", "
+ widget.setText(new_text)
+ widget.setCursorPosition(len(new_text))
+ self.popup().hide()
+
+
class FrontmatterEditor(QDialog):
def __init__(self, article: Article, blog_root: Path, parent=None):
super().__init__(parent)
@@ -45,9 +80,7 @@ class FrontmatterEditor(QDialog):
self._fields[key] = widget
elif key == "tags":
widget = QLineEdit(", ".join(str(v) for v in val) if isinstance(val, list) else str(val))
- completer = QCompleter(known_tags)
- completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
- widget.setCompleter(completer)
+ MultiTokenCompleter(known_tags, widget).attach(widget)
self._fields[key] = widget
else:
widget = QLineEdit(str(val))