2021-02-15 18:09:12 +00:00
|
|
|
-- Copyright (c) 2020-2021 shadmansaleh
|
2021-02-13 00:03:57 +00:00
|
|
|
-- MIT license, see LICENSE for more details.
|
2021-08-08 16:03:58 +00:00
|
|
|
local utils = require('lualine.utils.utils')
|
2021-04-11 08:20:41 +00:00
|
|
|
local Branch = require('lualine.component'):new()
|
|
|
|
-- vars
|
|
|
|
Branch.git_branch = ''
|
2021-01-20 10:19:10 +00:00
|
|
|
-- os specific path separator
|
2021-04-11 08:20:41 +00:00
|
|
|
Branch.sep = package.config:sub(1, 1)
|
|
|
|
-- event watcher to watch head file
|
|
|
|
Branch.file_changed = vim.loop.new_fs_event()
|
2021-08-09 09:04:15 +00:00
|
|
|
Branch.active_bufnr = '0'
|
2021-08-08 16:03:58 +00:00
|
|
|
local branch_cache = {} -- stores last known branch for a buffer
|
2021-04-11 08:20:41 +00:00
|
|
|
-- Initilizer
|
|
|
|
Branch.new = function(self, options, child)
|
|
|
|
local new_branch = self._parent:new(options, child or Branch)
|
|
|
|
if not new_branch.options.icon then
|
|
|
|
new_branch.options.icon = '' -- e0a0
|
|
|
|
end
|
|
|
|
-- run watch head on load so branch is present when component is loaded
|
|
|
|
Branch.update_branch()
|
|
|
|
-- update branch state of BufEnter as different Buffer may be on different repos
|
2021-08-08 16:03:58 +00:00
|
|
|
utils.define_autocmd('BufEnter', "lua require'lualine.components.branch'.update_branch()")
|
2021-04-11 08:20:41 +00:00
|
|
|
return new_branch
|
|
|
|
end
|
|
|
|
|
2021-08-08 16:03:58 +00:00
|
|
|
Branch.update_status = function(_, is_focused)
|
2021-08-09 09:04:15 +00:00
|
|
|
if Branch.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.
|
|
|
|
Branch.update_branch()
|
|
|
|
end
|
2021-08-08 16:03:58 +00:00
|
|
|
if not is_focused then return branch_cache[vim.fn.bufnr()] or '' end
|
|
|
|
return Branch.git_branch
|
|
|
|
end
|
2021-01-20 10:19:10 +00:00
|
|
|
|
|
|
|
-- returns full path to git directory for current directory
|
2021-04-11 08:20:41 +00:00
|
|
|
function Branch.find_git_dir()
|
2021-01-20 10:19:10 +00:00
|
|
|
-- get file dir so we can search from that dir
|
2021-08-03 09:28:05 +00:00
|
|
|
local file_dir = vim.fn.expand('%:p:h')
|
|
|
|
local git_file, git_dir
|
|
|
|
-- Search upward for .git file or folder
|
|
|
|
while (file_dir) do
|
|
|
|
local git_path = file_dir..Branch.sep..'.git'
|
|
|
|
local git_file_stat = vim.loop.fs_stat(git_path)
|
|
|
|
if (git_file_stat) then
|
|
|
|
if git_file_stat.type == 'directory' then
|
|
|
|
git_dir = git_path
|
|
|
|
elseif git_file_stat.type == 'file' then
|
|
|
|
git_file = git_path
|
|
|
|
end
|
|
|
|
break
|
|
|
|
end
|
|
|
|
file_dir = file_dir:match('(.*)'..Branch.sep..'.-')
|
|
|
|
end
|
|
|
|
|
|
|
|
if git_file then
|
2021-01-20 10:19:10 +00:00
|
|
|
-- separate git-dir or submodule is used
|
|
|
|
local file = io.open(git_file)
|
|
|
|
git_dir = file:read()
|
2021-03-15 23:37:46 +00:00
|
|
|
git_dir = git_dir:match('gitdir: (.+)$')
|
2021-01-20 10:19:10 +00:00
|
|
|
file:close()
|
|
|
|
-- submodule / relative file path
|
2021-04-11 08:20:41 +00:00
|
|
|
if git_dir:sub(1, 1) ~= Branch.sep and not git_dir:match('^%a:.*$') then
|
2021-03-15 23:37:46 +00:00
|
|
|
git_dir = git_file:match('(.*).git') .. git_dir
|
2021-01-08 09:51:11 +00:00
|
|
|
end
|
|
|
|
end
|
2021-01-20 10:19:10 +00:00
|
|
|
return git_dir
|
|
|
|
end
|
|
|
|
|
|
|
|
-- sets git_branch veriable to branch name or commit hash if not on branch
|
2021-04-11 08:20:41 +00:00
|
|
|
function Branch.get_git_head(head_file)
|
2021-01-20 10:19:10 +00:00
|
|
|
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/(.+)$')
|
2021-03-15 23:37:46 +00:00
|
|
|
if branch then
|
2021-04-11 08:20:41 +00:00
|
|
|
Branch.git_branch = branch
|
2021-03-15 23:37:46 +00:00
|
|
|
else
|
2021-04-11 08:20:41 +00:00
|
|
|
Branch.git_branch = HEAD:sub(1, 6)
|
2021-03-15 23:37:46 +00:00
|
|
|
end
|
2021-01-20 10:19:10 +00:00
|
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2021-04-11 08:20:41 +00:00
|
|
|
-- Update branch
|
|
|
|
function Branch.update_branch()
|
2021-08-09 09:04:15 +00:00
|
|
|
Branch.active_bufnr = tostring(vim.fn.bufnr())
|
2021-04-11 08:20:41 +00:00
|
|
|
Branch.file_changed:stop()
|
|
|
|
local git_dir = Branch.find_git_dir()
|
2021-08-03 09:28:05 +00:00
|
|
|
if git_dir and #git_dir > 0 then
|
2021-04-11 08:20:41 +00:00
|
|
|
local head_file = git_dir .. Branch.sep .. 'HEAD'
|
|
|
|
Branch.get_git_head(head_file)
|
|
|
|
Branch.file_changed:start(head_file, {}, vim.schedule_wrap(
|
|
|
|
function()
|
2021-03-15 23:37:46 +00:00
|
|
|
-- reset file-watch
|
2021-04-11 08:20:41 +00:00
|
|
|
Branch.update_branch()
|
2021-03-15 23:37:46 +00:00
|
|
|
end))
|
2021-01-20 10:19:10 +00:00
|
|
|
else
|
2021-04-11 08:20:41 +00:00
|
|
|
-- set to '' when git dir was not found
|
|
|
|
Branch.git_branch = ''
|
2021-01-20 10:19:10 +00:00
|
|
|
end
|
2021-08-08 16:03:58 +00:00
|
|
|
branch_cache[vim.fn.bufnr()] = Branch.git_branch
|
2021-01-20 10:19:10 +00:00
|
|
|
end
|
2021-01-04 00:38:01 +00:00
|
|
|
|
2021-04-11 08:20:41 +00:00
|
|
|
return Branch
|