Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit subject line of git commit message to 50 characters

Tags:

git

vim

I often use vim to format my git commit messages. A trend that I am seeing with increasing popularity is that the first line of the commit message should be limited to 50 characters and then subsequent lines should be limited to 72 characters.

I already know how to make my commit wrap at 72 characters based on my vimrc file:

syntax on
au FileType gitcommit set tw=72

Is there a way to make vim autowrap the first line at 50 characters and then 72 characters after that?

An equally good answer could highlight everything after the 50th column on only the first line to indicate that my header is too long ...

like image 330
mgilson Avatar asked May 12 '17 05:05

mgilson


1 Answers

You can use the CursorMoved and CursorMovedI autocommands to set the desired textwidth (or any other setting) based on the line the cursor is currently on:

augroup gitsetup
        autocmd!

        " Only set these commands up for git commits
        autocmd FileType gitcommit
                \ autocmd CursorMoved,CursorMovedI *
                        \ let &l:textwidth = line('.') == 1 ? 50 : 72
augroup end

The basic logic is simple: let &l:textwidth = line('.') == 1 ? 50 : 72, although the nested autocommands make it look rather funky. You could extract some of it out to a script-local function (fun! s:setup_git()) and call that, if you prefer.

The &:l syntax is the same as setlocal, by the way (but with setlocal we can't use an expression such as on the right-hand-side, only a simple string).

Some related questions:

  • Line number specific text-width setting.
  • Set paste mode when at beginning of line but auto-indent mode when anywhere else on the line?

Note that the default gitcommit.vim syntax file already stops highlighting the first line after 50 characters. From /usr/share/vim/vim80/syntax/gitcommit.vim:

syn match   gitcommitSummary    "^.\{0,50\}" contained containedin=gitcommitFirstLine nextgroup=gitcommitOverflow contains=@Spell
[..]
hi def link gitcommitSummary        Keyword

Only the first 50 lines get highlighted as a "Keyword" (light brown in my colour scheme), after that no highlighting is applied.

If also has:

syn match   gitcommitOverflow   ".*" contained contains=@Spell
[..]
"hi def link gitcommitOverflow      Error

Notice how it's commented out, probably because it's a bit too opinionated. You can easily add this to your vimrc though:

augroup gitsetup
        autocmd!

        " Only set these commands up for git commits
        autocmd FileType gitcommit
                \  hi def link gitcommitOverflow Error
                \| autocmd CursorMoved,CursorMovedI *
                        \  let &l:textwidth = line('.') == 1 ? 50 : 72
augroup end

Which will make everything after 50 characters show up as an error (you could, if you want, also use less obtrusive colours by choosing a different highlight group).

like image 114
Martin Tournoij Avatar answered Oct 10 '22 09:10

Martin Tournoij