On Fri, 5 May 2006, Max Dyckhoff wrote:

-----Original Message-----
From: Yakov Lerner [mailto:[EMAIL PROTECTED]
Sent: Friday, May 05, 2006 11:45 AM
To: Max Dyckhoff
Cc: vim@vim.org
Subject: Re: Commenting out a block of text

On 5/5/06, Max Dyckhoff <[EMAIL PROTECTED]> wrote:
F4 I want to do a block comment, namely put /* at the beginning of the
selection and */ at the end. Currently I am using a massive hack for
this (xi<HOME>/*<CR><HOME>*/<CR><up><up><esc>p) but was wondering if
there was anyway of doing a search and replace for an entire block,
something like

:s/start_of_visual_selection(.*)end_of_visual_selection/\/*\1\/*/

Try along the lines of
   :map <f4> <esc>`>ia*/<esc>`<i/*<esc>
OR
   :map <f4> <esc>`>iA<cr>*/<esc>`<O/*<esc>
depending on your needs. (all untested). This
came up recently in the list.

Yakov

Fabulous, thank you. There seems to be extraneous 'i's in the two
examples you provided; "ia*/" puts 'a*/' at the end of the comment.
Never knew that `< and `> jumped around in the visual block, thank you!

Max


[modified for bottom post]

As Yakov mentioned, your question recently came up in this list. It
started with

  http://www.vim.org/tips/tip.php?tip_id=346

I was inspired and wrote a more advanced version that handled markup
tags, comments, brackets and quotes depending on which mode you were in,
and if you were in visual block mode, wrap line-wise (following indent)
instead of character-wise.

This is what I have so far. It is pretty easy to modify it to add more
types of end tag matches. Whitespace that appear after the opening tag
is mirrored on the closing tag.

===
nnoremap <silent><Leader>t mzviw<Esc>:cal TagWrap("nt")<CR>
vnoremap <silent><Leader>t      <Esc>:cal TagWrap("vt")<CR>
nnoremap <silent><Leader>T mzviw<Esc>:cal TagWrap("nT")<CR>
vnoremap <silent><Leader>T      <Esc>:cal TagWrap("vT")<CR>

function! TagWrap(mode)
  let opentag = input("Opening ".a:mode[1]."ag? ")
  if opentag == ""
    if a:mode[0] == "n"
      normal! g`z
    elseif a:mode[0] == "v"
      normal! gv
    endif
    return ""
  endif

  if a:mode[1] == "T"
    let closetag = "</".substitute(opentag, "^\\(\\s*\\S\\+\\).*", "\\1", 
"").">"
    let opentag = "<".opentag.">"
  elseif a:mode[1] == "t"
    if opentag =~ "^/\\*"
      let match = substitute(strpart(opentag, 2), "^\\(\\s\\+\\)\\(.*\\)", "\\2\\1", 
"")."*/"
    elseif opentag =~ "^<!--"
      let match = substitute(strpart(opentag, 4), "^\\(\\s\\+\\)\\(.*\\)", "\\2\\1", 
"")."-->"
    elseif opentag =~ "^[{[<]"
      let match = substitute(strpart(opentag, 1), "^\\(\\s\\+\\)\\(.*\\)", "\\2\\1", 
"").nr2char(char2nr(opentag[0]) + 2)
    elseif opentag =~ "^("
      let match = substitute(strpart(opentag, 1), "^\\(\\s\\+\\)\\(.*\\)", "\\2\\1", 
"").")"
    elseif opentag =~ "^[\"'`]"
      let match = substitute(strpart(opentag, 1), "^\\(\\s\\+\\)\\(.*\\)", "\\2\\1", 
"").opentag[0]
    else
      let match = opentag
    endif
    let closetag = input("Closing ".a:mode[1]."ag? ", match)
  endif

  if visualmode() == "\<C-v>"
    let indent = indent("'<")
    let pad = ""
    while strlen(pad) < indent
      let pad = pad." "
    endwhile

    if closetag != ""
      '>put = ''
      call setline(line("'>") + 1, pad.closetag)
    endif
    '<put! = ''
    call setline(line("'<") - 1, pad.opentag)
    normal! ^
  else
    execute "normal! g`>a".closetag
    execute "normal! g`<mzi".opentag
    normal! g`z
  endif
endfunction
===

Use "\t" for a normal tag wrap. Use "\T" for a markup tag wrap of the
form <a>..</a>.

HTH.
--
Gerald

Reply via email to