diff --git a/bundle/git.vim/lua/git/command/branch.lua b/bundle/git.vim/lua/git/command/branch.lua index afa8db186..18106be41 100644 --- a/bundle/git.vim/lua/git/command/branch.lua +++ b/bundle/git.vim/lua/git/command/branch.lua @@ -119,6 +119,13 @@ function M.run(argv) local cmd = { 'git', 'branch' } + if #argv == 0 then + + require('git.ui.branch').open() + + return + end + if argv then for _, v in ipairs(argv) do table.insert(cmd, v) diff --git a/bundle/git.vim/lua/git/command/checkout.lua b/bundle/git.vim/lua/git/command/checkout.lua index c41b6df9f..235aa3f20 100644 --- a/bundle/git.vim/lua/git/command/checkout.lua +++ b/bundle/git.vim/lua/git/command/checkout.lua @@ -4,12 +4,14 @@ local job = require('spacevim.api.job') local nt = require('spacevim.api.notify') local log = require('git.log') local branch = require('git.command.branch') +local branch_ui = require('git.ui.branch') local function on_exit(id, code, single) log.debug('git-checkout exit code:' .. code .. ' single:' .. single) if code == 0 and single == 0 then vim.cmd('silent! checktime') branch.detect() + branch_ui.update() nt.notify('checkout done.') else nt.notify('checkout failed.', 'WarningMsg') @@ -21,6 +23,7 @@ function M.run(argv) for _, v in ipairs(argv) do table.insert(cmd, v) end + log.info('git checkout cmd:' .. vim.inspect(cmd)) job.start(cmd, { on_exit = on_exit }) end diff --git a/bundle/git.vim/lua/git/ui/branch.lua b/bundle/git.vim/lua/git/ui/branch.lua new file mode 100644 index 000000000..7947fcd78 --- /dev/null +++ b/bundle/git.vim/lua/git/ui/branch.lua @@ -0,0 +1,133 @@ +--============================================================================= +-- branch.lua --- branch manager ui +-- Copyright (c) 2016-2022 Wang Shidong & Contributors +-- Author: Wang Shidong < wsdjeg@outlook.com > +-- URL: https://spacevim.org +-- License: GPLv3 +--============================================================================= + +local M = {} + +local job = require('spacevim.api.job') +local log = require('git.log') +local nt = require('spacevim.api.notify') +local branch_manager_bufnr = -1 +local jobid = -1 +local branches = {} + +local function update_buffer_context() + local context = { 'local' } + local remote = '' + for _, b in ipairs(branches) do + if b.remote ~= remote then + table.insert(context, 'r:' .. b.remote) + remote = b.remote + end + table.insert(context, ' ' .. b.name) + end + + vim.api.nvim_buf_set_option(branch_manager_bufnr, 'modifiable', true) + vim.api.nvim_buf_set_lines(branch_manager_bufnr, 0, -1, false, context) + vim.api.nvim_buf_set_option(branch_manager_bufnr, 'modifiable', false) +end + +local function on_stdout(id, data) + if id ~= jobid then + return + end + for _, line in ipairs(data) do + log.info('>>' .. line) + if vim.startswith(line, ' remotes/') then + table.insert(branches, { + name = string.sub(line, vim.fn.stridx(line, '/', 10) + 2), + remote = vim.split(line, '/')[2], + islocal = false, + }) + else + table.insert(branches, { + name = vim.trim(line), + remote = '', + islocal = true, + }) + end + end +end + +local function on_stderr(id, data) + if id ~= jobid then + return + end + + for _, v in pairs(data) do + nt.notify(v, 'WarningMsg') + end +end + +local function on_exit(id, code, signal) + if id == jobid and code == 0 and signal == 0 then + update_buffer_context() + end +end + +local function update() + branches = {} + + local cmd = { 'git', 'branch', '--all' } + + jobid = job.start(cmd, { + on_stderr = on_stderr, + on_stdout = on_stdout, + on_exit = on_exit, + }) +end + +local function checkout_branch() + local line = vim.fn.getline('.') + if vim.startswith(line, ' * ') then + elseif vim.startswith(line, ' ') then + local branch = vim.trim(line) + vim.cmd('Git checkout ' .. branch) + end +end + +local function delete_branch() + local remote_line = vim.fn.search('^r:', 'bnW') + if remote_line == 0 then + local line = vim.fn.getline('.') + if vim.startswith(line, ' * ') then + elseif vim.startswith(line, ' ') then + local branch = vim.trim(line) + vim.cmd('Git checkout -d ' .. branch) + end + end +end + +function M.open() + if branch_manager_bufnr ~= -1 and vim.api.nvim_buf_is_valid(branch_manager_bufnr) then + vim.api.nvim_buf_delete(branch_manager_bufnr, { + force = true, + unload = false, + }) + end + vim.api.nvim_command('topleft vsplit __git_branch_manager__') + local lines = vim.o.columns * 30 / 100 + vim.api.nvim_command('vertical resize ' .. tostring(lines)) + vim.api.nvim_command( + 'setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nospell nonu norelativenumber winfixheight nomodifiable winfixwidth' + ) + vim.api.nvim_command('set filetype=SpaceVimGitBranchManager') + branch_manager_bufnr = vim.api.nvim_get_current_buf() + update() + vim.api.nvim_buf_set_keymap(branch_manager_bufnr, 'n', '', '', { + callback = checkout_branch, + }) + vim.api.nvim_buf_set_keymap(branch_manager_bufnr, 'n', 'dd', '', { + callback = delete_branch, + }) +end + +function M.update() + update() +end + +return M