mirror of
https://github.com/machakann/vim-sandwich.git
synced 2026-05-28 00:26:34 +02:00
347 lines
10 KiB
VimL
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:
|