What is countColumn for?

countColumn(string: string, n: number, tabSize: number) → number
Count the column position at the given offset into the string, taking extending characters and tab size into account.

From its test:
countColumn("a\t\tbc\tx", 0, 4)13
But I’d expect that to be column 0 (or 1?). Hasn’t it returned the total number of columns?

OK… how about other inputs (4 is between the ‘b’ and ‘c’):
countColumn("a\t\tbc\tx", 4, 4)17
That’s longer that the total columns!

All inputs: 0 to 2 → 13, 3 to 6 → 17, 7 → 21
Q: What does this map represent?

(findColumn works as per its description, but I’m after the inverse map - which countColumn isn’t. Should it be? (there’s no test for n other than 0))


My goal is to display column / visual column info in a statusbar.
Found this pattern countColumn(line.text.slice(0, offset - line.from), 0, view.state.tabSize) in the codebase. Hint: use 1 for tabSize (column in chars).

The interface for this is a mess, a result of the situation when lines could consist of multiple strings in the document structure and we’d have to iterate over those chunks to count columns. This is no longer the case and I should clean that up. The current interface always counts the entire string it is given, and its second argument is the column at the start of that string.

How about Line methods?
line.columnAt(pos, tabSize) // automatically subtracts line.from?
line.posAt(column, tabSize)

Just an idea, no real need if countColumn is updated to match its description.

So can a cluster be more than one column?
Unicode Text Segmentation shows some with unusual widths. A couple of ligatures, ffi and ffl, can be wider than a column. Digraphs can be a singular, two column char, e.g. DŽ.
Probably just missing monospace glyphs…

BTW cursor movement seems off for क्षि and ক্ষী, with an extra “pos” in the middle. U+093F, and others, aren’t in the list but look like combining chars?

I get the feeling bidi (especially with rectangular selections) would be tricky too.