In a mail thread, Alice and Bob both sent me mail with incredibly long lines. I would like to send a reply that looks like this:

alice> blah blah blah, foo dee bar dee baz, ho hum and then
alice> she said: "what do you think I am, a top poster?"

Teh lulz

bob> that's not funny

Yes it is lol :D

I want each line to have a maximum width of n characters, and I want each line to have a prefix of "${name}> ". I would like to not have to fiddle with each line, i.e. I would like to input something fairly close to the minimal [name 1, name 2, go wrap stuff], but in either case something that's O(1) in the length of the input lines (probably O(k) in the number of long lines, one g q } for each).

Is this possible, and how? If not, how can I best approximate it?


One option is to use :set formatoptions+=n in conjunction with a custom formatlistpat. The n option reformats numbered lists, prepending the equivalent number of spaces on wrapped lines. It can be adapted for use in this case by defining an appropriate list leader:

set fo+=n
let &flp='\w\+> '

To illustrate the effects, consider the following example:

alice> foo bar baz qux foo bar baz qux
bob> foo bar baz qux foo bar baz qux

Using tw=20 in this case, gq} produces:

alice> foo bar baz
       qux foo bar
       baz qux
bob> foo bar baz qux
     foo bar baz qux

This method properly wraps lines without changing tw, but it only prepends spaces. If name> must be prepended to each new line, another operation is required, but this at least handles the wrapping.

Alternatively, quotes in this format can be treated as comments. Unfortunately this method does not accept regex, and thus requires explicit names. The b flag can be used to require whitespace after the comment leader:

set comments+=b:alice>,b:bob>

With this, using the same example as above, reformatting produces:

alice> foo bar baz
alice> qux foo bar
alice> baz qux
bob> foo bar baz qux
bob> foo bar baz qux

Here's a simple function that utilizes this, and a corresponding command for convenience:

function! Format(name1, name2)
    execute "set comments+=b:" . a:name1 . ">,b:" . a:name2 . ">"
    execute "normal gq}"
    execute "set comments-=b:" . a:name1 . ">,b:" . a:name2 . ">"

command! -nargs=* F call Format(<f-args>)

Thus :F alice bob can be used to produce the sample results above.


If you have a fairly recent version of Vim (echo v:version > 703 || v:version == 703 && has("patch541")), you can use set formatoptions+=j.

This tells Vim, when reformatting with gqq, to preserve comment leaders (e.g. # in most scripting languages, or * for javadoc-style comments).

All that is left to do is set up comments correctly:

set comments+=b:alice>,b:bob>

As noted earlier comments does not support regexes yet, so you need to explicitly specify the names of all respondents.


One method, which I find deeply unsatisfying, is to:

  • compute the width within which the text of a long line is to be wrapped
  • set the wrap width (err, textwidth, no?) accordingly
  • wrap the long line
  • :'<,'>s/^/alice/
  • repeat for the next long line
  • when all long lines are done, restore the wrap width to normal.

In particular, I'm lazy and don't want to do the computation. The input is O(1) and O(k), though, so my requirement list is apparently incomplete. Such is life :-)

  • Why don't you start with that as a crude first macro / mapping, and iteratively improve it whenever you notice a potential for improvement? That's how I develop my customizations. Jan 17 '13 at 13:31
  • 1
    I don't understand your preoccupation with O()-notation? What does it have to do with the problem?! Jan 17 '13 at 13:32
  • 1. I don't know much about vim macro coding; and 2. I would think something like that was built-in. The big-oh is a way of counting stuff, with fuzz of a fairly precise type and amount---in this case keystrokes rather than CPU operations, but so what? Okay, you may argue that I'm overly specific in talking about counts at all, but I think the big-oh is a reasonable way of being overly specific ;-) Jan 17 '13 at 15:46
  • What is built-in is the great customizability of Vim; seriously, learn it (recording a macro is just qq, and from there, it's just a :nnoremap <key> ... to a mapping), or you'll never harvest the full power of Vim! Jan 17 '13 at 16:30
  • It's on my long todo list :) What's the key sequence for calculating the next textwidth and setting it accordindly? Don't I need to write some kind of script? Jan 17 '13 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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