├── .gitignore ├── README.md ├── autoload └── denite_gitto.vim ├── doc └── denite-gitto.txt ├── plugin └── denite_gitto.vim └── rplugin └── python3 └── denite ├── kind ├── gitto.py ├── gitto_branch.py ├── gitto_changes_status.py ├── gitto_log.py └── gitto_status.py └── source ├── gitto.py ├── gitto_branch.py ├── gitto_changes.py ├── gitto_log.py └── gitto_status.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .mypy_cache 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # denite-gitto 2 | denite.nvim + vim-gitto 3 | 4 | # Install 5 | ``` 6 | call dein#add('Shougo/denite.nvim') 7 | call dein#add('hrsh7th/vim-gitto') 8 | call dein#add('hrsh7th/vim-denite-gitto') 9 | ``` 10 | 11 | NOTE: you can use other plugin managers. 12 | 13 | # Usage 14 | 15 | ## `DeniteGitto gitto` 16 | 17 | 18 | 19 | 20 | ## `DeniteGitto gitto/status` 21 | 22 | 23 | 24 | 25 | ## `DeniteGitto gitto/branch` 26 | 27 | 28 | 29 | 30 | ## `DeniteGitto gitto/log` (repo) 31 | 32 | 33 | 34 | 35 | ## `DeniteGitto gitto/log` (file) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /autoload/denite_gitto.vim: -------------------------------------------------------------------------------- 1 | let s:current_working_dir = '' 2 | 3 | function! denite_gitto#start(args) 4 | let s:current_working_dir = g:gitto#config.get_buffer_path() 5 | execute printf('Denite %s', a:args) 6 | endfunction 7 | 8 | function! denite_gitto#run(feature, ...) 9 | return call(function('gitto#run_in_dir'), [s:current_working_dir, a:feature] + a:000) 10 | endfunction 11 | 12 | function! denite_gitto#commit(paths, amend) 13 | return gitto#view#commit_in_dir(s:current_working_dir, a:paths, a:amend) 14 | endfunction 15 | 16 | function! denite_gitto#diff_file_with_hash(path, info) 17 | return gitto#view#diff_file_with_hash_in_dir(s:current_working_dir, a:path, a:info) 18 | endfunction 19 | 20 | function! denite_gitto#diff_hash_with_hash(info1, info2) 21 | return gitto#view#diff_hash_with_hash_in_dir(s:current_working_dir, a:info1, a:info2) 22 | endfunction 23 | 24 | -------------------------------------------------------------------------------- /doc/denite-gitto.txt: -------------------------------------------------------------------------------- 1 | *denite-gitto* 2 | 3 | The denite.nvim source for git. 4 | 5 | ============================================================================== 6 | CONTENTS *denite-gitto-contents* 7 | 8 | INTRODUCTION |denite-gitto-intro| 9 | INSTALL |denite-gitto-install| 10 | COMMAND |denite-gitto-command| 11 | USAGE |denite-gitto-usage| 12 | gitto |denite-gitto-usage-gitto| 13 | gitto/status |denite-gitto-usage-gitto_status| 14 | gitto/branch |denite-gitto-usage-gitto_branch| 15 | gitto/log |denite-gitto-usage-gitto_log| 16 | gitto/changes |denite-gitto-usage-gitto_changes| 17 | EXAMPLE |denite-gitto-example| 18 | TODO |denite-gitto-todo| 19 | CHANGELOG |denite-gitto-changelog| 20 | 21 | ============================================================================== 22 | INTRODUCTION *denite-gitto-intro* 23 | 24 | denite-gitto provides git operations in denite.nvim's ui. 25 | The git operations are provided by separated vim plugin that's vim-gitto. 26 | 27 | Currently supported operations. 28 | 29 | - status 30 | - diff 31 | - commit 32 | - add 33 | - rm 34 | - checkout 35 | - reset 36 | 37 | - log 38 | - changes 39 | - changes_local 40 | - reset 41 | - reset_mixed 42 | - reset_soft 43 | - reset_hard 44 | 45 | - branch 46 | - new 47 | - delete 48 | - rename 49 | - checkout 50 | - fetch 51 | - pull 52 | - push 53 | - rebase 54 | - merge 55 | - merge_no_ff 56 | - merge_squash 57 | - changes_to 58 | - changes_from 59 | 60 | ============================================================================== 61 | INSTALL *denite-gitto-install* 62 | 63 | You must install bellow plugins. 64 | 65 | - Shougo/denite.nvim 66 | - hrsh7th/vim-gitto 67 | - hrsh7th/vim-denite-gitto 68 | 69 | Can use any plugin managers to install. 70 | 71 | 72 | ============================================================================== 73 | COMMAND *denite-gitto-command* 74 | > 75 | :DeniteGitto *** 76 | < 77 | This interface is same of `Denite` command. 78 | You can find the documentation in `Shougo/denite.nvim`. 79 | 80 | 81 | ============================================================================== 82 | USAGE *denite-gitto-usage* 83 | 84 | You can bellow operations via `DeniteGitto` command. 85 | 86 | --------------------------------------------------- *denite-gitto-usage-gitto* 87 | :DeniteGitto gitto~ 88 | 89 | Listing some git operations. 90 | You can use all features via this command. 91 | 92 | 93 | -------------------------------------------- *denite-gitto-usage-gitto_status* 94 | :DeniteGitto gitto/status~ 95 | 96 | Listing git status for current buffer's repo. 97 | Candidates can take bellow denite-actions. 98 | 99 | - diff (default) 100 | - reset 101 | - add 102 | - rm 103 | - checkout 104 | - checkout_ours 105 | - checkout_theirs 106 | - commit 107 | 108 | 109 | -------------------------------------------- *denite-gitto-usage-gitto_branch* 110 | :DeniteGitto gitto/branch~ 111 | 112 | Listing git branches for current buffer's repo. 113 | Candidate can take bellow denite-actions. 114 | 115 | - checkout (default) 116 | - delete 117 | - rename 118 | - new 119 | - merge 120 | - merge_no_ff 121 | - merge_squash 122 | - rebase 123 | - push 124 | - pull 125 | - fetch 126 | - changes_to: `git diff %CURRENT_BRANCH%...%SELECTED_BRANCH%` 127 | - changes_from: `git diff %SELECTED_BRANCH%...%CURRENT_BRANCH%` 128 | 129 | Note: merge/merge_no_ff/merge_squash/rebase/changes_to/changes_from will effect current branches. 130 | 131 | 132 | ----------------------------------------------- *denite-gitto-usage-gitto_log* 133 | :DeniteGitto gitto/log~ 134 | 135 | Listing git logs for current buffer's repo. 136 | Candidates can take bellow denite-actions. 137 | 138 | - changes (default) 139 | - changes_local 140 | - yank_revision 141 | - reset 142 | - reset_mixed 143 | - reset_soft 144 | - reset_hard 145 | 146 | 147 | ------------------------------------------- *denite-gitto-usage-gitto_changes* 148 | :DeniteGitto gitto/changes~ 149 | 150 | Listing git changeset for selected log. 151 | Candidate can take bellow denite-actions. 152 | 153 | - diff (default) 154 | 155 | 156 | ============================================================================== 157 | EXAMPLE *denite-gitto-example* 158 | 159 | Recommended settings are bellow. 160 | 161 | > 162 | " mapping. 163 | nnoremap git :DeniteGitto gitto 164 | 165 | " denite. 166 | autocmd FileType denite call s:denite_setting() 167 | function! s:denite_settings() abort 168 | 169 | ... some your settings ... 170 | 171 | nnoremap n denite#do_map('do_action', 'new') 172 | nnoremap d denite#do_map('do_action', 'delete') 173 | nnoremap denite#do_map('restore_sources') 174 | endfunction 175 | < 176 | 177 | If you type 'n' key in `DeniteGitto gitto/branch` source, will be create new branch. 178 | If you type 'd' key in `DeniteGItto gitto/branch` source, will be delete selected branches. 179 | If you type '' key, You can go back previous source. 180 | 181 | The `restore_sources` will be useful for bellow workflow. 182 | 183 | 1. Start `DeniteGitto gitto` source. 184 | 2. Select `repo log` candidate. 185 | 3. Get `git log` results. 186 | 4. Select suitable log. 187 | 5. Get `git diff --name-status` results. 188 | 6. Type ``. 189 | 7. Go back to previous `git log` results. 190 | 191 | 192 | ============================================================================== 193 | TODO *denite-gitto-todo* 194 | 195 | Support bellow operations. 196 | 197 | - gitto 198 | - rebase continue 199 | - rebase skip 200 | - rebase abort 201 | 202 | - stash 203 | - store 204 | - restore 205 | 206 | - log 207 | - revert 208 | - cherry-pick? 209 | 210 | ============================================================================== 211 | CHANGELOG *denite-gitto-changelog* 212 | 213 | 2019/09/13~ 214 | - Add `changes_to` and `changes_from` action to branch kind. 215 | 216 | 2019/07/31~ 217 | - Support renamed file commits 218 | 219 | 2019/06/25~ 220 | - Support `diff` action for status(renamed, untracked, deleted). 221 | 222 | 2019/06/25~ 223 | - Fix help. 224 | 225 | 2019/06/25~ 226 | - Add help. 227 | 228 | -------------------------------------------------------------------------------- /plugin/denite_gitto.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_denite_gitto') 2 | finish 3 | endif 4 | let g:loaded_denite_gitto = v:true 5 | 6 | command! -nargs=+ DeniteGitto call s:denite_gitto() 7 | function! s:denite_gitto(args) 8 | call denite_gitto#start(a:args) 9 | endfunction 10 | 11 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/gitto.py: -------------------------------------------------------------------------------- 1 | from denite.kind.base import Base 2 | 3 | class Kind(Base): 4 | def __init__(self, vim): 5 | super().__init__(vim) 6 | self.name = 'gitto' 7 | self.default_action = 'run' 8 | 9 | def action_run(self, context): 10 | target = context['targets'][0] 11 | if target['action__type'] == 'func': 12 | self.vim.call(target['action__func'], *target['action__args']) 13 | context['sources_queue'].append([{'name': 'gitto', 'args': []}]) 14 | elif target['action__type'] == 'source': 15 | context['sources_queue'].append(target['action__source']) 16 | 17 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/gitto_branch.py: -------------------------------------------------------------------------------- 1 | from denite.kind.base import Base 2 | 3 | class Kind(Base): 4 | def __init__(self, vim): 5 | super().__init__(vim) 6 | self.name = 'gitto/branch' 7 | self.default_action = 'checkout' 8 | self.redraw_actions = [] 9 | self.redraw_actions += ['checkout'] 10 | self.redraw_actions += ['delete'] 11 | self.redraw_actions += ['rename'] 12 | self.redraw_actions += ['new'] 13 | self.redraw_actions += ['merge'] 14 | self.redraw_actions += ['merge_no_ff'] 15 | self.redraw_actions += ['merge_squash'] 16 | self.redraw_actions += ['rebase'] 17 | self.redraw_actions += ['push'] 18 | self.redraw_actions += ['pull'] 19 | self.redraw_actions += ['fetch'] 20 | self.persist_actions = self.redraw_actions 21 | 22 | def action_checkout(self, context): 23 | branch = context['targets'][0]['action__branch'] 24 | self.vim.call('denite_gitto#run', 'branch#checkout', branch) 25 | 26 | def action_delete(self, context): 27 | choise = self.vim.call('input', 'delete?(yes/no): ') 28 | if choise in ['y', 'ye', 'yes']: 29 | for target in context['targets']: 30 | self.vim.call('denite_gitto#run', 'branch#delete', target['action__branch']) 31 | 32 | def action_rename(self, context): 33 | branch = context['targets'][0]['action__branch'] 34 | new_name = self.vim.call('input', 'rename branch {} -> '.format(branch['name'])) 35 | self.vim.call('denite_gitto#run', 'branch#rename', branch['name'], new_name) 36 | 37 | def action_changes_to(self, context): 38 | branch = context['targets'][0]['action__branch'] 39 | current = self.vim.call('denite_gitto#run', 'branch#current') 40 | context['sources_queue'].append([ 41 | {'name': 'gitto/changes', 'args': ['LOCAL', branch['name'], '']} 42 | ]) 43 | 44 | def action_changes_from(self, context): 45 | branch = context['targets'][0]['action__branch'] 46 | current = self.vim.call('denite_gitto#run', 'branch#current') 47 | context['sources_queue'].append([ 48 | {'name': 'gitto/changes', 'args': [branch['name'], 'LOCAL', '']} 49 | ]) 50 | 51 | def action_new(self, context): 52 | name = self.vim.call('input', 'create branch: ') 53 | self.vim.call('denite_gitto#run', 'branch#new', name) 54 | 55 | def action_merge(self, context): 56 | branch = context['targets'][0]['action__branch'] 57 | self.vim.call('denite_gitto#run', 'branch#merge', branch) 58 | 59 | def action_merge_no_ff(self, context): 60 | branch = context['targets'][0]['action__branch'] 61 | self.vim.call('denite_gitto#run', 'branch#merge', branch, {'--no-ff': True}) 62 | 63 | def action_merge_squash(self, context): 64 | branch = context['targets'][0]['action__branch'] 65 | self.vim.call('denite_gitto#run', 'branch#merge', branch, {'--squash': True}) 66 | 67 | def action_rebase(self, context): 68 | branch = context['targets'][0]['action__branch'] 69 | self.vim.call('denite_gitto#run', 'branch#rebase', branch) 70 | 71 | def action_push(self, context): 72 | branch = context['targets'][0]['action__branch'] 73 | self.vim.call('denite_gitto#run', 'branch#push', branch) 74 | 75 | def action_pull(self, context): 76 | branch = context['targets'][0]['action__branch'] 77 | self.vim.call('denite_gitto#run', 'branch#pull', branch) 78 | 79 | def action_fetch(self, context): 80 | for target in context['targets']: 81 | self.vim.call('denite_gitto#run', 'branch#fetch', target['action__branch']) 82 | 83 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/gitto_changes_status.py: -------------------------------------------------------------------------------- 1 | from denite.kind.base import Base 2 | 3 | class Kind(Base): 4 | def __init__(self, vim): 5 | super().__init__(vim) 6 | self.name = 'gitto/changes_status' 7 | self.default_action = 'diff' 8 | self.redraw_actions = ['diff'] 9 | self.persist_actions = self.redraw_actions 10 | 11 | def action_diff(self, context): 12 | from_hash = context['targets'][0]['action__changes']['from'] 13 | to_hash = context['targets'][0]['action__changes']['to'] 14 | 15 | statuses = [candidate['action__status'] for candidate in context['targets']] 16 | for status in statuses: 17 | if status['status'] == 'R': 18 | from_path = status['path_before_rename'] 19 | else: 20 | from_path = status['path'] 21 | 22 | if to_hash == 'LOCAL': 23 | self.vim.call('denite_gitto#diff_file_with_hash', status['path'], {'hash': from_hash, 'path': from_path}) 24 | else: 25 | self.vim.call('denite_gitto#diff_hash_with_hash', {'hash': to_hash, 'path': status['path']}, {'hash': from_hash, 'path': from_path}) 26 | 27 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/gitto_log.py: -------------------------------------------------------------------------------- 1 | from denite.kind.base import Base 2 | 3 | class Kind(Base): 4 | def __init__(self, vim): 5 | super().__init__(vim) 6 | self.name = 'gitto/log' 7 | self.default_action = 'changes' 8 | self.redraw_actions = [] 9 | self.redraw_actions += ['yank_revision'] 10 | self.redraw_actions += ['reset'] 11 | self.redraw_actions += ['reset_mixed'] 12 | self.redraw_actions += ['reset_soft'] 13 | self.redraw_actions += ['reset_hard'] 14 | self.persist_actions = self.redraw_actions 15 | 16 | def action_changes(self, context): 17 | log = context['targets'][0]['action__log'] 18 | path = context['targets'][0]['source_context']['__path'] 19 | 20 | if not len(log['parent_hashes']): 21 | self.vim.command('echomsg "{}"'.format('Selected log has\'nt parent.')) 22 | return 23 | 24 | context['sources_queue'].append([ 25 | {'name': 'gitto/changes', 'args': [log['parent_hashes'][0], log['commit_hash'], path]} 26 | ]) 27 | 28 | def action_changes_local(self, context): 29 | log = context['targets'][0]['action__log'] 30 | path = context['targets'][0]['source_context']['__path'] 31 | context['sources_queue'].append([ 32 | {'name': 'gitto/changes', 'args': [log['commit_hash'], 'LOCAL', path]} 33 | ]) 34 | 35 | def action_yank_revision(self, context): 36 | _yank(self.vim, context['targets'][0]['action__log']['commit_hash']) 37 | 38 | def action_reset(self, context): 39 | choise = self.vim.call('input', 'mixed/soft/hard: ') 40 | if choise in ['mixed', 'soft', 'hard']: 41 | if choise == 'mixed': 42 | self._reset(context, {'--mixed': True}) 43 | elif choise == 'soft': 44 | self._reset(context, {'--soft': True}) 45 | elif choise == 'hard': 46 | self._reset(context, {'--hard': True}) 47 | return 48 | 49 | def action_reset_mixed(self, context): 50 | self._reset(context, {'--mixed': True}) 51 | 52 | def action_reset_soft(self, context): 53 | self._reset(context, {'--soft': True}) 54 | 55 | def action_reset_hard(self, context): 56 | self._reset(context, {'--hard': True}) 57 | 58 | def _reset(self, context, opts): 59 | commit_hash = context['targets'][0]['action__log']['commit_hash'] 60 | self.vim.call('denite_gitto#run', 'log#reset', commit_hash, opts) 61 | 62 | def _yank(vim, word): 63 | vim.call('setreg', '"', word, 'v') 64 | if vim.call('has', 'clipboard'): 65 | vim.call('setreg', vim.eval('v:register'), word, 'v') 66 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/gitto_status.py: -------------------------------------------------------------------------------- 1 | from denite.kind.file import Kind as File 2 | 3 | class Kind(File): 4 | def __init__(self, vim): 5 | super().__init__(vim) 6 | self.name = 'gitto/status' 7 | self.default_action = 'diff' 8 | self.redraw_actions = [] 9 | self.redraw_actions += ['reset'] 10 | self.redraw_actions += ['rm'] 11 | self.redraw_actions += ['add'] 12 | self.redraw_actions += ['checkout'] 13 | self.redraw_actions += ['checkout_ours'] 14 | self.redraw_actions += ['checkout_theirs'] 15 | self.redraw_actions += ['diff'] 16 | self.persist_actions = self.redraw_actions 17 | 18 | def action_reset(self, context): 19 | self._per_status('status#reset', {}, context) 20 | 21 | def action_rm(self, context): 22 | self._per_status('status#rm', {}, context) 23 | 24 | def action_add(self, context): 25 | self._per_status('status#add', {}, context) 26 | 27 | def action_checkout(self, context): 28 | self._per_status('status#checkout', {}, context) 29 | 30 | def action_checkout_ours(self, context): 31 | self._per_status('status#checkout', {'--ours': True}, context) 32 | 33 | def action_checkout_theirs(self, context): 34 | self._per_status('status#checkout', {'--theirs': True}, context) 35 | 36 | def action_commit(self, context): 37 | self._commit(context, False) 38 | 39 | def action_commit_amend(self, context): 40 | self._commit(context, True) 41 | 42 | def action_diff(self, context): 43 | statuses = [candidate['action__status'] for candidate in context['targets']] 44 | for status in statuses: 45 | if status['status'] == '??': 46 | self.vim.command("tabnew {}".format(status['path'])) 47 | elif status['status'] == 'R ' or status['status'] == ' R': 48 | self.vim.call('denite_gitto#diff_file_with_hash', status['path'], {'hash': 'HEAD', 'path': status['path_before_rename']}) 49 | else: 50 | self.vim.call('denite_gitto#diff_file_with_hash', status['path'], {'hash': 'HEAD', 'path': status['path']}) 51 | 52 | def _per_status(self, action, args, context): 53 | paths = [candidate['action__path'] for candidate in context['targets']] 54 | self.vim.call('denite_gitto#run', action, paths) 55 | 56 | def _commit(self, context, amend): 57 | paths = [] 58 | for target in context['targets']: 59 | if target['action__status']['status'] == 'R ' or target['action__status']['status'] == ' R': 60 | paths.append(target['action__status']['path']) 61 | paths.append(target['action__status']['path_before_rename']) 62 | else: 63 | paths.append(target['action__status']['path']) 64 | self.vim.call('denite_gitto#commit', paths, amend) 65 | 66 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/gitto.py: -------------------------------------------------------------------------------- 1 | from denite.source.base import Base 2 | 3 | class Source(Base): 4 | 5 | def __init__(self, vim): 6 | super().__init__(vim) 7 | 8 | self.name = 'gitto' 9 | self.kind = 'gitto' 10 | self.vars = {} 11 | self.label_length = 18 12 | 13 | def gather_candidates(self, context): 14 | branches = self.vim.call('denite_gitto#run', 'branch#get', {'-a': True}) 15 | 16 | candidates = [] 17 | self._status(context, candidates) 18 | self._branch(context, candidates) 19 | self._log_for_root(context, candidates) 20 | self._log_for_file(context, candidates) 21 | self._fetch(context, candidates) 22 | self._set_upstream_to(context, candidates, branches) 23 | self._push(context, candidates, branches) 24 | self._push_force(context, candidates, branches) 25 | self._pull(context, candidates, branches) 26 | self._pull_rebase(context, candidates, branches) 27 | 28 | for candidate in candidates: 29 | candidate.update({ 30 | 'word': '{:{label}} | {}'.format(*candidate['word'], label=self.label_length), 31 | 'abbr': '{:{label}} | {}'.format(*candidate['word'], label=self.label_length) 32 | }) 33 | return candidates 34 | 35 | def _push(self, context, candidates, branches): 36 | if not self.is_pushable(branches): 37 | return 38 | 39 | current = self.current_branch(branches) 40 | candidates.append({ 41 | 'word': ['push', 'target is `{}/{}`, {} commits: {}'.format( 42 | current['remote'], 43 | current['name'], 44 | current['ahead'], 45 | current['subject'] 46 | )], 47 | 'action__type': 'func', 48 | 'action__func': 'denite_gitto#run', 49 | 'action__args': ['repo#push'] 50 | }) 51 | 52 | def _push_force(self, context, candidates, branches): 53 | if not self.is_pushable(branches): 54 | return 55 | 56 | current = self.current_branch(branches) 57 | candidates.append({ 58 | 'word': ['push force', 'target is `{}/{}`, {} commits: {}'.format( 59 | current['remote'], 60 | current['name'], 61 | current['ahead'], 62 | current['subject'] 63 | )], 64 | 'action__type': 'func', 65 | 'action__func': 'denite_gitto#run', 66 | 'action__args': ['repo#push', {'--force': True}] 67 | }) 68 | 69 | def _pull(self, context, candidates, branches): 70 | if not self.is_pullable(branches): 71 | return 72 | 73 | current = self.current_branch(branches) 74 | candidates.append({ 75 | 'word': ['pull', 'target is `{}`'.format(current['upstream'])], 76 | 'action__type': 'func', 77 | 'action__func': 'denite_gitto#run', 78 | 'action__args': ['repo#pull'] 79 | }) 80 | 81 | def _pull_rebase(self, context, candidates, branches): 82 | if not self.is_pullable(branches): 83 | return 84 | 85 | current = self.current_branch(branches) 86 | candidates.append({ 87 | 'word': ['pull rebase', 'target is `{}`'.format(current['upstream'])], 88 | 'action__type': 'func', 89 | 'action__func': 'denite_gitto#run', 90 | 'action__args': ['repo#pull', {'--rebase': True}] 91 | }) 92 | 93 | def _set_upstream_to(self, context, candidates, branches): 94 | current = self.current_branch(branches) 95 | if not current or len(current['upstream']) > 0: 96 | return 97 | 98 | same_name = self._get_same_name_other_branch(current, branches) 99 | if same_name: 100 | candidates.append({ 101 | 'word': ['set-upstream-to', '`{}`'.format( 102 | same_name['refname'] 103 | )], 104 | 'action__type': 'func', 105 | 'action__func': 'denite_gitto#run', 106 | 'action__args': ['branch#set_upstream_to', same_name] 107 | }) 108 | 109 | def _fetch(self, context, candidates): 110 | candidates.append({ 111 | 'word': ['fetch', 'fetch all and prune'], 112 | 'action__type': 'func', 113 | 'action__func': 'denite_gitto#run', 114 | 'action__args': ['repo#fetch', {'--all': True, '--prune': True}] 115 | }) 116 | 117 | def _status(self, context, candidates): 118 | candidates.append({ 119 | 'word': ['status', ''], 120 | 'action__type': 'source', 121 | 'action__source': [{'name': 'gitto/status', 'args': []}] 122 | }) 123 | 124 | def _branch(self, context, candidates): 125 | candidates.append({ 126 | 'word': ['branch', ''], 127 | 'action__type': 'source', 128 | 'action__source': [{'name': 'gitto/branch', 'args': ['-a']}] 129 | }) 130 | 131 | def _log_for_file(self, context, candidates): 132 | candidates.append({ 133 | 'word': ['file log', ''], 134 | 'action__type': 'source', 135 | 'action__source': [{'name': 'gitto/log', 'args': [self.vim.call('expand', '%:p')]}] 136 | }) 137 | 138 | def _log_for_root(self, context, candidates): 139 | candidates.append({ 140 | 'word': ['repo log', ''], 141 | 'action__type': 'source', 142 | 'action__source': [{'name': 'gitto/log', 'args': []}] 143 | }) 144 | 145 | def _get_same_name_other_branch(self, target, branches): 146 | for branch in branches: 147 | if target['refname'] != branch['refname'] and target['name'] == branch['name']: 148 | return branch 149 | return None 150 | 151 | 152 | def current_branch(self, branches): 153 | return next((branch for branch in branches if branch['current']), None) 154 | 155 | def is_pullable(self, branches): 156 | current = self.current_branch(branches) 157 | if not current: 158 | return False 159 | if len(current['upstream']) <= 0: 160 | return False 161 | if current['behind'] <= 0: 162 | return False 163 | return True 164 | 165 | def is_pushable(self, branches): 166 | current = self.current_branch(branches) 167 | same_name = self._get_same_name_other_branch(current, branches) 168 | if not current: 169 | return False 170 | if not same_name: 171 | return True 172 | if len(current['upstream']) <= 0: 173 | return False 174 | if current['ahead'] <= 0: 175 | return False 176 | return True 177 | 178 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/gitto_branch.py: -------------------------------------------------------------------------------- 1 | from denite.source.base import Base 2 | 3 | class Source(Base): 4 | 5 | def __init__(self, vim): 6 | super().__init__(vim) 7 | 8 | self.name = 'gitto/branch' 9 | self.kind = 'gitto/branch' 10 | self.vars = {} 11 | 12 | def gather_candidates(self, context): 13 | branches = self.vim.call('denite_gitto#run', 'branch#get', self._option(context)) 14 | 15 | lengths = self._column_len(branches, [ 16 | 'refname', 17 | 'remote', 18 | 'upstream' 19 | ]) 20 | 21 | return [{ 22 | 'word': '{:1} | {:{refname}} | {:{remote}} | {:{upstream}} | {}'.format( 23 | branch['HEAD'], 24 | branch['name'] if branch['local'] else branch['refname'], 25 | branch['remote'], 26 | branch['upstream'], 27 | branch['upstream_track'], 28 | refname=lengths['refname'], 29 | remote=lengths['remote'], 30 | upstream=lengths['upstream'] 31 | ), 32 | 'abbr': '{:1} | {:{refname}} | {:{remote}} | {:{upstream}} | {}'.format( 33 | branch['HEAD'], 34 | branch['name'] if branch['local'] else branch['refname'], 35 | branch['remote'], 36 | branch['upstream'], 37 | branch['upstream_track'], 38 | refname=lengths['refname'], 39 | remote=lengths['remote'], 40 | upstream=lengths['upstream'] 41 | ), 42 | 'action__branch': branch 43 | } for branch in branches] 44 | 45 | def _option(self, context): 46 | option = {} 47 | for arg in context['args']: 48 | parts = arg.split('=') 49 | if len(parts) == 1: 50 | option[parts[0]] = True 51 | elif len(parts) == 2: 52 | option[parts[0]] = parts[1] 53 | return option 54 | 55 | def _column_len(self, candidates, columns): 56 | lengths = {} 57 | for key in columns: 58 | lengths[key] = max([1] + [len(x[key]) for x in candidates]) 59 | return lengths 60 | 61 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/gitto_changes.py: -------------------------------------------------------------------------------- 1 | from denite.source.base import Base 2 | 3 | class Source(Base): 4 | 5 | def __init__(self, vim): 6 | super().__init__(vim) 7 | 8 | self.name = 'gitto/changes' 9 | self.kind = 'gitto/changes_status' 10 | self.vars = {} 11 | 12 | def gather_candidates(self, context): 13 | changes = self.vim.call('denite_gitto#run', 'changes#get', context['args'][0], context['args'][1]) 14 | if not len(changes['statuses']): 15 | return [] 16 | 17 | return [{ 18 | 'word': '{:>3} | {}'.format(status['status'], status['path']), 19 | 'abbr': '{:>3} | {}'.format(status['status'], status['path']), 20 | 'action__changes': changes, 21 | 'action__status': status, 22 | 'action__path': status['path'] 23 | } for status in changes['statuses'] if context['args'][2] == '' or context['args'][2] == status['path']] 24 | 25 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/gitto_log.py: -------------------------------------------------------------------------------- 1 | from denite.source.base import Base 2 | 3 | class Source(Base): 4 | 5 | def __init__(self, vim): 6 | super().__init__(vim) 7 | 8 | self.name = 'gitto/log' 9 | self.kind = 'gitto/log' 10 | self.is_public_context = True 11 | self.vars = {} 12 | self.vars['option'] = {} 13 | 14 | def on_init(self, context): 15 | context['__path'] = context['args'][0] if len(context['args']) > 0 else '' 16 | 17 | def gather_candidates(self, context): 18 | logs = self.vim.call('denite_gitto#run', 'log#get', self.vars['option'], context['__path']) 19 | if not len(logs): 20 | return [] 21 | 22 | lengths = self._column_len(logs, [ 23 | 'author_date', 24 | 'author_name', 25 | 'subject' 26 | ]) 27 | 28 | return [{ 29 | 'word': '{:{author_date}} | {} | {:{author_name}} | {:{subject}}'.format( 30 | log['author_date'], log['commit_hash'][0:7], log['author_name'], log['subject'], 31 | author_date=lengths['author_date'], 32 | commit_hash=7, 33 | author_name=lengths['author_name'], 34 | subject=lengths['subject'] 35 | ), 36 | 'abbr': '{:{author_date}} | {} | {:{author_name}} | {:{subject}}'.format( 37 | log['author_date'], log['commit_hash'][0:7], log['author_name'], log['subject'], 38 | author_date=lengths['author_date'], 39 | commit_hash=7, 40 | author_name=lengths['author_name'], 41 | subject=lengths['subject'] 42 | ), 43 | 'action__log': log, 44 | } for log in logs] 45 | 46 | def _column_len(self, candidates, columns): 47 | lengths = {} 48 | for key in columns: 49 | lengths[key] = max([1] + [len(x[key]) for x in candidates]) 50 | return lengths 51 | 52 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/gitto_status.py: -------------------------------------------------------------------------------- 1 | from denite.source.base import Base 2 | 3 | class Source(Base): 4 | 5 | def __init__(self, vim): 6 | super().__init__(vim) 7 | 8 | self.name = 'gitto/status' 9 | self.kind = 'gitto/status' 10 | self.vars = {} 11 | 12 | def gather_candidates(self, context): 13 | return [{ 14 | 'word': '{:>3} | {}'.format(status['status'], status['path']), 15 | 'abbr': '{:>3} | {}'.format(status['status'], status['path']), 16 | 'action__status': status, 17 | 'action__path': status['path'] 18 | } for status in self.vim.call('denite_gitto#run', 'status#get')] 19 | 20 | --------------------------------------------------------------------------------