1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-04 05:40:06 +08:00
SpaceVim/autoload/SpaceVim/layers/VersionControl.vim
2018-03-12 21:00:24 +08:00

318 lines
9.5 KiB
VimL

"=============================================================================
" VersionControl.vim --- SpaceVim version control layer
" Copyright (c) 2016-2017 Wang Shidong & Contributors
" Author: Wang Shidong < wsdjeg at 163.com >
" URL: https://spacevim.org
" License: GPLv3
"=============================================================================
scriptencoding utf-8
function! SpaceVim#layers#VersionControl#plugins() abort
let plugins = []
call add(plugins, ['mhinz/vim-signify', {'merged' : 0}])
call add(plugins, ['tpope/vim-fugitive', { 'merged' : 0}])
return plugins
endfunction
function! SpaceVim#layers#VersionControl#config() abort
let g:_spacevim_mappings_space.g = get(g:_spacevim_mappings_space, 'g', {'name' : '+VersionControl/git'})
let g:_spacevim_mappings_space.g.v = get(g:_spacevim_mappings_space.g, 'v', {'name' : '+VersionControl'})
call SpaceVim#mapping#space#def('nnoremap', ['g', '.'], 'call call('
\ . string(s:_function('s:buffer_transient_state')) . ', [])',
\ 'buffer transient state', 1)
call SpaceVim#layers#core#statusline#register_sections('vcs', s:_function('s:git_branch'))
call SpaceVim#layers#core#statusline#register_sections('hunks', s:_function('s:hunks'))
call add(g:spacevim_statusline_left_sections, 'vcs')
call add(g:spacevim_statusline_left_sections, 'hunks')
call SpaceVim#mapping#space#def('nnoremap', ['t', 'm', 'v'], 'call SpaceVim#layers#core#statusline#toggle_section("vcs")',
\ 'version control info', 1)
call SpaceVim#mapping#space#def('nnoremap', ['t', 'm', 'h'], 'call SpaceVim#layers#core#statusline#toggle_section("hunks")',
\ 'toggle the hunks summary', 1)
endfunction
"  master
function! s:git_branch() abort
if exists('g:loaded_fugitive')
let l:head = fugitive#head()
if empty(l:head)
call fugitive#detect(getcwd())
let l:head = fugitive#head()
endif
return empty(l:head) ? '' : '  '.l:head . ' '
endif
return ''
endfunction
" +0 ~0 -0
function! s:hunks() abort
let hunks = [0,0,0]
try
let hunks = sy#repo#get_stats()
catch
endtry
let rst = ''
if hunks[0] > 0
let rst .= hunks[0] . '+ '
endif
if hunks[1] > 0
let rst .= hunks[1] . '~ '
endif
if hunks[2] > 0
let rst .= hunks[2] . '- '
endif
return empty(rst) ? '' : ' ' . rst
endfunction
" vcs transient state functions:
" first we need to open a buffer contains:
" Switches
" -g Show graph (--graph)
" -c Show graph in color (--color)
"
" Options
" =n Limit number of commits (-n"256")
" =f Limit to files (-- )
" =a Limit to author (--author=)
"
" Actions
" l Log current
let s:git_log_switches = {
\ 'g' : {'desc' : 'Show graph', 'option' : '--graph'},
\ 'c' : {'desc' : 'Show graph in color', 'option' : '--color'},
\ 'd' : {'desc' : 'Show refnames', 'option' : '--decorate'},
\ 'S' : {'desc' : 'Show signatures', 'option' : '--show-signature'},
\ 'u' : {'desc' : 'Show diffs', 'option' : '--patch'},
\ 's' : {'desc' : 'Show diffstats', 'option' : '--stat'},
\ 'h' : {'desc' : 'Show header', 'option' : '++header'},
\ 'D' : {'desc' : 'Simplify by decoration', 'option' : '--simplify-by-decoration'},
\ 'f' : {'desc' : 'Follow renames when showing single-file log', 'option' : '--follow'},
\ }
let s:git_log_options = {
\ 'n' : {'desc' : 'Limit number of commits', 'option' : '-n'},
\ 'f' : {'desc' : 'Limit to files', 'option' : '--'},
\ 'a' : {'desc' : 'Limit to author', 'option' : '--author='},
\ 'o' : {'desc' : 'Order commits by', 'option' : '++order='},
\ 'g' : {'desc' : 'Search messages', 'option' : '--grep='},
\ 'G' : {'desc' : 'Search changes', 'option' : '-G'},
\ 'S' : {'desc' : 'Search occurrences', 'option' : '-S'},
\ 'L' : {'desc' : 'Trace line evolution', 'option' : '-L'},
\ }
let s:git_log_actions = {
\ 'l' : {'desc' : 'Log current'},
\ 'o' : {'desc' : 'Log other'},
\ 'h' : {'desc' : 'Log HEAD'},
\ 'L' : {'desc' : 'Log local branches'},
\ 'b' : {'desc' : 'Log all branches'},
\ 'a' : {'desc' : 'Log all references'},
\ 'r' : {'desc' : 'Reflog current'},
\ 'O' : {'desc' : 'Reflog other'},
\ 'H' : {'desc' : 'Reflog HEAD'},
\ }
function! s:generate_git_log_popup_content() abort
let lines = ['Switches']
for k in keys(s:git_log_switches)
call add(lines, ' -' . k . ' ' . s:git_log_switches[k]['desc'] . '(' . s:git_log_switches[k]['option'] . ')')
endfor
call add(lines, '')
call add(lines, 'Options')
for k in keys(s:git_log_options)
call add(lines, ' =' . k . ' ' . s:git_log_options[k]['desc'] . '(' . s:git_log_options[k]['option'] . ')')
endfor
call add(lines, '')
call add(lines, 'Actions')
let actions_line = ''
let i = 0
for k in ['l', 'L', 'r', 'o', 'b', 'O', 'h', 'a', 'H']
let i += 1
let actions_line .= ' ' . k . ' ' . s:git_log_actions[k]['desc']
let actions_line .= repeat(' ', i % 3 * 30 - len(actions_line))
if i%3 == 0
call add(lines, actions_line)
let actions_line = ''
endif
endfor
if !empty(actions_line)
call add(lines, actions_line)
let actions_line = ''
endif
return lines
endfunction
function! s:open_log_popup_buffer() abort
let content = s:generate_git_log_popup_content()
exe 'rightbelow ' . len(content) . 'split __SpaceVim_git_log_popup__'
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nospell nonumber norelativenumber nocursorline
setfiletype SpaceVimGitLogPopup
call setline(1, content)
endfunction
function! Gitlog() abort
call s:open_log_popup_buffer()
endfunction
function! s:show_repo_log() abort
endfunction
function! s:show_diff_of_unstaged_hunks() abort
endfunction
function! s:fetch_repo() abort
endfunction
function! s:pull_repo() abort
endfunction
function! s:push_repo() abort
endfunction
function! s:commit_popup() abort
endfunction
function! s:commit() abort
endfunction
function! s:revert_hunk() abort
endfunction
function! s:stage_hunk() abort
endfunction
function! s:show_hunk_diff() abort
endfunction
function! s:buffer_transient_state() abort
let state = SpaceVim#api#import('transient_state')
call state.set_title('VCS Transient State')
call state.defind_keys(
\ {
\ 'layout' : 'vertical split',
\ 'left' : [
\ {
\ 'key' : 'n',
\ 'desc' : 'next hunk',
\ 'func' : '',
\ 'cmd' : 'normal ]c',
\ 'exit' : 0,
\ },
\ {
\ 'key' : ['N', 'p'],
\ 'desc' : 'previous hunk',
\ 'func' : '',
\ 'cmd' : 'normal [c',
\ 'exit' : 0,
\ },
\ {
\ 'key' : {
\ 'name' : 'r/s/h',
\ 'pos' : [[0,1], [2,3], [4,5]],
\ 'handles' : [
\ ['r' , 'call call(' . string(s:_function('s:revert_hunk')) . ', [])'],
\ ['s' , 'call call(' . string(s:_function('s:stage_hunk')) . ', [])'],
\ ['h' , 'call call(' . string(s:_function('s:show_hunk_diff')) . ', [])'],
\ ],
\ },
\ 'desc' : 'revert/stage/show hunk',
\ 'func' : '',
\ 'cmd' : '',
\ 'exit' : 0,
\ },
\ {
\ 'key' : 't',
\ 'desc' : 'toggle diff signs',
\ 'func' : '',
\ 'cmd' : 'SignifyToggle',
\ 'exit' : 0,
\ },
\ ],
\ 'right' : [
\ {
\ 'key' : {
\ 'name' : 'w/u',
\ 'pos': [[0,1], [2,3]],
\ 'handles' : [
\ ['w', 'Gina add %'],
\ ['u', 'Gina reset %'],
\ ],
\ },
\ 'desc' : 'stage/unstage in current file',
\ 'func' : '',
\ 'cmd' : '',
\ 'exit' : 0,
\ },
\ {
\ 'key' : {
\ 'name' : 'c/C',
\ 'pos' : [[0,1], [2,3]],
\ 'handles' : [
\ ['c' , 'call call(' . string(s:_function('s:commit_popup')) . ', [])'],
\ ['C' , 'call call(' . string(s:_function('s:commit')) . ', [])'],
\ ],
\ },
\ 'desc' : 'commit with popup/direct commit',
\ 'func' : '',
\ 'cmd' : '',
\ 'exit' : 1,
\ },
\ {
\ 'key' : {
\ 'name' : 'f/F/P',
\ 'pos' : [[0,1], [2,3], [4,5]],
\ 'handles' : [
\ ['f' , 'call call(' . string(s:_function('s:fetch_repo')) . ', [])'],
\ ['F' , 'call call(' . string(s:_function('s:pull_repo')) . ', [])'],
\ ['P' , 'call call(' . string(s:_function('s:push_repo')) . ', [])'],
\ ],
\ },
\ 'desc' : 'fetch/pull/push popup',
\ 'func' : '',
\ 'cmd' : '',
\ 'exit' : 1,
\ },
\ {
\ 'key' : {
\ 'name' : 'l/D',
\ 'pos' : [[0,1], [2,3]],
\ 'handles' : [
\ ['l' , 'call call(' . string(s:_function('s:show_repo_log')) . ', [])'],
\ ['D' , 'call call(' . string(s:_function('s:show_diff_of_unstaged_hunks')) . ', [])'],
\ ],
\ },
\ 'desc' : 'log/diff popup',
\ 'func' : '',
\ 'cmd' : '',
\ 'exit' : 1,
\ },
\ ],
\ }
\ )
call state.open()
endfunction
" function() wrapper
if v:version > 703 || v:version == 703 && has('patch1170')
function! s:_function(fstr) abort
return function(a:fstr)
endfunction
else
function! s:_SID() abort
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction
let s:_s = '<SNR>' . s:_SID() . '_'
function! s:_function(fstr) abort
return function(substitute(a:fstr, 's:', s:_s, 'g'))
endfunction
endif