Skip to content

A filter language, in Core, so the three front-ends cannot disagree about it - #2

Merged
Hawkynt merged 1 commit into
mainfrom
query-language
Aug 17, 2026
Merged

A filter language, in Core, so the three front-ends cannot disagree about it#2
Hawkynt merged 1 commit into
mainfrom
query-language

Conversation

@Hawkynt

@Hawkynt Hawkynt commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Implements PRD §56field:value with comparisons, quoted strings, booleans, regex and unit-aware quantities — and the requirement that the same syntax work in GUI, TUI and CLI.

procman --filter 'cpu:>50 AND user:alice'
procman --filter 'memory:>1GiB NOT name:chrome'
procman --filter 'name:/^kworker/'

ProcessQuery lives in ProcessManager.Core; every front-end filters through ProcessView.TextFilter, so no front-end has its own dialect.

The registry made this cheap

Every field already had a stable key, a declared kind and a declared unit, so every field became filterable without being mentioned in the parser:

  • Kind decides the comparison. pid:1234 is numeric because a pid is an identifier; name:1234 is text because a name is text. Both look like digits.
  • Unit decides the arithmetic. 1G is 1073741824 against a byte field and 1000000000 against a count. That is a 7.4% error if conflated, and they are different questions. GiB/GB overrides the guess.

Two deliberate behaviours

  • A half-typed query degrades to substring search rather than matching nothing — somebody typing chrome: is midway through a working query, and blanking the list at every keystroke makes the box unusable. --filter does the opposite and refuses with the reason, because a script that silently matched nothing is worse than one that stopped.
  • An unknown value matches no comparison at all — not > 0, not == 0, not != 5. Claiming a process's memory is "not equal to 5" is a claim about a number we do not have (§72.3).

--help-fields

Prints every field, its aliases, per-platform notes and the grammar — generated from the registry. The old --sort help listed ten keys when there were seventeen, which is what a hand-kept list does.

Bugs the tests caught

Three, all in the parser, all fixed here:

  1. || was not a stop condition for the implicit-AND loop, so a || b parsed as a AND "||" AND b — the OR silently became an AND of two nonsense terms.
  2. An operator separated from its field by spaces (threads > 1) read as a free-text search for the word "threads".
  3. A keyword check that would have made ORacle into an OR followed by acle.

One test expectation of mine was also wrong rather than the code, and is corrected.

Verification

  • 209 tests (51 new), both UTF-8 and C locales
  • --self-test 25/25 · benchmarks within budget · golden frame unchanged

…cannot disagree about it

PRD §56 asks for field:value with comparisons, quoted strings, booleans, regex and unit-aware
quantities, and requires that the same syntax work in all three front-ends. ProcessQuery is that
parser, and it lives in Core with no front-end permitted its own dialect — every one of them filters
through ProcessView.TextFilter.

  procman --filter 'cpu:>50 AND user:alice'
  procman --filter 'memory:>1GiB NOT name:chrome'
  procman --filter 'name:/^kworker/'

The registry is what made this cheap: every field already had a stable key, a kind and a unit, so
every field became filterable without being mentioned here. The kind decides the comparison, which
is why "pid:1234" is numeric and "name:1234" is text though both look like digits. The unit decides
the arithmetic, which is why 1G is 1073741824 against a byte field and 1000000000 against a count —
getting that wrong is a 7.4% error, and the two are different questions.

Two behaviours that could have gone the other way, both deliberate:

  - A half-typed query degrades to a substring search rather than matching nothing. Somebody typing
    "chrome:" is midway through a working query, and blanking the list at every keystroke makes the
    box unusable. --filter does the opposite and refuses with the reason, because a script that
    silently matched nothing is worse than one that stopped.
  - An unknown value matches no comparison at all: not >0, not ==0, and not !=5. Claiming a
    process's memory is "not equal to 5" is a claim about a number we do not have.

--help-fields prints every field, its aliases and the grammar, generated from the registry. The old
--sort help listed ten keys when there were seventeen, which is what a hand-kept list does.

Three parser bugs the tests found and I fixed: "||" was not a stop condition so it parsed as a search
term and the OR silently became an AND of two nonsense words; an operator separated from its field by
spaces ("threads > 1") read as a search for the word "threads"; and a keyword check that would have
made "ORacle" an OR. 51 new tests, 209 total.
@Hawkynt
Hawkynt merged commit eb35fba into main Aug 17, 2026
11 checks passed
@Hawkynt
Hawkynt deleted the query-language branch August 17, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant