[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ELPA-diffs] elpa r422: * packages/vlf/vlf.el: Version 0.6
From: |
Stefan Monnier |
Subject: |
[ELPA-diffs] elpa r422: * packages/vlf/vlf.el: Version 0.6 |
Date: |
Mon, 22 Jul 2013 05:41:33 +0000 |
User-agent: |
Bazaar (2.6b2) |
------------------------------------------------------------
revno: 422
revision-id: address@hidden
parent: address@hidden
author: Andrey Kotlarski <address@hidden>
committer: Stefan Monnier <address@hidden>
branch nick: elpa
timestamp: Mon 2013-07-22 01:41:31 -0400
message:
* packages/vlf/vlf.el: Version 0.6
(vlf-mode): Setup revert and file write.
(vlf-format-buffer-name): Change format to indicate the chunk numbers.
(vlf-insert-file): Remove unused arg `file'.
(vlf-beginning-of-file, vlf-end-of-file, vlf-jump-to-chunk): New commands.
(vlf-mode-map): Use them. Add a `j' binding.
(vlf-revert): New function.
(vlf-next-batch, vlf-prev-batch, vlf-move-to-batch, vlf-move-to-chunk):
Set modtime. Better preserve point.
(vlf-file-shift-back, vlf-shift-batch, vlf-file-shift-forward)
(vlf-shift-batches): New functions.
(vlf-write): Use them when size of saved chunks has changed.
Pay attention to modtimes.
modified:
packages/vlf/vlf.el vlf.el-20120614203028-urlm47rgs71aoaqu-2
=== modified file 'packages/vlf/vlf.el'
--- a/packages/vlf/vlf.el 2013-07-22 05:25:38 +0000
+++ b/packages/vlf/vlf.el 2013-07-22 05:41:31 +0000
@@ -2,7 +2,7 @@
;; Copyright (C) 2006, 2012, 2013 Free Software Foundation, Inc.
-;; Version: 0.5
+;; Version: 0.6
;; Keywords: large files, utilities
;; Authors: 2006 Mathias Dahl <address@hidden>
;; 2012 Sam Steingold <address@hidden>
@@ -64,13 +64,10 @@
(vlf-change-batch-size t)))
(define-key map "s" 'vlf-re-search-forward)
(define-key map "r" 'vlf-re-search-backward)
- (define-key map "]" (lambda () "Jump to end of file content."
- (interactive)
- (vlf-insert-file buffer-file-name t)))
- (define-key map "[" (lambda () "Jump to beginning of file content."
- (interactive)
- (vlf-insert-file buffer-file-name)))
+ (define-key map "[" 'vlf-beginning-of-file)
+ (define-key map "]" 'vlf-end-of-file)
(define-key map "e" 'vlf-edit-mode)
+ (define-key map "j" 'vlf-jump-to-chunk)
map)
"Keymap for `vlf-mode'.")
@@ -79,6 +76,8 @@
(setq buffer-read-only t)
(set-buffer-modified-p nil)
(buffer-disable-undo)
+ (add-hook 'write-contents-functions 'vlf-write)
+ (setq revert-buffer-function 'vlf-revert)
(make-local-variable 'vlf-batch-size)
(put 'vlf-batch-size 'permanent-local t)
(make-local-variable 'vlf-start-pos)
@@ -88,6 +87,75 @@
(make-local-variable 'vlf-file-size)
(put 'vlf-file-size 'permanent-local t))
+;;;###autoload
+(defun vlf (file &optional from-end)
+ "View Large FILE. With FROM-END prefix, view from the back.
+Batches of the file data from FILE will be displayed in a read-only
+buffer. You can customize number of bytes displayed by customizing
+`vlf-batch-size'."
+ (interactive "fFile to open: \nP")
+ (with-current-buffer (generate-new-buffer "*vlf*")
+ (setq buffer-file-name file
+ vlf-file-size (nth 7 (file-attributes file)))
+ (vlf-insert-file from-end)
+ (vlf-mode)
+ (switch-to-buffer (current-buffer))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; integration with other packages
+
+;;;###autoload
+(defun dired-vlf (from-end)
+ "In Dired, visit the file on this line in VLF mode.
+With FROM-END prefix, view from the back."
+ (interactive "P")
+ (vlf (dired-get-file-for-visit) from-end))
+
+;;;###autoload
+(eval-after-load "dired"
+ '(define-key dired-mode-map "V" 'dired-vlf))
+
+;;;###autoload
+(defun vlf-if-file-too-large (size op-type &optional filename)
+ "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): \
+%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 nil)
+ (error ""))
+ ((memq char '(?a ?A))
+ (error "Aborted"))))))
+
+;; hijack `abort-if-file-too-large'
+;;;###autoload
+(fset 'abort-if-file-too-large 'vlf-if-file-too-large)
+
+;; non recent Emacs
+(unless (fboundp 'file-size-human-readable)
+ (defun file-size-human-readable (file-size)
+ "Print FILE-SIZE in MB."
+ (format "%.1fMB" (/ file-size 1024.0))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; utilities
+
(defun vlf-change-batch-size (decrease)
"Change the buffer-local value of `vlf-batch-size'.
Normally, the value is doubled;
@@ -102,16 +170,50 @@
(defun vlf-format-buffer-name ()
"Return format for vlf buffer name."
- (format "%s(%s)[%.2f%%%%](%d)"
+ (format "%s(%s)[%d/%d](%d)"
(file-name-nondirectory buffer-file-name)
(file-size-human-readable vlf-file-size)
- (/ (* 100 vlf-end-pos) (float vlf-file-size))
+ (/ vlf-end-pos vlf-batch-size)
+ (/ vlf-file-size vlf-batch-size)
vlf-batch-size))
(defun vlf-update-buffer-name ()
"Update the current buffer name."
(rename-buffer (vlf-format-buffer-name) t))
+(defun vlf-insert-file (&optional from-end)
+ "Insert first chunk of current file contents in current buffer.
+With FROM-END prefix, start from the back."
+ (if from-end
+ (setq vlf-start-pos (max 0 (- vlf-file-size vlf-batch-size))
+ vlf-end-pos vlf-file-size)
+ (setq vlf-start-pos 0
+ vlf-end-pos (min vlf-batch-size vlf-file-size)))
+ (vlf-move-to-chunk vlf-start-pos vlf-end-pos))
+
+(defun vlf-beginning-of-file ()
+ "Jump to beginning of file content."
+ (interactive)
+ (vlf-insert-file))
+
+(defun vlf-end-of-file ()
+ "Jump to end of file content."
+ (interactive)
+ (vlf-insert-file t))
+
+(defun vlf-revert (&rest args)
+ "Revert current chunk. Ignore ARGS."
+ (ignore args)
+ (vlf-move-to-chunk 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)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; batch movement
+
(defun vlf-next-batch (append)
"Display the next batch of file data.
When prefix argument is supplied and positive
@@ -121,7 +223,7 @@
(interactive "p")
(let ((end (+ vlf-end-pos (* vlf-batch-size
(abs append)))))
- (when (< vlf-file-size end) ; re-check file size
+ (when (< vlf-file-size end) ; re-check file size
(setq vlf-file-size (nth 7 (file-attributes buffer-file-name)))
(cond ((= vlf-end-pos vlf-file-size)
(error "Already at EOF"))
@@ -134,13 +236,13 @@
(goto-char (point-max))
(setq vlf-start-pos (- end vlf-batch-size))
(erase-buffer))
- (insert-file-contents buffer-file-name nil
- (if do-append
- vlf-end-pos
- vlf-start-pos)
+ (insert-file-contents buffer-file-name nil (if do-append
+ vlf-end-pos
+ vlf-start-pos)
end)
(goto-char pos))
(setq vlf-end-pos end))
+ (set-visited-file-modtime)
(set-buffer-modified-p nil)
(vlf-update-buffer-name))
@@ -168,6 +270,7 @@
vlf-end-pos))
(goto-char (- (point-max) pos))
(setq vlf-start-pos start))
+ (set-visited-file-modtime)
(set-buffer-modified-p nil)
(vlf-update-buffer-name))
@@ -181,92 +284,36 @@
(nth 7 (file-attributes buffer-file-name))
vlf-end-pos (min vlf-end-pos vlf-file-size)
vlf-start-pos (max 0 (- vlf-end-pos vlf-batch-size))))
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t)
+ (pos (point)))
(erase-buffer)
(insert-file-contents buffer-file-name nil
- vlf-start-pos vlf-end-pos))
+ vlf-start-pos vlf-end-pos)
+ (goto-char pos))
+ (set-visited-file-modtime)
(set-buffer-modified-p nil)
(vlf-update-buffer-name))
(defun vlf-move-to-chunk (start end)
"Move to chunk determined by START END."
- (if (< vlf-file-size end) ; re-check file size
+ (if (< vlf-file-size end) ; re-check file size
(setq vlf-file-size (nth 7
(file-attributes buffer-file-name))))
(setq vlf-start-pos (max 0 start)
vlf-end-pos (min end vlf-file-size))
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t)
+ (pos (point)))
(erase-buffer)
(insert-file-contents buffer-file-name nil
- vlf-start-pos vlf-end-pos))
+ vlf-start-pos vlf-end-pos)
+ (goto-char pos))
+ (set-visited-file-modtime)
(set-buffer-modified-p nil)
(vlf-update-buffer-name))
-(defun vlf-insert-file (file &optional from-end)
- "Insert first chunk of FILE contents in current buffer.
-With FROM-END prefix, start from the back."
- (if from-end
- (setq vlf-start-pos (max 0 (- vlf-file-size vlf-batch-size))
- vlf-end-pos vlf-file-size)
- (setq vlf-start-pos 0
- vlf-end-pos (min vlf-batch-size vlf-file-size)))
- (vlf-move-to-chunk vlf-start-pos vlf-end-pos))
-
-;;;###autoload
-(defun vlf (file &optional from-end)
- "View Large FILE. With FROM-END prefix, view from the back.
-Batches of the file data from FILE will be displayed in a read-only
-buffer. You can customize number of bytes displayed by customizing
-`vlf-batch-size'."
- (interactive "fFile to open: \nP")
- (with-current-buffer (generate-new-buffer "*vlf*")
- (setq buffer-file-name file
- vlf-file-size (nth 7 (file-attributes file)))
- (vlf-insert-file file from-end)
- (vlf-mode)
- (switch-to-buffer (current-buffer))))
-
-;;;###autoload
-(defun dired-vlf (from-end)
- "In Dired, visit the file on this line in VLF mode.
-With FROM-END prefix, view from the back."
- (interactive "P")
- (vlf (dired-get-file-for-visit) from-end))
-
-;;;###autoload
-(eval-after-load "dired"
- '(define-key dired-mode-map "V" 'dired-vlf))
-
-;;;###autoload
-(defun vlf-if-file-too-large (size op-type &optional filename)
- "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): \
-%s normally (o), %s with vlf (v) or abort (a)"
- (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 nil)
- (error ""))
- ((memq char '(?a ?A))
- (error "Aborted"))))))
-
-;;; hijack `abort-if-file-too-large'
-;;;###autoload
-(fset 'abort-if-file-too-large 'vlf-if-file-too-large)
-
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; search
+
(defun vlf-re-search (regexp count backward)
"Search for REGEXP COUNT number of times forward or BACKWARD."
(let* ((match-start-pos (+ vlf-start-pos (point)))
@@ -355,7 +402,8 @@
(delete-overlay overlay)))))
(defun vlf-re-search-forward (regexp count)
- "Search forward for REGEXP prefix COUNT number of times."
+ "Search forward for REGEXP prefix COUNT number of times.
+Search is performed chunk by chunk in `vlf-batch-size' memory."
(interactive (list (read-regexp "Search whole file"
(if regexp-history
(car regexp-history))
@@ -364,7 +412,8 @@
(vlf-re-search regexp count nil))
(defun vlf-re-search-backward (regexp count)
- "Search backward for REGEXP prefix COUNT number of times."
+ "Search backward for REGEXP prefix COUNT number of times.
+Search is performed chunk by chunk in `vlf-batch-size' memory."
(interactive (list (read-regexp "Search whole file backward"
(if regexp-history
(car regexp-history))
@@ -372,7 +421,9 @@
(or current-prefix-arg 1)))
(vlf-re-search regexp count t))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; editing
+
(defvar vlf-edit-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map text-mode-map)
@@ -389,16 +440,6 @@
"Editing: Type \\[vlf-write] to write chunk \
or \\[vlf-discard-edit] to discard changes.")))
-(defun vlf-write ()
- "Write current chunk to file. May overwrite existing content."
- (interactive)
- (when (or (= (buffer-size) (- vlf-end-pos vlf-start-pos))
- (y-or-n-p "Changed size of original chunk. \
-End of chunk will be garbled. Continue? "))
- (write-region nil nil buffer-file-name vlf-start-pos)
- (vlf-move-to-chunk vlf-start-pos vlf-end-pos)
- (vlf-mode)))
-
(defun vlf-discard-edit ()
"Discard edit and refresh chunk from file."
(interactive)
@@ -406,6 +447,119 @@
(vlf-mode)
(message "Switched to VLF mode."))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; saving
+
+(defun vlf-write ()
+ "Write current chunk to file. Always return true to disable save.
+If changing size of chunk shift remaining file content."
+ (interactive)
+ (when (and (derived-mode-p 'vlf-mode)
+ (buffer-modified-p)
+ (or (verify-visited-file-modtime)
+ (y-or-n-p "File has changed since visited or saved. \
+Save anyway? ")))
+ (let ((size-change (- vlf-end-pos vlf-start-pos
+ (length (encode-coding-region
+ (point-min) (point-max)
+ buffer-file-coding-system t))))
+ (pos (point)))
+ (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))))
+ (goto-char pos))
+ (vlf-move-to-chunk vlf-start-pos vlf-end-pos)
+ (vlf-mode)
+ t))
+
+(defun vlf-file-shift-back (size-change)
+ "Shift file contents SIZE-CHANGE bytes back."
+ (let ((coding-system buffer-file-coding-system))
+ (write-region nil nil buffer-file-name vlf-start-pos t)
+ (setq buffer-file-coding-system nil)
+ (let ((read-start-pos vlf-end-pos)
+ (reporter (make-progress-reporter "Adjusting file content"
+ vlf-end-pos
+ vlf-file-size)))
+ (while (vlf-shift-batch read-start-pos (- read-start-pos
+ size-change))
+ (setq read-start-pos (+ read-start-pos vlf-batch-size))
+ (progress-reporter-update reporter read-start-pos))
+ ;; pad end with space
+ (erase-buffer)
+ (insert-char 32 size-change)
+ (write-region nil nil buffer-file-name (- vlf-file-size
+ size-change) t)
+ (progress-reporter-done reporter))
+ (setq buffer-file-coding-system coding-system)))
+
+(defun vlf-shift-batch (read-pos write-pos)
+ "Read `vlf-batch-size' bytes from READ-POS and write them \
+back at WRITE-POS. Return nil if EOF is reached, t otherwise."
+ (erase-buffer)
+ (setq vlf-file-size (nth 7 (file-attributes buffer-file-name)))
+ (let ((read-end (+ read-pos vlf-batch-size)))
+ (insert-file-contents-literally buffer-file-name nil
+ read-pos
+ (min vlf-file-size read-end))
+ (write-region nil nil buffer-file-name write-pos t)
+ (< read-end vlf-file-size)))
+
+(defun vlf-file-shift-forward (size-change)
+ "Shift file contents SIZE-CHANGE bytes forward.
+Done by saving content up front and then writing previous batch."
+ (let ((vlf-buffer (current-buffer))
+ (temp-buffer (generate-new-buffer (concat " "
+ (buffer-name))))
+ (coding-system buffer-file-coding-system))
+ (let ((file buffer-file-name))
+ (set-buffer temp-buffer)
+ (setq buffer-file-name file))
+ (set-buffer vlf-buffer)
+ (let ((read-buffer temp-buffer)
+ (write-buffer vlf-buffer)
+ (size (+ vlf-batch-size size-change))
+ (read-pos vlf-end-pos)
+ (write-pos vlf-start-pos)
+ swap-buffer
+ (reporter (make-progress-reporter "Adjusting file content"
+ vlf-start-pos
+ vlf-file-size)))
+ (while (vlf-shift-batches size read-buffer read-pos
+ write-buffer write-pos)
+ (setq swap-buffer read-buffer
+ read-buffer write-buffer
+ write-buffer swap-buffer
+ write-pos (+ read-pos size-change)
+ read-pos (+ read-pos size))
+ (progress-reporter-update reporter write-pos))
+ (progress-reporter-done reporter))
+ (kill-buffer temp-buffer)
+ (set-buffer vlf-buffer)
+ (setq buffer-file-coding-system coding-system)))
+
+(defun vlf-shift-batches (size read-buffer read-pos
+ write-buffer write-pos)
+ "Read SIZE bytes in READ-BUFFER starting from READ-POS.
+Then write contents of WRITE-BUFFER to buffer file at WRITE-POS.
+Return nil if EOF is reached, t otherwise."
+ (let* ((file-size (nth 7 (file-attributes buffer-file-name)))
+ (read-more (< read-pos file-size)))
+ (when read-more
+ ;; read
+ (set-buffer read-buffer)
+ (erase-buffer)
+ (setq buffer-file-coding-system nil)
+ (insert-file-contents-literally buffer-file-name nil read-pos
+ (min file-size (+ read-pos
+ size))))
+ ;; write
+ (set-buffer write-buffer)
+ (write-region nil nil buffer-file-name write-pos t)
+ read-more))
+
(provide 'vlf)
;;; vlf.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [ELPA-diffs] elpa r422: * packages/vlf/vlf.el: Version 0.6,
Stefan Monnier <=