emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] externals/vlf 98ddc3a 198/310: Add by batch Ediff functionality.


From: Stefan Monnier
Subject: [elpa] externals/vlf 98ddc3a 198/310: Add by batch Ediff functionality.
Date: Sat, 28 Nov 2020 00:33:15 -0500 (EST)

branch: externals/vlf
commit 98ddc3afd9dff969bc4aa76029c5780e53988e66
Author: Andrey Kotlarski <m00naticus@gmail.com>
Commit: Andrey Kotlarski <m00naticus@gmail.com>

    Add by batch Ediff functionality.
---
 README.org   |  10 ++++
 vlf-base.el  |  28 ++++++---
 vlf-ediff.el | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 vlf.el       |   2 +-
 4 files changed, 219 insertions(+), 8 deletions(-)

diff --git a/README.org b/README.org
index 4c6abac..1333d2a 100644
--- a/README.org
+++ b/README.org
@@ -19,6 +19,7 @@ what it does in a nutshell:
 - automatic scrolling of batches
 - as VLF is minor mode, font locking and functionality of the
   respective major mode is also present
+- by batch Ediff comparison
 - VLF is added as an option when opening large files
 
 GNU Emacs 23 and 24 are supported.
@@ -147,3 +148,12 @@ file.
 If editing doesn't change size of the chunk, only this chunk is saved.
 Otherwise the remaining part of the file is adjusted batch by batch,
 so again you'd better have bigger current batch size.
+
+** By batch Ediff
+
+Use *M-x vlf-ediff-files* and *M-x vlf-ediff-buffers* to compare
+files/buffers batch by batch (batch size is queried in case of files
+or taken from the first buffer in case of buffers).  Moving after the
+last difference in current chunk searches for following one with
+difference.  The other way around if looking for difference before the
+first one.
diff --git a/vlf-base.el b/vlf-base.el
index a2ad0e0..4358a41 100644
--- a/vlf-base.el
+++ b/vlf-base.el
@@ -94,13 +94,27 @@ When given MINIMAL flag, skip non important operations.
 If same as current chunk is requested, do nothing.
 Return number of bytes moved back for proper decoding and number of
 bytes added to the end."
-  (unless (and (= start vlf-start-pos)
-               (= end vlf-end-pos))
-    (vlf-verify-size)
-    (let ((shifts (vlf-move-to-chunk-1 start end)))
-      (and shifts (not minimal)
-           (vlf-update-buffer-name))
-      shifts)))
+  (vlf-verify-size)
+  (cond ((or (<= end start) (<= end 0)
+             (<= vlf-file-size start))
+         (when (or (not (buffer-modified-p))
+                   (y-or-n-p "Chunk modified, are you sure? "))
+           (erase-buffer)
+           (set-buffer-modified-p nil)
+           (let ((place (if (<= vlf-file-size start)
+                            vlf-file-size
+                          0)))
+             (setq vlf-start-pos place
+                   vlf-end-pos place)
+             (if (not minimal)
+                 (vlf-update-buffer-name))
+             (cons (- start place) (- place end)))))
+        ((or (/= start vlf-start-pos)
+             (/= end vlf-end-pos))
+         (let ((shifts (vlf-move-to-chunk-1 start end)))
+           (and shifts (not minimal)
+                (vlf-update-buffer-name))
+           shifts))))
 
 (defun vlf-move-to-chunk-1 (start end)
   "Move to chunk enclosed by START END keeping as much edits if any.
diff --git a/vlf-ediff.el b/vlf-ediff.el
new file mode 100644
index 0000000..9c76d05
--- /dev/null
+++ b/vlf-ediff.el
@@ -0,0 +1,187 @@
+;;; vlf-ediff.el --- VLF ediff functionality
+
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+
+;; Keywords: large files, compare, ediff
+;; Author: Andrey Kotlarski <m00naticus@gmail.com>
+;; URL: https://github.com/m00natic/vlfi
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;; This package provides ediff functionality for VLF managed buffers
+;; in face of the `vlf-ediff-buffers' and `vlf-ediff-files' commands.
+
+;;; Code:
+
+(require 'vlf)
+(require 'ediff)
+
+(defvar vlf-ediff-session nil
+  "If non nil, specifies that ediff is done over VLF buffers.")
+(make-variable-buffer-local 'vlf-ediff-session)
+
+;;;###autoload
+(defun vlf-ediff-buffers (buffer-A buffer-B)
+  "Run batch by batch ediff over VLF buffers BUFFER-A and BUFFER-B.
+Batch size is determined by the size in BUFFER-A.
+Requesting next or previous difference at the end or beginning
+respectively of difference list, runs ediff over the adjacent chunks."
+  (interactive
+   (let (bf)
+     (list (setq bf (read-buffer "Buffer A to compare: "
+                                 (ediff-other-buffer "") t))
+           (read-buffer "Buffer B to compare: "
+                        (progn
+                          ;; realign buffers so that two visible bufs will be
+                          ;; at the top
+                          (save-window-excursion (other-window 1))
+                          (ediff-other-buffer bf))
+                        t))))
+  (set-buffer buffer-A)
+  (setq buffer-A (current-buffer)) ;names change, so reference by buffer object
+  (let ((vlf-size vlf-batch-size))
+    (vlf-beginning-of-file)
+    (set-buffer buffer-B)
+    (setq buffer-B (current-buffer))
+    (setq vlf-batch-size vlf-size))
+  (vlf-beginning-of-file)
+  (vlf-ediff-next buffer-A buffer-B 'vlf-next-chunk))
+
+;;;###autoload
+(defun vlf-ediff-files (file-A file-B batch-size)
+  "Run batch by batch ediff over FILE-A and FILE-B.
+Files are processed with VLF with BATCH-SIZE chunks.
+Requesting next or previous difference at the end or beginning
+respectively of difference list, runs ediff over the adjacent chunks."
+  (interactive
+   (let ((dir-A (if ediff-use-last-dir
+                    ediff-last-dir-A
+                  default-directory))
+         dir-B f)
+     (list (setq f (ediff-read-file-name
+                    "File A to compare"
+                    dir-A
+                    (ediff-get-default-file-name)
+                    'no-dirs))
+           (ediff-read-file-name "File B to compare"
+                                 (setq dir-B
+                                       (if ediff-use-last-dir
+                                           ediff-last-dir-B
+                                         (file-name-directory f)))
+                                 (progn
+                                   (ediff-add-to-history
+                                    'file-name-history
+                                    (ediff-abbreviate-file-name
+                                     (expand-file-name
+                                      (file-name-nondirectory f)
+                                      dir-B)))
+                                   (ediff-get-default-file-name f 1)))
+           (read-number "Batch size (in bytes): " vlf-batch-size))))
+  (let ((buffer-A (vlf file-A)))
+    (set (make-local-variable 'vlf-batch-size) batch-size)
+    (let ((buffer-B (vlf file-B)))
+      (vlf-ediff-buffers buffer-A buffer-B))))
+
+(defun vlf-next-chunk ()
+  "Move to next chunk."
+  (let ((new-start (+ vlf-start-pos vlf-batch-size)))
+    (vlf-move-to-chunk new-start (+ new-start vlf-batch-size))))
+
+(defun vlf-prev-chunk ()
+  "Move to previous chunk."
+  (let ((new-start (- vlf-start-pos vlf-batch-size)))
+    (vlf-move-to-chunk new-start (+ new-start vlf-batch-size))))
+
+(defun vlf-ediff-next (buffer-A buffer-B &optional next-func)
+  "Activate ediff over the next difference in BUFFER-A and BUFFER-B.
+NEXT-FUNC is used to jump to the next logical chunks in case there is
+no difference at the current ones."
+  (set-buffer buffer-A)
+  (setq buffer-A (current-buffer)) ;names change, so reference by buffer object
+  (let ((end-A (= vlf-start-pos vlf-end-pos))
+        (content (buffer-substring-no-properties (point-min)
+                                                 (point-max))))
+    (set-buffer buffer-B)
+    (setq buffer-B (current-buffer))
+    (let ((end-B (= vlf-start-pos vlf-end-pos)))
+      (while (and (or (not end-A) (not end-B))
+                  (equal content (buffer-substring-no-properties
+                                  (point-min) (point-max))))
+        (funcall next-func)
+        (setq end-B (= vlf-start-pos vlf-end-pos))
+        (with-current-buffer buffer-A
+          (funcall next-func)
+          (setq content (buffer-substring-no-properties (point-min)
+                                                        (point-max))
+                end-A (= vlf-start-pos vlf-end-pos))))
+      (when (and end-A end-B)
+        (message "No (more) differences")
+        (set-buffer buffer-A)
+        (if (eq next-func 'vlf-next-chunk)
+            (let ((max-file-size vlf-file-size))
+              (with-current-buffer buffer-B
+                (setq max-file-size (max max-file-size vlf-file-size))
+                (vlf-move-to-chunk (- max-file-size vlf-batch-size)
+                                   max-file-size))
+              (vlf-move-to-chunk (- max-file-size vlf-batch-size)
+                                 max-file-size))
+          (vlf-beginning-of-file)
+          (set-buffer buffer-B)
+          (vlf-beginning-of-file))))
+    (ediff-buffers buffer-A buffer-B
+                   `((lambda () (setq vlf-ediff-session t)
+                       (if (< 0 ediff-number-of-differences)
+                           (ediff-jump-to-difference
+                            ,(if (eq next-func 'vlf-next-chunk) 1
+                               -1))))))))
+
+(defadvice ediff-next-difference (around vlf-ediff-next-difference
+                                         compile activate)
+  "Quit ediff session, move to the next VLF chunk and search for\
+difference if at the end of difference list."
+  (if (and vlf-ediff-session
+           (<= (1- ediff-number-of-differences)
+               ediff-current-difference))
+      (let ((buffer-A ediff-buffer-A)
+            (buffer-B ediff-buffer-B))
+        (ediff-really-quit nil)
+        (set-buffer buffer-A)
+        (vlf-next-chunk)
+        (set-buffer buffer-B)
+        (vlf-next-chunk)
+        (vlf-ediff-next buffer-A buffer-B 'vlf-next-chunk))
+    ad-do-it))
+
+(defadvice ediff-previous-difference (around vlf-ediff-prev-difference
+                                             compile activate)
+  "Quit ediff session, move to the previous VLF chunk and search for\
+difference if at the beginning of difference list."
+  (if (and vlf-ediff-session
+           (<= ediff-current-difference 0))
+      (let ((buffer-A ediff-buffer-A)
+            (buffer-B ediff-buffer-B))
+        (ediff-really-quit nil)
+        (set-buffer buffer-A)
+        (vlf-prev-chunk)
+        (set-buffer buffer-B)
+        (vlf-prev-chunk)
+        (vlf-ediff-next buffer-A buffer-B 'vlf-prev-chunk))
+    ad-do-it))
+
+(provide 'vlf-ediff)
+
+;;; vlf-ediff.el ends here
diff --git a/vlf.el b/vlf.el
index c567854..927d557 100644
--- a/vlf.el
+++ b/vlf.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 2006, 2012-2014 Free Software Foundation, Inc.
 
-;; Version: 1.3
+;; Version: 1.4
 ;; Keywords: large files, utilities
 ;; Maintainer: Andrey Kotlarski <m00naticus@gmail.com>
 ;; Authors: 2006 Mathias Dahl <mathias.dahl@gmail.com>



reply via email to

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