{"thread":{"id":"6751","subject":"[PATCH 7/7] git-blame.el: Autoupdate while editing","startedAt":"2007-02-09T08:22:19Z","lastAt":"2007-02-09T11:05:51Z","messageCount":3,"participants":["David Kågedal","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"34047","messageId":"87ejozpwp0.fsf@morpheus.local","threadId":"6751","inReplyTo":null,"subject":"[PATCH 7/7] git-blame.el: Autoupdate while editing","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-02-09T08:22:19Z","receivedAt":"2007-02-09T08:22:19Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"This adds the support for automatically updating the buffer while editing.\nA configuration variable git-blame-autoupdate controls whether this should\nbe enabled or not.\n\nSigned-off-by: David Kågedal <davidk@lysator.liu.se>\n---\n contrib/emacs/git-blame.el |   95 +++++++++++++++++++++++++++++++++++++++----\n 1 files changed, 86 insertions(+), 9 deletions(-)\n\ndiff --git a/contrib/emacs/git-blame.el b/contrib/emacs/git-blame.el\nindex 7daa4e6..64ad50b 100644\n--- a/contrib/emacs/git-blame.el\n+++ b/contrib/emacs/git-blame.el\n@@ -102,6 +102,9 @@\n \n (defvar git-blame-ancient-color \"dark green\")\n \n+(defvar git-blame-autoupdate t\n+  \"*Automatically update the blame display while editing\")\n+\n (defvar git-blame-proc nil\n   \"The running git-blame process\")\n (make-variable-buffer-local 'git-blame-proc)\n@@ -114,6 +117,14 @@\n   \"A cache of git-blame information for the current buffer\")\n (make-variable-buffer-local 'git-blame-cache)\n \n+(defvar git-blame-idle-timer nil\n+  \"An idle timer that updates the blame\")\n+(make-variable-buffer-local 'git-blame-cache)\n+\n+(defvar git-blame-update-queue nil\n+  \"A queue of update requests\")\n+(make-variable-buffer-local 'git-blame-update-queue)\n+\n (defvar git-blame-mode nil)\n (make-variable-buffer-local 'git-blame-mode)\n (unless (assq 'git-blame-mode minor-mode-alist)\n@@ -129,6 +140,9 @@\n       (setq git-blame-mode (eq arg 1))\n     (setq git-blame-mode (not git-blame-mode)))\n   (make-local-variable 'git-blame-colors)\n+  (if git-blame-autoupdate\n+      (add-hook 'after-change-functions 'git-blame-after-change nil t)\n+    (remove-hook 'after-change-functions 'git-blame-after-change t))\n   (git-blame-cleanup)\n   (if git-blame-mode\n       (progn\n@@ -137,7 +151,8 @@\n               (setq git-blame-colors git-blame-dark-colors)\n             (setq git-blame-colors git-blame-light-colors)))\n         (setq git-blame-cache (make-hash-table :test 'equal))\n-        (git-blame-run))))\n+        (git-blame-run))\n+    (cancel-timer git-blame-idle-timer)))\n \n ;;;###autoload\n (defun git-reblame ()\n@@ -148,18 +163,24 @@\n   (git-blame-cleanup)\n   (git-blame-run))\n \n-(defun git-blame-run ()\n+(defun git-blame-run (&optional startline endline)\n   (if git-blame-proc\n       ;; Should maybe queue up a new run here\n       (message \"Already running git blame\")\n     (let ((display-buf (current-buffer))\n           (blame-buf (get-buffer-create\n-                      (concat \" git blame for \" (buffer-name)))))\n+                      (concat \" git blame for \" (buffer-name))))\n+          (args '(\"--incremental\" \"--contents\" \"-\")))\n+      (if startline\n+          (setq args (append args\n+                             (list \"-L\" (format \"%d,%d\" startline endline)))))\n+      (setq args (append args\n+                         (list (file-name-nondirectory buffer-file-name))))\n       (setq git-blame-proc\n-            (start-process \"git-blame\" blame-buf\n-                           \"git\" \"blame\"\n-                           \"--incremental\" \"--contents\" \"-\"\n-                           (file-name-nondirectory buffer-file-name)))\n+            (apply 'start-process\n+                   \"git-blame\" blame-buf\n+                   \"git\" \"blame\"\n+                   args))\n       (with-current-buffer blame-buf\n         (erase-buffer)\n         (make-local-variable 'git-blame-file)\n@@ -183,10 +204,28 @@\n     (setq git-blame-overlays nil)\n     (remove-git-blame-text-properties (point-min) (point-max)))\n \n+(defun git-blame-update-region (start end)\n+  \"Rerun blame to get updates between START and END\"\n+  (let ((overlays (overlays-in start end)))\n+    (while overlays\n+      (let ((overlay (pop overlays)))\n+        (if (< (overlay-start overlay) start)\n+            (setq start (overlay-start overlay)))\n+        (if (> (overlay-end overlay) end)\n+            (setq end (overlay-end overlay)))\n+        (setq git-blame-overlays (delete overlay git-blame-overlays))\n+        (delete-overlay overlay))))\n+  (remove-git-blame-text-properties start end)\n+  ;; We can be sure that start and end are at line breaks\n+  (git-blame-run (1+ (count-lines (point-min) start))\n+                 (count-lines (point-min) end)))\n+\n (defun git-blame-sentinel (proc status)\n   (with-current-buffer (process-buffer proc)\n     (with-current-buffer git-blame-file\n-      (setq git-blame-proc nil)))\n+      (setq git-blame-proc nil)\n+      (if git-blame-update-queue\n+          (git-blame-delayed-update))))\n   ;;(kill-buffer (process-buffer proc))\n   ;;(message \"git blame finished\")\n   )\n@@ -241,7 +280,8 @@\n   (save-excursion\n     (set-buffer git-blame-file)\n     (let ((info (gethash hash git-blame-cache))\n-          (inhibit-point-motion-hooks t))\n+          (inhibit-point-motion-hooks t)\n+          (inhibit-modification-hooks t))\n       (when (not info)\n         (let ((color (pop git-blame-colors)))\n           (unless color\n@@ -298,6 +338,43 @@\n       (message \"%s\" (nth 4 info))\n       (setq git-blame-last-identification info))))\n \n+;; (defun git-blame-after-save ()\n+;;   (when git-blame-mode\n+;;     (git-blame-cleanup)\n+;;     (git-blame-run)))\n+;; (add-hook 'after-save-hook 'git-blame-after-save)\n+\n+(defun git-blame-after-change (start end length)\n+  (when git-blame-mode\n+    (git-blame-enq-update start end)))\n+\n+(defvar git-blame-last-update nil)\n+(make-variable-buffer-local 'git-blame-last-update)\n+(defun git-blame-enq-update (start end)\n+  \"Mark the region between START and END as needing blame update\"\n+  ;; Try to be smart and avoid multiple callouts for sequential\n+  ;; editing\n+  (cond ((and git-blame-last-update\n+              (= start (cdr git-blame-last-update)))\n+         (setcdr git-blame-last-update end))\n+        ((and git-blame-last-update\n+              (= end (car git-blame-last-update)))\n+         (setcar git-blame-last-update start))\n+        (t\n+         (setq git-blame-last-update (cons start end))\n+         (setq git-blame-update-queue (nconc git-blame-update-queue\n+                                             (list git-blame-last-update)))))\n+  (unless (or git-blame-proc git-blame-idle-timer)\n+    (setq git-blame-idle-timer\n+          (run-with-idle-timer 0.5 nil 'git-blame-delayed-update))))\n+\n+(defun git-blame-delayed-update ()\n+  (setq git-blame-idle-timer nil)\n+  (if git-blame-update-queue\n+      (let ((first (pop git-blame-update-queue))\n+            (inhibit-point-motion-hooks t))\n+        (git-blame-update-region (car first) (cdr first)))))\n+\n (provide 'git-blame)\n \n ;;; git-blame.el ends here\n-- \n1.5.0.rc3.204.g93c76\n\n\n-- \nDavid Kågedal\n"},{"id":"34052","messageId":"eqhfqv$bnu$1@sea.gmane.org","threadId":"6751","inReplyTo":"87ejozpwp0.fsf@morpheus.local","subject":"Re: [PATCH 7/7] git-blame.el: Autoupdate while editing","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-02-09T09:46:40Z","receivedAt":"2007-02-09T09:46:40Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"[Cc: git@vger.kernel.org]\n\nDavid K?gedal wrote:\n\n> This adds the support for automatically updating the buffer while editing.\n> A configuration variable git-blame-autoupdate controls whether this should\n> be enabled or not.\n\nCan we use -L option of git-blame for this?\n\nBTW did you take a look at Font Lock modes: Fast Lock mode, Lazy Lock mode,\nJust-in-time Lock mode?\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"34057","messageId":"87veiboak0.fsf@morpheus.local","threadId":"6751","inReplyTo":"eqhfqv$bnu$1@sea.gmane.org","subject":"Re: [PATCH 7/7] git-blame.el: Autoupdate while editing","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-02-09T11:05:51Z","receivedAt":"2007-02-09T11:05:51Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> [Cc: git@vger.kernel.org]\n>\n> David K?gedal wrote:\n>\n>> This adds the support for automatically updating the buffer while editing.\n>> A configuration variable git-blame-autoupdate controls whether this should\n>> be enabled or not.\n>\n> Can we use -L option of git-blame for this?\n\nWe do.\n\n> BTW did you take a look at Font Lock modes: Fast Lock mode, Lazy Lock mode,\n> Just-in-time Lock mode?\n\nI know of them (I use lazy-lock-mode, which I think is the\ndefault). But what do you want me to look at?\n\n-- \nDavid Kågedal\n"}]}