unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
To: Samuel Wales <samologist@gmail.com>
Cc: help-gnu-emacs@gnu.org
Subject: Re: delete lines with overlays [workaround to diff mode]
Date: Wed, 30 Aug 2023 18:25:20 +0200	[thread overview]
Message-ID: <c65d7bd2-df60-a6af-fd89-0bf389099177@vodafonemail.de> (raw)
In-Reply-To: <CAJcAo8tWr3KPq0bt30w7a=ZzBF719tTb7-Mb=f9g7u9UGzfOUw@mail.gmail.com>

[Internet sucks at my current place, sorry for the split
sends/resends.]

On 2023-08-30  07:07, Samuel Wales wrote:

> currently 27

How convenient ... having that around here as well.

As Dmitry has noted in your bug#61396, the diff refinement machinery
probably already has what you are looking for, but without
ready-made switches to turn it on.

You might want to try whether the following modified function
`diff--refine-hunk' does what you need.  Not sure how proficient
you are in Elisp hacking, so I provide full instructions to get
it activated.

1. Start Emacs as "emacs -Q" to get reproducible results.  (This
   is required only for the initial tests.)
2. M-x load-library diff-mode RET to load the original library
3. Paste below function definition into *scratch* and press C-M-x
   with point in or after the definition to evaluate the modified
   function definition.
4. Then check whether the result matches your expectation.

The only lines I modified in the function are these:

-              (smerge-refine-regions beg-del beg-add beg-add end-add
-                                     nil #'diff-refine-preproc props-r props-a)))))

I replaced that by:

+              (smerge-refine-regions beg-del beg-add beg-add end-add
+                                     props-c nil nil nil)))))

Comments:

- `props-c' is responsible for highlighting changes in yellow
  (compared to `props-r' for removals, `props-a' for additions)
- Function `diff-refine-preproc' referenced in the original function
  strips off the leading '-' and '+' chars from the diffs to avoid
  getting them highlighted as refined diffs.
  When replacing the reference to that function by nil, these leading
  chars get processed by the refinement as well and are highlighted as
  changes if needed.  Hopefully, they did at least in the samples I
  checked.

You might also want to try:

+              (smerge-refine-regions beg-del beg-add beg-add end-add
+                                     props-c nil props-r props-a)))))

Anyway, here is the full modified function:

(defun diff--refine-hunk (start end)
  (require 'smerge-mode)
  (goto-char start)
  (let* ((style (diff-hunk-style))      ;Skips the hunk header as well.
         (beg (point))
         (props-c '((diff-mode . fine) (face . diff-refine-changed)))
         (props-r '((diff-mode . fine) (face . diff-refine-removed)))
         (props-a '((diff-mode . fine) (face . diff-refine-added))))

    (remove-overlays beg end 'diff-mode 'fine)

    (goto-char beg)
    (pcase style
      ('unified
       (while (re-search-forward "^-" end t)
         (let ((beg-del (progn (beginning-of-line) (point)))
               beg-add end-add)
           (when (and (diff--forward-while-leading-char ?- end)
                      ;; Allow for "\ No newline at end of file".
                      (progn (diff--forward-while-leading-char ?\\ end)
                             (setq beg-add (point)))
                      (diff--forward-while-leading-char ?+ end)
                      (progn (diff--forward-while-leading-char ?\\ end)
                             (setq end-add (point))))
             (smerge-refine-regions beg-del beg-add beg-add end-add
                                    props-c nil nil nil)))))
      ('context
       (let* ((middle (save-excursion (re-search-forward "^---" end)))
              (other middle))
         (while (re-search-forward "^\\(?:!.*\n\\)+" middle t)
           (smerge-refine-regions (match-beginning 0) (match-end 0)
                                  (save-excursion
                                    (goto-char other)
                                    (re-search-forward "^\\(?:!.*\n\\)+" end)
                                    (setq other (match-end 0))
                                    (match-beginning 0))
                                  other
                                  (if diff-use-changed-face props-c)
                                  #'diff-refine-preproc
                                  (unless diff-use-changed-face props-r)
                                  (unless diff-use-changed-face props-a)))))
      (_ ;; Normal diffs.
       (let ((beg1 (1+ (point))))
         (when (re-search-forward "^---.*\n" end t)
           ;; It's a combined add&remove, so there's something to do.
           (smerge-refine-regions beg1 (match-beginning 0)
                                  (match-end 0) end
                                  nil #'diff-refine-preproc props-r props-a)))))))



      parent reply	other threads:[~2023-08-30 16:25 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-29  5:32 delete lines with overlays [workaround to diff mode] Samuel Wales
2023-08-29 17:19 ` Marcin Borkowski
2023-08-29 22:03 ` Jens Schmidt via Users list for the GNU Emacs text editor
2023-08-30  5:07   ` Samuel Wales
2023-08-30 11:21     ` Jens Schmidt via Users list for the GNU Emacs text editor
2023-08-30 11:30     ` Jens Schmidt via Users list for the GNU Emacs text editor
2023-08-30 16:25     ` Jens Schmidt [this message]

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=c65d7bd2-df60-a6af-fd89-0bf389099177@vodafonemail.de \
    --to=jschmidt4gnu@vodafonemail.de \
    --cc=help-gnu-emacs@gnu.org \
    --cc=samologist@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.
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).