refactor: split branch component (#81)
This commit is contained in:
parent
0b599b0ace
commit
cc64ec3f7c
|
@ -1,50 +1,64 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
local M = {}
|
||||||
-- MIT license, see LICENSE for more details.
|
|
||||||
local M = require('lualine.component'):extend()
|
local require = require('lualine_require').require
|
||||||
local modules = require('lualine_require').lazy_require {
|
local utils = require 'lualine.utils.utils'
|
||||||
utils = 'lualine.utils.utils',
|
|
||||||
}
|
|
||||||
-- vars
|
-- vars
|
||||||
M.git_branch = ''
|
local current_git_branch = ''
|
||||||
M.git_dir = ''
|
local current_git_dir = ''
|
||||||
|
local branch_cache = {} -- stores last known branch for a buffer
|
||||||
|
local active_bufnr = '0'
|
||||||
-- os specific path separator
|
-- os specific path separator
|
||||||
M.sep = package.config:sub(1, 1)
|
local sep = package.config:sub(1, 1)
|
||||||
-- event watcher to watch head file
|
-- event watcher to watch head file
|
||||||
-- Use file wstch for non windows and poll for windows.
|
-- Use file wstch for non windows and poll for windows.
|
||||||
-- windows doesn't like file watch for some reason.
|
-- windows doesn't like file watch for some reason.
|
||||||
M.file_changed = M.sep ~= '\\' and vim.loop.new_fs_event() or vim.loop.new_fs_poll()
|
local file_changed = sep ~= '\\' and vim.loop.new_fs_event() or vim.loop.new_fs_poll()
|
||||||
M.active_bufnr = '0'
|
|
||||||
local branch_cache = {} -- stores last known branch for a buffer
|
|
||||||
-- Initilizer
|
|
||||||
M.init = function(self, options)
|
|
||||||
M.super.init(self, options)
|
|
||||||
if not self.options.icon then
|
|
||||||
self.options.icon = '' -- e0a0
|
|
||||||
end
|
|
||||||
-- run watch head on load so branch is present when component is loaded
|
|
||||||
M.find_git_dir()
|
|
||||||
-- update branch state of BufEnter as different Buffer may be on different repos
|
|
||||||
modules.utils.define_autocmd('BufEnter', "lua require'lualine.components.branch'.find_git_dir()")
|
|
||||||
end
|
|
||||||
|
|
||||||
M.update_status = function(_, is_focused)
|
|
||||||
if M.active_bufnr ~= vim.g.actual_curbuf then
|
|
||||||
-- Workaround for https://github.com/hoob3rt/lualine.nvim/issues/286
|
|
||||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
|
||||||
-- Diff is out of sync re sync it.
|
|
||||||
M.find_git_dir()
|
|
||||||
end
|
|
||||||
if not is_focused then
|
|
||||||
return branch_cache[vim.fn.bufnr()] or ''
|
|
||||||
end
|
|
||||||
return M.git_branch
|
|
||||||
end
|
|
||||||
|
|
||||||
local git_dir_cache = {} -- Stores git paths that we already know of
|
local git_dir_cache = {} -- Stores git paths that we already know of
|
||||||
-- returns full path to git directory for current directory
|
|
||||||
function M.find_git_dir()
|
-- sets git_branch veriable to branch name or commit hash if not on branch
|
||||||
|
local function get_git_head(head_file)
|
||||||
|
local f_head = io.open(head_file)
|
||||||
|
if f_head then
|
||||||
|
local HEAD = f_head:read()
|
||||||
|
f_head:close()
|
||||||
|
local branch = HEAD:match 'ref: refs/heads/(.+)$'
|
||||||
|
if branch then
|
||||||
|
current_git_branch = branch
|
||||||
|
else
|
||||||
|
current_git_branch = HEAD:sub(1, 6)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update branch
|
||||||
|
local function update_branch()
|
||||||
|
active_bufnr = tostring(vim.fn.bufnr())
|
||||||
|
file_changed:stop()
|
||||||
|
local git_dir = current_git_dir
|
||||||
|
if git_dir and #git_dir > 0 then
|
||||||
|
local head_file = git_dir .. sep .. 'HEAD'
|
||||||
|
get_git_head(head_file)
|
||||||
|
file_changed:start(
|
||||||
|
head_file,
|
||||||
|
sep ~= '\\' and {} or 1000,
|
||||||
|
vim.schedule_wrap(function()
|
||||||
|
-- reset file-watch
|
||||||
|
update_branch()
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
-- set to '' when git dir was not found
|
||||||
|
current_git_branch = ''
|
||||||
|
end
|
||||||
|
branch_cache[vim.fn.bufnr()] = current_git_branch
|
||||||
|
end
|
||||||
|
|
||||||
|
-- returns full path to git directory for dir_path or current directory
|
||||||
|
function M.find_git_dir(dir_path)
|
||||||
-- get file dir so we can search from that dir
|
-- get file dir so we can search from that dir
|
||||||
local file_dir = vim.fn.expand '%:p:h'
|
local file_dir = dir_path or vim.fn.expand '%:p:h'
|
||||||
local root_dir = file_dir
|
local root_dir = file_dir
|
||||||
local git_dir
|
local git_dir
|
||||||
-- Search upward for .git file or folder
|
-- Search upward for .git file or folder
|
||||||
|
@ -53,7 +67,7 @@ function M.find_git_dir()
|
||||||
git_dir = git_dir_cache[root_dir]
|
git_dir = git_dir_cache[root_dir]
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
local git_path = root_dir .. M.sep .. '.git'
|
local git_path = root_dir .. sep .. '.git'
|
||||||
local git_file_stat = vim.loop.fs_stat(git_path)
|
local git_file_stat = vim.loop.fs_stat(git_path)
|
||||||
if git_file_stat then
|
if git_file_stat then
|
||||||
if git_file_stat.type == 'directory' then
|
if git_file_stat.type == 'directory' then
|
||||||
|
@ -65,12 +79,12 @@ function M.find_git_dir()
|
||||||
git_dir = git_dir:match 'gitdir: (.+)$'
|
git_dir = git_dir:match 'gitdir: (.+)$'
|
||||||
file:close()
|
file:close()
|
||||||
-- submodule / relative file path
|
-- submodule / relative file path
|
||||||
if git_dir and git_dir:sub(1, 1) ~= M.sep and not git_dir:match '^%a:.*$' then
|
if git_dir and git_dir:sub(1, 1) ~= sep and not git_dir:match '^%a:.*$' then
|
||||||
git_dir = git_path:match '(.*).git' .. git_dir
|
git_dir = git_path:match '(.*).git' .. git_dir
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if git_dir then
|
if git_dir then
|
||||||
local head_file_stat = vim.loop.fs_stat(git_dir .. M.sep .. 'HEAD')
|
local head_file_stat = vim.loop.fs_stat(git_dir .. sep .. 'HEAD')
|
||||||
if head_file_stat and head_file_stat.type == 'file' then
|
if head_file_stat and head_file_stat.type == 'file' then
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
|
@ -78,54 +92,34 @@ function M.find_git_dir()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
root_dir = root_dir:match('(.*)' .. M.sep .. '.-')
|
root_dir = root_dir:match('(.*)' .. sep .. '.-')
|
||||||
end
|
end
|
||||||
|
|
||||||
git_dir_cache[file_dir] = git_dir
|
git_dir_cache[file_dir] = git_dir
|
||||||
if M.git_dir ~= git_dir then
|
if dir_path == nil and current_git_dir ~= git_dir then
|
||||||
M.git_dir = git_dir
|
current_git_dir = git_dir
|
||||||
M.update_branch()
|
update_branch()
|
||||||
end
|
end
|
||||||
return git_dir
|
return git_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
-- sets git_branch veriable to branch name or commit hash if not on branch
|
function M.init()
|
||||||
function M.get_git_head(head_file)
|
-- run watch head on load so branch is present when component is loaded
|
||||||
local f_head = io.open(head_file)
|
M.find_git_dir()
|
||||||
if f_head then
|
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||||
local HEAD = f_head:read()
|
utils.define_autocmd('BufEnter', "lua require'lualine.components.branch.git_branch'.find_git_dir()")
|
||||||
f_head:close()
|
|
||||||
local branch = HEAD:match 'ref: refs/heads/(.+)$'
|
|
||||||
if branch then
|
|
||||||
M.git_branch = branch
|
|
||||||
else
|
|
||||||
M.git_branch = HEAD:sub(1, 6)
|
|
||||||
end
|
end
|
||||||
|
function M.get_branch(bufnr)
|
||||||
|
if vim.g.actual_curbuf ~= nil and active_bufnr ~= vim.g.actual_curbuf then
|
||||||
|
-- Workaround for https://github.com/hoob3rt/lualine.nvim/issues/286
|
||||||
|
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||||
|
-- Diff is out of sync re sync it.
|
||||||
|
M.find_git_dir()
|
||||||
end
|
end
|
||||||
return nil
|
if bufnr then
|
||||||
|
return branch_cache[bufnr] or ''
|
||||||
end
|
end
|
||||||
|
return current_git_branch
|
||||||
-- Update branch
|
|
||||||
function M.update_branch()
|
|
||||||
M.active_bufnr = tostring(vim.fn.bufnr())
|
|
||||||
M.file_changed:stop()
|
|
||||||
local git_dir = M.git_dir
|
|
||||||
if git_dir and #git_dir > 0 then
|
|
||||||
local head_file = git_dir .. M.sep .. 'HEAD'
|
|
||||||
M.get_git_head(head_file)
|
|
||||||
M.file_changed:start(
|
|
||||||
head_file,
|
|
||||||
M.sep ~= '\\' and {} or 1000,
|
|
||||||
vim.schedule_wrap(function()
|
|
||||||
-- reset file-watch
|
|
||||||
M.update_branch()
|
|
||||||
end)
|
|
||||||
)
|
|
||||||
else
|
|
||||||
-- set to '' when git dir was not found
|
|
||||||
M.git_branch = ''
|
|
||||||
end
|
|
||||||
branch_cache[vim.fn.bufnr()] = M.git_branch
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
|
-- MIT license, see LICENSE for more details.
|
||||||
|
local M = require('lualine.component'):extend()
|
||||||
|
local require = require('lualine_require').require
|
||||||
|
local git_branch = require 'lualine.components.branch.git_branch'
|
||||||
|
|
||||||
|
-- Initilizer
|
||||||
|
M.init = function(self, options)
|
||||||
|
M.super.init(self, options)
|
||||||
|
if not self.options.icon then
|
||||||
|
self.options.icon = '' -- e0a0
|
||||||
|
end
|
||||||
|
git_branch.init()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.update_status = function(_, is_focused)
|
||||||
|
return git_branch.get_branch((not is_focused and vim.fn.bufnr()))
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
Loading…
Reference in New Issue