tags:

views:

103

answers:

3

I can easily select a rectangular area in a file provided this area contains text or spaces (or anything). I do it with visual block mode and motion keys. But when I try to create such area in a new file (or any file without text) I can't. Is there a way to 'expand' this area by automatically filling it with spaces for example? Or am I going in wrong direction?

The reason I want this:

I create a new file with vim and then would like to create a comment block similar to this:

##############################################
#                                            #
#  My comment goes here                      #
#                                            #
##############################################

I can do it over existing text using Ctrl+v+motion keys, then r# to create an area filled with pounds. Then similarly to cut out inner rectangle with spaces.

How do I use this technique on a new file?

Thanks.

+4  A: 

If you want to create a block like that in a new file, you could do something like 50i#EscY5P

So it's 50 times insert # followed by yank current line and put it 5 times. This will give you a 50x5 block of #.

Of course you still have to do, whatever you do to get from the block of #s to the comment in your post.

Brian Rasmussen
A: 

I don't think there's any to select text that isn't there, but the easy solution would be to "seed" it with something like 76a yy4p ... so draw 76 spaces, then copy the line 4 extra times.

sleepynate
+2  A: 

Apart from the (very good) answer from Brian Rasmussen, the only way I know of to do almost exactly what you're asking is to use virtualedit mode. This won't let you edit on non-existent lines, but it will let you edit beyond the end of existing lines. Therefore, to turn the current line into a load of # symbols, you could do this:

:set virtualedit=all
v50lr#

To make a 50x5 block, you could create 4 new blank lines and then do the same:

:set virtualedit=all
4o<ESC>
<C-V>4k50lr#

(where <C-V> means press Ctrl+V and <ESC> means press Esc).

I believe there are some plugins for various file types that make it much easier to create comment blocks like this, but I'm not sure which is best.

You could just do something like:

50i#<ESC>yyo#<ESC>48a<SPACE><ESC>a#<ENTER>#<SPACE><SPACE>My comment goes here<ESC>:exe<SPACE>'normal'<SPACE>(49-getpos('.')[2]).'a<SPACE>'<ENTER>a#<ENTER>#<ESC>48a<SPACE><ESC>a#<ESC>p

But maybe that's just me being silly! I'll leave it as an exercise for the reader to figure out what's going on there if you're interested (:help is your friend).

How about this as a slightly more serious alternative: bung the following in your vimrc or in a file in the plugins directory of the vim runtime folder (e.g. ~/.vim/plugins on Unix)

nmap <F4> :InsertCommentBlock<CR>
command! InsertCommentBlock call InsertCommentBlock()
function! InsertCommentBlock()
    let linelength = 50
    let linelist = []

    call add(linelist, repeat('#', linelength))
    call add(linelist, '#' . repeat(' ', linelength-2) . '#')
    let comment = input('Please enter a comment: ')
    call add(linelist, '#  ' . comment . repeat(' ', linelength - (4+len(comment))) . '#')
    call add(linelist, '#' . repeat(' ', linelength-2) . '#')
    call add(linelist, repeat('#', linelength))

    call append(line('.'), linelist)
endfunction

See:

:help function
:help 'virtualedit'
:help command
:help nmap
:help repeat()
:help append()
:help add()
:help getpos()
:help :exe

etc...

Al
Solid answer, gave me a lot to think about, thanks a ton!
Valentin Vasiliev