4

When I am writting a Latex document I generally like to keep an 80 column line width to keep things easy to read. However I don't like to use text wrapping because it can get in the way of typing equations.

Normally I will type a paragraph without caring how long the lines are, and eventually they gradually get longer, and longer, to the point where if I vsplit two documents the lines run off the end. So I will set textwitdth=80 and highlight an offending section in visual mode, and then use gq to format the selected text. However this is a bit more of a process than I have come accustomed to using vim I prefer to do things with only a few key strokes, or have it automatically done based on the file type.

I am looking for a way to either:

  1. script the application of a particular format (predetermined) to a selection of text
  2. Apply conditional formatting to a file-type based on some of the same identifiers used to conditionally highlight syntax

For those unfamiliar with latex:

A regular text section is by and large free of any syntax. When you
begin an equation  like this, 
\begin{equation}
\hat{H}\Psi = E\Psi
\end{equation}
I wouldn't want the lines inside to be wrapped automatically.

So there is a clear way of identifying math environments ie\begin..\end and Vim's ft plugin recognizes this for syntax highlighting. Can you apply conditional formatting in a similar way?

This (latex) is an example I am working with right now, but for example in general programming I would really like it if multi line comments could be wrapped without automatically wrapping regular code.

0

2 Answers 2

2

This is pretty much the same question as Prevent Vim from breaking up links mid-tag in markdown

For TeX equations it's slightly more involved, but not too much. We assume we're inside an equation if a line in the last 10 lines begins with \begin{equation}.

au CursorMovedI,CursorMoved *.tex let b:tex_textwidth = 80 | let b:tex_last_line = 0 | call ModifyTextWidth()

fun! ModifyTextWidth()
        " Only run if the cursor is on another line
        if line('.') == b:tex_last_line | return | endif
        let b:tex_last_line = line('.')

        " Try to find the start of an equation
        let l:eq = 0
        for i in range(1, 10)
                if getline(line('.') - i) =~ '^\\end{equation}' | break | endif

                " We're in an equation
                if getline(line('.') - i) =~ '^\\begin{equation}'
                        set textwidth=0
                        return
                endif
        endfor

        " Reset to original
        let &textwidth = b:tex_textwidth
endfun

I haven't extensively tested this, but it seems to work well with some samples I've found on the internet...

2

I have a similar setup with respect for writing mails. The idea is, to check the cursor position and depending on the current position set some formatting options.

" Dynamically set format options, depending on where you are in a
" mail, idea from Teemu Likonen:
" http://groups.google.com/group/vim_use/msg/f59e5c1adc6be2b3

let d_fo = &fo
let s:defaults = 'setlocal tw=72 ts=8 sts=4 sw=4 fo='.d_fo
execute s:defaults
let b:MailAreaDetect=1

"nnoremap <buffer> <LocalLeader>ma1 :call <SID>MailAreaDetect_On()
"    \ <bar> echo 'MailAreaDetect On'<CR>
"nnoremap <buffer> <LocalLeader>ma0 :call <SID>MailAreaDetect_Off()
"    \ <bar> echo 'MailAreaDetect Off'<CR>

nnoremap <buffer><silent> <F9> :call <SID>MailAreaDetect_Switch(0)<CR>
inoremap <buffer><silent> <F9> <C-\><C-O>:call <SID>MailAreaDetect_Switch(1)<CR>

function! s:MailAreaDetect_Switch(vmode)
    if b:MailAreaDetect
        silent call <SID>MailAreaDetect_Off()
        let b:MailAreaDetect=0
        echo 'MailAreaDetect Off'
        if a:vmode
            sleep 1
        endif
    else
        silent call <SID>MailAreaDetect_On()
        let b:MailAreaDetect=1
        echo 'MailAreaDetect On'
        if a:vmode
            sleep 1
        endif
    endif
endfu


function! s:MailAreaDetect_On()
    silent autocmd! MailAreaDetect CursorMoved,CursorMovedI
        \ <buffer> call <SID>AreaOptions()
    let b:MailAreaDetect=1
endfunction

function! s:MailAreaDetect_Off()
    silent autocmd! MailAreaDetect
    execute s:defaults
    let b:MailAreaDetect=0
endfunction

augroup MailAreaDetect
    autocmd!
    call <SID>MailAreaDetect_On()
augroup END

function! s:AreaOptions()
    execute s:defaults
    if <SID>CheckArea('\v^From( |: ).*\n','\v^$')
        "echo 'Header'
        setlocal fo-=a fo-=w fo-=t sts=0 sw=8 noet
    elseif getline('.') =~ '\m^\s*>'
        "echo 'Quotation'
        setlocal fo-=a fo-=w
    elseif <SID>CheckArea('\m^--- .*\n^+++ ','\v(^$|\n^-- $)')
        "echo 'Patch'
        setlocal fo-=a fo-=w fo-=t sts=0 sw=8 noet
    elseif <SID>CheckArea('^-- $','^$')
        "echo 'Signature'
        setlocal fo-=a fo-=w fo-=t sts=0 sw=8 noet
    else
        "echo 'My text'
        setlocal fo+=aw et
    endif
endfunction

function! s:CheckArea(start, end)
    return (search(a:start,'bcnW')-line('.')) >
        \ (search(a:end,'bnW')-line('.'))
endfunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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