sponsor Vim development Vim logo Vim Book Ad

intermediate Tip #1241: beautifully rearrange quotes in email replies using the fmt command.

 tip karma   Rating 3/6, Viewed by 1771 

Read and edit this tip on the Vim tip wiki. The wiki may have a more recent version of this tip.

created:   May 24, 2006 6:46      complexity:   intermediate
author:   Davide Alberani      as of Vim:   5.7

" Tip: beautifully rearrange quotes in email replies using the fmt command.
" Author: Davide Alberani <da @ erlug.linux.it>  http://erlug.linux.it/~da/
" Version: 0.1
" Date: 24 May 2006
" Description: editing email replies, I often end up cutting the quoted text
"              to leave only a short meaningful part, but many times this
"              will leave blocks of quoted lines with very heterogeneous
"              lengths - and this looks really bad; moreover sometimes the
"              sender is writing lines longer than 72 chars, and I want to
"              split it maintaining the original quote.
"              Calling the Vbq command you can rearrange isolated blocks
"              of quoted lines so that they will look _really_ good.
"              Every single block of quoted lines is stripped of its quote
"              and reformatted calling the 'fmt' unix program (I suppose you
"              can use any other similar tool) and then restored in place,
"              adding the quote again.
" Usage: I normally start editing my reply, removing the unnecessary quoted
"        text (without caring about leaving too long or too short quoted
"        lines) and then, after I've finished writing the reply, I call
"        the :Vbq command.
" Hints: read the comments in the code and modify it according to your needs.
" Warning: you need the fmt (or a similar filter) command installed.
" Keywords: quote, email, formatting, fmt.
" My VIM pages: http://erlug.linux.it/~da/vim/

" The function used to beautifully rearrange quoted lines.
function VeryBeautyQuote (...) range
  " The regular expression used to match quoted lines.
  " NOTE: modify this regexp if you have special needs.
  let re_quote = '^>\(\a\{-,3}[>|]\|[> \t|]\)\{,5}'
  set report=30000 " do not report the number of changed lines.
  let cur = a:firstline
  while cur <= a:lastline
     let str = getline(cur)
     " Match the quote.
     let comm = matchstr(str, re_quote)
     let newcomm = comm
     let commlen = strlen(comm)
     let filelen = line('$')
     if commlen > 0
       let startl = cur
       while newcomm == comm
         " Strip the quote from this group of quoted lines.
         let txt = substitute(str, re_quote, '', '')
         call setline(cur, txt)
         let cur = cur + 1
         let str = getline(cur)
         let newcomm = matchstr(str, re_quote)
       let cur = cur - 1
       " Execute fmt for format the (un-)quoted lines.
       " NOTE: you can call any other formatter that act like a command line
       "       filter.
       " NOTE: 72 is the maximum length of a single line, including
       "       the length of the quote.
       execute startl . ',' . cur . '!fmt -' . (72 - commlen)
       " If the length of the file was changed, move the cursor accordingly.
       let lendiff = filelen - line('$')
       if lendiff != 0
         let cur = cur - lendiff
       " Restore the stripped quote.
       execute startl . ',' . cur . 's/^/' . comm . '/g'
   let cur = cur + 1

" Execute this command to beautifully rearrange the quoted lines.
com Vbq :let strl = line('.')<Bar>:%call VeryBeautyQuote()<Bar>:exec strl

 rate this tip  Life Changing Helpful Unfulfilling 

<< place the cursor in the optimal position, editing email messages. | Move through the buffer list without wrecking your window/tab layout >>

Additional Notes

bheeshmar, May 24, 2006 20:16
gq<motion> is really smart and seems to be what you are looking for here...

You can select the text:

> quoted
> email should justify properly dsfalj djf kasjfjsdf    kffjkjfdsajfjf dfasdfasdfja kfsd
> even when disjoint

in visual mode, hit gq, and you will get:
> quoted email should justify properly dsfalj djf kasjfjsdf    kffjkjfdsajfjf
> dfasdfasdfja kfsd even when disjoint ~

I use it with function comments where it is aware of the commenting style and will preserve leading "//" and even transform:
* funky
* commenting
* style

* funky commenting style
Sybren, June 9, 2006 7:21
I mapped 'q':

map q gq}

With that mapping, the paragraph you are on will be rewrapped when you hit 'q'. Works like a charm :)
nummer5 at frittenforke dot de, July 31, 2006 9:14
well, q is for recording macros, another very useful feature. You should try it before you remap the command.
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
Sponsored by Web Concept Group Inc. SourceForge.net Logo