Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,33 @@ This works for just about everything that has an object-ID in git, and if you fi

See the built-in documentation for a comprehensive list of highlight groups. If your theme doesn't style a particular group, we'll try our best to do a nice job.

## Hooks

Neogit supports hooks for the following actions:

| Hook | Description | Hook Data |
| -------------------- | ------------------------------------------------ | -------------------------------------------------------------------- |
| `PreStatusRefreshed` | Before a status is reloaded | `{}` |
| `PreCommit` | Before a commit has been created | `{}` |
| `PrePush` | Before a push is made | `{}` |
| `PrePull` | Before a pull is made | `{}` |
| `PreFetch` | Before a fetch is made | `{}` |
| `PreBranchCreate` | Before a branch is created, starting from `base` | `{ branch_name: string, base: string? }` |
| `PreBranchDelete` | Before a branch is deleted | `{ branch_name: string }` |
| `PreBranchCheckout` | Before a branch is checked out | `{ branch_name: string }` |
| `PreBranchReset` | Before a branch is reset to a commit/branch | `{ branch_name: string, resetting_to: string }` |
| `PreBranchRename` | Before a branch is renamed | `{ branch_name: string, new_name: string }` |
| `PreRebase` | Before a rebase is started | `{ commit: string }` |
| `PreReset` | Before a branch is reset to a certain commit | `{ commit: string, mode: "soft"\|"mixed"\|"hard"\|"keep"\|"index" }` |
| `PreTagCreate` | Before a tag is placed on a certain commit | `{ name: string, ref: string }` |
| `PreTagDelete` | Before one or more tags are removed | `{ names: string[] }` |
| `PreCherryPick` | Before one or more commits are cherry-picked | `{ commits: string[] }` |
| `PreMerge` | Before a merge is started | `{ branch: string, args = string[] }` |
| `PreStash` | Before a stash is made | `{}` |
| `PreRefsRefreshed` | Before refs are refreshed | `{}` |
| `PreDiffLoaded` | Before a diff is loaded | `{?}` |
| `PreBisect` | Before a bisect is started | `{ type: string }` |
| `PreWorktreeCreate` | Before a worktree is created | `{ ref: string, path: string }` |

## Events

Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/buffers/refs_view/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local config = require("neogit.config")
local ui = require("neogit.buffers.refs_view.ui")
local popups = require("neogit.popups")
local status_maps = require("neogit.config").get_reversed_status_maps()
local hook = require("neogit.lib.hook")
local mapping = config.get_reversed_refs_view_maps()
local CommitViewBuffer = require("neogit.buffers.commit_view")
local Watcher = require("neogit.watcher")
Expand Down Expand Up @@ -327,6 +328,7 @@ function M:open()
end

function M:redraw()
hook.run("PreRefsRefreshed")
logger.debug("[REFS] Beginning redraw")
self.buffer.ui:render(unpack(ui.RefsView(git.refs.list_parsed(), self.head)))

Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/buffers/status/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local Watcher = require("neogit.watcher")
local a = require("plenary.async")
local logger = require("neogit.logger") -- TODO: Add logging
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

---@class Semaphore
---@field permits number
Expand Down Expand Up @@ -319,6 +320,7 @@ function M:refresh(partial, reason)
source = "status",
partial = partial,
callback = function()
hook.run("PreStatusRefreshed")
self:redraw(cursor, view)
event.send("StatusRefreshed")
logger.info("[STATUS] Refresh complete")
Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/buffers/status/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local config = require("neogit.config")
local a = require("plenary.async")
local state = require("neogit.lib.state")
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

local col = Ui.col
local row = Ui.row
Expand Down Expand Up @@ -238,6 +239,7 @@ local SectionItemFile = function(section, config)
end
end

hook.run("PreDiffLoaded", { diff = diff }) -- TODO: what should the data be?
ui.buf:with_locked_viewport(function()
this:append(DiffHunks(diff))
ui:update()
Expand Down
25 changes: 25 additions & 0 deletions lua/neogit/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,29 @@ end
---| "author-date"
---| "date"

---@alias NeogitHook
---| "PreStatusRefreshed"
---| "PreCommit"
---| "PrePush"
---| "PrePull"
---| "PreFetch"
---| "PreBranchCreate"
---| "PreBranchDelete"
---| "PreBranchCheckout"
---| "PreBranchReset"
---| "PreBranchRename"
---| "PreRebase"
---| "PreReset"
---| "PreTagCreate"
---| "PreTagDelete"
---| "PreCherryPick"
---| "PreMerge"
---| "PreStash"
---| "PreRefsRefreshed"
---| "PreDiffLoaded"
---| "PreBisect"
---| "PreWorktreeCreate"

---@class NeogitConfigStatusOptions
---@field recent_commit_count? integer The number of recent commits to display
---@field mode_padding? integer The amount of padding to add to the right of the mode column
Expand Down Expand Up @@ -401,6 +424,7 @@ end
---@field treesitter_diff_highlight? boolean Apply syntax highlighting to diff hunks via treesitter
---@field word_diff_highlight? boolean Apply word-diff highlighting to diff hunks
---@field builders? { [string]: fun(builder: PopupBuilder) }
---@field hooks? { [NeogitHook]: fun(data: table?) }

---Returns the default Neogit configuration
---@return NeogitConfig
Expand All @@ -419,6 +443,7 @@ function M.get_default_values()
log_date_format = nil,
log_pager = nil,
process_spinner = false,
hooks = {},
filewatcher = {
enabled = true,
},
Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/lib/git/bisect.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local git = require("neogit.lib.git")
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

---@class NeogitGitBisect
local M = {}
Expand All @@ -25,6 +26,7 @@ end
---@param good_revision string
---@param args? table
function M.start(bad_revision, good_revision, args)
hook.run("PreBisect", { type = "start" })
local result =
git.cli.bisect.args("start").arg_list(args).args(bad_revision, good_revision).call { long = true }

Expand Down
3 changes: 3 additions & 0 deletions lua/neogit/lib/git/cherry_pick.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local notification = require("neogit.lib.notification")
local util = require("neogit.lib.util")
local client = require("neogit.client")
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

---@class NeogitGitCherryPick
local M = {}
Expand All @@ -13,6 +14,7 @@ local M = {}
function M.pick(commits, args)
local cmd = git.cli["cherry-pick"].arg_list(util.merge(args, commits))

hook.run("PreCherryPick", { commits = commits })
local result
if vim.tbl_contains(args, "--edit") then
result = cmd.env(client.get_envs_git_editor()).call { pty = true }
Expand All @@ -36,6 +38,7 @@ function M.apply(commits, args)
end
end)

hook.run("PreCherryPick", { commits = commits })
local result = git.cli["cherry-pick"].no_commit.arg_list(util.merge(args, commits)).call { await = true }
if result:failure() then
notification.error("Cherry Pick failed. Resolve conflicts before continuing")
Expand Down
3 changes: 3 additions & 0 deletions lua/neogit/lib/git/fetch.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local git = require("neogit.lib.git")
local hook = require("neogit.lib.hook")

---@class NeogitGitFetch
local M = {}
Expand All @@ -9,13 +10,15 @@ local M = {}
---@param args string[]
---@return ProcessResult
function M.fetch_interactive(remote, branch, args)
hook.run("PreFetch")
return git.cli.fetch.args(remote or "", branch or "").arg_list(args).call { pty = true }
end

---@param remote string
---@param branch string
---@return ProcessResult
function M.fetch(remote, branch)
hook.run("PreFetch")
return git.cli.fetch.args(remote, branch).call { ignore_error = true }
end

Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/lib/git/merge.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local client = require("neogit.client")
local git = require("neogit.lib.git")
local notification = require("neogit.lib.notification")
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

---@class NeogitGitMerge
local M = {}
Expand All @@ -11,6 +12,7 @@ local function merge_command(cmd)
end

function M.merge(branch, args)
hook.run("PreMerge", { branch = branch, args = args })
local result = merge_command(git.cli.merge.args(branch).arg_list(args))
if result:failure() then
notification.error("Merging failed. Resolve conflicts before continuing")
Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/lib/git/pull.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
local git = require("neogit.lib.git")
local util = require("neogit.lib.util")
local hook = require("neogit.lib.hook")

---@class NeogitGitPull
local M = {}

function M.pull_interactive(remote, branch, args)
local client = require("neogit.client")
local envs = client.get_envs_git_editor()
hook.run("PrePull")
return git.cli.pull.env(envs).args(remote or "", branch or "").arg_list(args).call { pty = true }
end

Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/lib/git/push.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local git = require("neogit.lib.git")
local util = require("neogit.lib.util")
local hook = require("neogit.lib.hook")

---@class NeogitGitPush
local M = {}
Expand All @@ -10,6 +11,7 @@ local M = {}
---@param args string[]
---@return ProcessResult
function M.push_interactive(remote, branch, args)
hook.run("PrePush")
return git.cli.push.args(remote or "", branch or "").arg_list(args).call { pty = true }
end

Expand Down
8 changes: 8 additions & 0 deletions lua/neogit/lib/git/rebase.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local git = require("neogit.lib.git")
local client = require("neogit.client")
local notification = require("neogit.lib.notification")
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

---@class NeogitGitRebase
local M = {}
Expand All @@ -16,6 +17,7 @@ end
---@param args? string[] list of arguments to pass to git rebase
---@return ProcessResult
function M.instantly(commit, args)
hook.run("PreRebase", { commit = commit })
local result = git.cli.rebase.interactive.autostash.autosquash
.commit(commit)
.env({ GIT_SEQUENCE_EDITOR = ":", GIT_EDITOR = ":" })
Expand All @@ -36,6 +38,7 @@ function M.rebase_interactive(commit, args)
commit = ""
end

hook.run("PreRebase", { commit = commit })
local result = rebase_command(git.cli.rebase.interactive.arg_list(args).args(commit))
if result:failure() then
if result.stdout[1]:match("^hint: Waiting for your editor to close the file%.%.%. error") then
Expand All @@ -52,6 +55,7 @@ function M.rebase_interactive(commit, args)
end

function M.onto_branch(branch, args)
hook.run("PreRebase", { commit = branch })
local result = rebase_command(git.cli.rebase.args(branch).arg_list(args))
if result:failure() then
notification.error("Rebasing failed. Resolve conflicts before continuing")
Expand All @@ -67,6 +71,7 @@ function M.onto(start, newbase, args)
start = ""
end

hook.run("PreRebase", { commit = newbase })
local result = rebase_command(git.cli.rebase.onto.args(newbase, start).arg_list(args))
if result:failure() then
notification.error("Rebasing failed. Resolve conflicts before continuing")
Expand All @@ -80,6 +85,7 @@ end
---@param commit string rev name of the commit to reword
---@return ProcessResult|nil
function M.reword(commit)
hook.run("PreCommit")
local message = table.concat(git.log.full_message(commit), "\n")
local status = client.wrap(
git.cli.commit.only.allow_empty.edit.with_message(("amend! %s\n\n%s"):format(commit, message)),
Expand All @@ -99,6 +105,7 @@ end
function M.modify(commit)
local short_commit = git.rev_parse.abbreviate_commit(commit)
local editor = "nvim -c '%s/^pick \\(" .. short_commit .. ".*\\)/edit \\1/' -c 'wq'"
hook.run("PreRebase", { commit = commit })
local result = git.cli.rebase.interactive.autosquash.autostash
.commit(commit)
.in_pty(true)
Expand All @@ -113,6 +120,7 @@ end
function M.drop(commit)
local short_commit = git.rev_parse.abbreviate_commit(commit)
local editor = "nvim -c '%s/^pick \\(" .. short_commit .. ".*\\)/drop \\1/' -c 'wq'"
hook.run("PreRebase", { commit = commit })
local result = git.cli.rebase.interactive.autosquash.autostash
.commit(commit)
.in_pty(true)
Expand Down
8 changes: 8 additions & 0 deletions lua/neogit/lib/git/stash.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local input = require("neogit.lib.input")
local util = require("neogit.lib.util")
local config = require("neogit.config")
local event = require("neogit.lib.event")
local hook = require("neogit.lib.hook")

---@class NeogitGitStash
local M = {}
Expand All @@ -18,28 +19,33 @@ end

---@param args string[]
function M.stash_all(args)
hook.run("PreStash")
local result = git.cli.stash.push.files(".").arg_list(args).call()
event.send("Stash", { success = result:success() })
end

function M.stash_index()
hook.run("PreStash")
local result = git.cli.stash.staged.call()
event.send("Stash", { success = result:success() })
end

function M.stash_keep_index()
hook.run("PreStash")
local result = git.cli.stash.keep_index.files(".").call()
event.send("Stash", { success = result:success() })
end

---@param args string[]
---@param files string[]
function M.push(args, files)
hook.run("PreStash")
local result = git.cli.stash.push.arg_list(args).files(unpack(files)).call()
event.send("Stash", { success = result:success() })
end

function M.pop(stash)
hook.run("PreStash")
local result = git.cli.stash.apply.index.args(stash).call()

if result:success() then
Expand All @@ -52,6 +58,7 @@ function M.pop(stash)
end

function M.apply(stash)
hook.run("PreStash")
local result = git.cli.stash.apply.index.args(stash).call()

if result:failure() then
Expand All @@ -62,6 +69,7 @@ function M.apply(stash)
end

function M.drop(stash)
hook.run("PreStash")
local result = git.cli.stash.drop.args(stash).call()
event.send("Stash", { success = result:success() })
end
Expand Down
2 changes: 2 additions & 0 deletions lua/neogit/lib/git/worktree.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local git = require("neogit.lib.git")
local util = require("neogit.lib.util")
local Path = require("plenary.path")
local hook = require("neogit.lib.hook")

---@class NeogitGitWorktree
local M = {}
Expand All @@ -10,6 +11,7 @@ local M = {}
---@param path string absolute path
---@return boolean, string
function M.add(ref, path, params)
hook.run("PreWorktreeCreate", { ref = ref, path = path })
local result = git.cli.worktree.add.arg_list(params or {}).args(path, ref).call()
if result:success() then
return true, ""
Expand Down
15 changes: 15 additions & 0 deletions lua/neogit/lib/hook.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
local M = {}

local config = require("neogit.config")

---@param name NeogitHook
---@param data table?
function M.run(name, data)
assert(name, "hook must have name")

if config.values.hooks[name] then
config.values.hooks[name](data)
end
end

return M
Loading