Search code examples
vimlatexvikeymapping

How to make a keybind in vim, that lets the user insert, the repeats the insertion?


I would like to make a keybind that will let the user type something in insert mode, then goes to a different line, and puts what the user typed there. The purpose of this is for LaTeX \begin and \end. This is what I have so far:

autocmd Filetype tex inoremap `d \begin{}<CR><++><CR>\end{}<esc>2kf{a

At the end, a lets the user type in the \begin field, and I want to make it so that, when I exit insert mode, what I typed is put into the \end field. I honestly have no idea how to go about this. Any help is appreciated.


Solution

  • This is fairly hard to do for a single mapping.

    If you really want to roll your own, I think the simplest approach I can suggest here is to prompt the user for the environment type (with input()) and then use that name twice when inserting the block.

    This should work:

    function! LatexEnvironment()
        let name = input('Environment name: ')
        return "\\begin{".name."}\r\\end{".name."}\<C-o>O"
    endfunction
    autocmd Filetype tex inoremap <expr> `d LatexEnvironment()
    

    A much better approach here is to use a snippet engine.

    It's typically very easy to support multiple fields with repetitions and you can even set default values for fields in a snippet engine.

    For example, in UltiSnips, you can use the following snippet:

    snippet "\\?b(egin)?" "begin{} / end{}" br
    \begin{${1:something}}
        ${0:${VISUAL}}
    \end{$1}
    endsnippet
    

    Which is in fact a standard snippet you can find in the honza/vim-snippets library.