diff --git a/autoload/SpaceVim/layers/git.vim b/autoload/SpaceVim/layers/git.vim index ec67ff5a6..5f0382a21 100644 --- a/autoload/SpaceVim/layers/git.vim +++ b/autoload/SpaceVim/layers/git.vim @@ -47,6 +47,11 @@ " SPC g h r undo cursor hunk " SPC g h v preview cursor hunk " < +" @subsection commit omni function +" This layer also provides an omnifunc for git commit messages. It supports: +" 1. complete commit title, `fix:`, `doc:` etc. +" 2. complete github issue list +" 3. complete co-author info if exists('s:git_plugin') diff --git a/autoload/SpaceVim/plugins/gitcommit.vim b/autoload/SpaceVim/plugins/gitcommit.vim index 788360d61..4f3e6ec6c 100644 --- a/autoload/SpaceVim/plugins/gitcommit.vim +++ b/autoload/SpaceVim/plugins/gitcommit.vim @@ -6,6 +6,7 @@ " License: GPLv3 "============================================================================= +let s:list = SpaceVim#api#import('data#list') let s:pr_kind = g:spacevim_gitcommit_pr_icon let s:issue_kind = g:spacevim_gitcommit_issue_icon @@ -62,19 +63,56 @@ let s:commit_types = [ \ ] +" https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors +" https://stackoverflow.com/questions/58525836/git-magic-keywords-in-commit-messages-signed-off-by-co-authored-by-fixes +" https://www.reddit.com/r/git/comments/13d565i/git_trailers_what_are_they_for/ +" https://alchemists.io/articles/git_trailers +" https://git-scm.com/docs/git-interpret-trailers +" https://gitlab.com/gitlab-org/gitlab-foss/-/issues/31640 +" https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/CommitMessageConventions.html +let s:git_trailers = [ + \ { + \ 'word' : 'Co-Authored-By:', + \ 'menu' : 'multiple commit author' + \ }, + \ ] + +function! s:find_last_branch() abort + let reflog = systemlist('git reflog') + for log in reflog + " e059b76ca HEAD@{15}: checkout: moving from doc-help to master + if log =~# 'HEAD@{\d\+}: checkout: ' + return matchstr(log, 'HEAD@{\d\+}: checkout: moving from \zs\S*') + endif + endfor + return '' +endfunction + +function! s:generate_co_author() abort + let last_branch = s:find_last_branch() + call SpaceVim#logger#info('last branch:' . last_branch) + return s:list.uniq(systemlist('git log -n 5 --format="%aN <%aE>" ' . last_branch)) +endfunction + function! SpaceVim#plugins#gitcommit#complete(findstart, base) abort if a:findstart let s:complete_ol = 0 let s:complete_type = 0 + let s:complete_trailers = 0 + let s:complete_co_author = 0 let line = getline('.') let start = col('.') - 1 - while start > 0 && line[start - 1] !=# ' ' && line[start - 1] !=# '#' + while start > 0 && line[start - 1] !=# ' ' && line[start - 1] !=# '#' && line[start - 1] !=# ':' let start -= 1 endwhile if line[start - 1] ==# '#' let s:complete_ol = 1 elseif line('.') ==# 1 && start ==# 0 let s:complete_type = 1 + elseif line('.') !=# 1 && start ==# 0 + let s:complete_trailers = 1 + elseif getline('.') =~# '^Co-Authored-By:' && start >= 14 + let s:complete_co_author = 1 endif return start else @@ -82,6 +120,10 @@ function! SpaceVim#plugins#gitcommit#complete(findstart, base) abort return s:complete_pr(a:base) elseif s:complete_type == 1 return s:complete('types') + elseif s:complete_trailers == 1 + return s:complete('trailers') + elseif s:complete_co_author == 1 + return s:complete('co-author') endif let res = [] for m in s:cache_commits() @@ -101,6 +143,10 @@ endfunction function! s:complete(what) abort if a:what ==# 'types' return s:commit_types + elseif a:what ==# 'trailers' + return s:git_trailers + elseif a:what ==# 'co-author' + return s:generate_co_author() else return [] endif diff --git a/doc/SpaceVim.txt b/doc/SpaceVim.txt index ed548b54d..d63050385 100644 --- a/doc/SpaceVim.txt +++ b/doc/SpaceVim.txt @@ -2423,6 +2423,11 @@ The following key bindings will be definded when the `git` layer is loaded. SPC g h r undo cursor hunk SPC g h v preview cursor hunk < +COMMIT OMNI FUNCTION +This layer also provides an omnifunc for git commit messages. It supports: + 1. complete commit title, `fix:`, `doc:` etc. + 2. complete github issue list + 3. complete co-author info ============================================================================== GITHUB *SpaceVim-layers-github* diff --git a/docs/cn/layers/git.md b/docs/cn/layers/git.md index 43f207026..451e8b1e8 100644 --- a/docs/cn/layers/git.md +++ b/docs/cn/layers/git.md @@ -12,6 +12,7 @@ lang: zh - [启用模块](#启用模块) - [模块选项](#模块选项) - [快捷键](#快捷键) +- [Commit message 补全](#commit-message-补全) @@ -57,3 +58,11 @@ lang: zh | `SPC g h a` | stage current hunk | | `SPC g h r` | undo cursor hunk | | `SPC g h v` | preview cursor hunk | + +## Commit message 补全 + +在编辑 git commit message 时,可以使用快捷键 `ctrl-x_ctrl-o` 进行补全,可以补全: + +1. 标题前缀, 如 `fix:`、`doc:` 等; +2. GitHub issue 列表; +3. 上一次使用分支的 author 信息,便于添加 co-author diff --git a/docs/layers/git.md b/docs/layers/git.md index f69c39f40..2ab116b37 100644 --- a/docs/layers/git.md +++ b/docs/layers/git.md @@ -11,6 +11,7 @@ description: "This layer adds extensive support for git" - [Install](#install) - [Layer options](#layer-options) - [Key bindings](#key-bindings) +- [Omnifunc of commit message](#omnifunc-of-commit-message) @@ -56,3 +57,11 @@ if you want to use `fugitive` instead: | `SPC g h a` | stage current hunk | | `SPC g h r` | undo cursor hunk | | `SPC g h v` | preview cursor hunk | + +## Omnifunc of commit message + +This layer also provides omnifunc of commit message. The key binding is `ctrl-x_ctrl-o` in insert mode. + +1. complete commit title prefix, `fix:`, `doc:` etc. +2. complete github issue list +3. complete co-author info