diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2018-01-10 23:50:02 +0100 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2018-01-10 23:50:02 +0100 | 
| commit | 58709c49f6b6ede81dcf87752b09b8f64d84f1fc (patch) | |
| tree | 3d9a50b80abee303e4663475b7c1e9e6fd4b7f2c /autoload/vital/_crystal/Data | |
| parent | 3d5b784fa59b0e70e0174174ba894054aa5b02bc (diff) | |
| download | vim-polyglot-58709c49f6b6ede81dcf87752b09b8f64d84f1fc.tar.gz vim-polyglot-58709c49f6b6ede81dcf87752b09b8f64d84f1fc.zip  | |
Update
Diffstat (limited to 'autoload/vital/_crystal/Data')
| -rw-r--r-- | autoload/vital/_crystal/Data/List.vim | 26 | ||||
| -rw-r--r-- | autoload/vital/_crystal/Data/String.vim | 177 | 
2 files changed, 142 insertions, 61 deletions
diff --git a/autoload/vital/_crystal/Data/List.vim b/autoload/vital/_crystal/Data/List.vim index 55703b3d..1aac999f 100644 --- a/autoload/vital/_crystal/Data/List.vim +++ b/autoload/vital/_crystal/Data/List.vim @@ -1,5 +1,14 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1 +" ___vital___ +" NOTE: lines between '" ___vital___' is generated by :Vitalize. +" Do not mofidify the code nor insert new lines before '" ___vital___' +function! s:_SID() abort +  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$') +endfunction +execute join(['function! vital#_crystal#Data#List#import() abort', printf("return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'shift': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'drop_while': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'map_accum': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''}, \"vital#_crystal#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") +delfunction s:_SID +" ___vital___  " Utilities for list.  let s:save_cpo = &cpo @@ -175,6 +184,11 @@ function! s:take_while(f, xs) abort    return s:span(a:f, a:xs)[0]  endfunction +" similar to Haskell's Data.List.dropWhile +function! s:drop_while(f, xs) abort +  return s:span(a:f, a:xs)[1] +endfunction +  " similar to Haskell's Data.List.partition  function! s:partition(f, xs) abort    return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')] @@ -271,14 +285,22 @@ endfunction  " similar to Ruby's detect or Haskell's find.  function! s:find(list, default, f) abort +  let l:Call = type(a:f) is type(function('function')) +  \          ? function('call') +  \          : function('s:_call_string_expr') +    for x in a:list -    if eval(substitute(a:f, 'v:val', string(x), 'g')) +    if l:Call(a:f, [x])        return x      endif    endfor    return a:default  endfunction +function! s:_call_string_expr(expr, args) abort +  return map([a:args[0]], a:expr)[0] +endfunction +  " Returns the index of the first element which satisfies the given expr.  function! s:find_index(xs, f, ...) abort    let len = len(a:xs) @@ -426,7 +448,7 @@ function! s:combinations(list, r) abort    if a:r > len(a:list)      return []    elseif a:r < 0 -    throw 'vital: Data:List: {r} must be non-negative integer' +    throw 'vital: Data.List: {r} must be non-negative integer'    endif    let n = len(a:list)    let result = [] diff --git a/autoload/vital/_crystal/Data/String.vim b/autoload/vital/_crystal/Data/String.vim index c2e2382c..7d3ef2c3 100644 --- a/autoload/vital/_crystal/Data/String.vim +++ b/autoload/vital/_crystal/Data/String.vim @@ -1,5 +1,14 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1 +" ___vital___ +" NOTE: lines between '" ___vital___' is generated by :Vitalize. +" Do not mofidify the code nor insert new lines before '" ___vital___' +function! s:_SID() abort +  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$') +endfunction +execute join(['function! vital#_crystal#Data#String#import() abort', printf("return map({'starts_with': '', 'split3': '', 'replace_first': '', 'chop': '', 'unescape': '', 'split_posix_text': '', 'replace': '', 'scan': '', 'strwidthpart': '', 'common_head': '', 'reverse': '', 'escape_pattern': '', 'trim_end': '', '_vital_depends': '', 'wrap': '', 'join_posix_lines': '', 'contains_multibyte': '', 'truncate_skipping': '', 'split_leftright': '', 'ends_with': '', 'nsplit': '', 'strwidthpart_reverse': '', 'unescape_pattern': '', 'levenshtein_distance': '', 'trim_start': '', 'justify_equal_spacing': '', 'nr2hex': '', 'iconv': '', 'pad_left': '', 'nr2enc_char': '', 'lines': '', 'repair_posix_text': '', 'nr2byte': '', 'trim': '', 'diffidx': '', 'truncate': '', 'split_by_displaywidth': '', '_vital_created': '', 'padding_by_displaywidth': '', 'hash': '', 'chomp': '', 'pad_between_letters': '', 'dstring': '', 'pad_both_sides': '', 'substitute_last': '', 'pad_right': '', 'remove_ansi_sequences': '', '_vital_loaded': ''}, \"vital#_crystal#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") +delfunction s:_SID +" ___vital___  " Utilities for string.  let s:save_cpo = &cpo @@ -7,12 +16,21 @@ set cpo&vim  function! s:_vital_loaded(V) abort    let s:V = a:V -  let s:P = s:V.import('Prelude')    let s:L = s:V.import('Data.List')  endfunction  function! s:_vital_depends() abort -  return ['Prelude', 'Data.List'] +  return ['Data.List'] +endfunction + +function! s:_vital_created(module) abort +  " Expose script-local funcref +  if exists('s:strchars') +    let a:module.strchars = s:strchars +  endif +  if exists('s:wcswidth') +    let a:module.wcswidth = s:wcswidth +  endif  endfunction  " Substitute a:from => a:to by string. @@ -61,7 +79,7 @@ function! s:common_head(strs) abort    endif    let strs = len == 2 ? a:strs : sort(copy(a:strs))    let pat = substitute(strs[0], '.', '\="[" . escape(submatch(0), "^\\") . "]"', 'g') -  return pat == '' ? '' : matchstr(strs[-1], '\C^\%[' . pat . ']') +  return pat ==# '' ? '' : matchstr(strs[-1], '\C^\%[' . pat . ']')  endfunction  " Split to two elements of List. ([left, right]) @@ -130,9 +148,7 @@ endfunction  " even if a:str contains multibyte character(s).  " s:strchars(str) {{{  if exists('*strchars') -  function! s:strchars(str) abort -    return strchars(a:str) -  endfunction +  let s:strchars = function('strchars')  else    function! s:strchars(str) abort      return strlen(substitute(copy(a:str), '.', 'x', 'g')) @@ -210,7 +226,7 @@ function! s:nr2byte(nr) abort  endfunction  function! s:nr2enc_char(charcode) abort -  if &encoding == 'utf-8' +  if &encoding ==# 'utf-8'      return nr2char(a:charcode)    endif    let char = s:nr2byte(a:charcode) @@ -222,7 +238,7 @@ endfunction  function! s:nr2hex(nr) abort    let n = a:nr -  let r = "" +  let r = ''    while n      let r = '0123456789ABCDEF'[n % 16] . r      let n = n / 16 @@ -318,7 +334,7 @@ function! s:levenshtein_distance(str1, str2) abort    let letters2 = split(a:str2, '\zs')    let length1 = len(letters1)    let length2 = len(letters2) -  let distances = map(range(1, length1 + 1), 'map(range(1, length2 + 1), "0")') +  let distances = map(range(1, length1 + 1), 'map(range(1, length2 + 1), ''0'')')    for i1 in range(0, length1)      let distances[i1][0] = i1 @@ -373,7 +389,7 @@ function! s:split_by_displaywidth(expr, width, float, is_wrap) abort    let text = ''    while cs_index < len(cs) -    if cs[cs_index] is "\n" +    if cs[cs_index] is# "\n"        let text = s:padding_by_displaywidth(text, a:width, a:float)        let lines += [text]        let text = '' @@ -394,7 +410,7 @@ function! s:split_by_displaywidth(expr, width, float, is_wrap) abort          if a:is_wrap            if a:width < w              if a:width < strdisplaywidth(cs[cs_index]) -              while get(cs, cs_index, "\n") isnot "\n" +              while get(cs, cs_index, "\n") isnot# "\n"                  let cs_index += 1                endwhile                continue @@ -403,7 +419,7 @@ function! s:split_by_displaywidth(expr, width, float, is_wrap) abort              endif            endif          else -          while get(cs, cs_index, "\n") isnot "\n" +          while get(cs, cs_index, "\n") isnot# "\n"              let cs_index += 1            endwhile            continue @@ -440,8 +456,9 @@ function! s:truncate(str, width) abort    " http://github.com/mattn/googlereader-vim/tree/master    if a:str =~# '^[\x00-\x7f]*$' -    return len(a:str) < a:width ? -          \ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width) +    return len(a:str) < a:width +          \ ? printf('%-' . a:width . 's', a:str) +          \ : strpart(a:str, 0, a:width)    endif    let ret = a:str @@ -471,57 +488,20 @@ function! s:truncate_skipping(str, max, footer_width, separator) abort  endfunction  function! s:strwidthpart(str, width) abort -  if a:width <= 0 -    return '' -  endif -  let strarr = split(a:str, '\zs') -  let width = s:wcswidth(a:str) -  let index = len(strarr) -  let diff = (index + 1) / 2 -  let rightindex = index - 1 -  while width > a:width -    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], '') : '' +  let str = tr(a:str, "\t", ' ') +  let vcol = a:width + 2 +  return matchstr(str, '.*\%<' . (vcol < 0 ? 0 : vcol) . 'v')  endfunction  function! s:strwidthpart_reverse(str, width) abort -  if a:width <= 0 -    return '' -  endif -  let strarr = split(a:str, '\zs') -  let width = s:wcswidth(a:str) -  let strlen = len(strarr) -  let diff = (strlen + 1) / 2 -  let leftindex = 0 -  let index = -1 -  while width > a:width -    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):], '') : '' +  let str = tr(a:str, "\t", ' ') +  let vcol = s:wcswidth(str) - a:width +  return matchstr(str, '\%>' . (vcol < 0 ? 0 : vcol) . 'v.*')  endfunction  if v:version >= 703    " Use builtin function. -  function! s:wcswidth(str) abort -    return strwidth(a:str) -  endfunction +  let s:wcswidth = function('strwidth')  else    function! s:wcswidth(str) abort      if a:str =~# '^[\x00-\x7f]*$' @@ -564,9 +544,88 @@ else    endfunction  endif +function! s:remove_ansi_sequences(text) abort +  return substitute(a:text, '\e\[\%(\%(\d\+;\)*\d\+\)\?[mK]', '', 'g') +endfunction + +function! s:escape_pattern(str) abort +  " escape characters for no-magic +  return escape(a:str, '^$~.*[]\') +endfunction + +function! s:unescape_pattern(str) abort +  " unescape characters for no-magic +  return s:unescape(a:str, '^$~.*[]\') +endfunction + +function! s:unescape(str, chars) abort +  let chars = map(split(a:chars, '\zs'), 'escape(v:val, ''^$~.*[]\'')') +  return substitute(a:str, '\\\(' . join(chars, '\|') . '\)', '\1', 'g') +endfunction + +function! s:iconv(expr, from, to) abort +  if a:from ==# '' || a:to ==# '' || a:from ==? a:to +    return a:expr +  endif +  let result = iconv(a:expr, a:from, a:to) +  return empty(result) ? a:expr : result +endfunction + +" NOTE: +" A definition of a TEXT file is "A file that contains characters organized +" into one or more lines." +" A definition of a LINE is "A sequence of zero or more non- <newline>s +" plus a terminating <newline>" +" That's why {stdin} always ends with <newline> ideally. However, there are +" some programs which does not follow the POSIX rule and a Vim's way to join +" List into TEXT; join({text}, "\n"); does not add <newline> to the end of +" the last line. +" That's why add a trailing <newline> if it does not exist. +" REF: +" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392 +" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205 +" :help split() +" NOTE: +" it does nothing if the text is a correct POSIX text +function! s:repair_posix_text(text, ...) abort +  let newline = get(a:000, 0, "\n") +  return a:text =~# '\n$' ? a:text : a:text . newline +endfunction + +" NOTE: +" A definition of a TEXT file is "A file that contains characters organized +" into one or more lines." +" A definition of a LINE is "A sequence of zero or more non- <newline>s +" plus a terminating <newline>" +" REF: +" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392 +" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205 +function! s:join_posix_lines(lines, ...) abort +  let newline = get(a:000, 0, "\n") +  return join(a:lines, newline) . newline +endfunction + +" NOTE: +" A definition of a TEXT file is "A file that contains characters organized +" into one or more lines." +" A definition of a LINE is "A sequence of zero or more non- <newline>s +" plus a terminating <newline>" +" TEXT into List; split({text}, '\r\?\n', 1); add an extra empty line at the +" end of List because the end of TEXT ends with <newline> and keepempty=1 is +" specified. (btw. keepempty=0 cannot be used because it will remove +" emptylines in the head and the tail). +" That's why removing a trailing <newline> before proceeding to 'split' is required +" REF: +" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392 +" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205 +function! s:split_posix_text(text, ...) abort +  let newline = get(a:000, 0, '\r\?\n') +  let text = substitute(a:text, newline . '$', '', '') +  return split(text, newline, 1) +endfunction +  let &cpo = s:save_cpo  unlet s:save_cpo -  " vim:set et ts=2 sts=2 sw=2 tw=0:  endif  | 
