Smart textwidth on Vim when writing comments

I was checking my init.vim today trying to find how to improve it a bit.

I found this case that could be interesting to share... so there it goes.

I write a lot of documentation. One thing I always try to do is to keep the comments I write well aligned and easy to read. That's why I keep them at a length of 80 characters, I find that to be easier to read than long lines.

You can use the textwidth configuration in vim to do that.

set textwidth=80

Once the text you write gets to a width of 80 characters vim will split it to the next line.

vim auto splitting text

This is a very well known fact about vim, but you can read more about it if you're interested with :help textwidth

						*'textwidth'* *'tw'*
'textwidth' 'tw'	number	(default 0)
			local to buffer
	Maximum width of text that is being inserted.  A longer line will be
	broken after white space to get this width.  A zero value disables
	this.
	'textwidth' is set to 0 when the 'paste' option is set and restored
	when 'paste' is reset.
	When 'textwidth' is zero, 'wrapmargin' may be used.  See also
	'formatoptions' and |ins-textwidth|.
	When 'formatexpr' is set it will be used to break the line.

The thing is that I don't want vim to do the same on the code I write. Mainly because it will end up splitting the code on a different place than the one I would want it to.

I needed a way to set textwidth=80 when editing comments and then set textwidth=0 when not editing comments anymore.

Enter OnSyntaxChange. This plugin allows you to define vim autocommands that execute when the syntax of the current file changes, in our case, when we're editing comments.

I use vim-plug so I install it like this:

Plug 'inkarkat/vim-OnSyntaxChange'
" This is a dependency library from the same author that includes
" some autoload functions that he uses on the plugins he writes.
Plug 'inkarkat/vim-ingo-library'
" Add a new autocommand that will activate when the cursor is on a Comment and
" it either enters or leaves insert mode.
" 1. The name: `Comment` means the autocmd will be called
" `SyntaxCommentEnter{MODE}`
" 2. A regex to max the syntax, on our case any syntax similar to `Comment`
" will match to us.
" 3. Whether we want to generate it to all buffers or only a particular one,
" we're ok with only the current buffer.
" 4. To which mode we want to link the autocommand. We're only interested in
" the insert mode
call OnSyntaxChange#Install('Comment', '^Comment$', 1, 'i')

augroup auto_wrap_comments
  " Set textwidth to 80 when editing
  autocmd User SyntaxCommentEnterI setlocal textwidth=80
  " Remove it again when leaving insert mode
  autocmd User SyntaxCommentLeaveI setlocal tw=0
augroup END

And with that code on our init.vim we now have that the split behaves like this :)

Smart text width