diff options
| author | Danilo M. <danix@danix.xyz> | 2026-05-03 16:09:26 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-05-03 16:09:26 +0200 |
| commit | 365b911ba1288ccfb428602ba765750ad9d0a139 (patch) | |
| tree | 42467975cbb2208b576088e24d504077183bb0e3 /ui/frontmatter_editor.py | |
| parent | 86fd963587ce87b56f208daf07714c0f87a8cb08 (diff) | |
| download | publisher-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.py | 39 |
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)) |
