Search code examples
vimsyntax-highlightingfile-type

How do I define an exception for line breaks in Vim?


I edit files in Vim were I log terminal command lines along with descriptions of what I did. All my command lines start with $, so my files look like this:

This is a description of what this
command does, it can be quite long and
should have line breaks.

$ ./the_command.sh

These are actually Viki files, but I guess this question should apply to any file type. I have filetype detection on and the files are correctly identified.

The question now is:

I want (hard) line breaks to be inserted into all the text except for the actual copies of command lines, which could be easily identified by the leading $.

Is it possible in Vim to define an exception for applying the line break rule based on a pattern? Would I do that in the syntax file for viki files?

UPDATE Using a combination of what Herbert and Jefromi suggested, I now have this in my .vimrc:

au CursorMovedI *.viki call SetTextWidth()

function! SetTextWidth()
    if getline(".")=~'^\$'
        set textwidth=1000
    else
        set textwidth=80
    endif
endfunction

It does exactly what I want. Thanks guys!


Solution

  • I gather when you say you want "hard line breaks" you mean you want Vim to break a line automatically, as when it reaches a textwidth column. The best way to do this, I think, is to define an 'au' command that sets textwidth to a high number (higher than longest possible line) when it's on a line that begins with a "$".

    So something like this would change textwidth whenever you enter or exit insert mode on a line:

    au InsertEnter call SetTextWidth()
    au InsertLeave call SetTextWidth()
    
    function! SetTextWidth()
        if getline(line('.')) =~ '^\$'
            " [edit: 'set textwidth = 0' is preferable to line below]
            set textwidth =1000
        else
            set textwidth=78
        endif
    endfunction
    

    You might want to use the CursorMoved/CursorMovedI groups instead of InsertEnter/Leave since they're more fine-grained. They get triggered whenever you move the cursor, so the function ends up getting called lots more times, but function is simple enough that it's probably not going to introduce any noticeable degradation in performance.

    For doing without a function at all you could probably use something like this:

    au InsertEnter exec "set tw=" . getline(line('.'))=~'^\$' ? 1000 : 78
    au InsertLeave exec "set tw=" . getline(line('.'))=~'^\$' ? 1000 : 78