Vim Tips Wiki
Tip 346 Printable Monobook Previous Next

created October 16, 2002 · complexity basic · author fishburn · version 6.0

If you have a block of text and you want to wrap it in <TAG_NAME>...</TAG_NAME> then this function will prompt you for the tag name and wrap the text.

" These mappings and TagSelection function will allow you to place
" an XML tag around either the current word, or the current selected
" text.
" If the visual select is on a single line, the tag is wrapped
" around the text <this>way</this>. If the visual select
" extends over multiple lines, the tag is wrapped around the text
" <this>
" way
" </this>
" When you are prompted for the tag name, you can enter:
" Tag name? p class="classname" attri="bute"
" The select is wrapped with:
" <p class="classname" attri="bute">
" Your selection
" </p>
" Notice the attributes have been stripped from the closing tag.
" Use nmap, not nnoremap, since we do want to use an existing mapping.
nmap ,,, viw,,,
vnoremap ,,, <Esc>:call TagSelection()<CR>

function! TagSelection()
  let tag = input("Tag name (include attributes)? ")
  if strlen(tag) == 0

  " Save
  let saveB = @b
  " <C-R> seems to automatically reindent the line for some filetypes
  " this will disable it until we have applied our changes
  let saveIndent = &indentexpr
  let curl = line(".")
  let curc = col(".")
  let &indentexpr = ''

  " If the visual selection is over multiple lines, then place the
  " data between the tags on newlines:
  "   <tag>
  "   data
  "   </tag>
  let newline = ''
  if getline("'>") != getline("'<")
    let newline = "\n"
    let curl = line("'>")

  " Strip off all but the first word in the tag for the end tag
  let @b = newline . substitute(tag, '^[ \t"]*\(\<\S*\>\).*', '<\/\1>\e', "")
  let curc = curc + strlen(@b)
  exec "normal `>a\<C-R>b"
  let @b = substitute(tag, '^[ \t"]*\(\<.*\)', '<\1>\e', "") . newline
  let curc = curc + strlen(@b)
  exec "normal `<i\<C-R>b"

  " Now format the area
  exec "normal `<V'>j="

  " Restore
  let @b = saveB
  let &indentexpr = saveIndent
  call cursor(curl, curc)


Could this function be expanded to replace/change tags enclosing the current region/selected text?

Or use surround.vim -- Samvimes 15:13, 21 November 2008 (UTC)