From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Re: Syntactic fontification of diff hunks Date: Fri, 17 Aug 2018 01:27:37 +0300 Organization: LINKOV.NET Message-ID: <87r2iyc5gm.fsf@mail.linkov.net> References: <87in4af29r.fsf@mail.linkov.net> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1534458459 29659 195.159.176.226 (16 Aug 2018 22:27:39 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 16 Aug 2018 22:27:39 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) Cc: emacs-devel@gnu.org To: Kaushal Modi Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Aug 17 00:27:35 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fqQjv-0007Z1-9X for ged-emacs-devel@m.gmane.org; Fri, 17 Aug 2018 00:27:35 +0200 Original-Received: from localhost ([::1]:58340 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqQlz-00009N-Vc for ged-emacs-devel@m.gmane.org; Thu, 16 Aug 2018 18:29:43 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:43285) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqQlJ-00009H-PN for emacs-devel@gnu.org; Thu, 16 Aug 2018 18:29:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fqQlE-0001JT-5o for emacs-devel@gnu.org; Thu, 16 Aug 2018 18:29:01 -0400 Original-Received: from homie-sub3.mail.dreamhost.com ([69.163.253.7]:59551 helo=homiemail-a22.g.dreamhost.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fqQlD-0001J3-JJ for emacs-devel@gnu.org; Thu, 16 Aug 2018 18:28:55 -0400 Original-Received: from homiemail-a22.g.dreamhost.com (localhost [127.0.0.1]) by homiemail-a22.g.dreamhost.com (Postfix) with ESMTP id 012DC114066; Thu, 16 Aug 2018 15:28:54 -0700 (PDT) Original-Received: from localhost.linkov.net (m91-129-110-6.cust.tele2.ee [91.129.110.6]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by homiemail-a22.g.dreamhost.com (Postfix) with ESMTPSA id 14E3B114065; Thu, 16 Aug 2018 15:28:52 -0700 (PDT) In-Reply-To: (Kaushal Modi's message of "Thu, 16 Aug 2018 17:44:50 -0400") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 69.163.253.7 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:228613 Archived-At: --=-=-= Content-Type: text/plain > 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: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=diff-syntax.patch 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 --=-=-=--