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)
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))