| Age | Commit message (Collapse) | Author | Files | Lines |
|
QLineEdit::setCompleter hands completion to the line edit, which then
resets the completer's completionPrefix to the widget's entire text on
every keystroke. The prefix has to be the stem, so once the query grew
past its first token the whole-line prefix matched no candidate, the
popup stopped appearing, and the two reported symptoms followed: nothing
was there for Tab to accept, and Tab fell through to focus navigation.
Attach the completer with setWidget instead, which keeps the popup
anchored without ceding control of the prefix. complete() dereferences
widget() unconditionally, so leaving it unset segfaults rather than
degrading. Opening the popup then becomes ours to do on every edit.
Extend the existing event filter to route the keys the popup needs while
it is visible, and install it unconditionally now that it does more than
the completion_on_focus case. Enter accepts a completion only while the
popup is up, so returnPressed still runs the query when it is closed.
The existing tests called acceptCompletion() directly and so never
touched the widget, which is why neither bug was caught. Add four tests
that drive the real widget path plus one covering both settings of
completion_on_focus; the first two fail against the old code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Adds the complete_query action, whose registration the assertion in
registerActions() has been demanding since keymap gained the name: a
known action nothing implements would have been a silently dead binding.
Also lands the QueryCompleter half of the manual trigger, which the
keymap commit left behind: triggerCompletion() and the focus-in filter
gated on completion_on_focus.
Tags refresh at startup, after a sync, and after a mutation introduces a
tag not already known, since that is the tag most likely to be typed
again. onAllTagsReady deliberately drops the generation the signal
carries: a tag list is not an ordered query result, so a later one is
always at least as good as an earlier one and discarding on staleness
could only throw away a good list.
|
|
The free-form date hint is a footer label rather than a model row: a row
would be filtered away by the first non-matching keystroke and could be
selected and inserted, producing a query that errors.
QCompleter::setPopup takes a QAbstractItemView, so the label cannot be laid
out beside the view in a container widget. The footer sits in space reserved
with setViewportMargins inside the list view instead.
setItemDelegate must run after setPopup, not before: setPopup installs a
plain QStyledItemDelegate of its own and discards whatever was already set,
which silently drops the description column.
Accepting replaces exactly the span the tokenizer identified rather than
QCompleter's own completion prefix, which is a different span once a prefix
or a range bound is involved. Four tests drive that path directly instead of
through synthetic key events, since whether a key needs Shift is a
keyboard-layout property and could not decide the question.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
tag: and is: share the tag list, since notmuch aliases them. path: offers
each account maildir in both bare and recursive forms, the latter being
what Account::scopedQuery builds and not something a user would guess.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Keywords are syntax and stay untranslated; the descriptions beside them are
prose and go through tr().
The tables are free functions with no QObject to inherit tr() from, so the
file declares a VocabularyStrings context with Q_DECLARE_TR_FUNCTIONS rather
than borrowing QObject::tr, which would file every string under the QObject
context.
|
|
Each side of '..' is an independent value against the same model. Entries
that are themselves ranges are withheld once a range exists, since
date:1week....today is malformed.
The token is read to its full extent rather than truncated at the caret:
the separator deciding which bound is being edited can sit to the right
of the caret. Stems stay caret-bounded so matching never uses untyped
text.
|
|
subject:"foo bar has the cursor in free text, where offering keywords
would be wrong.
|
|
The replace span covers the value only, so accepting a completion never
overwrites the prefix that selected it.
|
|
Prefix completion only so far: the token under the cursor, bounded by
whitespace or an opening parenthesis rather than by the start of the line.
|