Vim における文字列について その2

Vim には byteidx() という関数が用意されていて,これを使って文字単位のインデックスからバイト単位のインデックスに変換できる.

" &encoding == 'utf-8'
byteidx('abc', 2)  " => 2
byteidx('あiうeお', 3) " => 7

これを用いると,例えばマルチバイト文字を含む文字列に対しても文字単位で動作する strpart() を書くことができる.

function! s:strpart(str, start, ...)
  let s = strpart(a:str, byteidx(a:str, a:start))
  if a:0 == 0
    return s
  else
    let i = byteidx(s, a:1)
    return i == -1 ? s : strpart(s, 0, i)
  endif
endfunction

s:strpart('あiうeお', 1, 2) " => 'iう'
s:strpart('あiうeお', 3, 1) " => 'e'

ちなみに i の値を見ているのは strpart('abc', 0, 4) が 'abc' を返すという仕様に合わせるための処理であって,本質的ではない.