Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top


I've just started using VIM and have become comfortable with navigation. I'm attempting to reduce repetitive tasks and thought I would take a crack at mapping. I was able to accomplish my task below with a map command, but would like to know what the best way is to do what I am doing.


I frequently write up text files with commands I use. In order to help navigate the files, I like to put a descriptive header above each command or step. For instance:

Randomly Generate Statsd Counters

should be formatted to look like this

** Randomly Generate Statsd Counters **


I probably spent way too much time on this, but came up with this map command in VIM. I should be able to navigate to any point on the Header line and hit a g key (The key doesn't matter), and be able to wrap the text with the header format. Here is the map:

nnoremap <buffer> g ^i**<space><esc>$a<space>**<esc>:let linelength = virtcol('.')<CR>O<esc>:exec "normal! " . linelength . "i*"<CR><esc><esc>jo<esc>:exec "normal! " . linelength . "i*"<cr><esc><esc>


I'm sure there is a better way to do this and I thought this would be a good opportunity to first attempt and then have my solution critiqued.

share|improve this question
up vote 5 down vote accepted

Your solution is interesting because it uses a heavy mix of normal mode commands, Ex commands and vimscript functions but yeah, it's way too long and complicated.

You are definitely right that there are (many) other ways.

Here is one that uses only normal mode commands:

nnoremap g I** <Esc>A **<Esc>yyPv$r*yyjp

Here is a variant:

nnoremap g ^c$** <C-r>" **<Esc>yyPv$r*yyjp

Here is one with Ex commands only:

nnoremap g :s/.*/** \0 **/\|t-1\|s/./*/\|t+1

Here is another one that calls a function:

nnoremap g :call MyBannerMaker()<CR>

function! MyBannerMaker()
    call setline('.', '** ' . getline('.') . ' **')
    put!=substitute(getline('.'), '.', '*', 'g')
    +put=substitute(getline('.'), '.', '*', 'g')

I'd suggest you look for readability, maintainability and extensibility first. Vim will execute the three mappings above instaneously despite their difference in length and apparent complexity so efficiency is kind of hard to measure, here.

share|improve this answer
Wonderful. Going through these examples and truly understanding them will help me immensely. Thank you. – Erds May 2 '14 at 22:15

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.