claude-pre-edit-1752105425
This commit is contained in:
parent
2a71451ca3
commit
cb524a6c14
|
@ -12,3 +12,6 @@ lazy-lock.json
|
||||||
|
|
||||||
# Development tracking
|
# Development tracking
|
||||||
.agent-work
|
.agent-work
|
||||||
|
|
||||||
|
# Claude Code hooks
|
||||||
|
.claude/
|
||||||
|
|
|
@ -17,3 +17,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
|
This line was added by Claude!
|
||||||
|
Testing hooks - this should trigger pre and post hooks!
|
||||||
|
Hooks are now properly installed!
|
||||||
|
|
|
@ -9,5 +9,6 @@ return {
|
||||||
dependencies = {
|
dependencies = {
|
||||||
'nvim-telescope/telescope.nvim', -- For agent picker
|
'nvim-telescope/telescope.nvim', -- For agent picker
|
||||||
'tpope/vim-fugitive', -- Already installed, for diffs
|
'tpope/vim-fugitive', -- Already installed, for diffs
|
||||||
|
'sindrets/diffview.nvim', -- For advanced diff viewing
|
||||||
},
|
},
|
||||||
}
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
-- Diff review system for nvim-claude using diffview.nvim
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- State tracking
|
||||||
|
M.current_review = nil
|
||||||
|
|
||||||
|
function M.setup()
|
||||||
|
-- Set up keybindings
|
||||||
|
M.setup_keybindings()
|
||||||
|
|
||||||
|
vim.notify('Diff review system loaded (using diffview.nvim)', vim.log.levels.DEBUG)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle Claude edit completion
|
||||||
|
function M.handle_claude_edit(stash_ref, pre_edit_ref)
|
||||||
|
if not stash_ref then
|
||||||
|
vim.notify('No stash reference provided for diff review', vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.notify('Processing Claude edit with stash: ' .. stash_ref, vim.log.levels.INFO)
|
||||||
|
|
||||||
|
-- Get list of changed files
|
||||||
|
local changed_files = M.get_changed_files(stash_ref)
|
||||||
|
if not changed_files or #changed_files == 0 then
|
||||||
|
vim.notify('No changes detected from Claude edit', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Initialize review session
|
||||||
|
M.current_review = {
|
||||||
|
stash_ref = stash_ref,
|
||||||
|
pre_edit_ref = pre_edit_ref, -- Store the pre-edit commit reference
|
||||||
|
timestamp = os.time(),
|
||||||
|
changed_files = changed_files,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Notify user about changes
|
||||||
|
vim.notify(string.format(
|
||||||
|
'Claude made changes to %d file(s): %s',
|
||||||
|
#changed_files,
|
||||||
|
table.concat(changed_files, ', ')
|
||||||
|
), vim.log.levels.INFO)
|
||||||
|
|
||||||
|
vim.notify('Use <leader>dd to open diffview, <leader>df for fugitive, <leader>dc to clear review', vim.log.levels.INFO)
|
||||||
|
|
||||||
|
-- Automatically open diffview
|
||||||
|
M.open_diffview()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get list of files changed in the stash
|
||||||
|
function M.get_changed_files(stash_ref)
|
||||||
|
local utils = require('nvim-claude.utils')
|
||||||
|
local cmd = string.format('git stash show %s --name-only', stash_ref)
|
||||||
|
local result = utils.exec(cmd)
|
||||||
|
|
||||||
|
if not result or result == '' then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local files = {}
|
||||||
|
for line in result:gmatch('[^\n]+') do
|
||||||
|
if line ~= '' then
|
||||||
|
table.insert(files, line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return files
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set up keybindings for diff review
|
||||||
|
function M.setup_keybindings()
|
||||||
|
-- Review actions
|
||||||
|
vim.keymap.set('n', '<leader>dd', M.open_diffview, { desc = 'Open Claude diff in diffview' })
|
||||||
|
vim.keymap.set('n', '<leader>df', M.open_fugitive, { desc = 'Open Claude diff in fugitive' })
|
||||||
|
vim.keymap.set('n', '<leader>dc', M.clear_review, { desc = 'Clear Claude review session' })
|
||||||
|
vim.keymap.set('n', '<leader>dl', M.list_changes, { desc = 'List Claude changed files' })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Open diffview for current review
|
||||||
|
function M.open_diffview()
|
||||||
|
if not M.current_review then
|
||||||
|
vim.notify('No active review session', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if diffview is available
|
||||||
|
local ok, diffview = pcall(require, 'diffview')
|
||||||
|
if not ok then
|
||||||
|
vim.notify('diffview.nvim not available, falling back to fugitive', vim.log.levels.WARN)
|
||||||
|
M.open_fugitive()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Use the pre-edit reference if available
|
||||||
|
if M.current_review.pre_edit_ref then
|
||||||
|
local cmd = 'DiffviewOpen ' .. M.current_review.pre_edit_ref
|
||||||
|
vim.notify('Opening diffview with pre-edit commit: ' .. cmd, vim.log.levels.INFO)
|
||||||
|
vim.cmd(cmd)
|
||||||
|
else
|
||||||
|
-- Fallback to comparing stash with its parent
|
||||||
|
vim.notify('No pre-edit commit found, falling back to stash comparison', vim.log.levels.WARN)
|
||||||
|
local cmd = string.format('DiffviewOpen %s^..%s', M.current_review.stash_ref, M.current_review.stash_ref)
|
||||||
|
vim.notify('Opening diffview: ' .. cmd, vim.log.levels.INFO)
|
||||||
|
vim.cmd(cmd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Open fugitive diff (fallback)
|
||||||
|
function M.open_fugitive()
|
||||||
|
if not M.current_review then
|
||||||
|
vim.notify('No active review session', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Use fugitive to show diff
|
||||||
|
local cmd = 'Gdiffsplit ' .. M.current_review.stash_ref
|
||||||
|
vim.notify('Opening fugitive: ' .. cmd, vim.log.levels.INFO)
|
||||||
|
vim.cmd(cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- List changed files
|
||||||
|
function M.list_changes()
|
||||||
|
if not M.current_review then
|
||||||
|
vim.notify('No active review session', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local files = M.current_review.changed_files
|
||||||
|
if #files == 0 then
|
||||||
|
vim.notify('No changes found', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create a telescope picker if available, otherwise just notify
|
||||||
|
local ok, telescope = pcall(require, 'telescope.pickers')
|
||||||
|
if ok then
|
||||||
|
M.telescope_changed_files()
|
||||||
|
else
|
||||||
|
vim.notify('Changed files:', vim.log.levels.INFO)
|
||||||
|
for i, file in ipairs(files) do
|
||||||
|
vim.notify(string.format(' %d. %s', i, file), vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Telescope picker for changed files
|
||||||
|
function M.telescope_changed_files()
|
||||||
|
local pickers = require('telescope.pickers')
|
||||||
|
local finders = require('telescope.finders')
|
||||||
|
local conf = require('telescope.config').values
|
||||||
|
|
||||||
|
pickers.new({}, {
|
||||||
|
prompt_title = 'Claude Changed Files',
|
||||||
|
finder = finders.new_table({
|
||||||
|
results = M.current_review.changed_files,
|
||||||
|
}),
|
||||||
|
sorter = conf.generic_sorter({}),
|
||||||
|
attach_mappings = function(_, map)
|
||||||
|
map('i', '<CR>', function(prompt_bufnr)
|
||||||
|
local selection = require('telescope.actions.state').get_selected_entry()
|
||||||
|
require('telescope.actions').close(prompt_bufnr)
|
||||||
|
vim.cmd('edit ' .. selection[1])
|
||||||
|
M.open_diffview()
|
||||||
|
end)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clear review session
|
||||||
|
function M.clear_review()
|
||||||
|
if M.current_review then
|
||||||
|
M.current_review = nil
|
||||||
|
|
||||||
|
-- Close diffview if it's open
|
||||||
|
pcall(function()
|
||||||
|
vim.cmd('DiffviewClose')
|
||||||
|
end)
|
||||||
|
|
||||||
|
vim.notify('Claude review session cleared', vim.log.levels.INFO)
|
||||||
|
else
|
||||||
|
vim.notify('No active Claude review session', vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
|
@ -0,0 +1,292 @@
|
||||||
|
-- Claude Code hooks integration for nvim-claude
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- Track hook state
|
||||||
|
M.pre_edit_commit = nil
|
||||||
|
|
||||||
|
function M.setup()
|
||||||
|
vim.notify('Hooks module loaded', vim.log.levels.DEBUG)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pre-tool-use hook: Create a commit snapshot of the current state
|
||||||
|
function M.pre_tool_use_hook()
|
||||||
|
local utils = require('nvim-claude.utils')
|
||||||
|
|
||||||
|
-- Check if we're in a git repository
|
||||||
|
local git_root = utils.get_project_root()
|
||||||
|
if not git_root then
|
||||||
|
vim.notify('Not in a git repository', vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create timestamp for snapshot
|
||||||
|
local timestamp = os.time()
|
||||||
|
local commit_msg = string.format('claude-pre-edit-%d', timestamp)
|
||||||
|
|
||||||
|
-- Stage all current changes (including untracked files)
|
||||||
|
local add_cmd = string.format('cd "%s" && git add -A', git_root)
|
||||||
|
local add_result, add_err = utils.exec(add_cmd)
|
||||||
|
|
||||||
|
if add_err then
|
||||||
|
vim.notify('Failed to stage changes: ' .. add_err, vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create a temporary commit
|
||||||
|
local commit_cmd = string.format('cd "%s" && git commit -m "%s" --allow-empty', git_root, commit_msg)
|
||||||
|
local commit_result, commit_err = utils.exec(commit_cmd)
|
||||||
|
|
||||||
|
if commit_err and not commit_err:match('nothing to commit') then
|
||||||
|
vim.notify('Failed to create snapshot commit: ' .. commit_err, vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Store the commit reference
|
||||||
|
M.pre_edit_commit = 'HEAD'
|
||||||
|
|
||||||
|
-- Also store in temp file for diff review to access
|
||||||
|
local temp_file = '/tmp/claude-pre-edit-commit'
|
||||||
|
utils.write_file(temp_file, 'HEAD')
|
||||||
|
|
||||||
|
vim.notify('Pre-Claude snapshot created: ' .. commit_msg, vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Post-tool-use hook: Create stash of Claude's changes and trigger diff review
|
||||||
|
function M.post_tool_use_hook()
|
||||||
|
vim.notify('Post-tool-use hook triggered', vim.log.levels.INFO)
|
||||||
|
|
||||||
|
-- Use vim.schedule to ensure we're in the main thread
|
||||||
|
vim.schedule(function()
|
||||||
|
local utils = require('nvim-claude.utils')
|
||||||
|
|
||||||
|
-- Refresh all buffers to show Claude's changes
|
||||||
|
vim.cmd('checktime')
|
||||||
|
|
||||||
|
-- Check if Claude made any changes
|
||||||
|
local git_root = utils.get_project_root()
|
||||||
|
if not git_root then
|
||||||
|
vim.notify('Not in a git repository', vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local status_cmd = string.format('cd "%s" && git status --porcelain', git_root)
|
||||||
|
local status_result = utils.exec(status_cmd)
|
||||||
|
|
||||||
|
if not status_result or status_result == '' then
|
||||||
|
vim.notify('No changes detected from Claude', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create a stash of Claude's changes (but keep them in working directory)
|
||||||
|
local timestamp = os.date('%Y-%m-%d %H:%M:%S')
|
||||||
|
local stash_msg = string.format('[claude-edit] %s', timestamp)
|
||||||
|
|
||||||
|
-- Use git stash create to create stash without removing changes
|
||||||
|
local stash_cmd = string.format('cd "%s" && git stash create -u', git_root)
|
||||||
|
local stash_hash, stash_err = utils.exec(stash_cmd)
|
||||||
|
|
||||||
|
if not stash_err and stash_hash and stash_hash ~= '' then
|
||||||
|
-- Store the stash with a message
|
||||||
|
stash_hash = stash_hash:gsub('%s+', '') -- trim whitespace
|
||||||
|
local store_cmd = string.format('cd "%s" && git stash store -m "%s" %s', git_root, stash_msg, stash_hash)
|
||||||
|
utils.exec(store_cmd)
|
||||||
|
|
||||||
|
-- Get the pre-edit commit reference
|
||||||
|
local pre_edit_ref = utils.read_file('/tmp/claude-pre-edit-commit')
|
||||||
|
if pre_edit_ref then
|
||||||
|
pre_edit_ref = pre_edit_ref:gsub('%s+', '') -- trim whitespace
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Trigger diff review
|
||||||
|
local ok, diff_review = pcall(require, 'nvim-claude.diff-review')
|
||||||
|
if ok then
|
||||||
|
diff_review.handle_claude_edit('stash@{0}', pre_edit_ref)
|
||||||
|
else
|
||||||
|
vim.notify('Diff review module not available: ' .. tostring(diff_review), vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vim.notify('Failed to create stash of Claude changes', vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Manual hook testing
|
||||||
|
function M.test_hooks()
|
||||||
|
vim.notify('=== Testing nvim-claude hooks ===', vim.log.levels.INFO)
|
||||||
|
|
||||||
|
-- Test pre-tool-use hook
|
||||||
|
vim.notify('1. Testing pre-tool-use hook (creating snapshot)...', vim.log.levels.INFO)
|
||||||
|
M.pre_tool_use_hook()
|
||||||
|
|
||||||
|
-- Simulate making a change
|
||||||
|
vim.notify('2. Make some changes to test files now...', vim.log.levels.INFO)
|
||||||
|
|
||||||
|
-- Test post-tool-use hook after a delay
|
||||||
|
vim.notify('3. Will trigger post-tool-use hook in 3 seconds...', vim.log.levels.INFO)
|
||||||
|
|
||||||
|
vim.defer_fn(function()
|
||||||
|
M.post_tool_use_hook()
|
||||||
|
end, 3000)
|
||||||
|
|
||||||
|
vim.notify('=== Hook testing started - make changes now! ===', vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Install Claude Code hooks
|
||||||
|
function M.install_hooks()
|
||||||
|
local utils = require('nvim-claude.utils')
|
||||||
|
|
||||||
|
-- Get project root
|
||||||
|
local project_root = utils.get_project_root()
|
||||||
|
if not project_root then
|
||||||
|
vim.notify('Not in a git repository', vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create .claude directory
|
||||||
|
local claude_dir = project_root .. '/.claude'
|
||||||
|
if not vim.fn.isdirectory(claude_dir) then
|
||||||
|
vim.fn.mkdir(claude_dir, 'p')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create hooks configuration
|
||||||
|
local server_name = vim.v.servername or 'NVIM'
|
||||||
|
local pre_command = string.format('nvim --headless --server %s --remote-send "<C-\\><C-N>:lua require(\'nvim-claude.hooks\').pre_tool_use_hook()<CR>" 2>/dev/null || true', server_name)
|
||||||
|
local post_command = string.format('nvim --headless --server %s --remote-send "<C-\\><C-N>:lua require(\'nvim-claude.hooks\').post_tool_use_hook()<CR>" 2>/dev/null || true', server_name)
|
||||||
|
|
||||||
|
local hooks_config = {
|
||||||
|
hooks = {
|
||||||
|
PreToolUse = {
|
||||||
|
{
|
||||||
|
matcher = ".*", -- Match all tools
|
||||||
|
hooks = {
|
||||||
|
{
|
||||||
|
type = "command",
|
||||||
|
command = pre_command
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PostToolUse = {
|
||||||
|
{
|
||||||
|
matcher = ".*", -- Match all tools
|
||||||
|
hooks = {
|
||||||
|
{
|
||||||
|
type = "command",
|
||||||
|
command = post_command
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Write hooks configuration
|
||||||
|
local settings_file = claude_dir .. '/settings.json'
|
||||||
|
local success, err = utils.write_json(settings_file, hooks_config)
|
||||||
|
|
||||||
|
if success then
|
||||||
|
-- Add .claude to gitignore if needed
|
||||||
|
local gitignore_path = project_root .. '/.gitignore'
|
||||||
|
local gitignore_content = utils.read_file(gitignore_path) or ''
|
||||||
|
|
||||||
|
if not gitignore_content:match('%.claude/') then
|
||||||
|
local new_content = gitignore_content .. '\n# Claude Code hooks\n.claude/\n'
|
||||||
|
utils.write_file(gitignore_path, new_content)
|
||||||
|
vim.notify('Added .claude/ to .gitignore', vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.notify('Claude Code hooks installed successfully', vim.log.levels.INFO)
|
||||||
|
vim.notify('Hooks configuration written to: ' .. settings_file, vim.log.levels.INFO)
|
||||||
|
else
|
||||||
|
vim.notify('Failed to install hooks: ' .. (err or 'unknown error'), vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Uninstall Claude Code hooks
|
||||||
|
function M.uninstall_hooks()
|
||||||
|
local utils = require('nvim-claude.utils')
|
||||||
|
|
||||||
|
-- Get project root
|
||||||
|
local project_root = utils.get_project_root()
|
||||||
|
if not project_root then
|
||||||
|
vim.notify('Not in a git repository', vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local settings_file = project_root .. '/.claude/settings.json'
|
||||||
|
|
||||||
|
if vim.fn.filereadable(settings_file) then
|
||||||
|
vim.fn.delete(settings_file)
|
||||||
|
vim.notify('Claude Code hooks uninstalled', vim.log.levels.INFO)
|
||||||
|
else
|
||||||
|
vim.notify('No hooks configuration found', vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Commands for manual hook management
|
||||||
|
function M.setup_commands()
|
||||||
|
vim.api.nvim_create_user_command('ClaudeTestHooks', function()
|
||||||
|
M.test_hooks()
|
||||||
|
end, {
|
||||||
|
desc = 'Test Claude Code hooks'
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command('ClaudeTestDiff', function()
|
||||||
|
local utils = require('nvim-claude.utils')
|
||||||
|
|
||||||
|
-- Check if we're in a git repository
|
||||||
|
local git_root = utils.get_project_root()
|
||||||
|
if not git_root then
|
||||||
|
vim.notify('Not in a git repository', vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if there are any changes
|
||||||
|
local status_cmd = string.format('cd "%s" && git status --porcelain', git_root)
|
||||||
|
local status_result = utils.exec(status_cmd)
|
||||||
|
|
||||||
|
if not status_result or status_result == '' then
|
||||||
|
vim.notify('No changes to test', vim.log.levels.INFO)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create test stash without restoring (to avoid conflicts)
|
||||||
|
local timestamp = os.date('%Y-%m-%d %H:%M:%S')
|
||||||
|
local stash_msg = string.format('[claude-test] %s', timestamp)
|
||||||
|
|
||||||
|
local stash_cmd = string.format('cd "%s" && git stash push -u -m "%s"', git_root, stash_msg)
|
||||||
|
local stash_result, stash_err = utils.exec(stash_cmd)
|
||||||
|
|
||||||
|
if stash_err then
|
||||||
|
vim.notify('Failed to create test stash: ' .. stash_err, vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Trigger diff review with the stash (no pre-edit ref for manual test)
|
||||||
|
local diff_review = require('nvim-claude.diff-review')
|
||||||
|
diff_review.handle_claude_edit('stash@{0}', nil)
|
||||||
|
|
||||||
|
-- Pop the stash to restore changes
|
||||||
|
vim.defer_fn(function()
|
||||||
|
local pop_cmd = string.format('cd "%s" && git stash pop --quiet', git_root)
|
||||||
|
utils.exec(pop_cmd)
|
||||||
|
vim.cmd('checktime') -- Refresh buffers
|
||||||
|
end, 100)
|
||||||
|
end, {
|
||||||
|
desc = 'Test Claude diff review with current changes'
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command('ClaudeInstallHooks', function()
|
||||||
|
M.install_hooks()
|
||||||
|
end, {
|
||||||
|
desc = 'Install Claude Code hooks for this project'
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command('ClaudeUninstallHooks', function()
|
||||||
|
M.uninstall_hooks()
|
||||||
|
end, {
|
||||||
|
desc = 'Uninstall Claude Code hooks for this project'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
|
@ -115,14 +115,19 @@ function M.setup(user_config)
|
||||||
M.utils = require('nvim-claude.utils')
|
M.utils = require('nvim-claude.utils')
|
||||||
M.commands = require('nvim-claude.commands')
|
M.commands = require('nvim-claude.commands')
|
||||||
M.registry = require('nvim-claude.registry')
|
M.registry = require('nvim-claude.registry')
|
||||||
|
M.hooks = require('nvim-claude.hooks')
|
||||||
|
M.diff_review = require('nvim-claude.diff-review')
|
||||||
|
|
||||||
-- Initialize submodules with config
|
-- Initialize submodules with config
|
||||||
M.tmux.setup(M.config.tmux)
|
M.tmux.setup(M.config.tmux)
|
||||||
M.git.setup(M.config.agents)
|
M.git.setup(M.config.agents)
|
||||||
M.registry.setup(M.config.agents)
|
M.registry.setup(M.config.agents)
|
||||||
|
M.hooks.setup()
|
||||||
|
M.diff_review.setup()
|
||||||
|
|
||||||
-- Set up commands
|
-- Set up commands
|
||||||
M.commands.setup(M)
|
M.commands.setup(M)
|
||||||
|
M.hooks.setup_commands()
|
||||||
|
|
||||||
-- Set up keymappings if enabled
|
-- Set up keymappings if enabled
|
||||||
if M.config.mappings then
|
if M.config.mappings then
|
||||||
|
|
|
@ -113,4 +113,38 @@ function M.tmux_supports_length_percent()
|
||||||
return M.tmux_version() >= 3.4
|
return M.tmux_version() >= 3.4
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Write JSON to file
|
||||||
|
function M.write_json(path, data)
|
||||||
|
local success, json = pcall(vim.fn.json_encode, data)
|
||||||
|
if not success then
|
||||||
|
return false, 'Failed to encode JSON: ' .. json
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = io.open(path, 'w')
|
||||||
|
if not file then
|
||||||
|
return false, 'Failed to open file for writing: ' .. path
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pretty print JSON
|
||||||
|
local formatted = json:gsub('},{', '},\n {'):gsub('\\{', '{\n '):gsub('\\}', '\n}')
|
||||||
|
file:write(formatted)
|
||||||
|
file:close()
|
||||||
|
return true, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Read JSON from file
|
||||||
|
function M.read_json(path)
|
||||||
|
local content = M.read_file(path)
|
||||||
|
if not content then
|
||||||
|
return nil, 'Failed to read file: ' .. path
|
||||||
|
end
|
||||||
|
|
||||||
|
local success, data = pcall(vim.fn.json_decode, content)
|
||||||
|
if not success then
|
||||||
|
return nil, 'Failed to decode JSON: ' .. data
|
||||||
|
end
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
Loading…
Reference in New Issue