Skip to content

Instantly share code, notes, and snippets.

@itchyny
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itchyny/9172059 to your computer and use it in GitHub Desktop.
Save itchyny/9172059 to your computer and use it in GitHub Desktop.
Binary search in strwidthpart, strwidthpart_reverse
function! s:new_strwidthpart(str, width)
if a:width <= 0
return ''
endif
" Split into array
let strarr = split(a:str, '\zs')
let width = s:wcswidth(a:str)
" Start binary search
let index = len(strarr)
let diff = index / 2
let rightindex = index - 1
while width > a:width && diff
let index = max([rightindex - diff + 1, 0])
let partwidth = s:wcswidth(join(strarr[(index):(rightindex)], ''))
if width - partwidth >= a:width || diff <= 1
let width -= partwidth
let rightindex = index - 1
endif
if diff > 1
let diff = diff / 2
endif
endwhile
return index ? join(strarr[:index - 1], '') : ''
endfunction
function! s:new_strwidthpart_reverse(str, width)
if a:width <= 0
return ''
endif
" Split into array
let strarr = split(a:str, '\zs')
let width = s:wcswidth(a:str)
let strlen = len(strarr)
" Start binary search
let diff = strlen / 2
let leftindex = 0
let index = -1
while width > a:width && diff
let index = min([leftindex + diff, strlen]) - 1
let partwidth = s:wcswidth(join(strarr[(leftindex):(index)], ''))
if width - partwidth >= a:width || diff <= 1
let width -= partwidth
let leftindex = index + 1
endif
if diff > 1
let diff = diff / 2
endif
endwhile
return index < strlen ? join(strarr[(index + 1):], '') : ''
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment