Partition the filter string into hintchars and content filter strings. Apply each part in sequence, reducing the list of active hints.
Update display after all filtering, adjusting labels if appropriate.
Consider: This is a poster child for separating data and display. If they weren't so tied here we could do a neat dynamic programming thing and just throw the data at a reactalike.
For each hintable element, add a hint
Get array of images in the viewport
Array of hintable elements in viewport
Elements are hintable if
Shorter hints
Hints that are prefixes of other hints are a bit annoying because you have to select them with Enter or Space.
This function removes hints that prefix other hints by observing that: let h = hintchars.length if n < h ** 2 then n / h = number of single character hintnames that would prefix later hints
So it removes them. This function is not yet clever enough to realise that if n > h ** 2 it should remove h + (n - h*2 - h) / h * 2 and so on, but we hardly ever see that many hints, so whatever.
An infinite stream of hints
Earlier hints prefix later hints
Uniform length hintnames
Array of items that can be killed with hint kill
If key is in hintchars, add it to filtstr and filter
Remove all hints, reset STATE. If abort is true, we're resetting because the user pressed escape. If it is false, we're resetting because the user selected a hint.
Returns elements that point to a saveable resource
Show only hints prefixed by fstr. Focus first match