mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-03-26 04:00:29 +08:00
233 lines
6.0 KiB
VimL
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:
|