From fcc03e202044797263c9ed4ac79b1e8b3b263d13 Mon Sep 17 00:00:00 2001 From: moyiz <8603313+moyiz@users.noreply.github.com> Date: Sun, 9 Mar 2025 19:36:12 +0200 Subject: [PATCH] feat: allow disabling builtin UI in favor of vim.notify --- README.md | 2 ++ lua/git-dev/init.lua | 64 +++++++++++++++++++++++++----------------- lua/git-dev/ui.lua | 2 ++ lua/git-dev/uistub.lua | 52 ++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 lua/git-dev/uistub.lua diff --git a/README.md b/README.md index ab7771d..2908b38 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,8 @@ M.config = { }, -- UI configuration. ui = { + -- Whether to enable builtin output buffer or fallback to `vim.notify`. + enabled = true, -- Auto-close window after repository was opened. auto_close = true, -- Delay window closing. diff --git a/lua/git-dev/init.lua b/lua/git-dev/init.lua index 8762982..6c5edfe 100644 --- a/lua/git-dev/init.lua +++ b/lua/git-dev/init.lua @@ -51,6 +51,8 @@ M.config = { }, -- UI configuration. ui = { + -- Whether to enable builtin output buffer or fallback to `vim.notify`. + enabled = true, -- Auto-close window after repository was opened. auto_close = true, -- Delay window closing. @@ -162,6 +164,7 @@ M.open = function(repo, ref, opts) local config = vim.tbl_deep_extend("force", M.config, opts or {}) local ui = M.ui ui:show() + ui:print("Opening " .. repo):emit() local gitcmd = require("git-dev.gitcmd"):init { cmd = config.git.command, @@ -189,7 +192,7 @@ M.open = function(repo, ref, opts) or parsed_repo.branch if not branch and parsed_repo.full_blob then - ui:print "Could not detect branch / tag / commit in given URI." + ui:print "Could not detect a ref in given URI, falling back to default." end local repo_dir = config.repositories_dir @@ -200,7 +203,7 @@ M.open = function(repo, ref, opts) ui:print(parsed_repo) end - local post_action_callback = vim.schedule_wrap(function() + local post_action_callback = function() if vim.fn.isdirectory(repo_dir) == 0 then ui:print( "Repository not found at: " .. parsed_repo.repo_url .. ", aborting..." @@ -279,6 +282,10 @@ M.open = function(repo, ref, opts) M.history:add(repo, ref, opts, parsed_repo) ui:print "Done." + end + + local clone_callback = vim.schedule_wrap(function() + pcall(post_action_callback) if config.ui.auto_close then ui:close(config.ui.close_after_ms) end @@ -288,7 +295,7 @@ M.open = function(repo, ref, opts) ui:print "Repository directory exists, refreshing..." gitcmd:refresh( { repo_dir = repo_dir, extra_args = config.git.fetch_args }, - post_action_callback + clone_callback ) else -- Fresh clone @@ -298,7 +305,7 @@ M.open = function(repo, ref, opts) repo_dir = repo_dir, branch = parsed_repo.branch, extra_args = config.git.clone_args, - }, post_action_callback) + }, clone_callback) end end @@ -462,26 +469,37 @@ M.setup = function(opts) vim.fn.mkdir(vim.fs.dirname(M.config.history.path), "p") -- Prepare UI - local win_config - if M.config.ui.mode == "split" then - local v = vim.version() - -- `nvim_open_win` supports splitting in Neovim>=0.10.0 - -- `ge` was added in 0.10.0. - if vim.version.lt({ v.major, v.minor, v.patch }, { 0, 10, 0 }) == false then - win_config = M.config.ui.split_win_config + if M.config.ui.enabled then + local win_config + if M.config.ui.mode == "split" then + local v = vim.version() + -- `nvim_open_win` supports splitting in Neovim>=0.10.0 + -- `ge` was added in 0.10.0. + if + vim.version.lt({ v.major, v.minor, v.patch }, { 0, 10, 0 }) == false + then + win_config = M.config.ui.split_win_config + else + vim.notify( + "Split mode is not supported in Neovim < 0.10.0. " + .. "Falling back to floating mode." + ) + win_config = M.config.ui.floating_win_config + end else - vim.notify( - "Split mode is not supported in Neovim < 0.10.0. " - .. "Falling back to floating mode." - ) win_config = M.config.ui.floating_win_config end + M.ui = require("git-dev.ui"):init { + win_config = win_config, + } + vim.api.nvim_create_user_command("GitDevToggleUI", function(_) + require("git-dev").toggle_ui() + end, { + desc = "Toggle output window.", + }) else - win_config = M.config.ui.floating_win_config + M.ui = require("git-dev.uistub"):init {} end - M.ui = require("git-dev.ui"):init { - win_config = win_config, - } -- Initialize store ---@type GitDevHistory @@ -496,7 +514,7 @@ M.setup = function(opts) xdg.enable(M.config.xdg_handler) vim.api.nvim_create_user_command("GitDevXDGHandle", function(cmd_args) local uri = U.parse_cmd_args(cmd_args) - M.ui:print(xdg.handle(uri)) + xdg.handle(uri) end, { desc = "xdg-open handler for git-dev.nvim URIs.", nargs = "*", @@ -541,12 +559,6 @@ M.setup = function(opts) complete = complete_from_session, }) - vim.api.nvim_create_user_command("GitDevToggleUI", function(_) - require("git-dev").toggle_ui() - end, { - desc = "Toggle output window.", - }) - vim.api.nvim_create_user_command( "GitDevRecents", "Telescope git_dev recents", diff --git a/lua/git-dev/ui.lua b/lua/git-dev/ui.lua index 3983842..b67f395 100644 --- a/lua/git-dev/ui.lua +++ b/lua/git-dev/ui.lua @@ -111,6 +111,8 @@ function UI:print(...) return self end +function UI:emit() end + ---Closes window after given delay. ---@param delay? integer Time to wait before closing the window in ms. function UI:close(delay) diff --git a/lua/git-dev/uistub.lua b/lua/git-dev/uistub.lua new file mode 100644 index 0000000..6dbcb96 --- /dev/null +++ b/lua/git-dev/uistub.lua @@ -0,0 +1,52 @@ +---A UI stub, implementing the same API as UI class. +---It concatenates with each `print` invocation, and displays text once closed +---with a single call to `vim.notify`. +---@class UIStub +local UIStub = {} + +function UIStub:init(o) + setmetatable(o or {}, self) + self.__index = self + return o +end + +function UIStub:show(_) + return self +end + +function UIStub:redraw() end +function UIStub:toggle(_) end + +local st = "" + +function UIStub:print(...) + -- Transform arguments into a space delimited string and append '\n'. + local args = { ... } + local s = "" + for i = 1, #args do + if type(args[i]) == "string" then + s = s .. " " .. args[i] + else + s = s .. " " .. vim.inspect(args[i]) + end + end + s = s .. "\n" + vim.schedule(function() + st = st .. s + end) + return self +end + +function UIStub:emit(_) + -- Schedule the write. + vim.schedule(function() + vim.notify(st) + st = "" + end) +end + +function UIStub:close() + self:emit() +end + +return UIStub