3.12 Making your own Macros via IMAP()

3.12.1 Why use IMAP()
3.12.2 IMAP() syntax

If you find the need to create your own macros, then you can use the IMAP() function provided with Latex-Suite. See Why use IMAP() for a short explanation of why you might prefer IMAP() over Vim's standard :imap command. An example best explains the usage:

:call IMAP('NOM', '\nomenclature{<++>}<++>', 'tex')

This will create a Latex-Suite-style mapping, where if you type NOM in insert mode, you will get \nomenclature{<++>}<++> with the cursor left in place of the first <++> characters. See IMAP() syntax for a detailed explanation of the IMAP() command.

For maps which are triggered for a given filetype, the IMAP() command above should be put in the filetype plugin script for that file. For example, for tex-specific mappings, the IMAP() calls should go in $VIM/ftplugin/tex.vim. For globally visible maps, you will need to use the following in either your ~/.vimrc or a file in your $VIM/plugin directory.

augroup MyIMAPs
    au!
    au VimEnter * call IMAP('Foo', 'foo', '')
augroup END

3.12.1 Why use IMAP()

Using IMAP instead of Vim's built-in :imap command has a couple of advantages:

  1. The 'ttimeout' option will generally limit how easily you can type the left hand side for a normal :imap. if you type the left hand side too slowly, then the mapping will not be activated.
  2. If you mistype one of the letters of the lhs, then the mapping is deactivated as soon as you backspace to correct the mistake.
  3. The characters in lhs are shown on top of each other. This is fairly distracting. This becomes a real annoyance when a lot of characters initiate mappings.

3.12.2 IMAP() syntax

Formally, the syntax which is used for the IMAP function is:

call IMAP (lhs, rhs, ft [, phs, phe])

ArgumentExplanation
lhs

This is the "left-hand-side" of the mapping. When you use IMAP, only the last character of this word is actually mapped, although the effect is that the whole word is mapped.

If you have two mappings which end in a common lhs, then the mapping with the longer lhs is used. For example, if you do

call IMAP('BarFoo', 'something', 'tex')
call IMAP('Foo', 'something else', 'tex')

Then typing BarFoo inserts "something", whereas Foo by itself inserts "something else".

Also, the nature of IMAP() makes creating certain combination of mappings impossible. For example if you have

call IMAP('foo', 'something', 'tex')
call IMAP('foobar', 'something else', 'tex')

Then you will never be able to trigger "foobar" because typing "foo" will immediately insert "something". This is the "cost" which you incur over the normal :imap command for the convenience of no 'timeout' problems, the ability to correct lhs etc.

rhs

The "right-hand-side" of the mapping. This is the expansion you will get when you type lhs.

This string can also contain special characters such as <enter> etc. To do this, you will need to specify the second argument in double-quotes as follows:

:call IMAP('EFE', "\\begin{figure}\<CR><++>\\end{figure}<++>", 'tex')

With this, typing EFE is equivalent to typing in the right-hand side with all the special characters in insert-mode. This has the advantage that if you have filetype indentation set up, then the right hand side will also be indented just as if you had typed it in normally.

You can also set up a Latex-Suite style mapping which calls a custom function as follows:

:call IMAP('FOO', "\<C-r>=MyFoonction()\<CR>", 'tex')

where MyFoonction is a custom function you have written. If MyFoonction also has to return a string containing <++> characters, then you will need to use the function IMAP_PutTextWithMovement(). An example best explains the usage:

call IMAP('FOO', "\<C-r>=AskVimFunc()\<CR>", 'vim')
" Askvimfunc: Asks For Function Name And Sets Up Template 
" Description: 
function! AskVimFunc()
    let name = input('Name of the function : ')
    if name == ''
        let name = "<+Function Name+>"
    end
    let islocal = input('Is this function scriptlocal ? [y]/n : ', 'y')
    if islocal == 'y'
        let sidstr = '<SID>'
    else
        let sidstr = ''
    endif
    return IMAP_PutTextWithMovement( 
        \ "\" ".name.": <+short description+> \<cr>" .
        \ "Description: <+long description+>\<cr>" . 
        \ "\<C-u>function! ".name."(<+arguments+>)<++>\<cr>" . 
        \       "<+function body+>\<cr>" . 
        \ "endfunction \" "
        \ )
endfunction

ft

The file type for which this mapping is active. When this string is left empty, the mapping applies for all file-types. A filetype specific mapping will always take precedence.

phs, phe

If you prefer to write the rhs with characters other than <+ and +> to denote place-holders, you can use the last 2 arguments to specify which characters in the rhs specify place-holders. By default, these are <+ and +> respectively.

Note that the phs and phe arguments do not control what characters will be displayed for the placeholders when the mapping is actually triggered. What characters are used to display place-holders when you trigger an IMAP are controlled by the Imap_PlaceHolderStart and Imap_PlaceHolderEnd settings.