From 79825b9c2180fc8f792097febccb1cfff741686a Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar Date: Mon, 13 Oct 2025 16:41:58 -0400 Subject: [PATCH] git-changes: v1 --- modules/home/all/terminal.nix | 1 + packages/git-changes.nix | 63 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 packages/git-changes.nix diff --git a/modules/home/all/terminal.nix b/modules/home/all/terminal.nix index 8a5b39e..1d9fcb0 100644 --- a/modules/home/all/terminal.nix +++ b/modules/home/all/terminal.nix @@ -45,6 +45,7 @@ in # Dev fuckport + git-changes sshuttle-via entr hackage-publish diff --git a/packages/git-changes.nix b/packages/git-changes.nix new file mode 100644 index 0000000..2d317e8 --- /dev/null +++ b/packages/git-changes.nix @@ -0,0 +1,63 @@ +# Watch for file changes in the current directory and automatically restart +# `git diff HEAD` to show both staged and unstaged changes. Useful for +# monitoring code changes made by LLMs in real-time without manually restarting +# the diff viewer. +{ writers, haskellPackages, git, coreutils, ... }: + +writers.writeHaskellBin "git-changes" +{ + libraries = with haskellPackages; [ + shh + fsnotify + ]; +} '' + {-# LANGUAGE TemplateHaskell #-} + import Shh + import System.FSNotify + import Control.Concurrent + import Control.Monad + import System.Process + import System.IO + import Data.List (isInfixOf) + + loadFromBins ["${git}", "${coreutils}"] + + main :: IO () + main = do + hSetBuffering stdout NoBuffering + + -- Start initial git diff + diffRef <- newMVar Nothing + let runDiff = do + -- Kill previous diff if running + oldProc <- takeMVar diffRef + case oldProc of + Just ph -> do + terminateProcess ph + void $ waitForProcess ph + Nothing -> return () + + -- Start new git diff + ph <- spawnCommand "${git}/bin/git diff HEAD" + putMVar diffRef (Just ph) + + -- Run initial diff + runDiff + + -- Watch for file changes + withManager $ \mgr -> do + _ <- watchTree + mgr + "." + (\event -> case event of + _ -> let path = eventPath event + in not (".git" `isInfixOf` path) + ) + (\_ -> do + putStrLn "File changed, restarting diff..." + runDiff + ) + + -- Keep running + forever $ threadDelay 1000000 +''