sponsor Vim development Vim logo Vim Book Ad

basic Tip #465: generic xml imap to make an element of any word you type

 tip karma   Rating 175/52, Viewed by 1993 

Read and edit this tip on the Vim tip wiki. The wiki may have a more recent version of this tip.

created:   April 29, 2003 12:05      complexity:   basic
author:   Bart van Deenen      as of Vim:   5.7

Hi all.

We're doing a lot of xml work, in docbook and custom xml files.  

I'd just like to share one macro I've developed, that I really can't live without.

imap ,,, <esc>bdwa<<esc>pa><cr></<esc>pa><esc>kA

If in isert mode I type programlisting,,,
the text immediately get's modified to
<programlisting>
</programlisting>
with the cursor in between, still in Insert mode.

The same happens with any other word i type followed by three commas.
<tryit>
</tryit>

It saves me a lot of work, and I'd like to share it. Hope you can use it

Bart van Deenen. ([email protected])

 rate this tip  Life Changing Helpful Unfulfilling 

<< search & replace the word under the cursor | Insert one character only >>

Additional Notes

gmann, April 29, 2003 18:46
please share any other mappings you like!  That one is quite nice!
[email protected], April 30, 2003 3:05
Chris Lear had a small modification, which allows the same imap to be used with namespaced elements (such as used all the time in xsl).

just change the b in B and the w in W, and the imap will go over the colon in the namespace.
[email protected], April 30, 2003 7:26
Is it possible to modify this map, so the indentation will be kept. So

test,,,<cr><tab>test2,,,

results in

<test>
        <test2>
        </test2>
<test>

It would also be nice, if it was possible to detect if the line already contains non-whitespace so

this is a bold,,,bold<esc>f> test

resulted in

this is a <bold>bold</bold> test

[email protected], April 30, 2003 12:33
Your question about indenting is easily fulfilled by :set ai  which sets auto indenting.

The other one is really intriguing, and I'll have a go at it, because that would indeed be helpfull

Bart van Deenen
bart ot vandeenensupport point com, May 1, 2003 8:31
Hi

I improved my imap with a function (my first in vim) (can probably be done in a one-liner :)

Put the following in xml.vim in your ftplugin directory, our source it in your .vimrc. The ^] and ^M are entered via <CTRL-V><esc> and <CTRL-V><CR>

function! Make_element()    
  "function to make an xml element at the current cursor position out of the      
  "contents of the just deleted unnamed register    "    
  "Bart van Deenen

    if match(getline('.'),'^\s*'.@".'\s*$') == -1
        "the deleted word was not alone on the line
         let @w = "i<^[ea></^[pa>^[F<i"
    else                 "the deleted word was on it's own on the line
         let @w = "i<^[ea>^M</^[pa>^[kA"    endif        
endfunction  

"include colon(58) for namespaces in xsl for instance
set iskeyword=@,48-57,_,192-255,58

imap <buffer>  ,,, <Esc>bye:call Make_element()<enter>@w

It seems to do the job with me.

Thanks for the question, I learned something from finding the answer

Bart van Deenen
bart van deenen, May 1, 2003 10:41
hi

it's probably better to use :setlocal iskeyword than :set

Bart
arnarb at oddi dot is, May 1, 2003 10:45
Just a quick note, instead of setting the "iskeyword" like that, you can use
:set iskeyword+=:
to add the colon to the list of characters/ranges, this way you won't break anything else if it depends on specific settings of iskeyword.

References
:help set+=
:help set-=
:help set<CTRL-D>
arnarb at oddi dot is, May 1, 2003 10:47
Nice.. that four minute difference between my comment and the one before that one was about the time it took me to write it :o) Hence.. I didn't see it until after I posted.
bart, May 1, 2003 11:11
Hi all

I uploaded this as vimscript #632.

Happy vimming!

Bart
[email protected], October 6, 2003 6:00
This tip is great, but it does not work if the word is only one character long, like "a" in html. If I type
a,,, the result is:
<
a></>

What is going wrong?

André
tobiasreif pinkjuice com, October 13, 2003 3:30
Hi

If you install vimscript #301 (Devin Weaver's xmledit) you can do

  i<foo>>

and get

  <foo>
    [cursore here]
  </foo>

Also see  vimtip #583 (Vim as XML Editor).

Have fun,
Tobi
Anonymous, November 29, 2003 4:48
André wrote:

This tip is great, but it does not work if the word is only one character long, like "a" in html. If I type
a,,, the result is:
<
a></>

It has to do with a part of the script where I use bye to go to the beginning of the word (a in your case), and yank the word into a buffer. Unfortunately the 'b' command skips over the start of the 'a' word, so you end up with garbage.

I don't have a fix yet, but if I find one, I'll post it. Somebody else?

Bart (the author of the tip)

P.S. sorry for the late answer, I was on honeymoon :-)
David Fishburn, December 9, 2004 12:05
This fixes the case where you have only one (or more) character(s):

      p,,,

Results in:
      <p>
      </p>

inoremap ,,, <esc>diwi<<esc>pa><cr></<esc>pa><esc>kA

Anonymous, February 6, 2005 4:48
I've added version 1.1 of vimscript#632 which correctly handles single character xml elements. I'm ill in bed today, that helps in finding the time for these kinds of fun things.

happy vimming

Bart
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
   
Sponsored by Web Concept Group Inc. SourceForge.net Logo