Documentation
¶
Overview ¶
Package query parses the filter grammar shared by tuilib's filterable components — the "bare substring / key:value column scope / ~regex" syntax pkg/table exposes in its filter bar.
It is a leaf: it imports nothing from tuilib, for the same reason pkg/geom doesn't. The component that applies a filter to rows it holds and a coordinator that translates the same filter into a remote request (query params, a WHERE clause) need the identical parse, and neither should have to import the other to get it.
The grammar: input is split on whitespace into AND-ed Terms. A bare term matches any cell as a case-insensitive substring. A term shaped "key:value" scopes the match to the single column whose title case-insensitively starts with key ("region:europe"); an ambiguous or unresolvable key falls through as a literal bare term, which is also how to search for a literal colon. A value prefixed with "~" compiles as a case-insensitive regex ("~^new", "region:~^euro"); a compile error falls back to a literal substring including the tilde, so Parse never refuses input and never returns an error.
Matching is ANSI-aware: cells are stripped of escape sequences before comparison, so colored content matches on its visible text.
Distinct / ActiveTerm / Candidates / Complete are the completion half of the grammar — what the filter bar needs to hint at a column's values while a "key:" term is being typed. They are pure functions over a candidate set, so a caller backed by a remote source can feed them facet values instead of values scraped from resident rows.
Index ¶
- func Candidates(distinct [][]string, col int, prefix string) []string
- func ColumnByPrefix(key string, columns []string) int
- func Complete(input string, columns []string, distinct [][]string) (string, bool)
- func Distinct(rows [][]string, ncols int) [][]string
- func LongestCommonPrefix(strs []string) string
- func MatchAll(cells []string, terms []Term) bool
- func NormalizeValues(values []string) []string
- type Active
- type Term
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Candidates ¶
Candidates returns the values in distinct[col] whose lowercased form starts with prefix. Returns nil when col is out of range, so a caller can pass an unresolved column index without guarding first.
func ColumnByPrefix ¶
ColumnByPrefix returns the index of the unique column whose title starts with key (case-insensitive), or -1 when there is no match or when the prefix is ambiguous across several columns.
func Complete ¶
Complete extends the in-progress key:value term to the longest common prefix of its remaining candidates and returns the rewritten input. ok is false when there is no active term, when nothing matches the partial value, or when the common prefix adds nothing to what is already typed — in which case input is returned unchanged.
func Distinct ¶
Distinct returns, for each of the ncols columns, the sorted unique lowercased ANSI-stripped values appearing in that column across rows. Empty cells are skipped, and a row shorter than ncols contributes nothing to the columns it lacks.
This is the candidate set behind Candidates and Complete. Rebuild it when the row set changes, not per keystroke — it is linear in the data. A caller whose rows are one page of a larger remote set should feed server-known facet values instead, since values scraped from a single page complete to answers that are wrong rather than merely incomplete.
func LongestCommonPrefix ¶
LongestCommonPrefix returns the longest byte-wise prefix shared by every string in strs, or "" when strs is empty or they share nothing.
func MatchAll ¶
MatchAll reports whether every term matches cells. Scoped terms test only their column (a short row is treated as having an empty cell there); bare terms match when any cell matches. An empty term slice matches everything.
func NormalizeValues ¶
NormalizeValues puts a candidate set into the form Candidates and Complete expect: ANSI-stripped, lowercased, empties dropped, deduped, sorted. Distinct applies it per column; call it directly when feeding candidates from somewhere other than resident rows — a facet endpoint, an enum, a schema — so server-supplied values compare the same way scraped ones do.
Types ¶
type Active ¶
type Active struct {
// Column is the resolved column index for Key.
Column int
// Title is that column's full title.
Title string
// Key is the key exactly as typed, which may be a prefix of Title.
// Completion writes this back verbatim so finishing a value never
// also rewrites "reg" into "Region" under the user's cursor.
Key string
// Value is the partial value typed after the colon, possibly empty.
Value string
// Start is the byte offset of the term's first character in the input,
// so a caller can splice a completion in without re-scanning.
Start int
}
Active describes the "key:value" term at the end of a filter input that the user is still typing — the term completion hints apply to.
func ActiveTerm ¶
ActiveTerm reports the trailing key:value term the user is mid-typing. ok is false when the input is empty, ends in whitespace (the term is finished), has no resolvable key before a colon, or carries a "~" regex value — enumerating a regex's matches isn't a useful hint.
type Term ¶
type Term struct {
// Column is the index of the column this term is scoped to, or -1
// when the term is bare and matches against any cell.
Column int
// Title is the resolved column title for a scoped term — the full
// title, not the prefix the user typed, so a caller building a remote
// request can use it as a field name directly. Empty for bare terms.
Title string
// Value is the lowercased literal matched as a substring. Empty when
// Regex is set.
Value string
// Regex is the compiled pattern for a "~"-prefixed value, already
// case-insensitive. Nil for literal terms.
Regex *regexp.Regexp
// Raw is the clause exactly as typed, including any "key:" prefix and
// "~" marker, so a query can be round-tripped or echoed back.
Raw string
}
Term is one AND-ed clause from a parsed filter string.