It's possible with some scripting. When editing a commit message, a temporary file .git/COMMIT_EDITMSG
is created with the contents of the commit.template
file.
With autocmd
we can execute a script that changes the content of the buffer:
function! s:expand_commit_template() abort
let context = {
\ 'MY_BRANCH': matchstr(system('git rev-parse --abbrev-ref HEAD'), '\p\+'),
\ 'AUTHOR': 'Tommy A',
\ }
let lnum = nextnonblank(1)
while lnum && lnum < line('$')
call setline(lnum, substitute(getline(lnum), '\${\(\w\+\)}',
\ '\=get(context, submatch(1), submatch(0))', 'g'))
let lnum = nextnonblank(lnum + 1)
endwhile
endfunction
autocmd BufRead */.git/COMMIT_EDITMSG call s:expand_commit_template()
For filling the template, we use a context
dict that defines expandable placeholders. For MY_BRANCH
, we get the current branch and use matchstr()
to get the first set of printable characters (otherwise, newline will be included as ^@
). I also included AUTHOR
to demonstrate that this can expand more than one placeholder.
The lines are scanned for text between ${
and }
. When found, the captured text in submatch(1)
is used as a key to get a value from context
to use as the substitution. If the key doesn't exist in context
, the fully matched text in submatch(0)
is returned effectively "ignoring" the match.
With the context
being {'MY_BRANCH': 'master', 'AUTHOR': 'Tommy A'}
and given the template:
This is my commit title [branch ${MY_BRANCH}]
Commit Body ${NON_EXISTENT}
- ${AUTHOR}
git commit
will display a buffer with:
This is my commit title [branch master]
Commit Body ${NON_EXISTENT}
- Tommy A
This will work with git commit
and vim-fugitive's :Gcommit
command.