Intelligent paragraph reflowing in vim?

I have the following function in my $VIM/ftplugin/context.vim file to format ConTeXt paragraphs (same as LaTeX: the environments are enclosed in \start... and \stop... instead of \begin{...} and \end{...}. It should be easy to adapt this to LaTeX (In fact, I think that I copied it originally from someone who had written it for LaTeX and adapted it to ConTeXt).

" Reformat lines (getting the spacing correct) {{{
fun! TeX_fmt()
    if (getline(".") != "")
    let save_cursor = getpos(".")
        let op_wrapscan = &wrapscan
        set nowrapscan
        let par_begin = '^\(%D\)\=\s*\($\|\\start\|\\stop\|\\Start\|\\Stop\|\\\(sub\)*section\>\|\\item\>\|\\NC\>\|\\blank\>\|\\noindent\>\)'
        let par_end   = '^\(%D\)\=\s*\($\|\\start\|\\stop\|\\Start\|\\Stop\|\\place\|\\\(sub\)*section\>\|\\item\>\|\\NC\>\|\\blank\>\)'
    try
      exe '?'.par_begin.'?+'
    catch /E384/
      1
    endtry
        norm V
    try
      exe '/'.par_end.'/-'
    catch /E385/
      $
    endtry
    norm gq
        let &wrapscan = op_wrapscan
    call setpos('.', save_cursor) 
    endif
endfun

nmap Q :call TeX_fmt()<CR>

I know it's against policy to answer commenting on other answers, but in this case -- given I lack the 50 reputation needed to comment directly on the relevant answer -- I think it's worth it.

The function provided by Aditya functions perfectly for LaTeX, mutatis mutandis, except for one detail: often after beginning an environment, or a section, the very next line will be a \label{}. The original TeX_fmt() function wrongly considers this line to be a part of the paragraph. To fix this, modify the line that sets par_begin, to this:

let par_begin = '^\(%D\)\=\s*\($\|\\label\|\\begin\|\\end\|\\[\|\\]\|\\\(sub\)*section\>\|\\item\>\|\\NC\>\|\\blank\>\|\\noindent\>\)'

Basically, you add a \label before the \begin.

Profit!!


The following solution only applies to paragraph formatting, it will properly work depending on the LaTeX styling settings.

Another possible solution would be to set a hard wrap of 80 characters.

http://vimcasts.org/episodes/hard-wrapping-text/

formatoptions:

t - Auto-wrap text using textwidth

c - Auto-wrap comments using textwidth, inserting the current comment leader automatically.

a - Automatic formatting of paragraphs.

Here are some of the commands to set it up:

:set formatoptions=tc
:set fo+=a
:set textwidth=80

Tip: Use the autocmd or ftplugin folder to setup these settings automatically according to filetype. Run help: ftplugin in vim for more info.

And read here for more information about formatting:

http://vimdoc.sourceforge.net/htmldoc/change.html#fo-table

Tags:

Vim

Automation