From b419f3e8d1d030576d7f8df6c7f8dfd0da05ee7e Mon Sep 17 00:00:00 2001 From: thefux Date: Sun, 6 Mar 2022 11:18:41 +0100 Subject: [PATCH] small refactoring --- lua/lazygit.lua | 163 ++---------------- lua/lazygit/utils.lua | 97 +++++++++++ lua/lazygit/window.lua | 85 +++++++++ .../_extensions/lazygit_telescope.lua | 4 +- 4 files changed, 203 insertions(+), 146 deletions(-) create mode 100644 lua/lazygit/utils.lua create mode 100644 lua/lazygit/window.lua diff --git a/lua/lazygit.lua b/lua/lazygit.lua index 5f94602..895c1cd 100644 --- a/lua/lazygit.lua +++ b/lua/lazygit.lua @@ -1,80 +1,33 @@ -vim = vim -local api = vim.api +local open_floating_window = require"lazygit.window".open_floating_window +local project_root_dir = require"lazygit.utils".project_root_dir +local is_lazygit_available = require"lazygit.utils".is_lazygit_available +local is_symlink = require"lazygit.utils".is_symlink + local fn = vim.fn --- store all git repositories visited in this session -local lazygit_visited_git_repos = {} -local function append_git_repo_path(repo_path) - if repo_path == nil or not fn.isdirectory(repo_path) then - return - end - - for _, path in ipairs(lazygit_visited_git_repos) do - if path == repo_path then - return - end - end - - table.insert(lazygit_visited_git_repos, tostring(repo_path)) -end - LAZYGIT_BUFFER = nil LAZYGIT_LOADED = false vim.g.lazygit_opened = 0 ---- Strip leading and lagging whitespace -local function trim(str) - return str:gsub('^%s+', ''):gsub('%s+$', '') -end +local function clean_up_after_exit() + -- Close the window where the LAZYGIT_BUFFER is + vim.cmd('silent! :q') + LAZYGIT_BUFFER = nil + LAZYGIT_LOADED = false + vim.g.lazygit_opened = 0 ---- Check if lazygit is available -local function is_lazygit_available() - return fn.executable('lazygit') == 1 -end - -local function is_symlink() - local resolved = fn.resolve(fn.expand('%:p')) - return resolved ~= fn.expand('%:p') -end - ---- Get project_root_dir for git repository -local function project_root_dir() - -- always use bash on Unix based systems. - local oldshell = vim.o.shell - if vim.fn.has('win32') == 0 then - vim.o.shell = 'bash' - end - - -- try symlinked file location instead - local gitdir = fn.system( - 'cd "' .. fn.fnamemodify(fn.resolve(fn.expand('%:p')), ':h') .. '" && git rev-parse --show-toplevel') - local isgitdir = fn.matchstr(gitdir, '^fatal:.*') == '' - - if isgitdir then - vim.o.shell = oldshell - append_git_repo_path(gitdir) - return trim(gitdir) - end - - -- revert to old shell - vim.o.shell = oldshell - - local repo_path = fn.getcwd(0, 0) - append_git_repo_path(repo_path) - - -- just return current working directory - return repo_path + -- make sure to update current open buffer after closing the window + -- + vim.cmd('silent! :checktime') end --- on_exit callback function to delete the open buffer when lazygit exits in a neovim terminal local function on_exit(job_id, code, event) - if code == 0 then - -- Close the window where the LAZYGIT_BUFFER is - vim.cmd('silent! :q') - LAZYGIT_BUFFER = nil - LAZYGIT_LOADED = false - vim.g.lazygit_opened = 0 + if code ~= 0 then + return end + + clean_up_after_exit() end --- Call lazygit @@ -87,84 +40,6 @@ local function exec_lazygit_command(cmd) vim.cmd 'startinsert' end ---- open floating window with nice borders -local function open_floating_window() - local floating_window_scaling_factor = vim.g.lazygit_floating_window_scaling_factor - - -- Why is this required? - -- vim.g.lazygit_floating_window_scaling_factor returns different types if the value is an integer or float - if type(floating_window_scaling_factor) == 'table' then - floating_window_scaling_factor = floating_window_scaling_factor[false] - end - - local status, plenary = pcall(require, 'plenary.window.float') - if status and vim.g.lazygit_floating_window_use_plenary and vim.g.lazygit_floating_window_use_plenary ~= 0 then - plenary.percentage_range_window(floating_window_scaling_factor, floating_window_scaling_factor) - return - end - - local height = math.ceil(vim.o.lines * floating_window_scaling_factor) - 1 - local width = math.ceil(vim.o.columns * floating_window_scaling_factor) - - local row = math.ceil(vim.o.lines - height) / 2 - local col = math.ceil(vim.o.columns - width) / 2 - - local border_opts = { - style = 'minimal', - relative = 'editor', - row = row - 1, - col = col - 1, - width = width + 2, - height = height + 2, - } - - local opts = { style = 'minimal', relative = 'editor', row = row, col = col, width = width, height = height } - - local topleft, topright, botleft, botright - local corner_chars = vim.g.lazygit_floating_window_corner_chars - if type(corner_chars) == 'table' and #corner_chars == 4 then - topleft, topright, botleft, botright = unpack(corner_chars) - else - topleft, topright, botleft, botright = '╭', '╮', '╰', '╯' - end - - local border_lines = { topleft .. string.rep('─', width) .. topright } - local middle_line = '│' .. string.rep(' ', width) .. '│' - for i = 1, height do - table.insert(border_lines, middle_line) - end - table.insert(border_lines, botleft .. string.rep('─', width) .. botright) - - -- create a unlisted scratch buffer for the border - local border_buffer = api.nvim_create_buf(false, true) - - -- set border_lines in the border buffer from start 0 to end -1 and strict_indexing false - api.nvim_buf_set_lines(border_buffer, 0, -1, true, border_lines) - -- create border window - local border_window = api.nvim_open_win(border_buffer, true, border_opts) - vim.cmd('set winhl=Normal:Floating') - - -- create a unlisted scratch buffer - if LAZYGIT_BUFFER == nil or vim.fn.bufwinnr(LAZYGIT_BUFFER) == -1 then - LAZYGIT_BUFFER = api.nvim_create_buf(false, true) - else - LAZYGIT_LOADED = true - end - -- create file window, enter the window, and use the options defined in opts - local _ = api.nvim_open_win(LAZYGIT_BUFFER, true, opts) - - vim.bo[LAZYGIT_BUFFER].filetype = 'lazygit' - - vim.cmd('setlocal bufhidden=hide') - vim.cmd('setlocal nocursorcolumn') - vim.cmd('set winblend=' .. vim.g.lazygit_floating_window_winblend) - - -- use autocommand to ensure that the border_buffer closes at the same time as the main buffer - local cmd = [[autocmd WinLeave silent! execute 'hide']] - vim.cmd(cmd) - cmd = [[autocmd WinLeave silent! execute 'silent bdelete! %s']] - vim.cmd(cmd:format(border_buffer)) -end --- :LazyGit entry point local function lazygit(path) @@ -176,6 +51,7 @@ local function lazygit(path) open_floating_window() local cmd = 'lazygit' + -- set path to the root path _ = project_root_dir() @@ -241,5 +117,4 @@ return { lazygitfilter = lazygitfilter, lazygitconfig = lazygitconfig, project_root_dir = project_root_dir, - lazygit_visited_git_repos = lazygit_visited_git_repos, } diff --git a/lua/lazygit/utils.lua b/lua/lazygit/utils.lua new file mode 100644 index 0000000..2b34859 --- /dev/null +++ b/lua/lazygit/utils.lua @@ -0,0 +1,97 @@ +local fn = vim.fn + +-- store all git repositories visited in this session +local lazygit_visited_git_repos = {} + +-- TODO:check if the repo isa git repo +local function append_git_repo_path(repo_path) + if repo_path == nil or not fn.isdirectory(repo_path) then + return + end + + for _, path in ipairs(lazygit_visited_git_repos) do + if path == repo_path then + return + end + end + + table.insert(lazygit_visited_git_repos, tostring(repo_path)) +end + + +--- Strip leading and lagging whitespace +local function trim(str) + return str:gsub('^%s+', ''):gsub('%s+$', '') +end + + +local function get_root() + local cwd = vim.loop.cwd() + local status, job = pcall(require, 'plenary.job') + if not status then + local gitdir = fn.system('git rev-parse --show-toplevel') + end + + local gitroot_job = job:new({ + 'git', + 'rev-parse', + '--show-toplevel', + cwd=cwd + }) + + local _, code = gitroot_job:sync() + if (code ~= 0) then + return nil + end + + return fn.getcwd(0, 0) +end + +--- Get project_root_dir for git repository +local function project_root_dir() + -- always use bash on Unix based systems. + local oldshell = vim.o.shell + if vim.fn.has('win32') == 0 then + vim.o.shell = 'bash' + end + + local root = get_root() + -- try symlinked file location instead + local gitdir = fn.system( + 'cd "' .. fn.fnamemodify(fn.resolve(fn.expand('%:p')), ':h') .. '" && git rev-parse --show-toplevel') + local isgitdir = fn.matchstr(gitdir, '^fatal:.*') == '' + + if isgitdir then + vim.o.shell = oldshell + append_git_repo_path(gitdir) + return trim(gitdir) + end + + -- revert to old shell + vim.o.shell = oldshell + + local repo_path = fn.getcwd(0, 0) + append_git_repo_path(repo_path) + + -- just return current working directory + return repo_path +end + +--- Check if lazygit is available +local function is_lazygit_available() + return fn.executable('lazygit') == 1 +end + +local function is_symlink() + local resolved = fn.resolve(fn.expand('%:p')) + return resolved ~= fn.expand('%:p') +end + + +return { + get_root = get_root, + project_root_dir = project_root_dir, + lazygit_visited_git_repos = lazygit_visited_git_repos, + is_lazygit_available = is_lazygit_available, + is_symlink = is_symlink, +} diff --git a/lua/lazygit/window.lua b/lua/lazygit/window.lua new file mode 100644 index 0000000..9d2a5eb --- /dev/null +++ b/lua/lazygit/window.lua @@ -0,0 +1,85 @@ +local api = vim.api + + +--- open floating window with nice borders +local function open_floating_window() + local floating_window_scaling_factor = vim.g.lazygit_floating_window_scaling_factor + + -- Why is this required? + -- vim.g.lazygit_floating_window_scaling_factor returns different types if the value is an integer or float + if type(floating_window_scaling_factor) == 'table' then + floating_window_scaling_factor = floating_window_scaling_factor[false] + end + + local status, plenary = pcall(require, 'plenary.window.float') + if status and vim.g.lazygit_floating_window_use_plenary and vim.g.lazygit_floating_window_use_plenary ~= 0 then + plenary.percentage_range_window(floating_window_scaling_factor, floating_window_scaling_factor) + return + end + + local height = math.ceil(vim.o.lines * floating_window_scaling_factor) - 1 + local width = math.ceil(vim.o.columns * floating_window_scaling_factor) + + local row = math.ceil(vim.o.lines - height) / 2 + local col = math.ceil(vim.o.columns - width) / 2 + + local border_opts = { + style = 'minimal', + relative = 'editor', + row = row - 1, + col = col - 1, + width = width + 2, + height = height + 2, + } + + local opts = { style = 'minimal', relative = 'editor', row = row, col = col, width = width, height = height } + + local topleft, topright, botleft, botright + local corner_chars = vim.g.lazygit_floating_window_corner_chars + if type(corner_chars) == 'table' and #corner_chars == 4 then + topleft, topright, botleft, botright = unpack(corner_chars) + else + topleft, topright, botleft, botright = '╭', '╮', '╰', '╯' + end + + local border_lines = { topleft .. string.rep('─', width) .. topright } + local middle_line = '│' .. string.rep(' ', width) .. '│' + for i = 1, height do + table.insert(border_lines, middle_line) + end + table.insert(border_lines, botleft .. string.rep('─', width) .. botright) + + -- create a unlisted scratch buffer for the border + local border_buffer = api.nvim_create_buf(false, true) + + -- set border_lines in the border buffer from start 0 to end -1 and strict_indexing false + api.nvim_buf_set_lines(border_buffer, 0, -1, true, border_lines) + -- create border window + local border_window = api.nvim_open_win(border_buffer, true, border_opts) + vim.cmd('set winhl=Normal:Floating') + + -- create a unlisted scratch buffer + if LAZYGIT_BUFFER == nil or vim.fn.bufwinnr(LAZYGIT_BUFFER) == -1 then + LAZYGIT_BUFFER = api.nvim_create_buf(false, true) + else + LAZYGIT_LOADED = true + end + -- create file window, enter the window, and use the options defined in opts + local _ = api.nvim_open_win(LAZYGIT_BUFFER, true, opts) + + vim.bo[LAZYGIT_BUFFER].filetype = 'lazygit' + + vim.cmd('setlocal bufhidden=hide') + vim.cmd('setlocal nocursorcolumn') + vim.cmd('set winblend=' .. vim.g.lazygit_floating_window_winblend) + + -- use autocommand to ensure that the border_buffer closes at the same time as the main buffer + local cmd = [[autocmd WinLeave silent! execute 'hide']] + vim.cmd(cmd) + cmd = [[autocmd WinLeave silent! execute 'silent bdelete! %s']] + vim.cmd(cmd:format(border_buffer)) +end + +return { + open_floating_window = open_floating_window, +} diff --git a/lua/telescope/_extensions/lazygit_telescope.lua b/lua/telescope/_extensions/lazygit_telescope.lua index f913e3d..2103a2a 100644 --- a/lua/telescope/_extensions/lazygit_telescope.lua +++ b/lua/telescope/_extensions/lazygit_telescope.lua @@ -3,7 +3,7 @@ local finders = require("telescope.finders") local action_set = require("telescope.actions.set") local action_state = require("telescope.actions.state") local conf = require("telescope.config").values -local lazygit = require("lazygit") +local lazygit_utils = require("lazygit.utils") local function open_lazygit(prompt_buf) @@ -31,7 +31,7 @@ local lazygit_repos = function(opts) } local repos = {} - for _, v in pairs(lazygit.lazygit_visited_git_repos) do + for _, v in pairs(lazygit_utils.lazygit_visited_git_repos) do local index = #repos + 1 -- retrieve git repo name local entry =