[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] 01/02: * packages/vlf: Perform search, occur and ediff opera
From: |
Andrey Kotlarski |
Subject: |
[elpa] 01/02: * packages/vlf: Perform search, occur and ediff operations over hexl content instead over raw data when hexl-mode is active. Allow vlf-occur results be saved to file and later reused. |
Date: |
Sat, 20 Sep 2014 16:08:05 +0000 |
m00natic pushed a commit to branch master
in repository elpa.
commit bdea86718db09678b8f16b2756ef458c544daaef
Author: Andrey Kotlarski <address@hidden>
Date: Sat Sep 20 18:41:06 2014 +0300
* packages/vlf: Perform search, occur and ediff operations over
hexl content instead over raw data when hexl-mode is active.
Allow vlf-occur results be saved to file and later reused.
* vlf.el (vlf): Use minimal batch size on remote files or if
manually specified.
Remove hooks used to disable/enable hexl-mode.
* vlf-integrate.el (abort-if-file-too-large): Don't use vlf-mode
if file size is less than default batch size.
* vlf-base.el (vlf-batch-size): Increase default batch size.
(vlf-move-to-chunk-1, vlf-move-to-chunk-2): Restore hexl-mode if
has been active on start.
* vlf-write.el (vlf-write): Restore hexl-mode if active on start
and don't ask spurious questions.
* vlf-search.el (vlf-re-search): Search over hexl content in case
hexl-mode is active on start.
(vlf-goto-line): Don't optimize search in case hexl-mode is
active.
* vlf-ediff.el (vlf-ediff-files): Use minimal batch size before
applying specified.
(vlf-ediff-next): Ediff over hexl-mode content when active instead
over raw data.
* vlf-occur.el (vlf-occur-vlf-file, vlf-occur-vlf-buffer)
(vlf-occur-regexp, vlf-occur-hexl, vlf-occur-lines): New
variables.
(vlf-occur-mode-map): Add save binding.
(vlf-occur-mode): Hook custom save function.
(vlf-occur-next-match, vlf-occur-prev-match): Use
get-text-property instead of get-char-property.
(vlf-occur-visit): Activate hexl-mode if it has been used during
occur.
(vlf-occur, vlf-build-occur): Perform occur over hexl content if
hexl-mode is active on start.
(vlf-occur-save, vlf-occur-load): New commands.
---
packages/vlf/vlf-base.el | 204 +++++++++++++++++++++----------------
packages/vlf/vlf-ediff.el | 23 +++--
packages/vlf/vlf-integrate.el | 7 +-
packages/vlf/vlf-occur.el | 229 +++++++++++++++++++++++++++++++++--------
packages/vlf/vlf-search.el | 86 +++++++++-------
packages/vlf/vlf-write.el | 66 +++++++------
packages/vlf/vlf.el | 35 ++----
7 files changed, 416 insertions(+), 234 deletions(-)
diff --git a/packages/vlf/vlf-base.el b/packages/vlf/vlf-base.el
index 98b6831..30e9b27 100644
--- a/packages/vlf/vlf-base.el
+++ b/packages/vlf/vlf-base.el
@@ -27,8 +27,8 @@
;;; Code:
-(defcustom vlf-batch-size 1024
- "Defines how large each batch of file data is (in bytes)."
+(defcustom vlf-batch-size 1000000
+ "Defines how large each batch of file data initially is (in bytes)."
:group 'vlf :type 'integer)
(put 'vlf-batch-size 'permanent-local t)
@@ -108,8 +108,7 @@ bytes added to the end."
0)))
(setq vlf-start-pos place
vlf-end-pos place)
- (if (not minimal)
- (vlf-update-buffer-name))
+ (or minimal (vlf-update-buffer-name))
(cons (- start place) (- place end)))))
((or (/= start vlf-start-pos)
(/= end vlf-end-pos))
@@ -126,85 +125,113 @@ bytes added to the end."
(let* ((modified (buffer-modified-p))
(start (max 0 start))
(end (min end vlf-file-size))
+ (hexl (derived-mode-p 'hexl-mode))
+ restore-hexl hexl-undo-list
(edit-end (if modified
- (+ vlf-start-pos
- (length (encode-coding-region
- (point-min) (point-max)
- buffer-file-coding-system t)))
- vlf-end-pos)))
- (cond
- ((or (< edit-end start) (< end vlf-start-pos)
- (not (verify-visited-file-modtime (current-buffer))))
- (when (or (not modified)
- (y-or-n-p "Chunk modified, are you sure? ")) ;full chunk
renewal
- (set-buffer-modified-p nil)
- (vlf-move-to-chunk-2 start end)))
- ((and (= start vlf-start-pos) (= end edit-end))
- (or modified (vlf-move-to-chunk-2 start end)))
- ((or (and (<= start vlf-start-pos) (<= edit-end end))
- (not modified)
- (y-or-n-p "Chunk modified, are you sure? "))
- (run-hooks 'vlf-before-chunk-update)
- (let ((shift-start 0)
- (shift-end 0))
- (let ((pos (+ (position-bytes (point)) vlf-start-pos))
- (inhibit-read-only t))
- (cond ((= end vlf-start-pos)
- (or (eq buffer-undo-list t)
- (setq buffer-undo-list nil))
- (vlf-with-undo-disabled (erase-buffer))
- (setq modified nil))
- ((< end edit-end)
- (setq end (car (vlf-delete-region
- (point-min) vlf-start-pos edit-end
- end (min (or (byte-to-position
- (- end vlf-start-pos))
- (point-min))
- (point-max))
- nil))))
- ((< edit-end end)
- (vlf-with-undo-disabled
- (setq shift-end (cdr (vlf-insert-file-contents
- vlf-end-pos end nil t
- (point-max)))))))
- (setq vlf-end-pos (+ end shift-end))
- (cond ((= start edit-end)
- (or (eq buffer-undo-list t)
- (setq buffer-undo-list nil))
- (vlf-with-undo-disabled
- (delete-region (point-min) (point)))
- (setq modified nil))
- ((< vlf-start-pos start)
- (let ((del-info (vlf-delete-region
- (point-min) vlf-start-pos
- vlf-end-pos start
- (min (or (byte-to-position
- (- start vlf-start-pos))
- (point))
- (point-max)) t)))
- (setq start (car del-info))
- (vlf-shift-undo-list (- (point-min)
- (cdr del-info)))))
- ((< start vlf-start-pos)
- (let ((edit-end-pos (point-max)))
- (vlf-with-undo-disabled
- (setq shift-start (car (vlf-insert-file-contents
- start vlf-start-pos t nil
- edit-end-pos)))
- (goto-char (point-min))
- (insert (delete-and-extract-region
- edit-end-pos (point-max))))
- (vlf-shift-undo-list (- (point-max)
- edit-end-pos)))))
- (setq start (- start shift-start))
- (goto-char (or (byte-to-position (- pos start))
- (byte-to-position (- pos vlf-start-pos))
- (point-max)))
- (setq vlf-start-pos start))
- (set-buffer-modified-p modified)
- (set-visited-file-modtime)
- (run-hooks 'vlf-after-chunk-update)
- (cons shift-start shift-end))))))
+ (progn
+ (when hexl
+ (setq restore-hexl t
+ hexl-undo-list buffer-undo-list
+ buffer-undo-list t)
+ (hexl-mode-exit))
+ (+ vlf-start-pos
+ (length (encode-coding-region
+ (point-min) (point-max)
+ buffer-file-coding-system t))))
+ vlf-end-pos))
+ (shifts
+ (cond
+ ((or (< edit-end start) (< end vlf-start-pos)
+ (not (verify-visited-file-modtime (current-buffer))))
+ (when (or (not modified)
+ (y-or-n-p "Chunk modified, are you sure? ")) ;full chunk
renewal
+ (set-buffer-modified-p nil)
+ (if (consp hexl-undo-list)
+ (setq hexl-undo-list nil))
+ (vlf-move-to-chunk-2 start end)))
+ ((and (= start vlf-start-pos) (= end edit-end))
+ (unless modified
+ (if (consp hexl-undo-list)
+ (setq hexl-undo-list nil))
+ (vlf-move-to-chunk-2 start end)))
+ ((or (and (<= start vlf-start-pos) (<= edit-end end))
+ (not modified)
+ (y-or-n-p "Chunk modified, are you sure? "))
+ (run-hooks 'vlf-before-chunk-update)
+ (when (and hexl (not restore-hexl))
+ (if (consp buffer-undo-list)
+ (setq buffer-undo-list nil))
+ (hexl-mode-exit))
+ (let ((shift-start 0)
+ (shift-end 0))
+ (let ((pos (+ (position-bytes (point)) vlf-start-pos))
+ (inhibit-read-only t))
+ (cond ((= end vlf-start-pos)
+ (or (eq buffer-undo-list t)
+ (setq buffer-undo-list nil))
+ (vlf-with-undo-disabled (erase-buffer))
+ (setq modified nil))
+ ((< end edit-end)
+ (setq end (car (vlf-delete-region
+ (point-min) vlf-start-pos
+ edit-end end
+ (min (or (byte-to-position
+ (- end vlf-start-pos))
+ (point-min))
+ (point-max))
+ nil))))
+ ((< edit-end end)
+ (vlf-with-undo-disabled
+ (setq shift-end (cdr (vlf-insert-file-contents
+ vlf-end-pos end nil t
+ (point-max)))))))
+ (setq vlf-end-pos (+ end shift-end))
+ (cond ((= start edit-end)
+ (or (eq buffer-undo-list t)
+ (setq buffer-undo-list nil))
+ (vlf-with-undo-disabled
+ (delete-region (point-min) (point)))
+ (setq modified nil))
+ ((< vlf-start-pos start)
+ (let ((del-info (vlf-delete-region
+ (point-min) vlf-start-pos
+ vlf-end-pos start
+ (min (or
+ (byte-to-position
+ (- start vlf-start-pos))
+ (point))
+ (point-max)) t)))
+ (setq start (car del-info))
+ (vlf-shift-undo-list (- (point-min)
+ (cdr del-info)))))
+ ((< start vlf-start-pos)
+ (let ((edit-end-pos (point-max)))
+ (vlf-with-undo-disabled
+ (setq shift-start (car
+ (vlf-insert-file-contents
+ start vlf-start-pos t nil
+ edit-end-pos)))
+ (goto-char (point-min))
+ (insert (delete-and-extract-region
+ edit-end-pos (point-max))))
+ (vlf-shift-undo-list (- (point-max)
+ edit-end-pos)))))
+ (setq start (- start shift-start))
+ (goto-char (or (byte-to-position (- pos start))
+ (byte-to-position (- pos vlf-start-pos))
+ (point-max)))
+ (setq vlf-start-pos start))
+ (set-buffer-modified-p modified)
+ (set-visited-file-modtime)
+ (when hexl
+ (hexl-mode)
+ (setq restore-hexl nil))
+ (run-hooks 'vlf-after-chunk-update)
+ (cons shift-start shift-end))))))
+ (when restore-hexl
+ (hexl-mode)
+ (setq buffer-undo-list hexl-undo-list))
+ shifts))
(defun vlf-move-to-chunk-2 (start end)
"Unconditionally move to chunk enclosed by START END bytes.
@@ -218,11 +245,14 @@ bytes added to the end."
(let ((inhibit-read-only t)
(pos (position-bytes (point))))
(vlf-with-undo-disabled
- (erase-buffer)
- (setq shifts (vlf-insert-file-contents vlf-start-pos
- vlf-end-pos t t)
- vlf-start-pos (- vlf-start-pos (car shifts))
- vlf-end-pos (+ vlf-end-pos (cdr shifts)))
+ (let ((hexl (derived-mode-p 'hexl-mode)))
+ (if hexl (hexl-mode-exit t))
+ (erase-buffer)
+ (setq shifts (vlf-insert-file-contents vlf-start-pos
+ vlf-end-pos t t)
+ vlf-start-pos (- vlf-start-pos (car shifts))
+ vlf-end-pos (+ vlf-end-pos (cdr shifts)))
+ (if hexl (hexl-mode)))
(goto-char (or (byte-to-position (+ pos (car shifts)))
(point-max)))))
(set-buffer-modified-p nil)
diff --git a/packages/vlf/vlf-ediff.el b/packages/vlf/vlf-ediff.el
index 2b7c63f..ef9d5c7 100644
--- a/packages/vlf/vlf-ediff.el
+++ b/packages/vlf/vlf-ediff.el
@@ -34,7 +34,6 @@
"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.
@@ -93,10 +92,10 @@ respectively of difference list, runs ediff over the
adjacent chunks."
dir-B)))
(ediff-get-default-file-name f 1)))
(read-number "Batch size (in bytes): " vlf-batch-size))))
- (let ((buffer-A (vlf file-A)))
+ (let ((buffer-A (vlf file-A t)))
(set-buffer buffer-A)
(vlf-set-batch-size batch-size)
- (let ((buffer-B (vlf file-B)))
+ (let ((buffer-B (vlf file-B t)))
(vlf-ediff-buffers buffer-A buffer-B))))
(defadvice ediff-next-difference (around vlf-ediff-next-difference
@@ -161,12 +160,14 @@ logical chunks in case there is no difference at the
current ones."
(point-max-A (point-max))
(font-lock-A font-lock-mode)
(min-file-size vlf-file-size)
- (forward-p (eq next-func 'vlf-next-chunk)))
+ (forward-p (eq next-func 'vlf-next-chunk))
+ (is-hexl (derived-mode-p 'hexl-mode)))
(font-lock-mode 0)
(set-buffer buffer-B)
(run-hook-with-args 'vlf-before-batch-functions 'ediff)
(setq buffer-B (current-buffer)
- min-file-size (min min-file-size vlf-file-size))
+ min-file-size (min min-file-size vlf-file-size)
+ is-hexl (or is-hexl (derived-mode-p 'hexl-mode)))
(let ((tramp-verbose (if (boundp 'tramp-verbose)
(min tramp-verbose 2)))
(end-B (= vlf-start-pos vlf-end-pos))
@@ -187,7 +188,7 @@ logical chunks in case there is no difference at the
current ones."
buffer-B (point-min) (point-max)))
(with-current-buffer ediff-buffer
(ediff-update-diffs)
- (and (not end-A) (not end-B)
+ (and (not end-A) (not end-B) (not is-hexl)
(vlf-ediff-refine buffer-A
buffer-B))
(zerop ediff-number-of-differences))))
@@ -221,9 +222,10 @@ logical chunks in case there is no difference at the
current ones."
(vlf-beginning-of-file))
(set-buffer ediff-buffer)
(ediff-update-diffs)
- (if (or (not forward-p)
- (and (not end-A) (not end-B)))
- (vlf-ediff-refine buffer-A buffer-B)))
+ (or is-hexl
+ (if (or (not forward-p)
+ (and (not end-A) (not end-B)))
+ (vlf-ediff-refine buffer-A buffer-B))))
(setq done t))
(unless done
(set-buffer buffer-A)
@@ -234,7 +236,8 @@ logical chunks in case there is no difference at the
current ones."
(vlf-move-to-chunk (car chunk-B) (cdr chunk-B))
(set-buffer ediff-buffer)
(ediff-update-diffs)
- (vlf-ediff-refine buffer-A buffer-B))
+ (or is-hexl
+ (vlf-ediff-refine buffer-A buffer-B)))
(set-buffer buffer-A)
(if font-lock-A (font-lock-mode 1))
(run-hook-with-args 'vlf-after-batch-functions 'ediff)
diff --git a/packages/vlf/vlf-integrate.el b/packages/vlf/vlf-integrate.el
index 435ac45..7bc8f94 100644
--- a/packages/vlf/vlf-integrate.el
+++ b/packages/vlf/vlf-integrate.el
@@ -29,6 +29,10 @@
(defgroup vlf nil "View Large Files in Emacs."
:prefix "vlf-" :group 'files)
+(defcustom vlf-batch-size 1000000
+ "Defines how large each batch of file data initially is (in bytes)."
+ :group 'vlf :type 'integer)
+
(defcustom vlf-application 'ask
"Determines when `vlf' will be offered on opening files.
Possible values are: nil to never use it;
@@ -98,7 +102,8 @@ OP-TYPE specifies the file operation being performed over
FILENAME."
(vlf filename)
(error ""))
((and large-file-warning-threshold
- (< large-file-warning-threshold size))
+ (< large-file-warning-threshold size)
+ (< vlf-batch-size size))
(if (eq vlf-application 'dont-ask)
(progn (vlf filename)
(error ""))
diff --git a/packages/vlf/vlf-occur.el b/packages/vlf/vlf-occur.el
index cea885e..2dac4a4 100644
--- a/packages/vlf/vlf-occur.el
+++ b/packages/vlf/vlf-occur.el
@@ -29,6 +29,21 @@
(require 'vlf)
+(defvar vlf-occur-vlf-file nil "VLF file that is searched.")
+(make-variable-buffer-local 'vlf-occur-vlf-file)
+
+(defvar vlf-occur-vlf-buffer nil "VLF buffer that is scanned.")
+(make-variable-buffer-local 'vlf-occur-vlf-buffer)
+
+(defvar vlf-occur-regexp)
+(make-variable-buffer-local 'vlf-occur-regexp)
+
+(defvar vlf-occur-hexl nil "Is `hexl-mode' active?")
+(make-variable-buffer-local 'vlf-occur-hexl)
+
+(defvar vlf-occur-lines 0 "Number of lines scanned by `vlf-occur'.")
+(make-variable-buffer-local 'vlf-occur-lines)
+
(defvar vlf-occur-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "n" 'vlf-occur-next-match)
@@ -37,16 +52,18 @@
(define-key map "\M-\r" 'vlf-occur-visit-new-buffer)
(define-key map [mouse-1] 'vlf-occur-visit)
(define-key map "o" 'vlf-occur-show)
+ (define-key map [remap save-buffer] 'vlf-occur-save)
map)
"Keymap for command `vlf-occur-mode'.")
(define-derived-mode vlf-occur-mode special-mode "VLF[occur]"
- "Major mode for showing occur matches of VLF opened files.")
+ "Major mode for showing occur matches of VLF opened files."
+ (add-hook 'write-file-functions 'vlf-occur-save nil t))
(defun vlf-occur-next-match ()
"Move cursor to next match."
(interactive)
- (if (eq (get-char-property (point) 'face) 'match)
+ (if (eq (get-text-property (point) 'face) 'match)
(goto-char (next-single-property-change (point) 'face)))
(goto-char (or (text-property-any (point) (point-max) 'face 'match)
(text-property-any (point-min) (point)
@@ -55,9 +72,9 @@
(defun vlf-occur-prev-match ()
"Move cursor to previous match."
(interactive)
- (if (eq (get-char-property (point) 'face) 'match)
+ (if (eq (get-text-property (point) 'face) 'match)
(goto-char (previous-single-property-change (point) 'face)))
- (while (not (eq (get-char-property (point) 'face) 'match))
+ (while (not (eq (get-text-property (point) 'face) 'match))
(goto-char (or (previous-single-property-change (point) 'face)
(point-max)))))
@@ -91,26 +108,38 @@ EVENT may hold details of the invocation."
(goto-char (posn-point (event-end event))))
(let* ((pos (point))
(pos-relative (- pos (line-beginning-position) 1))
- (file (get-char-property pos 'file)))
- (if file
- (let ((chunk-start (get-char-property pos 'chunk-start))
- (chunk-end (get-char-property pos 'chunk-end))
- (vlf-buffer (get-char-property pos 'buffer))
+ (chunk-start (get-text-property pos 'chunk-start)))
+ (if chunk-start
+ (let ((chunk-end (get-text-property pos 'chunk-end))
+ (file (if (file-exists-p vlf-occur-vlf-file)
+ vlf-occur-vlf-file
+ (setq vlf-occur-vlf-file
+ (read-file-name
+ (concat vlf-occur-vlf-file
+ " doesn't exist, locate it: ")))))
+ (vlf-buffer vlf-occur-vlf-buffer)
+ (not-hexl (not vlf-occur-hexl))
(occur-buffer (current-buffer))
- (match-pos (+ (get-char-property pos 'line-pos)
+ (match-pos (+ (get-text-property pos 'line-pos)
pos-relative)))
(cond (current-prefix-arg
- (setq vlf-buffer (vlf file))
+ (setq vlf-buffer (vlf file t))
+ (or not-hexl (hexl-mode))
(switch-to-buffer occur-buffer))
((not (buffer-live-p vlf-buffer))
- (or (catch 'found
- (dolist (buf (buffer-list))
- (set-buffer buf)
- (and vlf-mode (equal file buffer-file-name)
- (setq vlf-buffer buf)
- (throw 'found t))))
- (setq vlf-buffer (vlf file)))
- (switch-to-buffer occur-buffer)))
+ (unless (catch 'found
+ (dolist (buf (buffer-list))
+ (set-buffer buf)
+ (and vlf-mode
+ (equal file buffer-file-name)
+ (eq (not (derived-mode-p 'hexl-mode))
+ not-hexl)
+ (setq vlf-buffer buf)
+ (throw 'found t))))
+ (setq vlf-buffer (vlf file t))
+ (or not-hexl (hexl-mode)))
+ (switch-to-buffer occur-buffer)
+ (setq vlf-occur-vlf-buffer vlf-buffer)))
(pop-to-buffer vlf-buffer)
(vlf-move-to-chunk chunk-start chunk-end)
(goto-char match-pos)))))
@@ -124,14 +153,19 @@ Prematurely ending indexing will still show what's found
so far."
(if (buffer-modified-p) ;use temporary buffer not to interfere with
modifications
(let ((vlf-buffer (current-buffer))
(file buffer-file-name)
- (batch-size vlf-batch-size))
+ (batch-size vlf-batch-size)
+ (is-hexl (derived-mode-p 'hexl-mode)))
(with-temp-buffer
- (setq buffer-file-name file)
+ (setq buffer-file-name file
+ buffer-file-truename file
+ buffer-undo-list t)
(set-buffer-modified-p nil)
(set (make-local-variable 'vlf-batch-size) batch-size)
(vlf-mode 1)
- (goto-char (point-min))
+ (if is-hexl
+ (hexl-mode))
(run-hook-with-args 'vlf-before-batch-functions 'occur)
+ (goto-char (point-min))
(vlf-with-undo-disabled
(vlf-build-occur regexp vlf-buffer))
(run-hook-with-args 'vlf-after-batch-functions 'occur)))
@@ -155,7 +189,6 @@ Prematurely ending indexing will still show what's found so
far."
(line 1)
(last-match-line 0)
(last-line-pos (point-min))
- (file buffer-file-name)
(total-matches 0)
(match-end-pos (+ vlf-start-pos (position-bytes (point))))
(occur-buffer (generate-new-buffer
@@ -165,10 +198,13 @@ Prematurely ending indexing will still show what's found
so far."
(line-regexp (concat "\\(?5:[\n\C-m]\\)\\|\\(?10:"
regexp "\\)"))
(batch-step (/ vlf-batch-size 8))
+ (is-hexl (derived-mode-p 'hexl-mode))
(end-of-file nil)
(reporter (make-progress-reporter
(concat "Building index for " regexp "...")
vlf-start-pos vlf-file-size)))
+ (with-current-buffer occur-buffer
+ (setq buffer-undo-list t))
(unwind-protect
(progn
(while (not end-of-file)
@@ -197,8 +233,6 @@ Prematurely ending indexing will still show what's found so
far."
(number-to-string line)
'face 'shadow)))
(insert (propertize line-text ; insert line
- 'file file
- 'buffer vlf-buffer
'chunk-start chunk-start
'chunk-end chunk-end
'mouse-face '(highlight)
@@ -222,35 +256,142 @@ Prematurely ending indexing will still show what's found
so far."
(setq end-of-file (= vlf-end-pos vlf-file-size))
(unless end-of-file
(let ((batch-move (- vlf-end-pos batch-step)))
- (vlf-move-to-batch (if (< batch-move match-end-pos)
- match-end-pos
- batch-move) t))
- (goto-char (if (< vlf-start-pos match-end-pos)
- (or (byte-to-position (- match-end-pos
- vlf-start-pos))
- (point-min))
- (point-min)))
+ (vlf-move-to-batch (if (or is-hexl
+ (< match-end-pos
+ batch-move))
+ batch-move
+ match-end-pos) t))
+ (goto-char (if (or is-hexl
+ (<= match-end-pos vlf-start-pos))
+ (point-min)
+ (or (byte-to-position (- match-end-pos
+ vlf-start-pos))
+ (point-min))))
(setq last-match-line 0
last-line-pos (line-beginning-position))
(progress-reporter-update reporter vlf-end-pos))))
(progress-reporter-done reporter))
(set-buffer-modified-p nil)
(if (zerop total-matches)
- (progn (with-current-buffer occur-buffer
- (set-buffer-modified-p nil))
- (kill-buffer occur-buffer)
+ (progn (kill-buffer occur-buffer)
(message "No matches for \"%s\"" regexp))
- (with-current-buffer occur-buffer
- (goto-char (point-min))
- (insert (propertize
- (format "%d matches in %d lines for \"%s\" \
+ (let ((file buffer-file-name)
+ (dir default-directory))
+ (with-current-buffer occur-buffer
+ (goto-char (point-min))
+ (insert (propertize
+ (format "%d matches from %d lines for \"%s\" \
in file: %s" total-matches line regexp file)
- 'face 'underline))
- (set-buffer-modified-p nil)
- (forward-char 2)
- (vlf-occur-mode))
+ 'face 'underline))
+ (set-buffer-modified-p nil)
+ (forward-char 2)
+ (vlf-occur-mode)
+ (setq default-directory dir
+ vlf-occur-vlf-file file
+ vlf-occur-vlf-buffer vlf-buffer
+ vlf-occur-regexp regexp
+ vlf-occur-hexl is-hexl
+ vlf-occur-lines line)))
(display-buffer occur-buffer)))))
+
+;; save, load vlf-occur data
+
+(defun vlf-occur-save (file)
+ "Serialize `vlf-occur' results to FILE which can later be reloaded."
+ (interactive (list (or buffer-file-name
+ (read-file-name "Save vlf-occur results in: "
+ nil nil nil
+ (concat
+ (file-name-nondirectory
+ vlf-occur-vlf-file)
+ ".vlfo")))))
+ (setq buffer-file-name file)
+ (let ((vlf-occur-save-buffer
+ (generate-new-buffer (concat "*VLF-occur-save "
+ (file-name-nondirectory file)
+ "*"))))
+ (with-current-buffer vlf-occur-save-buffer
+ (setq buffer-file-name file
+ buffer-undo-list t)
+ (insert ";; -*- eval: (vlf-occur-load) -*-\n"))
+ (prin1 (list vlf-occur-vlf-file vlf-occur-regexp vlf-occur-hexl
+ vlf-occur-lines)
+ vlf-occur-save-buffer)
+ (save-excursion
+ (goto-char (point-min))
+ (while (zerop (forward-line))
+ (let* ((pos (1+ (point)))
+ (line (get-char-property (1- pos) 'before-string)))
+ (if line
+ (prin1 (list (string-to-number line)
+ (get-text-property pos 'chunk-start)
+ (get-text-property pos 'chunk-end)
+ (get-text-property pos 'line-pos)
+ (buffer-substring-no-properties
+ pos (line-end-position)))
+ vlf-occur-save-buffer)))))
+ (with-current-buffer vlf-occur-save-buffer
+ (save-buffer))
+ (kill-buffer vlf-occur-save-buffer))
+ t)
+
+;;;###autoload
+(defun vlf-occur-load ()
+ "Load serialized `vlf-occur' results from current buffer."
+ (interactive)
+ (goto-char (point-min))
+ (let* ((vlf-occur-data-buffer (current-buffer))
+ (header (read vlf-occur-data-buffer))
+ (vlf-file (nth 0 header))
+ (regexp (nth 1 header))
+ (all-lines (nth 3 header))
+ (file buffer-file-name)
+ (vlf-occur-buffer
+ (generate-new-buffer (concat "*VLF-occur "
+ (file-name-nondirectory file)
+ "*"))))
+ (switch-to-buffer vlf-occur-buffer)
+ (setq buffer-file-name file
+ buffer-undo-list t)
+ (goto-char (point-min))
+ (let ((match-count 0)
+ (form 0))
+ (while (setq form (ignore-errors (read vlf-occur-data-buffer)))
+ (goto-char (point-max))
+ (insert "\n:")
+ (let* ((overlay-pos (1- (point)))
+ (overlay (make-overlay overlay-pos (1+ overlay-pos)))
+ (line (number-to-string (nth 0 form)))
+ (pos (point)))
+ (overlay-put overlay 'before-string
+ (propertize line 'face 'shadow))
+ (insert (propertize (nth 4 form) 'chunk-start (nth 1 form)
+ 'chunk-end (nth 2 form)
+ 'mouse-face '(highlight)
+ 'line-pos (nth 3 form)
+ 'help-echo (concat "Move to line "
+ line)))
+ (goto-char pos)
+ (while (re-search-forward regexp nil t)
+ (add-text-properties
+ (match-beginning 0) (match-end 0)
+ (list 'face 'match 'help-echo
+ (format "Move to match %d"
+ (setq match-count (1+ match-count))))))))
+ (kill-buffer vlf-occur-data-buffer)
+ (goto-char (point-min))
+ (insert (propertize
+ (format "%d matches from %d lines for \"%s\" in file: %s"
+ match-count all-lines regexp vlf-file)
+ 'face 'underline)))
+ (set-buffer-modified-p nil)
+ (vlf-occur-mode)
+ (setq vlf-occur-vlf-file vlf-file
+ vlf-occur-regexp regexp
+ vlf-occur-hexl (nth 2 header)
+ vlf-occur-lines all-lines)))
+
(provide 'vlf-occur)
;;; vlf-occur.el ends here
diff --git a/packages/vlf/vlf-search.el b/packages/vlf/vlf-search.el
index 0462cb2..3b81d57 100644
--- a/packages/vlf/vlf-search.el
+++ b/packages/vlf/vlf-search.el
@@ -43,6 +43,7 @@ BATCH-STEP is amount of overlap between successive chunks."
(match-start-pos (+ vlf-start-pos (position-bytes (point))))
(match-end-pos match-start-pos)
(to-find count)
+ (is-hexl (derived-mode-p 'hexl-mode))
(font-lock font-lock-mode)
(reporter (make-progress-reporter
(concat "Searching for " regexp "...")
@@ -72,16 +73,18 @@ BATCH-STEP is amount of overlap between successive chunks."
(- vlf-batch-size
batch-step))))
(vlf-move-to-batch
- (if (< match-start-pos batch-move)
- (- match-start-pos vlf-batch-size)
- batch-move) t))
- (goto-char (if (< match-start-pos
- vlf-end-pos)
- (or (byte-to-position
+ (if (or is-hexl
+ (<= batch-move match-start-pos))
+ batch-move
+ (- match-start-pos vlf-batch-size)) t))
+ (goto-char (if (or is-hexl
+ (<= vlf-end-pos
+ match-start-pos))
+ (point-max)
+ (or (byte-to-position
(- match-start-pos
vlf-start-pos))
- (point-max))
- (point-max)))
+ (point-max))))
(progress-reporter-update
reporter (- vlf-file-size
vlf-start-pos)))))
@@ -100,15 +103,17 @@ BATCH-STEP is amount of overlap between successive
chunks."
(throw 'end-of-file nil))
(t (let ((batch-move (- vlf-end-pos batch-step)))
(vlf-move-to-batch
- (if (< batch-move match-end-pos)
- match-end-pos
- batch-move) t))
- (goto-char (if (< vlf-start-pos match-end-pos)
- (or (byte-to-position
+ (if (or is-hexl
+ (< match-end-pos batch-move))
+ batch-move
+ match-end-pos) t))
+ (goto-char (if (or is-hexl
+ (<= match-end-pos vlf-start-pos))
+ (point-min)
+ (or (byte-to-position
(- match-end-pos
vlf-start-pos))
- (point-min))
- (point-min)))
+ (point-min))))
(progress-reporter-update reporter
vlf-end-pos)))))
(progress-reporter-done reporter))
@@ -189,6 +194,7 @@ Search is performed chunk by chunk in `vlf-batch-size'
memory."
(start-pos vlf-start-pos)
(end-pos vlf-end-pos)
(pos (point))
+ (is-hexl (derived-mode-p 'hexl-mode))
(font-lock font-lock-mode)
(success nil))
(font-lock-mode 0)
@@ -203,19 +209,20 @@ Search is performed chunk by chunk in `vlf-batch-size'
memory."
(inhibit-read-only t))
(setq n (1- n))
(vlf-with-undo-disabled
- (while (and (< (- end start) n)
- (< n (- vlf-file-size start)))
- (erase-buffer)
- (insert-file-contents-literally buffer-file-name
- nil start end)
- (goto-char (point-min))
- (while (re-search-forward "[\n\C-m]" nil t)
- (setq n (1- n)))
- (vlf-verify-size)
- (setq start end
- end (min vlf-file-size
- (+ start vlf-batch-size)))
- (progress-reporter-update reporter start))
+ (or is-hexl
+ (while (and (< (- end start) n)
+ (< n (- vlf-file-size start)))
+ (erase-buffer)
+ (insert-file-contents-literally buffer-file-name
+ nil start end)
+ (goto-char (point-min))
+ (while (re-search-forward "[\n\C-m]" nil t)
+ (setq n (1- n)))
+ (vlf-verify-size)
+ (setq start end
+ end (min vlf-file-size
+ (+ start vlf-batch-size)))
+ (progress-reporter-update reporter start)))
(when (< n (- vlf-file-size end))
(vlf-move-to-chunk-2 start end)
(goto-char (point-min))
@@ -229,17 +236,18 @@ Search is performed chunk by chunk in `vlf-batch-size'
memory."
(inhibit-read-only t))
(setq n (- n))
(vlf-with-undo-disabled
- (while (and (< (- end start) n) (< n end))
- (erase-buffer)
- (insert-file-contents-literally buffer-file-name nil
- start end)
- (goto-char (point-max))
- (while (re-search-backward "[\n\C-m]" nil t)
- (setq n (1- n)))
- (setq end start
- start (max 0 (- end vlf-batch-size)))
- (progress-reporter-update reporter
- (- vlf-file-size end)))
+ (or is-hexl
+ (while (and (< (- end start) n) (< n end))
+ (erase-buffer)
+ (insert-file-contents-literally buffer-file-name
+ nil start end)
+ (goto-char (point-max))
+ (while (re-search-backward "[\n\C-m]" nil t)
+ (setq n (1- n)))
+ (setq end start
+ start (max 0 (- end vlf-batch-size)))
+ (progress-reporter-update reporter
+ (- vlf-file-size end))))
(when (< n end)
(vlf-move-to-chunk-2 start end)
(goto-char (point-max))
diff --git a/packages/vlf/vlf-write.el b/packages/vlf/vlf-write.el
index 1c5db49..5c94113 100644
--- a/packages/vlf/vlf-write.el
+++ b/packages/vlf/vlf-write.el
@@ -37,37 +37,43 @@ If changing size of chunk, shift remaining file content."
(or (verify-visited-file-modtime (current-buffer))
(y-or-n-p "File has changed since visited or saved.\
Save anyway? ")))
+ (widen)
(run-hook-with-args 'vlf-before-batch-functions 'write)
- (if (zerop vlf-file-size) ;new file
- (progn (write-region nil nil buffer-file-name vlf-start-pos t)
- (setq vlf-file-size (vlf-get-file-size
- buffer-file-truename)
- vlf-end-pos vlf-file-size)
- (vlf-update-buffer-name))
- (widen)
- (let* ((region-length (length (encode-coding-region
- (point-min) (point-max)
- buffer-file-coding-system t)))
- (size-change (- vlf-end-pos vlf-start-pos
- region-length)))
- (if (zerop size-change)
- (write-region nil nil buffer-file-name vlf-start-pos t)
- (let ((tramp-verbose (if (boundp 'tramp-verbose)
- (min tramp-verbose 2)))
- (pos (point))
- (font-lock font-lock-mode))
- (font-lock-mode 0)
- (if (< 0 size-change)
- (vlf-file-shift-back size-change)
- (vlf-file-shift-forward (- size-change)))
- (if font-lock (font-lock-mode 1))
- (vlf-move-to-chunk-2 vlf-start-pos
- (if (< (- vlf-end-pos vlf-start-pos)
- vlf-batch-size)
- (+ vlf-start-pos vlf-batch-size)
- vlf-end-pos))
- (vlf-update-buffer-name)
- (goto-char pos)))))
+ (let ((hexl (derived-mode-p 'hexl-mode)))
+ (when hexl
+ (if (consp buffer-undo-list)
+ (setq buffer-undo-list nil))
+ (hexl-mode-exit))
+ (if (zerop vlf-file-size) ;new file
+ (progn (write-region nil nil buffer-file-name vlf-start-pos t)
+ (setq vlf-file-size (vlf-get-file-size
+ buffer-file-truename)
+ vlf-end-pos vlf-file-size)
+ (vlf-update-buffer-name))
+ (let* ((region-length (length (encode-coding-region
+ (point-min) (point-max)
+ buffer-file-coding-system t)))
+ (size-change (- vlf-end-pos vlf-start-pos
+ region-length)))
+ (if (zerop size-change)
+ (write-region nil nil buffer-file-name vlf-start-pos t)
+ (let ((tramp-verbose (if (boundp 'tramp-verbose)
+ (min tramp-verbose 2)))
+ (pos (point))
+ (font-lock font-lock-mode))
+ (font-lock-mode 0)
+ (if (< 0 size-change)
+ (vlf-file-shift-back size-change)
+ (vlf-file-shift-forward (- size-change)))
+ (if font-lock (font-lock-mode 1))
+ (vlf-move-to-chunk-2 vlf-start-pos
+ (if (< (- vlf-end-pos vlf-start-pos)
+ vlf-batch-size)
+ (+ vlf-start-pos vlf-batch-size)
+ vlf-end-pos))
+ (vlf-update-buffer-name)
+ (goto-char pos)))))
+ (if hexl (hexl-mode)))
(run-hook-with-args 'vlf-after-batch-functions 'write))
t)
diff --git a/packages/vlf/vlf.el b/packages/vlf/vlf.el
index 2e3c9a1..8eb2a4c 100644
--- a/packages/vlf/vlf.el
+++ b/packages/vlf/vlf.el
@@ -145,17 +145,22 @@ values are: `write', `ediff', `occur', `search',
`goto-line'."
(setq vlf-mode t))
;;;###autoload
-(defun vlf (file)
- "View Large FILE in batches.
+(defun vlf (file &optional minimal)
+ "View Large FILE in batches. When MINIMAL load just a few bytes.
You can customize number of bytes displayed by customizing
`vlf-batch-size'.
Return newly created buffer."
- (interactive "fFile to open: ")
+ (interactive (list (read-file-name "File to open: ") nil))
(let ((vlf-buffer (generate-new-buffer "*vlf*")))
(set-buffer vlf-buffer)
(set-visited-file-name file)
(set-buffer-modified-p nil)
+ (if (or minimal (file-remote-p file))
+ (set (make-local-variable 'vlf-batch-size) 1024))
(vlf-mode 1)
+ (when minimal ;restore batch size to default value
+ (kill-local-variable 'vlf-batch-size)
+ (make-local-variable 'vlf-batch-size))
(switch-to-buffer vlf-buffer)
vlf-buffer))
@@ -206,24 +211,8 @@ When prefix argument is negative
(goto-char (point-max)))
ad-do-it))
-;; hexl mode integration
-(defun vlf-hexl-before (&optional operation)
- "Temporarily disable `hexl-mode' for OPERATION."
- (when (derived-mode-p 'hexl-mode)
- (hexl-mode-exit)
- (set (make-local-variable 'vlf-restore-hexl-mode) operation)))
-
-(defun vlf-hexl-after (&optional operation)
- "Re-enable `hexl-mode' if active before OPERATION."
- (when (and (boundp 'vlf-restore-hexl-mode)
- (eq vlf-restore-hexl-mode operation))
- (hexl-mode)
- (kill-local-variable 'vlf-restore-hexl-mode)))
-
-(add-hook 'vlf-before-batch-functions 'vlf-hexl-before)
-(add-hook 'vlf-after-batch-functions 'vlf-hexl-after)
-(add-hook 'vlf-before-chunk-update 'vlf-hexl-before)
-(add-hook 'vlf-after-chunk-update 'vlf-hexl-after)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; hexl mode integration
(eval-after-load "hexl"
'(progn
@@ -279,8 +268,8 @@ with the prefix argument DECREASE it is halved."
(vlf-verify-size)
(vlf-move-to-batch vlf-file-size))
-(defun vlf-revert (&optional _ignore-auto noconfirm)
- "Revert current chunk. Ignore _IGNORE-AUTO.
+(defun vlf-revert (&optional _auto noconfirm)
+ "Revert current chunk. Ignore _AUTO.
Ask for confirmation if NOCONFIRM is nil."
(interactive)
(when (or noconfirm