1
0
mirror of https://github.com/m00natic/vlfi.git synced 2025-11-08 02:51:38 +00:00

23 Commits
1.0 ... 1.2

Author SHA1 Message Date
Andrey Kotlarski
290c4ac885 Fix save with adjustment. 2013-12-13 17:08:13 +02:00
Andrey Kotlarski
db1da304d5 Use buffer-file-truename for file size determination and remove
superfluous checks to vlf-verify-size when saving.  Fix vlf-revert not
to ask unnecessary.
2013-12-13 02:32:30 +02:00
Andrey Kotlarski
655805ce48 Fix vlf-next-batch-from-point behaviour near end of file. 2013-12-13 02:30:29 +02:00
Andrey Kotlarski
bb482f0b0f Fix file size determination for symbolic links. 2013-12-12 16:16:32 +02:00
Andrey Kotlarski
9ffb968793 Remove defadvice abort-if-file-too-large argument list so it works
correctly with GNU Emacs 23.
2013-12-12 14:47:28 +02:00
Andrey Kotlarski
099adab959 Fix abort-if-file-too-large advice not to activate VLF in case of empty
file.
2013-12-12 13:47:49 +02:00
Andrey Kotlarski
65b4d7413f Refactor vlf-write. 2013-12-12 02:20:03 +02:00
Andrey Kotlarski
2e2bca6999 Fix file size determination after save and move vlf-with-undo-disabled
macro before vlf-mode declaration.
2013-12-12 02:07:25 +02:00
Andrey Kotlarski
ea46386cbc Don't apply VLF by default over image and pdf files. 2013-12-11 16:15:26 +02:00
Andrey Kotlarski
d1af56d776 Fix opening of files for GNU Emacs 23. 2013-12-11 16:07:14 +02:00
Andrey Kotlarski
152462a654 Fix autoloads in last commit. 2013-12-11 16:01:12 +02:00
Andrey Kotlarski
9c50487982 Introduce list of major modes where VLF will not activate. 2013-12-11 15:58:35 +02:00
Andrey Kotlarski
88924f9c05 Fix vlf-write behaviour for newly created file. 2013-12-11 13:07:51 +02:00
Andrey Kotlarski
2aea17ab38 Fix behaviour when size is missing (creating file) in
abort-if-file-too-large, vlf-mode is started over existing buffer.
Rename default vlf-application value to `ask'.
2013-12-11 12:01:26 +02:00
Andrey Kotlarski
72fec35f44 Update README and bump version. 2013-12-11 03:21:08 +02:00
Andrey Kotlarski
a0cafa71ea Explicitly offer vlf-prefix-map so user can easily define another prefix
for vlf-mode-map.  Remove vlf-refresh and refine vlf-revert.
2013-12-11 02:56:01 +02:00
Andrey Kotlarski
c68c34ea90 Add vlf-application customization which refines control over when
vlf-mode is automatically invoked or offered.
2013-12-11 02:54:44 +02:00
Andrey Kotlarski
c0a85cdcfe Fix position when moving to overlapping chunk. 2013-12-11 02:51:46 +02:00
Andrey Kotlarski
371c560f4b Bump version and remove warning - save is now reliable. 2013-12-11 01:11:13 +02:00
Andrey Kotlarski
a3901b8f1a Fix deletion when moving to partially overlapping chunk and enable more
intelligent behaviour in cases of overlapping and modifications.
2013-12-09 01:55:41 +02:00
Andrey Kotlarski
f4ee23c07f Fix chunk end adjustment and save for current and older Emacsen. 2013-12-08 21:11:08 +02:00
Andrey Kotlarski
959bbc7661 Disable undo in cases of partial chunk move. 2013-12-08 17:22:23 +02:00
Andrey Kotlarski
0080991fa9 Fix chunk end adjustment and save for trunk Emacs. 2013-12-08 17:21:34 +02:00
2 changed files with 279 additions and 164 deletions

View File

@@ -17,6 +17,8 @@ what it does in a nutshell:
- newly added content is acknowledged if file has changed size
meanwhile
- automatic scrolling of batches
- as VLF is minor mode, font locking and functionality of the
respective major mode is also present
- VLF is added as an option when opening large files
GNU Emacs 23 and 24 are supported.
@@ -43,6 +45,30 @@ integer value), VLF will probably not quite work.
* Detail usage
** Applicability
You can control when vlf-mode is invoked or offered as choice with the
*vlf-application* customization option. By default it will offer VLF
when opening large files. There are also options to never use it (you
can still call *vlf* command explicitly); to use it without asking for
large files or to invoke it on all files. Here's example setup such
that vlf-mode automatically launches for large files:
#+BEGIN_EXAMPLE
(custom-set-variables
'(vlf-application 'dont-ask))
#+END_EXAMPLE
** Keymap
All VLF operations are grouped under the *C-c C-v* prefix by default.
Here's example how to add another prefix (*C-x v*):
#+BEGIN_EXAMPLE
(eval-after-load "vlf"
'(define-key vlf-prefix-map "\C-xv" vlf-mode-map))
#+END_EXAMPLE
** Control batch size
*C-c C-v +* and *C-c C-v -* control current batch size by factors
@@ -53,11 +79,11 @@ refresh with *C-c C-v g*.
** Move around
*C-c C-v PgUp* and *C-c C-v PgDn* move batch by batch. With positive
*C-c C-v n* and *C-c C-v p* move batch by batch. With positive
prefix argument they move prefix number of batches. With negative -
append prefix number of batches.
*C-c C-v n* displays batch starting from current point.
*C-c C-v SPC* displays batch starting from current point.
*C-c C-v [* and *C-c C-v ]* take you to the beginning and end of file
respectively.
@@ -88,15 +114,8 @@ from the beginning, so again the bigger current batch size, the
quicker. With negative argument, lines are counted from the end of
file.
** Reload
*C-c C-v g* discards modifications (if such) and reloads chunk.
** Edit and save
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.
*Warning* Saving changes to non-ASCII chunks is a bit risky right
now.

406
vlf.el
View File

@@ -2,7 +2,7 @@
;; Copyright (C) 2006, 2012, 2013 Free Software Foundation, Inc.
;; Version: 1.0
;; Version: 1.2
;; Keywords: large files, utilities
;; Maintainer: Andrey Kotlarski <m00naticus@gmail.com>
;; Authors: 2006 Mathias Dahl <mathias.dahl@gmail.com>
@@ -45,10 +45,23 @@
(defcustom vlf-batch-size 1024
"Defines how large each batch of file data is (in bytes)."
:type 'integer
:group 'vlf)
:group 'vlf
:type 'integer)
(put 'vlf-batch-size 'permanent-local t)
;;;###autoload
(defcustom vlf-application 'ask
"Determines when `vlf' will be offered on opening files.
Possible values are: nil to never use it;
`ask' offer `vlf' when file size is beyond `large-file-warning-threshold';
`dont-ask' automatically use `vlf' for large files;
`always' use `vlf' for all files."
:group 'vlf
:type '(radio (const :format "%v " nil)
(const :format "%v " ask)
(const :format "%v " dont-ask)
(const :format "%v" always)))
;;; Keep track of file position.
(defvar vlf-start-pos 0
"Absolute position of the visible chunk start.")
@@ -61,11 +74,10 @@
(put 'vlf-file-size 'permanent-local t)
(defvar vlf-mode-map
(let ((map-prefix (make-sparse-keymap))
(map (make-sparse-keymap)))
(define-key map [next] 'vlf-next-batch)
(define-key map [prior] 'vlf-prev-batch)
(define-key map "n" 'vlf-next-batch-from-point)
(let ((map (make-sparse-keymap)))
(define-key map "n" 'vlf-next-batch)
(define-key map "p" 'vlf-prev-batch)
(define-key map " " 'vlf-next-batch-from-point)
(define-key map "+" 'vlf-change-batch-size)
(define-key map "-"
(lambda () "Decrease vlf batch size by factor of 2."
@@ -78,26 +90,41 @@
(define-key map "]" 'vlf-end-of-file)
(define-key map "j" 'vlf-jump-to-chunk)
(define-key map "l" 'vlf-goto-line)
(define-key map "g" 'vlf-refresh)
(define-key map-prefix "\C-c\C-v" map)
map-prefix)
(define-key map "g" 'vlf-revert)
map)
"Keymap for `vlf-mode'.")
(defvar vlf-prefix-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-c\C-v" vlf-mode-map)
map)
"Prefixed keymap for `vlf-mode'.")
(defmacro vlf-with-undo-disabled (&rest body)
"Execute BODY with temporarily disabled undo."
`(let ((undo-enabled (not (eq buffer-undo-list t))))
(if undo-enabled
(buffer-disable-undo))
(unwind-protect (progn ,@body)
(if undo-enabled
(buffer-enable-undo)))))
(define-minor-mode vlf-mode
"Mode to browse large files in."
:lighter " VLF"
:group 'vlf
:keymap vlf-mode-map
:keymap vlf-prefix-map
(if vlf-mode
(progn
(set (make-local-variable 'require-final-newline) nil)
(add-hook 'write-file-functions 'vlf-write nil t)
(set (make-local-variable 'revert-buffer-function)
'vlf-revert)
(make-local-variable 'vlf-batch-size)
(set (make-local-variable 'vlf-start-pos) -1)
(make-local-variable 'vlf-end-pos)
(set (make-local-variable 'vlf-file-size)
(vlf-get-file-size buffer-file-name))
(vlf-get-file-size buffer-file-truename))
(set (make-local-variable 'vlf-start-pos) 0)
(set (make-local-variable 'vlf-end-pos) 0)
(let* ((pos (position-bytes (point)))
(start (* (/ pos vlf-batch-size) vlf-batch-size)))
(goto-char (byte-to-position (- pos start)))
@@ -108,13 +135,11 @@
(y-or-n-p (format "Load whole file (%s)? "
(file-size-human-readable
vlf-file-size))))
(kill-local-variable 'require-final-newline)
(remove-hook 'write-file-functions 'vlf-write t)
(let ((pos (+ vlf-start-pos (position-bytes (point)))))
(vlf-with-undo-disabled
(erase-buffer)
(insert-file-contents buffer-file-name))
(set-visited-file-modtime)
(set-buffer-modified-p nil)
(insert-file-contents buffer-file-name t nil nil t))
(goto-char (byte-to-position pos)))
(rename-buffer (file-name-nondirectory buffer-file-name) t))))
@@ -143,37 +168,84 @@ You can customize number of bytes displayed by customizing
(eval-after-load "dired"
'(define-key dired-mode-map "V" 'dired-vlf))
;;;###autoload
(defcustom vlf-forbidden-modes-list
'(archive-mode tar-mode jka-compr git-commit-mode image-mode
doc-view-mode doc-view-mode-maybe)
"Major modes which VLF will not be automatically applied to."
:group 'vlf
:type '(list symbol))
;;;###autoload
(defun vlf-determine-major-mode (filename)
"Determine major mode from FILENAME."
(let ((name filename)
(remote-id (file-remote-p filename))
mode)
;; Remove backup-suffixes from file name.
(setq name (file-name-sans-versions name))
;; Remove remote file name identification.
(and (stringp remote-id)
(string-match (regexp-quote remote-id) name)
(setq name (substring name (match-end 0))))
(setq mode
(if (memq system-type '(windows-nt cygwin))
;; System is case-insensitive.
(let ((case-fold-search t))
(assoc-default name auto-mode-alist 'string-match))
;; System is case-sensitive.
(or ;; First match case-sensitively.
(let ((case-fold-search nil))
(assoc-default name auto-mode-alist 'string-match))
;; Fallback to case-insensitive match.
(and auto-mode-case-fold
(let ((case-fold-search t))
(assoc-default name auto-mode-alist
'string-match))))))
(if (and mode (consp mode))
(cadr mode)
mode)))
;;;###autoload
(defadvice abort-if-file-too-large (around vlf-if-file-too-large
(size op-type
&optional filename)
compile activate)
"If file SIZE larger than `large-file-warning-threshold', \
allow user to view file with `vlf', open it normally, or abort.
OP-TYPE specifies the file operation being performed over FILENAME."
(and large-file-warning-threshold size
(> size large-file-warning-threshold)
(let ((char nil))
(while (not (memq (setq char
(read-event
(propertize
(format
"File %s is large (%s): \
(cond
((or (not size) (zerop size)))
((or (not vlf-application)
(not filename)
(memq (vlf-determine-major-mode filename)
vlf-forbidden-modes-list))
ad-do-it)
((eq vlf-application 'always)
(vlf filename)
(error ""))
((and large-file-warning-threshold
(< large-file-warning-threshold size))
(if (eq vlf-application 'dont-ask)
(progn (vlf filename)
(error ""))
(let ((char nil))
(while (not (memq (setq char
(read-event
(propertize
(format
"File %s is large (%s): \
%s normally (o), %s with vlf (v) or abort (a)"
(if filename
(file-name-nondirectory filename)
"")
(file-size-human-readable size)
op-type op-type)
'face 'minibuffer-prompt)))
'(?o ?O ?v ?V ?a ?A))))
(cond ((memq char '(?o ?O)))
((memq char '(?v ?V))
(vlf filename)
(error ""))
((memq char '(?a ?A))
(error "Aborted"))))))
(if filename
(file-name-nondirectory filename)
"")
(file-size-human-readable size)
op-type op-type)
'face 'minibuffer-prompt)))
'(?o ?O ?v ?V ?a ?A))))
(cond ((memq char '(?v ?V))
(vlf filename)
(error ""))
((memq char '(?a ?A))
(error "Aborted"))))))))
;; scroll auto batching
(defadvice scroll-up (around vlf-scroll-up
@@ -197,7 +269,7 @@ OP-TYPE specifies the file operation being performed over FILENAME."
(unless (fboundp 'file-size-human-readable)
(defun file-size-human-readable (file-size)
"Print FILE-SIZE in MB."
(format "%.1fMB" (/ file-size 1048576.0))))
(format "%.3fMB" (/ file-size 1048576.0))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; utilities
@@ -223,12 +295,12 @@ with the prefix argument DECREASE it is halved."
(defun vlf-get-file-size (file)
"Get size in bytes of FILE."
(nth 7 (file-attributes file)))
(or (nth 7 (file-attributes file)) 0))
(defun vlf-verify-size ()
"Update file size information if necessary and visited file time."
(unless (verify-visited-file-modtime (current-buffer))
(setq vlf-file-size (vlf-get-file-size buffer-file-name))
(setq vlf-file-size (vlf-get-file-size buffer-file-truename))
(set-visited-file-modtime)))
(defun vlf-insert-file (&optional from-end)
@@ -255,25 +327,19 @@ With FROM-END prefix, start from the back."
(defun vlf-revert (&optional _ignore-auto noconfirm)
"Revert current chunk. Ignore _IGNORE-AUTO.
Ask for confirmation if NOCONFIRM is nil."
(if (or noconfirm
(yes-or-no-p (format "Revert buffer from file %s? "
buffer-file-name)))
(vlf-move-to-chunk-2 vlf-start-pos vlf-end-pos)))
(interactive)
(when (or noconfirm
(yes-or-no-p (format "Revert buffer from file %s? "
buffer-file-name)))
(set-buffer-modified-p nil)
(set-visited-file-modtime)
(vlf-move-to-chunk-2 vlf-start-pos vlf-end-pos)))
(defun vlf-jump-to-chunk (n)
"Go to to chunk N."
(interactive "nGoto to chunk: ")
(vlf-move-to-batch (* (1- n) vlf-batch-size)))
(defmacro vlf-with-undo-disabled (&rest body)
"Execute BODY with temporarily disabled undo."
`(let ((undo-enabled (not (eq buffer-undo-list t))))
(if undo-enabled
(buffer-disable-undo))
(unwind-protect (progn ,@body)
(if undo-enabled
(buffer-enable-undo)))))
(defun vlf-no-modifications ()
"Ensure there are no buffer modifications."
(if (buffer-modified-p)
@@ -291,8 +357,7 @@ When prefix argument is negative
append next APPEND number of batches to the existing buffer."
(interactive "p")
(vlf-verify-size)
(let* ((end (min (+ vlf-end-pos (* vlf-batch-size
(abs append)))
(let* ((end (min (+ vlf-end-pos (* vlf-batch-size (abs append)))
vlf-file-size))
(start (if (< append 0)
vlf-start-pos
@@ -308,8 +373,7 @@ When prefix argument is negative
(interactive "p")
(if (zerop vlf-start-pos)
(error "Already at BOF"))
(let* ((start (max 0 (- vlf-start-pos (* vlf-batch-size
(abs prepend)))))
(let* ((start (max 0 (- vlf-start-pos (* vlf-batch-size (abs prepend)))))
(end (if (< prepend 0)
vlf-end-pos
(+ start vlf-batch-size))))
@@ -329,7 +393,8 @@ When given MINIMAL flag, skip non important operations."
(defun vlf-next-batch-from-point ()
"Display batch of file data starting from current point."
(interactive)
(vlf-move-to-batch (+ vlf-start-pos (position-bytes (point)) -1))
(let ((start (+ vlf-start-pos (position-bytes (point)) -1)))
(vlf-move-to-chunk start (+ start vlf-batch-size)))
(goto-char (point-min)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -342,11 +407,8 @@ If same as current chunk is requested, do nothing."
(unless (and (= start vlf-start-pos)
(= end vlf-end-pos))
(vlf-verify-size)
(if (buffer-modified-p)
(if (vlf-move-to-chunk-1 start end)
(or minimal (vlf-update-buffer-name)))
(vlf-move-to-chunk-2 start end)
(or minimal (vlf-update-buffer-name)))))
(if (vlf-move-to-chunk-1 start end)
(or minimal (vlf-update-buffer-name)))))
(defun vlf-move-to-chunk-1 (start end)
"Move to chunk determined by START END keeping as much edits if any.
@@ -363,6 +425,7 @@ Return t if move hasn't been canceled."
((or (<= edit-end start) (<= end vlf-start-pos))
(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)
t))
((or (and (<= start vlf-start-pos) (<= edit-end end))
@@ -373,38 +436,57 @@ Return t if move hasn't been canceled."
(shift-end 0)
(inhibit-read-only t))
(cond ((< end edit-end)
(delete-region (byte-to-position (1+
(- end
vlf-start-pos)))
(point-max)))
(let* ((del-pos (1+ (byte-to-position
(- end vlf-start-pos))))
(del-len (length (encode-coding-region
del-pos (point-max)
buffer-file-coding-system
t))))
(setq end (- (if (zerop vlf-end-pos)
vlf-file-size
vlf-end-pos)
del-len))
(vlf-with-undo-disabled
(delete-region del-pos (point-max)))))
((< edit-end end)
(let ((edit-end-pos (point-max)))
(goto-char edit-end-pos)
(insert-file-contents buffer-file-name nil
vlf-end-pos end)
(setq shift-end (cdr (vlf-adjust-chunk
vlf-end-pos end nil t
edit-end-pos))))))
(vlf-with-undo-disabled
(insert-file-contents buffer-file-name nil
vlf-end-pos end)
(setq shift-end (cdr (vlf-adjust-chunk
vlf-end-pos end nil t
edit-end-pos)))))))
(cond ((< vlf-start-pos start)
(delete-region (point-min) (byte-to-position
(- start vlf-start-pos))))
(let* ((del-pos (1+ (byte-to-position
(- start vlf-start-pos))))
(del-len (length (encode-coding-region
(point-min) del-pos
buffer-file-coding-system
t))))
(setq start (+ vlf-start-pos del-len))
(vlf-with-undo-disabled
(delete-region (point-min) del-pos))))
((< start vlf-start-pos)
(let ((edit-end-pos (point-max)))
(goto-char edit-end-pos)
(insert-file-contents buffer-file-name nil
start vlf-start-pos)
(setq shift-start (car
(vlf-adjust-chunk start
vlf-start-pos
t nil
edit-end-pos)))
(goto-char (point-min))
(insert (delete-and-extract-region edit-end-pos
(point-max))))))
(setq vlf-start-pos (- start shift-start)
vlf-end-pos (+ end shift-end))
(goto-char (or (byte-to-position (- pos vlf-start-pos))
(point-max))))
(vlf-with-undo-disabled
(insert-file-contents buffer-file-name nil
start vlf-start-pos)
(setq shift-start (car
(vlf-adjust-chunk start
vlf-start-pos
t nil
edit-end-pos)))
(goto-char (point-min))
(insert (delete-and-extract-region edit-end-pos
(point-max)))))))
(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
vlf-end-pos (+ end shift-end)))
(set-buffer-modified-p modified)
t))))
@@ -429,49 +511,58 @@ Return t if move hasn't been canceled."
(defun vlf-adjust-chunk (start end &optional adjust-start adjust-end
position)
"Adjust chunk at absolute START to END till content can be \
"Adjust chunk at absolute START to END till content can be\
properly decoded. ADJUST-START determines if trying to prepend bytes\
to the beginning, ADJUST-END - add to the end.
to the beginning, ADJUST-END - append to the end.
Use buffer POSITION as start if given.
Return number of bytes moved back for proper decoding and number of
bytes added to the end."
(let ((position (or position (point-min)))
(shift-start 0)
(shift-end 0)
(chunk-size (- end start)))
;; adjust beginning
(let ((shift-start 0)
(shift-end 0))
(if adjust-start
(while (and (not (zerop start))
(< shift-start 4)
(< 4 (abs (- chunk-size
(length (encode-coding-region
position (point-max)
buffer-file-coding-system
t))))))
(setq shift-start (1+ shift-start)
start (1- start)
chunk-size (1+ chunk-size))
(delete-region position (point-max))
(goto-char position)
(insert-file-contents buffer-file-name nil start end)))
;; adjust end
(when (and adjust-end (< end vlf-file-size))
(let ((expected-size (buffer-size)))
(while (and (= expected-size (buffer-size))
(< end vlf-file-size))
(setq shift-end (1+ shift-end)
end (1+ end))
(delete-region position (point-max))
(goto-char position)
(insert-file-contents buffer-file-name nil start end)))
(when (< end vlf-file-size)
(setq shift-end (1- shift-end)
end (1- end))
(delete-region position (point-max))
(goto-char position)
(insert-file-contents buffer-file-name nil start end)))
(let ((position (or position (point-min)))
(chunk-size (- end start)))
(while (and (not (zerop start))
(< shift-start 4)
(< 4 (abs (- chunk-size
(length (encode-coding-region
position (point-max)
buffer-file-coding-system
t))))))
(setq shift-start (1+ shift-start)
start (1- start)
chunk-size (1+ chunk-size))
(delete-region position (point-max))
(goto-char position)
(insert-file-contents buffer-file-name nil start end))))
(if adjust-end
(cond ((vlf-partial-decode-shown-p) ;remove raw bytes from end
(goto-char (point-max))
(while (eq (char-charset (preceding-char)) 'eight-bit)
(setq shift-end (1- shift-end))
(delete-char -1)))
((< end vlf-file-size) ;add bytes until new character is displayed
(let ((position (or position (point-min)))
(expected-size (buffer-size)))
(while (and (progn
(setq shift-end (1+ shift-end)
end (1+ end))
(delete-region position (point-max))
(goto-char position)
(insert-file-contents buffer-file-name
nil start end)
(< end vlf-file-size))
(= expected-size (buffer-size))))))))
(cons shift-start shift-end)))
(defun vlf-partial-decode-shown-p ()
"Determine if partial decode codes are displayed.
This seems to be the case with GNU/Emacs before 24.4."
(cond ((< emacs-major-version 24) t)
((< 24 emacs-major-version) nil)
(t ;; TODO: use (< emacs-minor-version 4) after 24.4 release
(string-lessp emacs-version "24.3.5"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; search
@@ -858,15 +949,6 @@ in file: %s" total-matches line regexp file)
(vlf-occur-mode))
(display-buffer occur-buffer)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; editing
(defun vlf-refresh ()
"Discard edit and refresh chunk from file."
(interactive)
(set-buffer-modified-p nil)
(vlf-move-to-chunk vlf-start-pos vlf-end-pos))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; saving
@@ -874,22 +956,36 @@ in file: %s" total-matches line regexp file)
"Write current chunk to file. Always return true to disable save.
If changing size of chunk, shift remaining file content."
(interactive)
(when (and (buffer-modified-p)
(or (verify-visited-file-modtime (current-buffer))
(y-or-n-p "File has changed since visited or saved. \
Save anyway? ")))
(let ((pos (point))
(size-change (- vlf-end-pos vlf-start-pos
(length (encode-coding-region
(point-min) (point-max)
buffer-file-coding-system t)))))
(cond ((zerop size-change)
(write-region nil nil buffer-file-name vlf-start-pos t))
((< 0 size-change)
(vlf-file-shift-back size-change))
(t (vlf-file-shift-forward (- size-change))))
(vlf-move-to-chunk-2 vlf-start-pos vlf-end-pos)
(goto-char pos)))
(and (buffer-modified-p)
(or (verify-visited-file-modtime (current-buffer))
(y-or-n-p "File has changed since visited or saved. \
Save anyway? "))
(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 ((pos (point)))
(if (< 0 size-change)
(vlf-file-shift-back size-change)
(vlf-file-shift-forward (- size-change))
(vlf-verify-size))
(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))))))
t)
(defun vlf-file-shift-back (size-change)