The set of operator and textobject plugins to search/select/edit sandwiched textobjects.
sandwich.vimis a set of operator and textobject plugins to add/delete/replace surroundings of a sandwiched textobject, like (foo), "bar".
Press
sa{motion/textobject}{addition}. For example, a key sequence
saiw(makes foo to (foo).
Press
sdbor
sd{deletion}. For example, key sequences
sdbor
sd(makes (foo) to foo.
sdbsearches a set of surrounding automatically.
Press
srb{addition}or
sr{deletion}{addition}. For example, key sequences
srb"or
sr("makes (foo) to "foo".
That's all. Now you already know enough about
sandwich.vim. If you are using vim-surround, you can use a preset keymappings similar as it. See here
sandwich.vimhas some functional input for {addition}/{deletion}. Check here!
This plugin provides functions to add/delete/replace surroundings of a sandwiched text. These functions are implemented genuinely by utilizing operator/textobject framework. Thus their action can be repeated by
.command without any dependency. It consists of two parts, operator-sandwich and textobj-sandwich.
A sandwiched text could be resolved into two parts, {surrounding} and {surrounded text}.
Add surroundings: mapped to the key sequence
sa
Delete surroundings: mapped to the key sequence
sd
Replace surroundings: mapped to the key sequence
sr
iband
ab
isand
as
iband
isselects {surrounded text}.
aband
asselects {surrounded text} including {surrounding}s.
|| {surrounding}{surrounded text}{surrounding} ||
The point is that it would be nice to be shared the definitions of {surrounding}s pairs in all kinds of operations. User can freely add new settings to extend the functionality. If
g:sandwich#recipeswas defined, this plugin works with the settings inside. As a first step, it would be better to copy the default settings in
g:sandwich#default_recipes.
vim let g:sandwich#recipes = deepcopy(g:sandwich#default_recipes)Each setting, it is called
recipe, is a set of a definition of {surrounding}s pair and options. The key named
bunsis used for the definition of {surrounding}. ``` let g:sandwich#recipes += [{'buns': [{surrounding}, {surrounding}], 'option-name1': {value1}, 'option-name2': {value2} ...}]
For example: {'buns': ['(', ')']} foo ---> (foo) ```
Or there is a different way, use external textobjects to define {surrounding}s from the difference of two textobjects. ``` let g:sandwich#recipes += [{'external': [{textobj-i}, {textobj-a}], 'option-name1': {value1}, 'option-name2': {value} ...}]
For example: {'external': ['it', 'at']}
foo ---> foo ```As for the default operators, the possible key input in normal mode is like this.
[count1]{operator}[count2]{textobject}Default operators do not distinguish
[count1]and
[count2]but operator-sandwich does.
[count1]is given for
{operators}and
[count2]is given for
{textobject}.
Operator-sandwich works linewise with the linewise-visual selection and linewise motions.
" press Vsa( foo ---> ( foo )
Using
commandoption, user can execute vim Ex-commands after an action. For example it can be used to adjust indent automatically.
let g:sandwich#recipes += [ \ { \ 'buns' : ['{', '}'], \ 'motionwise' : ['line'], \ 'kind' : ['add'], \ 'linewise' : 1, \ 'command' : ["'[+1,']-1normal! >>"], \ }, \ { \ 'buns' : ['{', '}'], \ 'motionwise' : ['line'], \ 'kind' : ['delete'], \ 'linewise' : 1, \ 'command' : ["'[,']normal! < { foo }" press V2jsd { ---> foo foo }
Operator-sandwich also can work blockwise with the blockwise-visual selection and blockwise motions.
" press 2j2lsa( foo (foo) bar ---> (bar) baz (baz)
There is an option to skip white space
skip_space, it is valid in default. Empty line is ignored.
" press 3j$sa( fooooooo (fooooooo) baaaar ---> (baaaar)baaaz (baaaz)
The option
exprenables to evaluate surroundings (
buns) before adding/deleting/replacing surroundings. The following recipe is an simple example to wrap texts by html style tags.
let g:sandwich#recipes += [ \ { \ 'buns' : ['TagInput(1)', 'TagInput(0)'], \ 'expr' : 1, \ 'filetype': ['html'], \ 'kind' : ['add', 'replace'], \ 'action' : ['add'], \ 'input' : ['t'], \ }, \ ]function! TagInput(is_head) abort if a:is_head let s:TagLast = input('Tag: ') if s:TagLast !=# '' let tag = printf('', s:TagLast) else throw 'OperatorSandwichCancel' endif else let tag = printf('%s>', matchstr(s:TagLast, '^\a[^[:blank:]>/]*')) endif return tag endfunction
The option
regexis to regard surroundings (
buns) as regular expressions to match and delete/replace. The following recipe is an simple example to delete both ends of html tag.
let g:sandwich#recipes += [ \ { \ 'buns' : ['/]*.\{-}>', \ '\a[^[:blank:]>/]*>'], \ 'regex' : 1, \ 'filetype': ['html'], \ 'nesting' : 1, \ 'input' : ['t'], \ }, \ ]
However the above example is not so accurate. Instead of the example, there are excellent built-in textobjects
itand
at, these external textobjects also can be utilized through
external.
let g:sandwich#recipes += [ \ { \ 'external': ['it', 'at'], \ 'noremap' : 1, \ 'filetype': ['html'], \ 'input' : ['t'], \ }, \ ]