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

[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


reply via email to

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