aboutsummaryrefslogtreecommitdiffstats
path: root/autoload/gitcha.vim
blob: 13d61bf16e704efe370b94d3205b3c8332567e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
" Save user-defined 'completeopt's so they can be restored after running this
" custom completion function
let s:old_completeopt = &completeopt

" Completion for Git SHAs in the current repository
function! gitcha#GitSHAComplete()
	let line = getline('.')
	let start = col('.')
	while start > 0 && line[start - 2] =~ '[0-9a-f]'
		let start -= 1
	endwhile

	" Match Git SHAs in the current repository
	let matches = []
	let revs = system('git rev-list --all --pretty=oneline --no-abbrev-commit')
	let base = line[start - 1 : col('.') - 1]

	for m in s:BuildMatchDictionary(revs)
		if m['word'] =~ '^' . base
			call add(matches, m)
		endif
	endfor

	set completeopt=menu,menuone,preview

	call complete(start, matches)

	let &completeopt = s:old_completeopt

	return ''
endfunction

" Takes rev-list output from:
"   $ git rev-list --all --pretty=oneline --no-abbrev-commit
"
" Creates a dictionary to be used for matching that uses commit SHAs for the
" completion word and the commit subject as extra text.
function! s:BuildMatchDictionary(rev_list)
	let matches = []
	let commits = split(a:rev_list, '\n')

	for commit in commits
		let separator = stridx(commit, ' ')
		let sha = strpart(commit, 0, separator)
		let subject = strpart(commit, separator + 1)

		call add(matches, {
			\ 'word': sha,
			\ 'abbr': strpart(sha, 0, 10),
			\ 'menu': subject
		\ })
	endfor

	return matches
endfunction