Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

add branch_recent source #3

Merged
merged 2 commits into from

3 participants

@f110

ブランチは最近変更されたものの間で切り替えることが多いことから、最近変更された順にブランチを表示するsouceを作成しました。

これは git-branch-recent のような動作をします。

:Unite giti/branch_recent でローカルのブランチを最新から30件表示します。

screen shot 2013-09-12 at 1 25 12 am

@kmnk
Owner

unite に sort 機能があるので、使えないかなと考えていましたが、 git for-each-ref 経由で git コマンドから直接取れるのであれば、問題ないように思いました。
テストまで書いていただいてありがとうございます(テストはそのうちもっと良い感じに書けるように考えたいです…)。
merge してしまおうと思います。

@kmnk kmnk merged commit 0382fb7 into from
@f110 f110 deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 11, 2013
  1. @f110

    add branch_recent source

    f110 authored
  2. @f110
This page is out of date. Refresh to see the latest.
View
64 autoload/giti/branch_recent.vim
@@ -0,0 +1,64 @@
+" File: branch_recent.vim
+" Author: Fumihiro Ito <fmhrit@gmail.com>
+" Version: 0.0.1
+" License: MIT Licence
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! giti#branch_recent#recent()"{{{
+ return s:build_formatted_branch_data(
+\ s:get_recent_updated_branches('refs/heads/'))
+endfunction"}}}
+
+function! s:get_recent_updated_branches(target)"{{{
+ return split(
+\ giti#system('for-each-ref --sort=-committerdate --count=30 --format="%(refname:short),%(committerdate:relative),%(objectname:short),%(contents:subject)" ' . a:target),
+\ '\n')
+endfunction"}}}
+
+function! s:build_formatted_branch_data(branch_list)"{{{
+ let branch_data = map(
+\ a:branch_list,
+\ 's:build_branch_data_from_formatted_line(v:val)'
+\ )
+ let name_width = s:calc_max_width(branch_data, "name")
+ let date_width = s:calc_max_width(branch_data, "relativedate")
+
+ return map(
+\ branch_data, '{
+\ "name" : s:align_in_width_with_whitespace(v:val.name, name_width),
+\ "relativedate" : s:align_in_width_with_whitespace(v:val.relativedate, date_width),
+\ "objectname" : v:val.objectname,
+\ "message" : v:val.message,
+\ }')
+endfunction"}}}
+
+function! s:calc_max_width(datas, key)"{{{
+ let max_width = 0
+ for data in a:datas
+ if strlen(get(data, a:key, "")) > max_width
+ let max_width = strlen(get(data, a:key, ""))
+ endif
+ endfor
+
+ return max_width
+endfunction"}}}
+
+function! s:align_in_width_with_whitespace(val, width)"{{{
+ return printf('%-'.(a:width + 1).'s', a:val)
+endfunction"}}}
+
+function! s:build_branch_data_from_formatted_line(line)"{{{
+ let splitted = split(a:line, ",")
+ return {
+\ 'name' : splitted[0],
+\ 'relativedate' : splitted[1],
+\ 'objectname' : splitted[2],
+\ 'message' : join(splitted[3:], ","),
+\ }
+endfunction"}}}
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" __END__
View
74 autoload/unite/sources/giti/branch_recent.vim
@@ -0,0 +1,74 @@
+" File: branch_recent.vim
+" Author: Fumihiro Ito <fmhrit@gmail.com>
+" Version: 0.1.0
+" License: MIT Licence
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! unite#sources#giti#branch_recent#define()"{{{
+ return [s:source, unite#sources#giti#branch#new#define()]
+endfunction"}}}
+
+let s:source = {
+\ 'name' : 'giti/branch_recent',
+\ 'description' : 'display recent changed branches',
+\}
+
+function! s:source.gather_candidates(args, context)"{{{
+ call unite#print_message('[giti/branch_recent]')
+ return map(giti#branch_recent#recent(), '{
+\ "word" : s:build_word(v:val),
+\ "source" : s:source.name,
+\ "kind" : "giti/branch",
+\ "action__name" : v:val.name,
+\ "action__is_new" : 0,
+\ }')
+endfunction"}}}
+
+function! s:source.change_candidates(args, context)"{{{
+ if !strlen(a:context.input)
+ return []
+ endif
+ return [{
+\ "word" : "[new branch] " . a:context.input,
+\ "source" : s:source.name,
+\ "kind" : "giti/branch",
+\ "action__name" : a:context.input,
+\ "action__is_new" : 1,
+\ }, {
+\ "word" : "[checkout branch] " . a:context.input,
+\ "source" : s:source.name,
+\ "kind" : "giti/branch",
+\ "action__name" : a:context.input,
+\ "action__is_new" : 0,
+\ }]
+endfunction"}}}
+
+" local functions {{{
+let s:word_format = '%s(%s) %s| %s'
+function! s:build_word(val)"{{{
+ return printf(s:word_format,
+\ a:val.name,
+\ a:val.objectname,
+\ a:val.relativedate,
+\ a:val.message)
+endfunction"}}}
+
+" }}}
+
+" context getter {{{
+function! s:get_SID()
+ return matchstr(expand('<sfile>'), '<SNR>\d\+_')
+endfunction
+let s:SID = s:get_SID()
+delfunction s:get_SID
+
+function! unite#sources#giti#branch_recent#__context__()
+ return { 'sid': s:SID, 'scope': s: }
+endfunction
+"}}}
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" __END__
View
33 test/autoload/giti/test_branch_recent.vim
@@ -0,0 +1,33 @@
+let s:tc = unittest#testcase#new('autoload/giti/branch_recent.vim')
+
+function! s:tc.SETUP()"{{{
+ function! giti#system(command)"{{{
+ let b:system_called_with = a:command
+ return "branch-recent,2 hours ago,89abcde,second commit\nmaster,9 weeks ago,1234567,initial commit"
+ endfunction"}}}
+endfunction"}}}
+
+function! s:tc.test_recent()"{{{
+ call self.assert_equal(
+\ [
+\ {
+\ 'name' : 'branch-recent ',
+\ 'relativedate' : '2 hours ago ',
+\ 'objectname' : '89abcde',
+\ 'message' : 'second commit',
+\ },
+\ {
+\ 'name' : 'master ',
+\ 'relativedate' : '9 weeks ago ',
+\ 'objectname' : '1234567',
+\ 'message' : 'initial commit',
+\ }
+\ ],
+\ giti#branch_recent#recent(),
+\ )
+ call self.assert_equal(
+\ 'for-each-ref --sort=-committerdate --count=30 --format="%(refname:short),%(committerdate:relative),%(objectname:short),%(contents:subject)" refs/heads/',
+\ b:system_called_with)
+endfunction"}}}
+
+unlet s:tc
View
51 test/autoload/unite/sources/giti/test_branch_recent.vim
@@ -0,0 +1,51 @@
+let s:tc = unittest#testcase#new(
+\ 'autoload/unite/sources/giti/branch_recent.vim',
+\ unite#sources#giti#branch#__context__()
+\)
+
+function! s:tc.SETUP()"{{{
+endfunction"}}}
+function! s:tc.TEARDOWN()"{{{
+endfunction"}}}
+
+function! s:tc.test_define()"{{{
+ call self.assert_equal(
+\ type([]),
+\ type(unite#sources#giti#branch_recent#define()),
+\ )
+ call self.assert_throw('E118', 'call self.call("unite#sources#giti#branch_recent#define", [""])')
+endfunction"}}}
+
+function! s:tc.source_should_have()"{{{
+ let source = self.get('s:source')
+ call self.assert_equal(type({}), type(source))
+ call self.assert_equal(type(''), type(source.name))
+ call self.assert_equal(type(''), type(source.description))
+ call self.assert_equal(type(function('tr')), type(source.gather_candidates))
+ call self.assert_equal(type(function('tr')), type(source.change_candidates))
+endfunction"}}}
+
+function! s:tc.test_source_gather_candidate()"{{{
+ let source = self.get('s:source')
+ let candidates = source.gather_candidates('', '')
+ call self.assert_equal(type([]), type(candidates))
+ call self.assert(has_key(candidates[0], 'word'))
+ call self.assert(has_key(candidates[0], 'source'))
+ call self.assert(has_key(candidates[0], 'kind'))
+ call self.assert(has_key(candidates[0], 'action__name'))
+ call self.assert(has_key(candidates[0], 'action__is_new'))
+endfunction"}}}
+
+function! s:tc.test_source_change_candidate()"{{{
+ let source = self.get('s:source')
+ let candidates = source.change_candidates('', {'input' : 'hoge'})
+ call self.assert(len(candidates), 2)
+ call self.assert_equal(type([]), type(candidates))
+ call self.assert(has_key(candidates[0], 'word'))
+ call self.assert(has_key(candidates[0], 'source'))
+ call self.assert(has_key(candidates[0], 'kind'))
+ call self.assert(has_key(candidates[0], 'action__name'))
+ call self.assert(has_key(candidates[0], 'action__is_new'))
+endfunction"}}}
+
+unlet s:tc
Something went wrong with that request. Please try again.