Files
2017-03-13 00:19:28 +08:00

347 lines
10 KiB
VimL

" opt object - managing options
function! sandwich#opt#new(kind, defaultopt, argopt) abort "{{{
let opt = deepcopy(s:opt)
if a:kind ==# 'auto' || a:kind ==# 'query'
let opt.recipe = {}
let opt.of = function('s:of_for_textobj')
let opt.filter = s:default_values['textobj']['filter']
call opt.update('arg', a:argopt)
call opt.update('default', a:defaultopt)
else
let opt.recipe_add = {}
let opt.recipe_delete = {}
let opt.of = function('s:of_for_' . a:kind)
let opt.filter = s:default_values[a:kind]['filter']
call opt.update('arg', a:argopt)
endif
return opt
endfunction
"}}}
function! sandwich#opt#defaults(kind, ...) abort "{{{
if a:kind ==# 'auto' || a:kind ==# 'query'
return deepcopy(s:default_values['textobj'][a:kind])
elseif a:kind ==# 'add' || a:kind ==# 'delete' || a:kind ==# 'replace'
let motionwise = get(a:000, 0, 'char')
return deepcopy(s:default_values[a:kind][motionwise])
else
return {}
endif
endfunction
"}}}
" opt "{{{
let s:opt = {
\ 'default' : {},
\ 'arg' : {},
\ 'filter' : '',
\ }
"}}}
function! s:opt.clear(target) dict abort "{{{
call filter(self[a:target], 0)
endfunction
"}}}
function! s:opt.update(target, dict) dict abort "{{{
call self.clear(a:target)
call extend(self[a:target], filter(deepcopy(a:dict), self.filter), 'force')
endfunction
"}}}
function! s:opt.has(opt_name) dict abort "{{{
return has_key(self.default, a:opt_name)
endfunction
"}}}
function! s:opt.max(opt_name, ...) dict abort "{{{
let minimum = get(a:000, 0, 0)
let list = []
if has_key(self['recipe_delete'], a:opt_name)
let list += [self['recipe_delete'][a:opt_name]]
endif
if has_key(self['recipe_add'], a:opt_name)
let list += [self['recipe_add'][a:opt_name]]
endif
if list == []
let list += [self._of(a:opt_name)]
endif
return max([minimum] + list)
endfunction
"}}}
function! s:opt.get(opt_name, kind, ...) dict abort "{{{
return self.has(a:opt_name) ? self.of(a:opt_name, a:kind) : get(a:000, 0, 0)
endfunction
"}}}
function! s:opt._of(opt_name, ...) dict abort "{{{
let kind = get(a:000, 0, '')
if kind !=# '' && has_key(self[kind], a:opt_name)
return self[kind][a:opt_name]
elseif has_key(self['arg'], a:opt_name)
return self['arg'][a:opt_name]
else
return self['default'][a:opt_name]
endif
endfunction
"}}}
function! s:of_for_add(opt_name, ...) dict abort "{{{
return self._of(a:opt_name, 'recipe_add')
endfunction
"}}}
function! s:of_for_delete(opt_name, ...) dict abort "{{{
return self._of(a:opt_name, 'recipe_delete')
endfunction
"}}}
function! s:of_for_replace(opt_name, ...) dict abort "{{{
let kind = get(a:000, 0, '')
if kind !=# ''
return self._of(a:opt_name, kind)
else
if a:opt_name ==# 'cursor'
" recipe_add > recipe_delete > arg > default
if has_key(self.recipe_add, a:opt_name)
return self.recipe_add[a:opt_name]
else
return self._of(a:opt_name, 'recipe_delete')
endif
elseif a:opt_name ==# 'query_once'
return self._of(a:opt_name, 'recipe_add')
elseif a:opt_name ==# 'regex'
return self._of(a:opt_name, 'recipe_delete')
elseif a:opt_name ==# 'expr'
return self._of(a:opt_name, 'recipe_add')
elseif a:opt_name ==# 'listexpr'
return self._of(a:opt_name, 'recipe_add')
elseif a:opt_name ==# 'noremap'
return self._of(a:opt_name, '')
elseif a:opt_name ==# 'skip_space'
return self._of(a:opt_name, 'recipe_delete')
elseif a:opt_name ==# 'skip_char'
return self._of(a:opt_name, 'recipe_delete')
elseif a:opt_name ==# 'highlight'
return self._of(a:opt_name, '')
elseif a:opt_name ==# 'hi_duration'
return self._of(a:opt_name, '')
elseif a:opt_name ==# 'command'
let commands = []
let commands += get(self.recipe_delete, a:opt_name, [])
let commands += get(self.recipe_add, a:opt_name, [])
if commands == []
let commands += self._of(a:opt_name)
endif
return commands
elseif a:opt_name ==# 'linewise'
return self.max(a:opt_name)
elseif a:opt_name ==# 'autoindent'
return self._of(a:opt_name, 'recipe_add')
elseif a:opt_name ==# 'indentkeys'
return self._of(a:opt_name, 'recipe_add')
elseif a:opt_name ==# 'indentkeys+'
return self._of(a:opt_name, 'recipe_add')
elseif a:opt_name ==# 'indentkeys-'
return self._of(a:opt_name, 'recipe_add')
else
" should not reach here!
throw 'OperatorSandwichError:Replace:InvalidOption:' . a:opt_name
endif
endif
endfunction
"}}}
function! s:of_for_textobj(opt_name) dict abort "{{{
if has_key(self['recipe'], a:opt_name)
return self['recipe'][a:opt_name]
elseif has_key(self['arg'], a:opt_name)
return self['arg'][a:opt_name]
else
return self['default'][a:opt_name]
endif
endfunction
"}}}
" default values "{{{
let s:default_values = {}
let s:default_values.add = {}
let s:default_values.add.char = {
\ 'cursor' : 'default',
\ 'query_once' : 0,
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'noremap' : 1,
\ 'skip_space' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ 'autoindent' : -1,
\ 'indentkeys' : 0,
\ 'indentkeys+': 0,
\ 'indentkeys-': 0,
\ }
let s:default_values.add.line = {
\ 'cursor' : 'default',
\ 'query_once' : 0,
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'noremap' : 1,
\ 'skip_space' : 1,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 1,
\ 'autoindent' : -1,
\ 'indentkeys' : 0,
\ 'indentkeys+': 0,
\ 'indentkeys-': 0,
\ }
let s:default_values.add.block = {
\ 'cursor' : 'default',
\ 'query_once' : 0,
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'noremap' : 1,
\ 'skip_space' : 1,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ 'autoindent' : -1,
\ 'indentkeys' : 0,
\ 'indentkeys+': 0,
\ 'indentkeys-': 0,
\ }
let s:default_values.add.filter = printf('v:key =~# ''\%%(%s\)''', join(keys(s:default_values['add']['char']), '\|'))
let s:default_values.delete = {}
let s:default_values.delete.char = {
\ 'cursor' : 'default',
\ 'noremap' : 1,
\ 'regex' : 0,
\ 'skip_space' : 1,
\ 'skip_char' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ }
let s:default_values.delete.line = {
\ 'cursor' : 'default',
\ 'noremap' : 1,
\ 'regex' : 0,
\ 'skip_space' : 2,
\ 'skip_char' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 1,
\ }
let s:default_values.delete.block = {
\ 'cursor' : 'default',
\ 'noremap' : 1,
\ 'regex' : 0,
\ 'skip_space' : 1,
\ 'skip_char' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ }
let s:default_values.delete.filter = printf('v:key =~# ''\%%(%s\)''', join(keys(s:default_values['delete']['char']), '\|'))
let s:default_values.replace = {}
let s:default_values.replace.char = {
\ 'cursor' : 'default',
\ 'query_once' : 0,
\ 'regex' : 0,
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'noremap' : 1,
\ 'skip_space' : 1,
\ 'skip_char' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ 'autoindent' : -1,
\ 'indentkeys' : 0,
\ 'indentkeys+': 0,
\ 'indentkeys-': 0,
\ }
let s:default_values.replace.line = {
\ 'cursor' : 'default',
\ 'query_once' : 0,
\ 'regex' : 0,
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'noremap' : 1,
\ 'skip_space' : 2,
\ 'skip_char' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ 'autoindent' : -1,
\ 'indentkeys' : 0,
\ 'indentkeys+': 0,
\ 'indentkeys-': 0,
\ }
let s:default_values.replace.block = {
\ 'cursor' : 'default',
\ 'query_once' : 0,
\ 'regex' : 0,
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'noremap' : 1,
\ 'skip_space' : 1,
\ 'skip_char' : 0,
\ 'highlight' : 3,
\ 'hi_duration': 200,
\ 'command' : [],
\ 'linewise' : 0,
\ 'autoindent' : -1,
\ 'indentkeys' : 0,
\ 'indentkeys+': 0,
\ 'indentkeys-': 0,
\ }
let s:default_values.replace.filter = printf('v:key =~# ''\%%(%s\)''', join(keys(s:default_values['replace']['char']), '\|'))
let s:default_values.textobj = {}
let s:default_values.textobj.auto = {
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'regex' : 0,
\ 'skip_regex' : [],
\ 'skip_regex_head': [],
\ 'skip_regex_tail': [],
\ 'quoteescape' : 0,
\ 'expand_range' : -1,
\ 'nesting' : 0,
\ 'synchro' : 1,
\ 'noremap' : 1,
\ 'syntax' : [],
\ 'inner_syntax' : [],
\ 'match_syntax' : 0,
\ 'skip_break' : 0,
\ 'skip_expr' : [],
\ }
let s:default_values.textobj.query = {
\ 'expr' : 0,
\ 'listexpr' : 0,
\ 'regex' : 0,
\ 'skip_regex' : [],
\ 'skip_regex_head': [],
\ 'skip_regex_tail': [],
\ 'quoteescape' : 0,
\ 'expand_range' : -1,
\ 'nesting' : 0,
\ 'synchro' : 1,
\ 'noremap' : 1,
\ 'syntax' : [],
\ 'inner_syntax' : [],
\ 'match_syntax' : 0,
\ 'skip_break' : 0,
\ 'skip_expr' : [],
\ }
let s:default_values.textobj.filter = printf('v:key =~# ''\%%(%s\)''', join(keys(s:default_values.textobj.auto), '\|'))
"}}}
" vim:set foldmethod=marker:
" vim:set commentstring="%s:
" vim:set ts=2 sts=2 sw=2: