1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 21:00:06 +08:00
SpaceVim/bundle/open-browser.vim/autoload/vital/_openbrowser/Data/Optional.vim

202 lines
4.6 KiB
VimL
Raw Normal View History

2020-06-13 14:06:35 +08:00
" ___vital___
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
" Do not modify 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#_openbrowser#Data#Optional#import() abort', printf("return map({'flat_map': '', 'has': '', 'flatten': '', 'some': '', 'apply': '', 'last': '', 'get_unsafe': '', 'new': '', 'is_optional': '', 'echo': '', 'exists': '', 'map': '', 'empty': '', 'get': '', 'first': '', 'unset': '', 'bind': '', 'none': '', 'get_or': '', 'set': '', 'optional': ''}, \"vital#_openbrowser#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
delfunction s:_SID
" ___vital___
let s:save_cpo = &cpo
set cpo&vim
" NOTE: These are verbose to avoid key's unintentional confliction ;(
let s:SOME_KEY = 'vital_data_optional_some' | lockvar s:SOME_KEY
let s:NONE_KEY = 'vital_data_optional_none' | lockvar s:NONE_KEY
function! s:_require_optional(...) abort
for x in a:000
if !s:is_optional(x)
throw printf('vital: Data.Optional: Not an optional value `%s`', string(x))
endif
unlet x
endfor
endfunction
function! s:_require_optionals(xs) abort
call call(function('s:_require_optional'), a:xs)
endfunction
function! s:none() abort
let none = {}
let none[s:NONE_KEY] = {}
return none
endfunction
function! s:some(v) abort
let some = {}
let some[s:SOME_KEY] = a:v
return some
endfunction
function! s:new(v, ...) abort
return a:v == v:null || (a:0 > 0 && a:v == a:1)
\ ? s:none()
\ : s:some(a:v)
endfunction
function! s:is_optional(v) abort
return s:empty(a:v) || s:exists(a:v)
endfunction
function! s:empty(o) abort
return (type(a:o) is type({})) && has_key(a:o, s:NONE_KEY)
endfunction
function! s:exists(o) abort
return (type(a:o) is type({})) && has_key(a:o, s:SOME_KEY)
endfunction
function! s:set(o, v) abort
if s:empty(a:o)
unlet a:o[s:NONE_KEY]
endif
let a:o[s:SOME_KEY] = a:v
endfunction
function! s:unset(o) abort
if s:exists(a:o)
unlet a:o[s:SOME_KEY]
endif
let a:o[s:NONE_KEY] = {}
endfunction
function! s:get(o) abort
if s:empty(a:o)
throw 'vital: Data.Optional: An empty Data.Optional value'
endif
return a:o[s:SOME_KEY]
endfunction
function! s:get_unsafe(o) abort
return a:o[s:SOME_KEY]
endfunction
function! s:get_or(o, alt) abort
return get(a:o, s:SOME_KEY, a:alt())
endfunction
function! s:has(o, type) abort
return !s:empty(a:o) && (type(a:o[s:SOME_KEY]) is a:type)
endfunction
function! s:apply(f, ...) abort
call s:_require_optionals(a:000)
let args = []
for x in a:000
if s:empty(x)
return s:none()
endif
call add(args, s:get(x))
unlet x
endfor
return s:some(call(a:f, args))
endfunction
function! s:map(x, f) abort
if s:empty(a:x)
return s:none()
endif
let naked_result = call(a:f, [s:get(a:x)])
return s:some(naked_result)
endfunction
function! s:bind(f, ...) abort
call s:_require_optionals(a:000)
let args = []
for x in a:000
if s:empty(x)
return s:none()
endif
call add(args, s:get(x))
endfor
return call(a:f, args)
endfunction
let s:FLATTEN_DEFAULT_LIMIT = 1 | lockvar s:FLATTEN_DEFAULT_LIMIT
function! s:flatten(x, ...) abort
let limit = get(a:000, 0, s:FLATTEN_DEFAULT_LIMIT)
if limit is 0
return s:_flatten_fully(a:x)
endif
return s:_flatten_with_limit(a:x, limit)
endfunction
" Returns true for some({non optional}).
" Otherwise, returns false.
" (Returns false for none().)
function! s:_has_a_nest(x) abort
return s:exists(a:x) && !s:is_optional(s:get(a:x))
endfunction
function! s:_flatten_with_limit(x, limit) abort
if s:empty(a:x) || s:_has_a_nest(a:x) || (a:limit <= 0)
return a:x
endif
return s:_flatten_with_limit(s:get(a:x), a:limit - 1)
endfunction
function! s:_flatten_fully(x) abort
if s:empty(a:x) || s:_has_a_nest(a:x)
return a:x
endif
return s:_flatten_fully(s:get(a:x))
endfunction
function! s:flat_map(f, x) abort
return s:bind(a:f, a:x)
endfunction
function! s:optional(x, f, g) abort
return s:get_or(s:map(a:x, a:f), a:g)
endfunction
function! s:first(xs) abort
for x in a:xs
if s:exists(x)
return x
endif
endfor
return s:none()
endfunction
function! s:last(xs) abort
return s:first(reverse(copy(a:xs)))
endfunction
function! s:_echo(x) abort
if s:empty(a:x)
echo 'None'
return
endif
echo 'Some (' . s:get(a:x) . ')'
endfunction
function! s:echo(o, ...) abort
call s:_require_optional(a:o)
execute 'echohl' get(a:000, 0, 'None')
call s:map(a:o, function('s:_echo'))
echohl None
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo