I'm currently making a program where I have to display an information with println() BUT I must also ensure it does not overflow the terminal's current line width.
So I used a crate to get the terminal's width in characters (let's call it N), and only kepts the N first characters of the string.
Problem, some of these characters are non-printable: the color escape sequences are considered as characters. Which results in the string being stripped too early.
How could I achieve the stripping so that I display at most N visible characters while keeping all the color escape sequences inside it?
Ah yes, this is an annoying problem.
The solution depends heavily on how you are constructing the "colored" strings.
If you are dealing with static strings, you can iterate through them and find the actual length. Inefficient but simple.
You can construct a ColoredString struct, which wraps around a String which has escape sequences. You can then keep track of the number of escape sequences included, and subtract them from the string length.
In order to truncate efficiently, you need to keep track of more information. If N is fixed, then you can find it out once and cache the result. If N is dynamic (which might be the case if you are handling terminal resizing), then there are many ways to go about it, where you need to tradeoff between space and time.
The most time efficient way would be to store the string index for each visible character in a map. This will take a lot of space for long strings, so you might want to store every 5th or 10th character's index.
Another way would be store the indices of the escape sequences and use that to find out how many extra characters you need to include in the final substring.
I suspect that the only reliable answer is another API from the whatever terminal crate you're using to ask it how long something is, and work based on that.
You might also be able to write using terminal APIs that offer rendering truncation, rather than going through println!.
It depends on your terminal and font and maybe the locale too. I don't think there's a sane and completely correct way (the less sane way involves paint-query-adjust across different terminal capabilities). I'm not saying don't try (in fact thank you for doing so), but just noting it's a best-effort situation.
I don't think so. These double-width characters move the cursor correctly. The cuneiform sigil, however, seems to have a Unicode width of 1. This doesn't make much sense to me, as that's supposed to be the display width.