unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Juri Linkov <juri@linkov.net>
To: Kaushal Modi <kaushal.modi@gmail.com>
Cc: emacs-devel@gnu.org
Subject: Re: Syntactic fontification of diff hunks
Date: Fri, 17 Aug 2018 01:27:37 +0300	[thread overview]
Message-ID: <87r2iyc5gm.fsf@mail.linkov.net> (raw)
In-Reply-To: <CAFyQvY1OidR41Aqq+EU+tSbiSxQCZKGy8RhzU_v9sEJcu70qVw@mail.gmail.com> (Kaushal Modi's message of "Thu, 16 Aug 2018 17:44:50 -0400")

[-- Attachment #1: Type: text/plain, Size: 159 bytes --]

> 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:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: diff-syntax.patch --]
[-- Type: text/x-diff, Size: 3764 bytes --]

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	other threads:[~2018-08-16 22:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-16 21:08 Syntactic fontification of diff hunks Juri Linkov
2018-08-16 21:44 ` Kaushal Modi
2018-08-16 22:27   ` Juri Linkov [this message]
2018-08-16 22:33     ` Kaushal Modi
2018-08-16 22:41       ` Juri Linkov
2018-08-17  5:41 ` Yuri Khan
2018-08-17  6:00   ` Andreas Röhler
2018-08-17  6:47     ` Yuri Khan
2018-08-17 17:47       ` Juri Linkov
2018-08-17 18:34         ` Yuri Khan
2018-08-19 20:57           ` Juri Linkov
2018-08-18 20:02       ` Andreas Röhler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r2iyc5gm.fsf@mail.linkov.net \
    --to=juri@linkov.net \
    --cc=emacs-devel@gnu.org \
    --cc=kaushal.modi@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).