123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- scriptencoding utf-8
- function! coc#string#get_character(line, col) abort
- return strchars(strpart(a:line, 0, a:col - 1))
- endfunction
- function! coc#string#last_character(line) abort
- return strcharpart(a:line, strchars(a:line) - 1, 1)
- endfunction
- function! coc#string#reflow(lines, width) abort
- let lines = []
- let currlen = 0
- let parts = []
- for line in a:lines
- for part in split(line, '\s\+')
- let w = strwidth(part)
- if currlen + w + 1 >= a:width
- if len(parts) > 0
- call add(lines, join(parts, ' '))
- endif
- if w >= a:width
- call add(lines, part)
- let currlen = 0
- let parts = []
- else
- let currlen = w
- let parts = [part]
- endif
- continue
- endif
- call add(parts, part)
- let currlen = currlen + w + 1
- endfor
- endfor
- if len(parts) > 0
- call add(lines, join(parts, ' '))
- endif
- return empty(lines) ? [''] : lines
- endfunction
- function! coc#string#content_height(lines, width) abort
- let len = 0
- for line in a:lines
- if strwidth(line) <= a:width
- let len = len + 1
- else
- let currlen = 0
- for part in split(line, '\<\|\>\|\ze\s')
- let w = strwidth(part)
- if currlen + w >= a:width
- if currlen + w == a:width
- let len = len + 1
- let currlen = 0
- else
- let len = len + (a:width + w)/a:width
- let currlen = w%a:width
- endif
- else
- let currlen = currlen + w
- endif
- endfor
- if currlen > 0
- let len = len + 1
- endif
- endif
- endfor
- return len == 0 ? 1 : len
- endfunction
- " get change between two lines
- function! coc#string#diff(curr, previous, col) abort
- let end = strpart(a:curr, a:col - 1)
- let start = strpart(a:curr, 0, a:col -1)
- let endOffset = 0
- let startOffset = 0
- let currLen = strchars(a:curr)
- let prevLen = strchars(a:previous)
- if len(end)
- let endLen = strchars(end)
- for i in range(min([prevLen, endLen]))
- if strcharpart(end, endLen - 1 - i, 1) ==# strcharpart(a:previous, prevLen -1 -i, 1)
- let endOffset = endOffset + 1
- else
- break
- endif
- endfor
- endif
- let remain = endOffset == 0 ? a:previous : strcharpart(a:previous, 0, prevLen - endOffset)
- if len(remain)
- for i in range(min([strchars(remain), strchars(start)]))
- if strcharpart(remain, i, 1) ==# strcharpart(start, i ,1)
- let startOffset = startOffset + 1
- else
- break
- endif
- endfor
- endif
- return {
- \ 'start': startOffset,
- \ 'end': prevLen - endOffset,
- \ 'text': strcharpart(a:curr, startOffset, currLen - startOffset - endOffset)
- \ }
- endfunction
- function! coc#string#apply(content, diff) abort
- let totalLen = strchars(a:content)
- let endLen = totalLen - a:diff['end']
- return strcharpart(a:content, 0, a:diff['start']).a:diff['text'].strcharpart(a:content, a:diff['end'], endLen)
- endfunction
- " insert inserted to line at position, use ... when result is too long
- " line should only contains character has strwidth equals 1
- function! coc#string#compose(line, position, inserted) abort
- let width = strwidth(a:line)
- let text = a:inserted
- let res = a:line
- let need_truncate = a:position + strwidth(text) + 1 > width
- if need_truncate
- let remain = width - a:position - 3
- if remain < 2
- " use text for full line, use first & end of a:line, ignore position
- let res = strcharpart(a:line, 0, 1)
- let w = strwidth(res)
- for i in range(strchars(text))
- let c = strcharpart(text, i, 1)
- let a = strwidth(c)
- if w + a <= width - 1
- let w = w + a
- let res = res . c
- endif
- endfor
- let res = res.strcharpart(a:line, w)
- else
- let res = strcharpart(a:line, 0, a:position)
- let w = strwidth(res)
- for i in range(strchars(text))
- let c = strcharpart(text, i, 1)
- let a = strwidth(c)
- if w + a <= width - 3
- let w = w + a
- let res = res . c
- endif
- endfor
- let res = res.'..'
- let w = w + 2
- let res = res . strcharpart(a:line, w)
- endif
- else
- let first = strcharpart(a:line, 0, a:position)
- let res = first . text . strcharpart(a:line, a:position + strwidth(text))
- endif
- return res
- endfunction
|