1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-03-26 04:00:29 +08:00
2022-03-27 13:38:54 +08:00

233 lines
6.0 KiB
VimL

"=============================================================================
" string.vim --- SpaceVim string API
" Copyright (c) 2016-2022 Wang Shidong & Contributors
" Author: Wang Shidong < wsdjeg@outlook.com >
" URL: https://spacevim.org
" License: GPLv3
"=============================================================================
""
" @section data#string, api-data-string
" @parentsection api
"
" @subsection Functions
"
" split(str [, sep [, keepempty[, max]]])
"
" run vim command, and return the output of such command.
"
" trim(str)
"
" remove space at the begin and end of a string, same as |trim()|
"
" fill(str, length[, char])
"
" fill string to length with {char}, if {char} is omnit, a space is used.
let s:self = {}
function! s:self.trim(str) abort
let str = substitute(a:str, '\s*$', '', 'g')
return substitute(str, '^\s*', '', 'g')
endfunction
" strcharpart is added in v7.4.1761
"
if exists('*strcharpart')
function! s:self.strcharpart(str, start, ...) abort
return call('strcharpart', [a:str, a:start] + a:000)
endfunction
else
function! s:self.strcharpart(str, start, ...) abort
let chars = self.string2chars(a:str)
return join(chars[a:start : get(a:000, 0, -1)], '')
endfunction
endif
function! s:self.fill(str, length, ...) abort
if strwidth(a:str) <= a:length
let l:string = a:str
else
let l:rightmost = 0
while strwidth(self.strcharpart(a:str, 0, l:rightmost)) < a:length
let l:rightmost += 1
endwhile
let l:string = self.strcharpart(a:str, 0, l:rightmost)
endif
let char = get(a:000, 0, ' ')
if type(char) !=# 1 || len(char) > 1
let char = ' '
endif
let l:spaces = repeat(char, a:length - strwidth(l:string))
return l:string . l:spaces
endfunction
function! s:self.toggle_case(str) abort
let chars = []
for char in self.string2chars(a:str)
if char2nr(char) >= 97 && char2nr(char) <= 122
call add(chars, nr2char(char2nr(char) - 32))
elseif char2nr(char) >= 65 && char2nr(char) <= 90
call add(chars, nr2char(char2nr(char) + 32))
else
call add(chars, char)
endif
endfor
return join(chars, '')
endfunction
function! s:self.fill_left(str, length, ...) abort
if strwidth(a:str) <= a:length
let l:string = a:str
else
let l:string = self.strcharpart(a:str, strwidth(a:str) - a:length, a:length)
endif
let char = get(a:000, 0, ' ')
if type(char) !=# 1 || len(char) > 1
let char = ' '
endif
let l:spaces = repeat(char, a:length - strwidth(l:string))
return l:spaces . l:string
endfunction
function! s:self.fill_middle(str, length, ...) abort
if strwidth(a:str) <= a:length
let l:string = a:str
else
let l:string = self.strcharpart(a:str, (a:length/2 < 1 ? 1 : a:length/2), a:length)
endif
let l:numofspaces = a:length - strwidth(l:string)
let char = get(a:000, 0, ' ')
if type(char) !=# 1 || len(char) > 1
let char = ' '
endif
let l:halfspaces = repeat(char, l:numofspaces/2)
let l:rst = l:halfspaces . l:string . l:halfspaces
if l:numofspaces % 2
let l:rst .= char
endif
return l:rst
endfunction
function! s:self.trim_start(str) abort
return substitute(a:str, '^\s*', '', 'g')
endfunction
function! s:self.trim_end(str) abort
return substitute(a:str, '\s*$', '', 'g')
endfunction
" note: this function only works when encoding is utf-8
" ref: https://github.com/SpaceVim/SpaceVim/pull/2515
function! s:self.string2chars(str) abort
let save_enc = &encoding
let &encoding = 'utf-8'
let chars = split(a:str, '\zs')
let &encoding = save_enc
return chars
endfunction
if exists('*strcharpart') && 0
function! s:self.matchstrpos(str, need, ...) abort
return call('matchstrpos', [a:str, a:need] + a:000)
endfunction
else
function! s:self.matchstrpos(str, need, ...) abort
let matchedstr = call('matchstr', [a:str, a:need] + a:000)
let matchbegin = call('match', [a:str, a:need] + a:000)
let matchend = call('matchend', [a:str, a:need] + a:000)
return [matchedstr, matchbegin, matchend]
endfunction
endif
function! s:self.strAllIndex(str, need, use_expr) abort
if a:use_expr
let rst = []
let idx = self.matchstrpos(a:str, a:need)
while idx[1] != -1
call add(rst, [idx[1], idx[2]])
let idx = self.matchstrpos(a:str, a:need, idx[2])
endwhile
return rst
else
let rst = []
let idx = match(a:str, "\\<" . a:need . "\\>")
while idx != -1
call add(rst, [idx, idx+len(a:need)])
let idx = match(a:str, "\\<" . a:need . "\\>", idx + 1 + len(a:need))
endwhile
return rst
endif
endfunction
function! s:self.strQ2B(str) abort
let save_enc = &encoding
let &encoding = 'utf-8'
let chars = self.string2chars(a:str)
let bchars = []
for char in chars
let nr = char2nr(char)
if nr == 12288
call add(bchars, nr2char(32))
elseif nr == 8216 || nr == 8217
call add(bchars, nr2char(39))
elseif nr >= 65281 && nr <= 65374
call add(bchars, nr2char(nr - 65248))
else
call add(bchars, char)
endif
endfor
let &encoding = save_enc
return join(bchars, '')
endfunction
function! s:self.strB2Q(str) abort
let save_enc = &encoding
let &encoding = 'utf-8'
let chars = self.string2chars(a:str)
let bchars = []
for char in chars
let nr = char2nr(char)
if nr == 32
call add(bchars, nr2char(12288))
elseif nr >= 32 && nr <= 126
call add(bchars, nr2char(nr + 65248))
else
call add(bchars, char)
endif
endfor
let &encoding = save_enc
return join(bchars, '')
endfunction
function! s:self.split(str, ...) abort
let sep = get(a:000, 0, '')
let keepempty = get(a:000, 1, 0)
let max = get(a:000, 2, -1)
let rlist = split(a:str, sep, keepempty)
if max >= 2
let rst = []
for item in rlist
if len(rst) >= max - 1
break
endif
call add(rst, item)
endfor
let last = join(rlist[max-1:], sep)
call add(rst, last)
return rst
else
return rlist
endif
endfunction
function! SpaceVim#api#data#string#get() abort
return deepcopy(s:self)
endfunction
" vim:set et sw=2: