From 5ddd3dcb4e4c176db5093a6d4f364d22b82fd675 Mon Sep 17 00:00:00 2001 From: twio142 <64556708+twio142@users.noreply.github.com> Date: Tue, 21 Oct 2025 01:38:15 +0200 Subject: [PATCH 1/4] feat(repo): allow making ephemeral repositories persistent Users can now make a repository, initially opened as ephemeral, persistent. This prevents the repository from being deleted when Neovim exits. A new `:GitDevPersist` user command has been introduced for this purpose. This is implemented by: - Removing the "VimLeavePre" autocmd responsible for cleanup. - Updating the session state to reflect the change. - Persisting this choice in the history by updating the record's options, ensuring the repository is opened as non-ephemeral in the future. - Linking the active session context to its history record via a new `history_key`. --- lua/git-dev/history.lua | 15 ++++++++++++++- lua/git-dev/init.lua | 35 ++++++++++++++++++++++++++++++++++- lua/git-dev/session.lua | 1 + 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lua/git-dev/history.lua b/lua/git-dev/history.lua index b588883..96ba1bb 100644 --- a/lua/git-dev/history.lua +++ b/lua/git-dev/history.lua @@ -22,14 +22,17 @@ end ---@field ref table ---@field opts table +---@return string @key function History:add(repo, ref, opts, parsed_repo) ---@type GitDevHistoryRecord local record = { args = { repo = repo, ref = ref, opts = opts }, parsed = parsed_repo, } - self._store:set(self:key(record), record) + local key = self:key(record) + self._store:set(key, record) self:trim() + return key end function History:get() @@ -41,6 +44,16 @@ function History:key(record) return record.args.repo .. "|" .. vim.json.encode(record.args.ref) end +function History:update_opts(key, opts) + local record = self._store:get(key) + if not record then + return + end + record.args.opts = + vim.tbl_deep_extend("force", record.args.opts or {}, opts or {}) + self._store:set(key, record) +end + ---Purges all history records. function History:purge() self._store:purge() diff --git a/lua/git-dev/init.lua b/lua/git-dev/init.lua index 9f0b9b5..3983f1c 100644 --- a/lua/git-dev/init.lua +++ b/lua/git-dev/init.lua @@ -280,7 +280,8 @@ M.open = function(repo, ref, opts) ) -- Add this call to history store. - M.history:add(repo, ref, opts, parsed_repo) + local history_key = M.history:add(repo, ref, opts, parsed_repo) + repo_ctx.history_key = history_key ui:print "Done." end @@ -366,6 +367,29 @@ M.close_buffers = function(repo, ref) return deleted end +---Makes a repository persistent. +---It will remove the autocmd that deletes the repository directory when +---nvim exits. +---If no repository is given, assume it is related to current buffer. +---@param repo? string +---@param ref? GitRef +M.persist = function(repo, ref) + local repo_ctx = get_session_repo(repo, ref) + if not repo_ctx then + vim.notify "Could not determine repository session." + return + end + if repo_ctx.ephemeral_autocmd_id then + vim.api.nvim_del_autocmd(repo_ctx.ephemeral_autocmd_id) + repo_ctx.ephemeral_autocmd_id = nil + M.session:set_repo(repo_ctx) + M.history:update_opts(repo_ctx.history_key, { ephemeral = false }) + vim.notify("Repository is now persistent: " .. repo_ctx.repo) + else + vim.notify("Repository is already persistent: " .. repo_ctx.repo) + end +end + ---Cleans a repository. It will close all associated buffers and delete the ---repository directory if it was ephemeral. ---If no repository is given, assume it is related to current buffer. @@ -541,6 +565,15 @@ M.setup = function(opts) .. "with custom paths.", }) + vim.api.nvim_create_user_command("GitDevPersist", function(cmd_args) + local repo, ref = U.parse_cmd_args(cmd_args) + require("git-dev").persist(repo, ref) + end, { + desc = "Make repository persistent", + nargs = "*", + complete = complete_from_session, + }) + vim.api.nvim_create_user_command("GitDevCloseBuffers", function(cmd_args) local repo, ref = U.parse_cmd_args(cmd_args) require("git-dev").close_buffers(repo, ref) diff --git a/lua/git-dev/session.lua b/lua/git-dev/session.lua index b37ab22..757a200 100644 --- a/lua/git-dev/session.lua +++ b/lua/git-dev/session.lua @@ -5,6 +5,7 @@ ---@field ephemeral_autocmd_id? number ---@field read_only_autocmd_id? number ---@field set_session_autocmd_id? number +---@field history_key string ---@alias GitDevSessionRepos table From e0d763a851441c8ffa1d178f090014dd2d33b409 Mon Sep 17 00:00:00 2001 From: twio142 <64556708+twio142@users.noreply.github.com> Date: Tue, 21 Oct 2025 01:49:13 +0200 Subject: [PATCH 2/4] docs: document the new `GitDevPersist` command --- README.md | 17 +++++++++++++++++ doc/git-dev.txt | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/README.md b/README.md index 2908b38..dbe080e 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ Lazier (documentation will not be available until first use): "GitDevClean", "GitDevCleanAll", "GitDevCloseBuffers", + "GitDevPersist", "GitDevOpen", "GitDevRecents", "GitDevToggleUI", @@ -167,6 +168,22 @@ Supports auto-completion. - `repo` - Same as `open`. - `ref` - Same as `open`. +### :floppy_disk: Persist Repository +API: `require("git-dev").persist(repo, ref)` + +Command: `GitDevPersist` + +Make an ephemeral repository persistent. It will not be deleted when Neovim +exits. +If `repo` is omitted, try to determine repository from current buffer. +If `ref` is omitted, assume it is related to current buffer if an explicit +repository was given. +Supports auto-completion. + +#### Parameters +- `repo` - Same as `open`. +- `ref` - Same as `open`. + ### :toothbrush: Clean API: `require("git-dev").clean(repo, ref, opts)` diff --git a/doc/git-dev.txt b/doc/git-dev.txt index e750f23..7157937 100644 --- a/doc/git-dev.txt +++ b/doc/git-dev.txt @@ -92,6 +92,24 @@ PARAMETERS ~ - `ref` - Same as `open`. +PERSIST *git-dev-usage-persist* + +API: `require("git-dev").persist(repo, ref)` + +Command: `GitDevPersist` + +Make an ephemeral repository persistent. It will not be deleted when Neovim +exits. If `repo` is omitted, try to determine repository from current buffer. If +`ref` is omitted, assume it is related to current buffer if an explicit +repository was given. Supports auto-completion. + + +PARAMETERS ~ + +- `repo` - Same as `open`. +- `ref` - Same as `open`. + + CLEAN *git-dev-usage-clean* API: `require("git-dev").clean(repo, ref, opts)` From 7df197fb80c4ecac6499e67d6382dde0a5901cbf Mon Sep 17 00:00:00 2001 From: twio142 <64556708+twio142@users.noreply.github.com> Date: Thu, 23 Oct 2025 14:38:08 +0200 Subject: [PATCH 3/4] fixup! feat(repo): allow making ephemeral repositories persistent --- lua/git-dev/history.lua | 2 +- lua/git-dev/init.lua | 7 ++++--- lua/git-dev/session.lua | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lua/git-dev/history.lua b/lua/git-dev/history.lua index 96ba1bb..77ec54d 100644 --- a/lua/git-dev/history.lua +++ b/lua/git-dev/history.lua @@ -22,7 +22,7 @@ end ---@field ref table ---@field opts table ----@return string @key +---@return Key function History:add(repo, ref, opts, parsed_repo) ---@type GitDevHistoryRecord local record = { diff --git a/lua/git-dev/init.lua b/lua/git-dev/init.lua index 3983f1c..c410c5e 100644 --- a/lua/git-dev/init.lua +++ b/lua/git-dev/init.lua @@ -280,8 +280,7 @@ M.open = function(repo, ref, opts) ) -- Add this call to history store. - local history_key = M.history:add(repo, ref, opts, parsed_repo) - repo_ctx.history_key = history_key + repo_ctx.history_key = M.history:add(repo, ref, opts, parsed_repo) ui:print "Done." end @@ -383,7 +382,9 @@ M.persist = function(repo, ref) vim.api.nvim_del_autocmd(repo_ctx.ephemeral_autocmd_id) repo_ctx.ephemeral_autocmd_id = nil M.session:set_repo(repo_ctx) - M.history:update_opts(repo_ctx.history_key, { ephemeral = false }) + if repo_ctx.history_key then + M.history:update_opts(repo_ctx.history_key, { ephemeral = false }) + end vim.notify("Repository is now persistent: " .. repo_ctx.repo) else vim.notify("Repository is already persistent: " .. repo_ctx.repo) diff --git a/lua/git-dev/session.lua b/lua/git-dev/session.lua index 757a200..29913d0 100644 --- a/lua/git-dev/session.lua +++ b/lua/git-dev/session.lua @@ -5,7 +5,7 @@ ---@field ephemeral_autocmd_id? number ---@field read_only_autocmd_id? number ---@field set_session_autocmd_id? number ----@field history_key string +---@field history_key? Key ---@alias GitDevSessionRepos table From c1700bad18ec19e6d5932d664d8699e727d0ba7e Mon Sep 17 00:00:00 2001 From: twio142 <64556708+twio142@users.noreply.github.com> Date: Tue, 21 Oct 2025 01:49:13 +0200 Subject: [PATCH 4/4] fixup! docs: document the new `GitDevPersist` command --- README.md | 2 +- doc/git-dev.txt | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/README.md b/README.md index dbe080e..4687c91 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,8 @@ Lazier (documentation will not be available until first use): "GitDevClean", "GitDevCleanAll", "GitDevCloseBuffers", - "GitDevPersist", "GitDevOpen", + "GitDevPersist", "GitDevRecents", "GitDevToggleUI", "GitDevXDGHandle", diff --git a/doc/git-dev.txt b/doc/git-dev.txt index 7157937..e750f23 100644 --- a/doc/git-dev.txt +++ b/doc/git-dev.txt @@ -92,24 +92,6 @@ PARAMETERS ~ - `ref` - Same as `open`. -PERSIST *git-dev-usage-persist* - -API: `require("git-dev").persist(repo, ref)` - -Command: `GitDevPersist` - -Make an ephemeral repository persistent. It will not be deleted when Neovim -exits. If `repo` is omitted, try to determine repository from current buffer. If -`ref` is omitted, assume it is related to current buffer if an explicit -repository was given. Supports auto-completion. - - -PARAMETERS ~ - -- `repo` - Same as `open`. -- `ref` - Same as `open`. - - CLEAN *git-dev-usage-clean* API: `require("git-dev").clean(repo, ref, opts)`