Question

I am using :set textwidth=80 to make the Vim editor do hard wrapping automatically. However, sometimes for certain lines within a file (e.g. tables in LaTeX), I do not want Vim to do any hard wrapping automatically. Is there a way to mark certain lines to disable hard wrapping in Vim? Or automatically :set textwidth=0 just for specified lines?

Was it helpful?

Solution

There's nothing out-of-the-box, but you can build a solution with an :autocmd <buffer> on the CursorMoved,CursorMovedI events. On each move of the cursor, you have to check whether you're currently in one of those "certain lines", and modify the local 'textwidth' option accordingly:

autocmd CursorMoved,CursorMovedI <buffer> if IsSpecialLine() | setlocal textwidth=0 | else | setlocal textwidth=80 | endif

Put this into ~/.vim/after/ftplugin/tex.vim. (This requires that you have :filetype plugin on; use of the after directory allows you to override any default filetype settings done by $VIMRUNTIME/ftplugin/tex.vim.) Alternatively, you could define an :autocmd FileType tex autocmd ... directly in your ~/.vimrc, but this tends to become unwieldy once you have many customizations.

For the IsSpecialLine() function, you probably need to match a regular expression on the current line (getline('.') =~# "..."). If you can identify the "certain lines" through syntax highlighting, my OnSyntaxChange plugin can do all the work for you.

OTHER TIPS

I've tried Ingo Karkat answer. Although it does work very well and does what the OP asks, I find it distracting (if I have long tables with row hundreds of characters long, there are a lot of shifts up and down when passing over tables) and can slow down a lot vim on big files (the textwidth and wrap are changed for the whole file, so running the autocmd for every cursor movement can be costly).

So I propose a static solution based on the idea that hopefully you have to modify a table as few times as possible. I've added the following to my ftplugin/tex.vim file:

" By default the text is 
let s:textwidth = 90
let &l:textwidth=s:textwidth

" Toggle between "textwidth and wrap" and "textwidth=0 and nowrap".
" When editing a table, can be useful to have all the '&' aligned (using e.g.
" ':Tabularize /&') but without line brakes and wraps. Besides it's very
" annoying when line brakes "happen" while editing.
" As hopefully tables must be edited only from time to time, one can toggle
" wrap and textwidth by hand. 
function! ToggleTwWrap() "{{{
  " if textwidth and wrap is used, then disable them
  if &textwidth > 0 
    let &l:textwidth=0
    setlocal nowrap
  else " otherwise re-enable them
    let &l:textwidth=s:textwidth
    setlocal wrap
  endif
endfunction

So now if I want to edit manually a table I simply do

:call ToggleTwWrap()

to disable wrapping and textwidth and then again when I'm done with the table.

And of course you can create a command or a map

You can certainly set it for specific file types, but I don't think you can change those settings (or any, really) for individual lines.

Ingo Karat's answer works but setting textwidth on every single cursor move is too slow. This adapted version will only call setlocal textwidth= if the text width is actually going to change. This speeds things up considerably:

autocmd CursorMoved,CursorMovedI <buffer> if IsSpecialLine() | if &textwidth != 0 | setlocal textwidth=0 | endif | else | if &textwidth != 80 | setlocal textwidth=80 | endif | endif
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top