1

When using Vim to edit commit messages I want the modeline from the ~/.gitmessage template to be recognised, so I can use the colorcolumn feature to highlight the conventional line length limits.

How can Vim be forced to recognise the modeline in the template? It doesn't seem to trigger.

There doesn't seem to be anything on this in this exchange and web searches don't provide any sources.

3 Answers 3

2

You should simply do the Vim side of this where it is supposed to be done, in after/ftplugin/gitcommit.vim.

If you want to take the "modeline" route, just put the following line in that file:

setlocal modeline

but be advised that this has security implications.

If you want to take a more "in-Vim" route, just put the following line in that file:

setlocal colorcolumn=50,73

Note that this is a bit naïve because those numbers are not a hard rule: they are conventions that can change from project to project. The following is slightly smarter because it uses user-modifiable variables instead of hardcoded numbers:

:let &l:colorcolumn = get(g:, 'gitcommit_summary_length', 50) .. ',' .. (&textwidth == 0 ? 73 : &textwidth + 1)

But I don't know of a "universal" way for project maintainers to set both message line length and summary length at the project level so this looks like the best "in-vim" compromise for now.

FWIW, I think that your original commit.template strategy is the best, here.


Now, regarding the last section of your self-answer…

Doing stuff in $VIMRUNTIME might seem like a good idea if you really don't want your settings to be applied on a pre-user basis but it is generally a bad idea that should not be advised lightly.

  • As can be seen from its path on OP's machine, $VIMRUNTIME is major.minor version-dependent. This means that whatever the user did in /usr/share/vim/vim82/ will need to be redone in /usr/share/vim/vim90/, and so on when the user choses to upgrade. That's more work than necessary, and more opportunities for breaking things.

    Note: some distributions, like MacVim, may not be affected by this potential issue.

  • Even if the user doesn't upgrade to another major.minor version, patch level updates can and will happen, that could silently override the user's changes to $VIMRUNTIME. That's more bad surprises that will require even more work than necessary and create even more breakage opportunities.

  • It is very easy to accidentally introduce the wrong line endings when editing files in $VIMRUNTIME, which can lead to all kinds of troubles.

This is all very fragile so, if you are not an admin of some kind, or maintaining an in-house image or something, please keep your fingers out of $VIMRUNTIME.


FWIW, this is how you can set EditorConfig at the project or global level:

[.git/COMMIT_EDITMSG]
max_line_length = 63

but it only gives you textwidth. There is no officially supported way to set a desired summary length so that's only half the battle.

As mentioned in the comments, .gitconfig and .git/config files can contain arbitrary values (I had no idea) but those things are local so they can't be used by project maintainers to "enforce" a particular summary line length as it would require tooling support… that doesn't seem to exist ATM. .gitattributes could be more helpful, maybe, because it can be tracked.

4
  • 1
    I like +0 for textwidth, IIRC. Also, Git’s config can store arbitrary key-values, so you could drop something in there. You could also try .editorconfig but I haven’t played with the what the pattern would be to target COMMIT_EDITMSG Commented Aug 22 at 12:12
  • 1
    @D.BenKnoble see my edit. Commented Aug 22 at 13:20
  • 1
    I don't get the "slightly smarter" version. So we're not hardcoding 50 but we use a variable instead which we hardcode to 50. I don't see the advantage that gives us. Regarding commit.template, this only works if we use a --local setting and commit the template to the repo (OP uses a global template in their first self-answer). Commented Aug 22 at 21:16
  • This answer was accepted because it covers the most bases and depth. If you want a little more detail to step you through the simple solution mentioned at the top of this answer see this answer Commented Aug 24 at 6:51
1

Locate Git commit message template

I think Git may read the ~/.gitmessage file as a commit message template by default, but if it doesn't, set the Git config option commit.template to ~/.gitmessage or whatever is preferred.

Use git config --list to show current Git configuration.

Create Git commit message template

Once Git is using the commit message template, add the required modeline to the template. The following modeline sets highlighting at the conventional first and subsequent line length limits:

# vim: set colorcolumn=50,73:

Configure Vim to read modelines in Git commit messages

If your Vim is configured with :set modeline for normal use, you may not require this, but if Vim is editing commit messages with nomodeline set you can configure specific settings for Git messages by adding this to the vimrc file:

autocmd FileType gitcommit setlocal modeline

Now Vim will automatically run the modeline when used to edit Git commit messages and will therefore automatically highlight the line lengths for you.

3
  • 1
    Any reason not to set your options in gitcommit.vim directly? Surely, any editor other than Vim cannot make sense of the modeline so going through a template to set a Vim-only option seems needlessly complicated. Commented Aug 21 at 12:12
  • 1
    I was going to say: I might have an answer that helps you out more :) or at least helps make things more precise. When I get some time… Commented Aug 21 at 16:29
  • Thanks very much indeed @Friedrich and D. Ben Knoble for reaching out with that. I've just done what you suggested and it's a much improved solution. I use a commit message template anyway but your method is much cleaner. Git also adds lines at the bottom of the commit message which means you have to put the modeline at the top of the template which means you have to delete it from the message manually every time. I guess I'll add another answer and make a mental note to ask more questions on Vi stack exchange. Thanks! Commented Aug 22 at 0:10
1

Thanks to @Friedrich and @D.BenKnoble for a much better way of applying Vim settings specifically in Git commit messages only.

Setup Local File Type Settings Directory

If your Vim installation doesn't already have the local file type setup, you need to create it. The settings need to be in a directory called ftplugin. To override the system settings the ftplugin directory needs to be inside a directory called after (so the settings are applied after the system settings).

Therefore, inside your local Vim configuration directory (~/.vim/ probably, or ~/.config/vim if you've gone to that trouble), create an after directory and inside that create a ftplugin directory. For example:

mkdir -p /home/username/.vim/after/ftplugin/

Create a Local Git Commit File Type Settings File

The "file type" of the Vim buffer when editing a Git commit message is gitcommit. You can check this by using :set ft? when in a Git commit edit session. Vim responds filetype=gitcommit.

Therefore you need to create a new file inside the aforementioned directory called gitcommit.vim. Vim will run this file when starting every Git commit edit session:

vim /home/username/.vim/after/ftplugin/gitcommit.vim

Add Specific Git Commit Message Settings

Now simply edit this file to add your preferred settings for Git commit messages. To set the line length indicators enter:

setlocal colorcolumn=50,73

This will apply the conventional line length indicators appropriate for Git commit messages, after Vim has applied the built-in defaults, with no need for a Git commit message template, and no pollution of your Git commit message template if you do use one.

3
  • 2
    Installation runtime files are usually overwritten on updates Commented Aug 22 at 12:10
  • 1
    ...unless the package manager panics because of the manual changes. Bottom line: don't touch files in $VIMRUNTIME. Commented Aug 22 at 13:39
  • Thanks for all the advice from everyone about not using $VIMRUNTIME. I going to edit that bit out of the answer. Commented Aug 23 at 14:51

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.