We are mis-communicating. My suggestion is _not_ to compute the
:align-to from the width of the prefix+candidate+suffix. My
suggestion is to calculate the width of <Type>+scroll-bar, then use
:align-to relative to the right edge of the window, like this:
:align-to (- right (N))
where N is the pixel-width of <Type>+scroll-bar
> The reason for this is that `string-pixel-width` will be
> called on all of these concatenated strings, and the maximum of which will be given as the width to a function
> to render the child frame. This also answers your next question, yes the pop up width is already calculated
> dynamically, but against a max width, this is what I mean by "confined", hence the need for truncation before
> blitzing the strings to a child frame. :align-to (- right suffix-width) will lead `string-pixel-width` to return a
> ridiculously large number that, funnily enough, is calculated from the current window's text area width, instead
> of the child frame's window, of which the size is unknown at this time.
I don't understand this. What is "suffix-width" in the above text,
and in what units is it measured? And why the size of the window is
unknown?
> As to the reason for a max width, let's just say there exists language servers such as Rust Analyzer, that will
> return the signature of a function as the completion annotation, which can be quite long. Nobody wants their
> completion pop up box taking up half the screen.
Long strings can be truncated with one of the known methods. Those
methods will not give you pixel accuracy, you don't need that if you
use :align-to relative to the right edge of the window.
Here are more gaps to fill in for you. The margin and the scroll bar widths are both calculated relative to the `default-font-width`, the reason for that is, assuming most of the text is in the default font, if it is 20px wide, it's undesirable to have a fixed scroll bar size of 3px. The scroll bar and the margin need to scale with the default font size to fight for just enough of the user's attention when viewed. This can be known with some refactoring by the time `string-pixel-width` is called on all the formatted completion strings, but the whole issue is the "right" in :align-to (- right <whatever>) would be referring to the window from which you calculate `string-pixel-width` from, not the window in the child frame, because we are trying calculate the child frame width from the content width at this point. What you are suggesting has a logical circular dependency here, which is why I explained to you that :align-to can only be calculated from `(+ prefix-column-width candidate--column-width (- suffix-column-width suffix-width)`. The suffix width means the annotation's pixel width, the part you keep calling type, which is not necessarily the case. I.e:
```
;; you just calculated the width of the space from the left to the right of the __current-window__ minus some offset
(let ((content-width (cl-loop for (prefix candidate suffix) in formatted-lines maximize (string-pixel-width (concat prefix candidate (propertize " " :align-to `(- right ,(whatever))) suffix)))))
....
;; now you just made a child frame as large as your current window's width minus whatever, presumably much smaller than your current window's width, thus this frame now covers most of your screen.
(make-frame `((width . ,content-width)))
```
I don't understand this, either. Why cannot the calculation of the
frame parameters take the scroll-bar into account, so as to avoid its
deletion/truncation?
For the second time, there's a max child frame width variable that "confines" how large it can be, the implication is it can be < content width, therefore necessitates programmatic truncation of the content width, which __does not__ include the scroll bar.
IOW, your proposed idea will work for the simple cases, but falls
apart for a general-purpose API which will rightfully be expected to
work in any situation and use case supported by Emacs.
Ok, makes sense. Thanks for filling in the missing parts for me. Here's some further questions.
WRT case 1, translating tab sizes is a simple multiplication, it sounds to me it can still be fast by bypassing windows. Is this correct? Anything else that can slow this case down?
WRT case 2, boldly extrapolating from my simple benchmarks, resolving the font from faces takes ~10% of the time in `string-pixel-width`, besides saving and restoring window states and scanning window positions, what else does "string-pixel-width" spend on the other 90% of the time?
The existing
high-level C APIs, which we use in window-text-pixel-size and its ilk,
are inappropriate, because they are unable to reliably find a buffer
or string position that corresponds to a given pixel-width.
Agreed.