New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latex commands and environments #2

Closed
maxfl opened this Issue Jul 9, 2015 · 13 comments

Comments

Projects
None yet
3 participants
@maxfl

maxfl commented Jul 9, 2015

Based on example from #1 I have added similar function for commands (code is below). It works, but seems to have some limitations:

  1. When used with vib/vab commands it prompts input for each recipe with expr. Is there is a way to avoid checking these commands in 'b'?
  2. Delete/replace operators does not work.

I think that both these issues could be resolved in case it is possible to define a regular expression for the delete operator. It is done it in the example with only limitation, the regex and expr recipes have different hotkeys. For a some reason I can not use vile/vilc (for regex based recipes), is it expected behaviour?

In #1 there was a note that such a functionality is supposed to be done via snippets plugins. I disagree with it. Snippets are useful when you write new text. But when you have already existing text you wish to wrap with environment, snippets can not be used. The task of replacing environment is also out of the scope of snippets.

        let g:sandwich#recipes += [
                    \   {
                    \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['e']
                    \   },
                    \   {
                    \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c']
                    \   },
                    \   {
                    \       'buns'    : ['\\begin\*\?{[^}]*}\(\[.*\]\)\?', '\\end\*\?{[^}]*}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'regex'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['le']
                    \   },
                    \   {
                    \       'buns'    : ['\\\a\+\*\?{', '}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'regex'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['lc']
                    \   },
                    \ ]
@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Jul 9, 2015

Owner

I see. Probably using 'kind' and 'action' filters, the problems can be solved. Please try the following settings.

        let g:sandwich#recipes += [
                    \   {
                    \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c']
                    \   },
                    \   {
                    \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['e']
                    \   },
                    \   {
                    \       'buns'    : ['\\\a\+\*\?{', '}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c']
                    \   },
                    \   {
                    \       'buns'    : ['\\begin\*\?{[^}]*}\(\[.*\]\)\?', '\\end\*\?{[^}]*}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['e']
                    \   },
                    \ ]

This setting enables to use same inputs ('c' and 'e') without confusing these settings depending on situations.

There are several points.

Using 'kind' filter, user can limit the recipes to be used depending on kinds of operators ('add', 'delete', 'replace') and textobjects ('auto', 'query').

Using 'action' filter, user can limit the recipes to be used depending on kinds of operator processes. There are two kinds of processes, 'add' and 'delete', and there are three kinds of operators, 'add', 'delete' and 'replace'. 'add' operator consists only of 'add' process. 'delete' operator consists only of 'delete'. 'replace' operator carry out 'delete' process and then carry out 'add' process to replace texts.

operator add delete replace
action add delete delete/add

Therefore the expr recipes should be used only in 'add' process and the regex recipes should be used in 'delete' process (and textobjects). However 'regex' option has same effect with 'delete' action filter, thus I omitted here.

Because the pattern \\\a\+\*\?{ matched \begin{ too, thus I switched the order. The latter recipe has higher priority if the other conditions are same.

Owner

machakann commented Jul 9, 2015

I see. Probably using 'kind' and 'action' filters, the problems can be solved. Please try the following settings.

        let g:sandwich#recipes += [
                    \   {
                    \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c']
                    \   },
                    \   {
                    \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['e']
                    \   },
                    \   {
                    \       'buns'    : ['\\\a\+\*\?{', '}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c']
                    \   },
                    \   {
                    \       'buns'    : ['\\begin\*\?{[^}]*}\(\[.*\]\)\?', '\\end\*\?{[^}]*}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['e']
                    \   },
                    \ ]

This setting enables to use same inputs ('c' and 'e') without confusing these settings depending on situations.

There are several points.

Using 'kind' filter, user can limit the recipes to be used depending on kinds of operators ('add', 'delete', 'replace') and textobjects ('auto', 'query').

Using 'action' filter, user can limit the recipes to be used depending on kinds of operator processes. There are two kinds of processes, 'add' and 'delete', and there are three kinds of operators, 'add', 'delete' and 'replace'. 'add' operator consists only of 'add' process. 'delete' operator consists only of 'delete'. 'replace' operator carry out 'delete' process and then carry out 'add' process to replace texts.

operator add delete replace
action add delete delete/add

Therefore the expr recipes should be used only in 'add' process and the regex recipes should be used in 'delete' process (and textobjects). However 'regex' option has same effect with 'delete' action filter, thus I omitted here.

Because the pattern \\\a\+\*\?{ matched \begin{ too, thus I switched the order. The latter recipe has higher priority if the other conditions are same.

@maxfl

This comment has been minimized.

Show comment
Hide comment
@maxfl

maxfl Jul 9, 2015

@machakann, thank you, I'm totally impressed on how vim-sandwich is designed. Works perfectly.

Also I had a problem with vis/vas keys because of misreading the documentation for textobj-sandwich. The phrase 'These are mapped to key sequences is and as in
default.' is a bit misleading if you try to read 'is' and 'as' as valid words (:, so may be it worth highlighting or quoting them.

So far the updated version is below. I've removed wrong '*?' for the environment and added 'linewise' option for environment and group. Also I removed character/block group definition since it is not gonna be used:

        let g:sandwich#recipes += [
                \   {
                \       'buns'    : ['\begingroup', '\endgroup'],         
                \       'nesting' : 1, 'input': [ '\gr' ],   
                \       'filetype': ['tex', 'plaintex'], 
                \       'linewise': 1 
                \   },
                \   {
                \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['add', 'replace'],
                \       'action'  : ['add'],
                \       'expr'    : 1,
                \       'nesting' : 1,
                \       'input'   : ['c']
                \   },
                \   {
                \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['add', 'replace'],
                \       'action'  : ['add'],
                \       'expr'    : 1,
                \       'nesting' : 1,
                \       'linewise' : 1,
                \       'input'   : ['e']
                \   },
                \   {
                \       'buns'    : ['\\\a\+\*\?{', '}'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                \       'regex'   : 1,
                \       'nesting' : 1,
                \       'input'   : ['c']
                \   },
                \   {
                \       'buns'    : ['\\begin{[^}]*}\(\[.*\]\)\?', '\\end{[^}]*}'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                \       'regex'   : 1,
                \       'nesting' : 1,
                \       'linewise' : 1,
                \       'input'   : ['e']
                \   },
                \ ]

maxfl commented Jul 9, 2015

@machakann, thank you, I'm totally impressed on how vim-sandwich is designed. Works perfectly.

Also I had a problem with vis/vas keys because of misreading the documentation for textobj-sandwich. The phrase 'These are mapped to key sequences is and as in
default.' is a bit misleading if you try to read 'is' and 'as' as valid words (:, so may be it worth highlighting or quoting them.

So far the updated version is below. I've removed wrong '*?' for the environment and added 'linewise' option for environment and group. Also I removed character/block group definition since it is not gonna be used:

        let g:sandwich#recipes += [
                \   {
                \       'buns'    : ['\begingroup', '\endgroup'],         
                \       'nesting' : 1, 'input': [ '\gr' ],   
                \       'filetype': ['tex', 'plaintex'], 
                \       'linewise': 1 
                \   },
                \   {
                \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['add', 'replace'],
                \       'action'  : ['add'],
                \       'expr'    : 1,
                \       'nesting' : 1,
                \       'input'   : ['c']
                \   },
                \   {
                \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['add', 'replace'],
                \       'action'  : ['add'],
                \       'expr'    : 1,
                \       'nesting' : 1,
                \       'linewise' : 1,
                \       'input'   : ['e']
                \   },
                \   {
                \       'buns'    : ['\\\a\+\*\?{', '}'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                \       'regex'   : 1,
                \       'nesting' : 1,
                \       'input'   : ['c']
                \   },
                \   {
                \       'buns'    : ['\\begin{[^}]*}\(\[.*\]\)\?', '\\end{[^}]*}'],
                \       'filetype': ['tex', 'plaintex'],
                \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                \       'regex'   : 1,
                \       'nesting' : 1,
                \       'linewise' : 1,
                \       'input'   : ['e']
                \   },
                \ ]
@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Jul 9, 2015

Owner

I see. You are right, I will revise the documents. If you have any problem, please tell me. Thank you!

Owner

machakann commented Jul 9, 2015

I see. You are right, I will revise the documents. If you have any problem, please tell me. Thank you!

@machakann machakann added the question label Jul 24, 2015

@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Dec 3, 2016

Owner

Hello, I would like to pack the latex recipes as a macro file to introduce latex users, if you don't mind. If you don't like that idea, please tell me. Probably it would be available like this.

runtime macros/sandwich/ftplugin/latex.vim
Owner

machakann commented Dec 3, 2016

Hello, I would like to pack the latex recipes as a macro file to introduce latex users, if you don't mind. If you don't like that idea, please tell me. Probably it would be available like this.

runtime macros/sandwich/ftplugin/latex.vim
@maxfl

This comment has been minimized.

Show comment
Hide comment
@maxfl

maxfl Dec 3, 2016

sure I do not mind, please, use them

maxfl commented Dec 3, 2016

sure I do not mind, please, use them

@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Dec 4, 2016

Owner

Thank you!

Owner

machakann commented Dec 4, 2016

Thank you!

@telemachus

This comment has been minimized.

Show comment
Hide comment
@telemachus

telemachus Dec 27, 2016

@maxfl @machakann Sorry to wake up this older issue. I've borrowed some of these LaTeX recipes, and they work very well. Thank you for them. But I have two questions:

  1. Why do you set nesting to 1 (on) for single and double quotations? I wouldn't think that those really nest, do they? I'm not sure it matters, but I'm curious to understand better.
  2. For machakann in particular, do you still plan to include these somehow within vim-sandwich or have you set that idea aside?

In any case, thank you both for vim-sandwich and these recipes.

telemachus commented Dec 27, 2016

@maxfl @machakann Sorry to wake up this older issue. I've borrowed some of these LaTeX recipes, and they work very well. Thank you for them. But I have two questions:

  1. Why do you set nesting to 1 (on) for single and double quotations? I wouldn't think that those really nest, do they? I'm not sure it matters, but I'm curious to understand better.
  2. For machakann in particular, do you still plan to include these somehow within vim-sandwich or have you set that idea aside?

In any case, thank you both for vim-sandwich and these recipes.

@maxfl

This comment has been minimized.

Show comment
Hide comment
@maxfl

maxfl Dec 27, 2016

@telemachus, in fact I did not think of it too much. Also probably it's a copy-paste issue. You are correct that they are usually not nested, but you can do it and I do not think it's forbidden. Does it cause any issues?

maxfl commented Dec 27, 2016

@telemachus, in fact I did not think of it too much. Also probably it's a copy-paste issue. You are correct that they are usually not nested, but you can do it and I do not think it's forbidden. Does it cause any issues?

@maxfl

This comment has been minimized.

Show comment
Hide comment
@maxfl

maxfl Dec 27, 2016

Just in case, there are the latest sandwiches I have, including unicode, which are now relevant for lualatex/xelatex

        let g:sandwich#recipes = [
                    \	{'buns': ["`", "'"],                 'nesting': 1, 'input': [ "u'" ]  },
                    \	{'buns': ['', ''],                 'nesting': 1, 'input': [ 'u"' ]  },
                    \	{'buns': ['', ''],                 'nesting': 1, 'input': [ 'U"', 'ug', 'u,' ]  },
                    \	{'buns': ['«', '»'],                 'nesting': 1, 'input': [ 'u<', 'uf' ]  },
                    \ ]

        let g:sandwich#recipes += [
                    \   {'buns': ["`", "'"],                 'nesting': 1, 'input': [ "l'", "l`" ], 'filetype': ['tex', 'plaintex'] },
                    \	{'buns': ["``", "''"],               'nesting': 1, 'input': [ 'l"' ],    'filetype': ['tex',       'plaintex'], },
                    \	{'buns': ['"`', "\"'"],              'nesting': 1, 'input': [ 'L"' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': [",,", "``"],               'nesting': 1, 'input': [ 'l,' ],    'filetype': ['tex',       'plaintex'], },
                    \	{'buns': ['<<', '>>'],               'nesting': 1, 'input': [ 'l<' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\{', '\}'],               'nesting': 1, 'input': [ '\{' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },
                    \	{'buns': ['\[', '\]'],               'nesting': 1, 'input': [ '\[' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },

        let g:sandwich#recipes += [
                    \   {'buns': ['\left(',           '\right)'],           'nesting': 1, 'input': [ 'm(' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '(,)' },
                    \	{'buns': ['\left[',           '\right]'],           'nesting': 1, 'input': [ 'm[' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '[,]' },
                    \	{'buns': ['\left|',           '\right|'],           'nesting': 1, 'input': [ 'm|' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\left\{',          '\right\}'],          'nesting': 1, 'input': [ 'm{' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },
                    \	{'buns': ['\left\langle ',    '\right\rangle '],    'nesting': 1, 'input': [ 'm<' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\bigleft(',        '\bigright)'],        'nesting': 1, 'input': [ 'M(' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '(,)' },
                    \	{'buns': ['\bigleft[',        '\bigright]'],        'nesting': 1, 'input': [ 'M[' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '[,]' },
                    \	{'buns': ['\bigleft|',        '\bigright|'],        'nesting': 1, 'input': [ 'M|' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\bigleft\{',       '\bigright\}'],       'nesting': 1, 'input': [ 'M{' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },
                    \	{'buns': ['\bigleft\langle ', '\bigright\rangle '], 'nesting': 1, 'input': [ 'M<' ],    'filetype': ['tex',       'plaintex'] },
                    \ ]

        function! TexEnvCompl(argread, cmdline, cursorpos) abort
            let n = strlen(a:argread)
            let list = copy(g:TexEnvironments)
            if n > 0
                let list = filter(list, 'v:val[: n-1] ==# a:argread')
            endif
            return list
        endfunction

        function! TexEnvInput(is_head) abort
            if a:is_head
                let b:TexEnvLast = input('Environment-name: ', '', 'customlist,TexEnvCompl')
                let command = printf('\begin{%s}', b:TexEnvLast)
            else
                let command = printf('\end{%s}', b:TexEnvLast)
            endif
            return command
        endfunction

        function! TexCmdInput(is_head) abort
            if a:is_head
                let l:TexCmdLast = input('Command: ', '')
                let command = printf('\%s{', l:TexCmdLast)
            else
                let command = '}'
            endif
            return command
        endfunction

        let g:sandwich#recipes += [
                    \   {
                    \       'buns'    : ['\begingroup', '\endgroup'],
                    \       'nesting' : 1,
                    \       'input': [ '\gr' ],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'linewise': 1
                    \   },
                    \   {
                    \       'buns'    : ['\toprule', '\bottomrule'],
                    \       'nesting' : 1,
                    \       'input': [ '\tr', '\br' ],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'linewise': 1
                    \   },
                    \   {
                    \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c'],
                    \       'indentkeys-' : '{,},0{,0}'
                    \   },
                    \   {
                    \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'linewise' : 1,
                    \       'input'   : ['e'],
                    \       'indentkeys-' : '{,},0{,0}',
                    \       'autoindent' : 0
                    \   },
                    \   {
                    \       'buns'    : ['\\\a\+\*\?{', '}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c'],
                    \       'indentkeys-' : '{,},0{,0}'
                    \   },
                    \   {
                    \       'buns'    : ['\\begin{[^}]*}\(\[.*\]\)\?', '\\end{[^}]*}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'linewise' : 1,
                    \       'input'   : ['e'],
                    \       'indentkeys-' : '{,},0{,0}',
                    \       'autoindent' : 0
                    \   },
                    \   {
                    \       'buns'    : ['\(\\left\((\|\[\||\|\\{\|\\langle\|\\lvert\)\|\\left\.\)', '\(\\right\()\|]\||\|\\}\|\\rangle\|\\rvert\)\|\\right\.\)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['ma'],
                    \       'indentkeys-' : '{,},0{,0}',
                    \       'autoindent' : 0
                    \   },
                    \ ]

maxfl commented Dec 27, 2016

Just in case, there are the latest sandwiches I have, including unicode, which are now relevant for lualatex/xelatex

        let g:sandwich#recipes = [
                    \	{'buns': ["`", "'"],                 'nesting': 1, 'input': [ "u'" ]  },
                    \	{'buns': ['', ''],                 'nesting': 1, 'input': [ 'u"' ]  },
                    \	{'buns': ['', ''],                 'nesting': 1, 'input': [ 'U"', 'ug', 'u,' ]  },
                    \	{'buns': ['«', '»'],                 'nesting': 1, 'input': [ 'u<', 'uf' ]  },
                    \ ]

        let g:sandwich#recipes += [
                    \   {'buns': ["`", "'"],                 'nesting': 1, 'input': [ "l'", "l`" ], 'filetype': ['tex', 'plaintex'] },
                    \	{'buns': ["``", "''"],               'nesting': 1, 'input': [ 'l"' ],    'filetype': ['tex',       'plaintex'], },
                    \	{'buns': ['"`', "\"'"],              'nesting': 1, 'input': [ 'L"' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': [",,", "``"],               'nesting': 1, 'input': [ 'l,' ],    'filetype': ['tex',       'plaintex'], },
                    \	{'buns': ['<<', '>>'],               'nesting': 1, 'input': [ 'l<' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\{', '\}'],               'nesting': 1, 'input': [ '\{' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },
                    \	{'buns': ['\[', '\]'],               'nesting': 1, 'input': [ '\[' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },

        let g:sandwich#recipes += [
                    \   {'buns': ['\left(',           '\right)'],           'nesting': 1, 'input': [ 'm(' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '(,)' },
                    \	{'buns': ['\left[',           '\right]'],           'nesting': 1, 'input': [ 'm[' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '[,]' },
                    \	{'buns': ['\left|',           '\right|'],           'nesting': 1, 'input': [ 'm|' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\left\{',          '\right\}'],          'nesting': 1, 'input': [ 'm{' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },
                    \	{'buns': ['\left\langle ',    '\right\rangle '],    'nesting': 1, 'input': [ 'm<' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\bigleft(',        '\bigright)'],        'nesting': 1, 'input': [ 'M(' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '(,)' },
                    \	{'buns': ['\bigleft[',        '\bigright]'],        'nesting': 1, 'input': [ 'M[' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '[,]' },
                    \	{'buns': ['\bigleft|',        '\bigright|'],        'nesting': 1, 'input': [ 'M|' ],    'filetype': ['tex',       'plaintex'] },
                    \	{'buns': ['\bigleft\{',       '\bigright\}'],       'nesting': 1, 'input': [ 'M{' ],    'filetype': ['tex',       'plaintex'], 'indentkeys-' : '{,},0{,0}' },
                    \	{'buns': ['\bigleft\langle ', '\bigright\rangle '], 'nesting': 1, 'input': [ 'M<' ],    'filetype': ['tex',       'plaintex'] },
                    \ ]

        function! TexEnvCompl(argread, cmdline, cursorpos) abort
            let n = strlen(a:argread)
            let list = copy(g:TexEnvironments)
            if n > 0
                let list = filter(list, 'v:val[: n-1] ==# a:argread')
            endif
            return list
        endfunction

        function! TexEnvInput(is_head) abort
            if a:is_head
                let b:TexEnvLast = input('Environment-name: ', '', 'customlist,TexEnvCompl')
                let command = printf('\begin{%s}', b:TexEnvLast)
            else
                let command = printf('\end{%s}', b:TexEnvLast)
            endif
            return command
        endfunction

        function! TexCmdInput(is_head) abort
            if a:is_head
                let l:TexCmdLast = input('Command: ', '')
                let command = printf('\%s{', l:TexCmdLast)
            else
                let command = '}'
            endif
            return command
        endfunction

        let g:sandwich#recipes += [
                    \   {
                    \       'buns'    : ['\begingroup', '\endgroup'],
                    \       'nesting' : 1,
                    \       'input': [ '\gr' ],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'linewise': 1
                    \   },
                    \   {
                    \       'buns'    : ['\toprule', '\bottomrule'],
                    \       'nesting' : 1,
                    \       'input': [ '\tr', '\br' ],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'linewise': 1
                    \   },
                    \   {
                    \       'buns'    : ['TexCmdInput(1)', 'TexCmdInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c'],
                    \       'indentkeys-' : '{,},0{,0}'
                    \   },
                    \   {
                    \       'buns'    : ['TexEnvInput(1)', 'TexEnvInput(0)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['add', 'replace'],
                    \       'action'  : ['add'],
                    \       'expr'    : 1,
                    \       'nesting' : 1,
                    \       'linewise' : 1,
                    \       'input'   : ['e'],
                    \       'indentkeys-' : '{,},0{,0}',
                    \       'autoindent' : 0
                    \   },
                    \   {
                    \       'buns'    : ['\\\a\+\*\?{', '}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['c'],
                    \       'indentkeys-' : '{,},0{,0}'
                    \   },
                    \   {
                    \       'buns'    : ['\\begin{[^}]*}\(\[.*\]\)\?', '\\end{[^}]*}'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'linewise' : 1,
                    \       'input'   : ['e'],
                    \       'indentkeys-' : '{,},0{,0}',
                    \       'autoindent' : 0
                    \   },
                    \   {
                    \       'buns'    : ['\(\\left\((\|\[\||\|\\{\|\\langle\|\\lvert\)\|\\left\.\)', '\(\\right\()\|]\||\|\\}\|\\rangle\|\\rvert\)\|\\right\.\)'],
                    \       'filetype': ['tex', 'plaintex'],
                    \       'kind'    : ['delete', 'replace', 'auto', 'query'],
                    \       'regex'   : 1,
                    \       'nesting' : 1,
                    \       'input'   : ['ma'],
                    \       'indentkeys-' : '{,},0{,0}',
                    \       'autoindent' : 0
                    \   },
                    \ ]
@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Dec 27, 2016

Owner

Hi, @maxfl @telemachus

  1. I didn't aware of it! Probably you are right, setting nesting as 0 would be better. I think it is good thing to set nesting explicitly because vim-sandwich switch algorithms to search strings internally.

  2. Yes. Sorry, I was busy with my business these days, but new year holidays are coming soon!

Thank you for your comments and patience.

Owner

machakann commented Dec 27, 2016

Hi, @maxfl @telemachus

  1. I didn't aware of it! Probably you are right, setting nesting as 0 would be better. I think it is good thing to set nesting explicitly because vim-sandwich switch algorithms to search strings internally.

  2. Yes. Sorry, I was busy with my business these days, but new year holidays are coming soon!

Thank you for your comments and patience.

@telemachus

This comment has been minimized.

Show comment
Hide comment
@telemachus

telemachus Dec 27, 2016

Thanks for the feedback both of you! @machakann There's no rush at all. Thanks for the reply. (Hope your holidays are good!)

@maxfl I'm not sure if nesting is a problem or not. I have run into one small issue, but it may have nothing to do with nesting. It has to do with switching single quotes to double quotes if there is a contraction inside the original sentence. Here are some examples. | indicates the position of the cursor. The problem occurs both when using LaTeX and when using unicode curly quotes, but it's even worse in the case of a LaTeX environment. I've tried to explain in the comments below.

`|This isn't so much fun.'    # If you try to change from here, the result will be ``This isn''t so much fun.'
`This isn't |so much fun.'    # If you try to change from single to double LaTeX quotes here, it won't work at all. The engine can't see the ` apparently.

‘|This isn’t so fun!’    # Won't work with cursor here. Result is: “This isn”t so fun!’
‘This isn’|t so fun!’    # Works fine if cursor is past wrong single curly quote. Result is: “This isn’t so fun!”

telemachus commented Dec 27, 2016

Thanks for the feedback both of you! @machakann There's no rush at all. Thanks for the reply. (Hope your holidays are good!)

@maxfl I'm not sure if nesting is a problem or not. I have run into one small issue, but it may have nothing to do with nesting. It has to do with switching single quotes to double quotes if there is a contraction inside the original sentence. Here are some examples. | indicates the position of the cursor. The problem occurs both when using LaTeX and when using unicode curly quotes, but it's even worse in the case of a LaTeX environment. I've tried to explain in the comments below.

`|This isn't so much fun.'    # If you try to change from here, the result will be ``This isn''t so much fun.'
`This isn't |so much fun.'    # If you try to change from single to double LaTeX quotes here, it won't work at all. The engine can't see the ` apparently.

‘|This isn’t so fun!’    # Won't work with cursor here. Result is: “This isn”t so fun!’
‘This isn’|t so fun!’    # Works fine if cursor is past wrong single curly quote. Result is: “This isn’t so fun!”
@maxfl

This comment has been minimized.

Show comment
Hide comment
@maxfl

maxfl Dec 27, 2016

Thank you, @telemachus, for the example. I myself have never experienced this issue. From my understanding almost nothing may be done to fix it. At least nothing elegant.

One may introduce some complex regexp that tries to avoid common cases like "isn't". Also some excluded/ignored patterns may be introduced as a feature of the plugin for each sandwich definition.

maxfl commented Dec 27, 2016

Thank you, @telemachus, for the example. I myself have never experienced this issue. From my understanding almost nothing may be done to fix it. At least nothing elegant.

One may introduce some complex regexp that tries to avoid common cases like "isn't". Also some excluded/ignored patterns may be introduced as a feature of the plugin for each sandwich definition.

@telemachus

This comment has been minimized.

Show comment
Hide comment
@telemachus

telemachus Dec 27, 2016

Also some excluded/ignored patterns may be introduced as a feature of the plugin for each sandwich definition.

Thanks for mentioning this. I'll probably try something along these lines for most common cases and otherwise, just deal with it manually on the rare cases that it comes up.

telemachus commented Dec 27, 2016

Also some excluded/ignored patterns may be introduced as a feature of the plugin for each sandwich definition.

Thanks for mentioning this. I'll probably try something along these lines for most common cases and otherwise, just deal with it manually on the rare cases that it comes up.

machakann added a commit that referenced this issue Feb 8, 2017

machakann added a commit that referenced this issue Feb 9, 2017

I missed adding new files.
Related to #2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment