emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Syntactic fontification of diff hunks


From: Juri Linkov
Subject: Re: Syntactic fontification of diff hunks
Date: Fri, 17 Aug 2018 01:27:37 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu)

> Looks nice.
>
> Where you supposed to attach the patch too? :)

The patch is on the screenshot :)

But if you want to try, here it is for your convenience:

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index b91a2ba45a..175687f184 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -96,6 +96,11 @@ diff-font-lock-refine
   :version "27.1"
   :type 'boolean)
 
+(defcustom diff-font-lock-syntaxify t
+  "If non-nil, diff hunk font-lock includes syntax highlighting."
+  :version "27.1"
+  :type 'boolean)
+
 (defcustom diff-font-lock-prettify nil
   "If non-nil, font-lock will try and make the format prettier."
   :version "27.1"
@@ -402,7 +411,8 @@ diff-font-lock-keywords
      (2 font-lock-comment-face))
     ("^[^-=+*!<>#].*\n" (0 'diff-context))
     (,#'diff--font-lock-prettify)
-    (,#'diff--font-lock-refined)))
+    (,#'diff--font-lock-refined)
+    (,#'diff--font-lock-syntaxify)))
 
 (defconst diff-font-lock-defaults
   '(diff-font-lock-keywords t nil nil nil (font-lock-multiline . nil)))
@@ -2230,6 +2246,66 @@ diff--font-lock-prettify
                              'display "")))))
   nil)
 
+;;; Syntactic fontification
+
+(defun diff--font-lock-syntaxify (max)
+  "Highlight language syntax in diff hunks."
+  (when diff-font-lock-syntaxify
+    (when (get-char-property (point) 'diff--font-lock-syntaxified)
+      (goto-char (next-single-char-property-change
+                  (point) 'diff--font-lock-syntaxified nil max)))
+    (let* ((min (point))
+           (beg (or (ignore-errors (diff-beginning-of-hunk))
+                    (ignore-errors (let ((diff-auto-refine-mode nil))
+                                     (diff-hunk-next))
+                                   (point))
+                    max)))
+      (while (< beg max)
+        (let ((file (save-excursion
+                      (diff-beginning-of-file)
+                      (when (looking-at "^\\S-+\\s-+\\(\\S-+\\)")
+                        (match-string 1))))
+              (end (save-excursion (goto-char beg) (diff-end-of-hunk) 
(point))))
+          (if (< end min) (setq beg min))
+          (unless (or (< end beg)
+                      (get-char-property beg 'diff--font-lock-syntaxified))
+            (diff--syntaxify-hunk beg end file)
+            (let ((ol (make-overlay beg end)))
+              (overlay-put ol 'diff--font-lock-syntaxified t)
+              (overlay-put ol 'evaporate t)))
+          (goto-char (max beg end))
+          (setq beg (or (ignore-errors (let ((diff-auto-refine-mode nil))
+                                         (diff-hunk-next))
+                                       (point))
+                        max))))))
+  nil)
+
+(defun diff--syntaxify-hunk (beg end file-name)
+  (let (props (buffer (current-buffer)))
+    (with-temp-buffer
+      (insert-buffer-substring-no-properties buffer beg end)
+      (goto-char (point-min))
+      (while (re-search-forward "^[-+!]" nil t)
+        (replace-match " " nil nil))
+      (let ((buffer-file-name file-name))
+        (set-auto-mode))
+      (jit-lock-register #'font-lock-fontify-region)
+      (jit-lock-fontify-now (point-min) (point-max))
+      (goto-char (point-min))
+      (let* ((from (point)) to
+             (val (get-text-property from 'face)))
+        (while (setq to (next-single-property-change from 'face))
+          (when val (push (list from to val) props))
+          (setq val (get-text-property to 'face)
+                from to))))
+    (dolist (prop props)
+      (let ((ol (make-overlay (+ beg (nth 0 prop) -1)
+                              (+ beg (nth 1 prop) -1)
+                              nil 'front-advance nil)))
+        (overlay-put ol 'evaporate t)
+        (overlay-put ol 'face (nth 2 prop))
+        ol))))
+
 ;;; Support for converting a diff to diff3 markers via `wiggle'.
 
 ;; Wiggle can be found at http://neil.brown.name/wiggle/ or in your nearest

reply via email to

[Prev in Thread] Current Thread [Next in Thread]