I'm doing some string processing in vimscript. I obtained a byte index for a character in the string and now want to obtain the character at that byte index. For single-byte charsets (like latin1) this is not a problem:
let char = string[offset]
But what if the string is (potentially) multi-byte?
I implemented the following:
function s:GetCharAtByteIdx(str, index) " AFAIK maximum length of utf8-char is 4 byte let sp = a:str[a:index:(a:index+3)] let chr = strcharpart(sp, 0, 1) return [ chr, (a:index + strlen(chr)) ] endfunction
This function returns the character at the given byte-index and the byte-index of the following character. It works as expected.
Is there a better solution? Maybe a internal function I missed?
A (now deleted) comment proposed to use
matchstr(str, '\%2c.') to get the character at byte offset 2. The resulting function would be:
function s:GetCharAtByteIndex(str, index) let chr = matchstr(a:str, '\%' . (a:index+1) . 'c.') return [ chr, (a:index + strlen(chr)) ] endfunction
The tests were successful, but the test execution time increased from ~10 to ~15 seconds (5 Vim startup, 200 test overall + same for nvim).
a:str[a:index:(a:index+3)]to get the first four bytes?
split()the string and return the index.
split()help with the byte offset?