mirror of
https://github.com/m00natic/vlfi.git
synced 2025-01-18 20:10:47 +00:00
Merge branch 'master' into chunk-opt2
This commit is contained in:
parent
3c2fb6b93e
commit
02a37c4192
20
README.org
20
README.org
@ -1,13 +1,12 @@
|
|||||||
* View Large Files Improved
|
* View Large Files
|
||||||
|
|
||||||
An Emacs mode that allows viewing, editing and searching in large
|
An Emacs mode that allows viewing, editing and searching in large
|
||||||
files in chunks. Batch size can be adjusted on the fly and bounds the
|
files in chunks. Batch size can be adjusted on the fly and bounds the
|
||||||
memory that is to be used for operations on the file.
|
memory that is to be used for operations on the file.
|
||||||
|
|
||||||
This mode builds on the bare bones GNU ELPA vlf.el. It adds the
|
This is development version of the GNU ELPA [[http://elpa.gnu.org/packages/vlf][vlf.el]] package. Here's
|
||||||
following improvements:
|
what it does in a nutshell:
|
||||||
|
|
||||||
- proper dealing with Unicode
|
|
||||||
- regular expression search on whole file (in constant memory
|
- regular expression search on whole file (in constant memory
|
||||||
determined by current batch size)
|
determined by current batch size)
|
||||||
- chunk editing (if size has changed, saving is done in constant
|
- chunk editing (if size has changed, saving is done in constant
|
||||||
@ -18,8 +17,7 @@ following improvements:
|
|||||||
- newly added content is acknowledged if file has changed size
|
- newly added content is acknowledged if file has changed size
|
||||||
meanwhile
|
meanwhile
|
||||||
- automatic scrolling of batches
|
- automatic scrolling of batches
|
||||||
- VLFI is added as an option when opening large files and given dired
|
- VLFI is added as an option when opening large files
|
||||||
key-binding
|
|
||||||
|
|
||||||
GNU Emacs 23 and 24 are supported.
|
GNU Emacs 23 and 24 are supported.
|
||||||
|
|
||||||
@ -48,15 +46,15 @@ integer value), VLFI will probably not quite work.
|
|||||||
VLFI is derived from special-mode and keeps all its properties. For
|
VLFI is derived from special-mode and keeps all its properties. For
|
||||||
example you can directly press digits to enter prefix arguments.
|
example you can directly press digits to enter prefix arguments.
|
||||||
|
|
||||||
** Changing major mode
|
** Change major mode
|
||||||
|
|
||||||
You can (temporarily) change major mode to whatever you like (for
|
You can change major mode to whatever you like (for example
|
||||||
example hexl-mode). Saving will insert contents as intended. You can
|
hexl-mode). Saving will insert contents as intended. You can return
|
||||||
return to *vlfi-mode* too.
|
to *vlfi-mode* too.
|
||||||
|
|
||||||
* Detail usage
|
* Detail usage
|
||||||
|
|
||||||
** Controlling batch size
|
** Control batch size
|
||||||
|
|
||||||
*+* and *-* control current batch size by factors of 2.
|
*+* and *-* control current batch size by factors of 2.
|
||||||
|
|
||||||
|
104
vlfi.el
104
vlfi.el
@ -1,12 +1,14 @@
|
|||||||
;;; vlfi.el --- View Large Files Improved -*- lexical-binding: t -*-
|
;;; vlfi.el --- View Large Files -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; Copyright (C) 2006, 2012, 2013 Free Software Foundation, Inc.
|
;; Copyright (C) 2006, 2012, 2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;; Version: 0.8
|
;; Version: 0.9.1
|
||||||
;; Keywords: large files, utilities
|
;; Keywords: large files, utilities
|
||||||
|
;; Maintainer: Andrey Kotlarski <m00naticus@gmail.com>
|
||||||
;; Authors: 2006 Mathias Dahl <mathias.dahl@gmail.com>
|
;; Authors: 2006 Mathias Dahl <mathias.dahl@gmail.com>
|
||||||
;; 2012 Sam Steingold <sds@gnu.org>
|
;; 2012 Sam Steingold <sds@gnu.org>
|
||||||
;; 2013 Andrey Kotlarski <m00naticus@gmail.com>
|
;; 2013 Andrey Kotlarski <m00naticus@gmail.com>
|
||||||
|
;; URL: https://github.com/m00natic/vlfi
|
||||||
|
|
||||||
;; This file is free software; you can redistribute it and/or modify
|
;; This file is free software; you can redistribute it and/or modify
|
||||||
;; it under the terms of the GNU General Public License as published by
|
;; it under the terms of the GNU General Public License as published by
|
||||||
@ -30,7 +32,9 @@
|
|||||||
;; The buffer uses VLFI mode, which defines several commands for
|
;; The buffer uses VLFI mode, which defines several commands for
|
||||||
;; moving around, searching and editing selected part of file.
|
;; moving around, searching and editing selected part of file.
|
||||||
|
|
||||||
;; This package is upgraded version of the vlf.el package.
|
;; This package was inspired by a snippet posted by Kevin Rodgers,
|
||||||
|
;; showing how to use `insert-file-contents' to extract part of a
|
||||||
|
;; file.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
@ -49,6 +53,7 @@
|
|||||||
"Absolute position of the visible chunk start.")
|
"Absolute position of the visible chunk start.")
|
||||||
(defvar vlfi-end-pos 0 "Absolute position of the visible chunk end.")
|
(defvar vlfi-end-pos 0 "Absolute position of the visible chunk end.")
|
||||||
(defvar vlfi-file-size 0 "Total size of presented file.")
|
(defvar vlfi-file-size 0 "Total size of presented file.")
|
||||||
|
(defvar vlfi-encode-size 0 "Size in bytes of current batch decoded.")
|
||||||
|
|
||||||
(defvar vlfi-mode-map
|
(defvar vlfi-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
@ -70,23 +75,25 @@
|
|||||||
map)
|
map)
|
||||||
"Keymap for `vlfi-mode'.")
|
"Keymap for `vlfi-mode'.")
|
||||||
|
|
||||||
|
(put 'vlfi-batch-size 'permanent-local t)
|
||||||
|
(put 'vlfi-start-pos 'permanent-local t)
|
||||||
|
(put 'vlfi-end-pos 'permanent-local t)
|
||||||
|
(put 'vlfi-file-size 'permanent-local t)
|
||||||
|
(put 'vlfi-encode-size 'permanent-local t)
|
||||||
|
|
||||||
(define-derived-mode vlfi-mode special-mode "VLFI"
|
(define-derived-mode vlfi-mode special-mode "VLFI"
|
||||||
"Mode to browse large files in."
|
"Mode to browse large files in."
|
||||||
(setq buffer-read-only t)
|
(setq buffer-read-only t)
|
||||||
(set-buffer-modified-p nil)
|
(set-buffer-modified-p nil)
|
||||||
(buffer-disable-undo)
|
(buffer-disable-undo)
|
||||||
(make-local-variable 'write-file-functions)
|
(add-hook 'write-file-functions 'vlfi-write nil t)
|
||||||
(add-hook 'write-file-functions 'vlfi-write)
|
|
||||||
(make-local-variable 'revert-buffer-function)
|
(make-local-variable 'revert-buffer-function)
|
||||||
(setq revert-buffer-function 'vlfi-revert)
|
(setq revert-buffer-function 'vlfi-revert)
|
||||||
(make-local-variable 'vlfi-batch-size)
|
(make-local-variable 'vlfi-batch-size)
|
||||||
(put 'vlfi-batch-size 'permanent-local t)
|
|
||||||
(make-local-variable 'vlfi-start-pos)
|
(make-local-variable 'vlfi-start-pos)
|
||||||
(put 'vlfi-start-pos 'permanent-local t)
|
|
||||||
(make-local-variable 'vlfi-end-pos)
|
(make-local-variable 'vlfi-end-pos)
|
||||||
(put 'vlfi-end-pos 'permanent-local t)
|
|
||||||
(make-local-variable 'vlfi-file-size)
|
(make-local-variable 'vlfi-file-size)
|
||||||
(put 'vlfi-file-size 'permanent-local t))
|
(make-local-variable 'vlfi-encode-size))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun vlfi (file)
|
(defun vlfi (file)
|
||||||
@ -96,9 +103,9 @@ buffer. You can customize number of bytes displayed by customizing
|
|||||||
`vlfi-batch-size'."
|
`vlfi-batch-size'."
|
||||||
(interactive "fFile to open: ")
|
(interactive "fFile to open: ")
|
||||||
(with-current-buffer (generate-new-buffer "*vlfi*")
|
(with-current-buffer (generate-new-buffer "*vlfi*")
|
||||||
|
(set-visited-file-name file)
|
||||||
(vlfi-mode)
|
(vlfi-mode)
|
||||||
(setq buffer-file-name file
|
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name))
|
||||||
vlfi-file-size (vlfi-get-file-size file))
|
|
||||||
(vlfi-insert-file)
|
(vlfi-insert-file)
|
||||||
(switch-to-buffer (current-buffer))))
|
(switch-to-buffer (current-buffer))))
|
||||||
|
|
||||||
@ -116,9 +123,12 @@ buffer. You can customize number of bytes displayed by customizing
|
|||||||
'(define-key dired-mode-map "V" 'dired-vlfi))
|
'(define-key dired-mode-map "V" 'dired-vlfi))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun vlfi-if-file-too-large (size op-type &optional filename)
|
(defadvice abort-if-file-too-large (around vlfi-if-file-too-large
|
||||||
|
(size op-type
|
||||||
|
&optional filename)
|
||||||
|
compile activate)
|
||||||
"If file SIZE larger than `large-file-warning-threshold', \
|
"If file SIZE larger than `large-file-warning-threshold', \
|
||||||
allow user to view file with `vlfi', open it normally or abort.
|
allow user to view file with `vlfi', open it normally, or abort.
|
||||||
OP-TYPE specifies the file operation being performed over FILENAME."
|
OP-TYPE specifies the file operation being performed over FILENAME."
|
||||||
(and large-file-warning-threshold size
|
(and large-file-warning-threshold size
|
||||||
(> size large-file-warning-threshold)
|
(> size large-file-warning-threshold)
|
||||||
@ -143,15 +153,12 @@ OP-TYPE specifies the file operation being performed over FILENAME."
|
|||||||
((memq char '(?a ?A))
|
((memq char '(?a ?A))
|
||||||
(error "Aborted"))))))
|
(error "Aborted"))))))
|
||||||
|
|
||||||
;; hijack `abort-if-file-too-large'
|
|
||||||
;;;###autoload
|
|
||||||
(fset 'abort-if-file-too-large 'vlfi-if-file-too-large)
|
|
||||||
|
|
||||||
;; scroll auto batching
|
;; scroll auto batching
|
||||||
(defadvice scroll-up (around vlfi-scroll-up
|
(defadvice scroll-up (around vlfi-scroll-up
|
||||||
activate compile)
|
activate compile)
|
||||||
"Slide to next batch if at end of buffer in `vlfi-mode'."
|
"Slide to next batch if at end of buffer in `vlfi-mode'."
|
||||||
(if (and (eq major-mode 'vlfi-mode)
|
(if (and (derived-mode-p 'vlfi-mode)
|
||||||
(eobp))
|
(eobp))
|
||||||
(progn (vlfi-next-batch 1)
|
(progn (vlfi-next-batch 1)
|
||||||
(goto-char (point-min)))
|
(goto-char (point-min)))
|
||||||
@ -160,7 +167,7 @@ OP-TYPE specifies the file operation being performed over FILENAME."
|
|||||||
(defadvice scroll-down (around vlfi-scroll-down
|
(defadvice scroll-down (around vlfi-scroll-down
|
||||||
activate compile)
|
activate compile)
|
||||||
"Slide to previous batch if at beginning of buffer in `vlfi-mode'."
|
"Slide to previous batch if at beginning of buffer in `vlfi-mode'."
|
||||||
(if (and (eq major-mode 'vlfi-mode)
|
(if (and (derived-mode-p 'vlfi-mode)
|
||||||
(bobp))
|
(bobp))
|
||||||
(progn (vlfi-prev-batch 1)
|
(progn (vlfi-prev-batch 1)
|
||||||
(goto-char (point-max)))
|
(goto-char (point-max)))
|
||||||
@ -180,8 +187,6 @@ OP-TYPE specifies the file operation being performed over FILENAME."
|
|||||||
Normally, the value is doubled;
|
Normally, the value is doubled;
|
||||||
with the prefix argument DECREASE it is halved."
|
with the prefix argument DECREASE it is halved."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(or (assq 'vlfi-batch-size (buffer-local-variables))
|
|
||||||
(error "%s is not local in this buffer" 'vlfi-batch-size))
|
|
||||||
(setq vlfi-batch-size (if decrease
|
(setq vlfi-batch-size (if decrease
|
||||||
(/ vlfi-batch-size 2)
|
(/ vlfi-batch-size 2)
|
||||||
(* vlfi-batch-size 2)))
|
(* vlfi-batch-size 2)))
|
||||||
@ -204,6 +209,12 @@ with the prefix argument DECREASE it is halved."
|
|||||||
"Get size in bytes of FILE."
|
"Get size in bytes of FILE."
|
||||||
(nth 7 (file-attributes file)))
|
(nth 7 (file-attributes file)))
|
||||||
|
|
||||||
|
(defun vlfi-verify-size ()
|
||||||
|
"Update file size information if necessary and visited file time."
|
||||||
|
(unless (verify-visited-file-modtime (current-buffer))
|
||||||
|
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name))
|
||||||
|
(set-visited-file-modtime)))
|
||||||
|
|
||||||
(defun vlfi-insert-file (&optional from-end)
|
(defun vlfi-insert-file (&optional from-end)
|
||||||
"Insert first chunk of current file contents in current buffer.
|
"Insert first chunk of current file contents in current buffer.
|
||||||
With FROM-END prefix, start from the back."
|
With FROM-END prefix, start from the back."
|
||||||
@ -225,13 +236,12 @@ With FROM-END prefix, start from the back."
|
|||||||
(interactive)
|
(interactive)
|
||||||
(vlfi-insert-file t))
|
(vlfi-insert-file t))
|
||||||
|
|
||||||
(defun vlfi-revert (&optional ignore-auto noconfirm)
|
(defun vlfi-revert (&optional _ignore-auto noconfirm)
|
||||||
"Revert current chunk. Ignore IGNORE-AUTO.
|
"Revert current chunk. Ignore _IGNORE-AUTO.
|
||||||
Ask for confirmation if NOCONFIRM is nil."
|
Ask for confirmation if NOCONFIRM is nil."
|
||||||
(ignore ignore-auto)
|
(if (or noconfirm
|
||||||
(or noconfirm
|
(yes-or-no-p (format "Revert buffer from file %s? "
|
||||||
(yes-or-no-p (format "Revert buffer from file %s? "
|
buffer-file-name)))
|
||||||
buffer-file-name))
|
|
||||||
(vlfi-move-to-chunk vlfi-start-pos vlfi-end-pos)))
|
(vlfi-move-to-chunk vlfi-start-pos vlfi-end-pos)))
|
||||||
|
|
||||||
(defun vlfi-jump-to-chunk (n)
|
(defun vlfi-jump-to-chunk (n)
|
||||||
@ -249,8 +259,7 @@ When prefix argument is supplied and positive
|
|||||||
When prefix argument is negative
|
When prefix argument is negative
|
||||||
append next APPEND number of batches to the existing buffer."
|
append next APPEND number of batches to the existing buffer."
|
||||||
(interactive "p")
|
(interactive "p")
|
||||||
(or (verify-visited-file-modtime (current-buffer))
|
(vlfi-verify-size)
|
||||||
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name)))
|
|
||||||
(let* ((end (min (+ vlfi-end-pos (* vlfi-batch-size
|
(let* ((end (min (+ vlfi-end-pos (* vlfi-batch-size
|
||||||
(abs append)))
|
(abs append)))
|
||||||
vlfi-file-size))
|
vlfi-file-size))
|
||||||
@ -279,8 +288,7 @@ When prefix argument is negative
|
|||||||
"Move to batch determined by START.
|
"Move to batch determined by START.
|
||||||
Adjust according to file start/end and show `vlfi-batch-size' bytes.
|
Adjust according to file start/end and show `vlfi-batch-size' bytes.
|
||||||
When given MINIMAL flag, skip non important operations."
|
When given MINIMAL flag, skip non important operations."
|
||||||
(or (verify-visited-file-modtime (current-buffer))
|
(vlfi-verify-size)
|
||||||
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name)))
|
|
||||||
(let ((start (max 0 start))
|
(let ((start (max 0 start))
|
||||||
(end (min (+ vlfi-start-pos vlfi-batch-size)
|
(end (min (+ vlfi-start-pos vlfi-batch-size)
|
||||||
vlfi-file-size)))
|
vlfi-file-size)))
|
||||||
@ -417,10 +425,13 @@ Return cons \(success-status . number-of-bytes-moved-back\)."
|
|||||||
|
|
||||||
(defun vlfi-decode-status (size)
|
(defun vlfi-decode-status (size)
|
||||||
"Check if decoding followed by encoding results in SIZE bytes."
|
"Check if decoding followed by encoding results in SIZE bytes."
|
||||||
(= size (length (encode-coding-string
|
(< (abs (- size (setq vlfi-encode-size
|
||||||
(decode-coding-region (point-min) (point-max)
|
(length (encode-coding-string
|
||||||
buffer-file-coding-system t)
|
(decode-coding-region
|
||||||
buffer-file-coding-system t))))
|
(point-min) (point-max)
|
||||||
|
buffer-file-coding-system t)
|
||||||
|
buffer-file-coding-system t)))))
|
||||||
|
4))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; search
|
;;; search
|
||||||
@ -666,9 +677,9 @@ Prematurely ending indexing will still show what's found so far."
|
|||||||
(pos (point)))
|
(pos (point)))
|
||||||
(vlfi-beginning-of-file)
|
(vlfi-beginning-of-file)
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(vlfi-build-occur regexp)
|
(unwind-protect (vlfi-build-occur regexp)
|
||||||
(vlfi-move-to-chunk start-pos end-pos)
|
(vlfi-move-to-chunk start-pos end-pos)
|
||||||
(goto-char pos)))
|
(goto-char pos))))
|
||||||
|
|
||||||
(defun vlfi-build-occur (regexp)
|
(defun vlfi-build-occur (regexp)
|
||||||
"Build occur style index for REGEXP."
|
"Build occur style index for REGEXP."
|
||||||
@ -804,17 +815,19 @@ or \\[vlfi-discard-edit] to discard changes.")))
|
|||||||
|
|
||||||
(defun vlfi-write ()
|
(defun vlfi-write ()
|
||||||
"Write current chunk to file. Always return true to disable save.
|
"Write current chunk to file. Always return true to disable save.
|
||||||
If changing size of chunk shift remaining file content."
|
If changing size of chunk, shift remaining file content."
|
||||||
(interactive)
|
(interactive)
|
||||||
(when (and (buffer-modified-p)
|
(when (and (buffer-modified-p)
|
||||||
(or (verify-visited-file-modtime (current-buffer))
|
(or (verify-visited-file-modtime (current-buffer))
|
||||||
(y-or-n-p "File has changed since visited or saved. \
|
(y-or-n-p "File has changed since visited or saved. \
|
||||||
Save anyway? ")))
|
Save anyway? ")))
|
||||||
(let ((pos (point))
|
(let ((pos (point))
|
||||||
(size-change (- vlfi-end-pos vlfi-start-pos
|
(size-change (- vlfi-encode-size
|
||||||
(length (encode-coding-region
|
(setq vlfi-encode-size
|
||||||
(point-min) (point-max)
|
(length (encode-coding-region
|
||||||
buffer-file-coding-system t)))))
|
(point-min) (point-max)
|
||||||
|
buffer-file-coding-system
|
||||||
|
t))))))
|
||||||
(cond ((zerop size-change)
|
(cond ((zerop size-change)
|
||||||
(write-region nil nil buffer-file-name vlfi-start-pos t))
|
(write-region nil nil buffer-file-name vlfi-start-pos t))
|
||||||
((< 0 size-change)
|
((< 0 size-change)
|
||||||
@ -840,6 +853,7 @@ Save anyway? ")))
|
|||||||
(progress-reporter-update reporter read-start-pos))
|
(progress-reporter-update reporter read-start-pos))
|
||||||
;; pad end with space
|
;; pad end with space
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
|
(vlfi-verify-size)
|
||||||
(insert-char 32 size-change)
|
(insert-char 32 size-change)
|
||||||
(write-region nil nil buffer-file-name (- vlfi-file-size
|
(write-region nil nil buffer-file-name (- vlfi-file-size
|
||||||
size-change) t)
|
size-change) t)
|
||||||
@ -849,8 +863,7 @@ Save anyway? ")))
|
|||||||
"Read `vlfi-batch-size' bytes from READ-POS and write them \
|
"Read `vlfi-batch-size' bytes from READ-POS and write them \
|
||||||
back at WRITE-POS. Return nil if EOF is reached, t otherwise."
|
back at WRITE-POS. Return nil if EOF is reached, t otherwise."
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(or (verify-visited-file-modtime (current-buffer))
|
(vlfi-verify-size)
|
||||||
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name)))
|
|
||||||
(let ((read-end (+ read-pos vlfi-batch-size)))
|
(let ((read-end (+ read-pos vlfi-batch-size)))
|
||||||
(insert-file-contents-literally buffer-file-name nil
|
(insert-file-contents-literally buffer-file-name nil
|
||||||
read-pos
|
read-pos
|
||||||
@ -884,8 +897,7 @@ Done by saving content up front and then writing previous batch."
|
|||||||
Then write initial buffer content to file at WRITE-POS.
|
Then write initial buffer content to file at WRITE-POS.
|
||||||
If HIDE-READ is non nil, temporarily hide literal read content.
|
If HIDE-READ is non nil, temporarily hide literal read content.
|
||||||
Return nil if EOF is reached, t otherwise."
|
Return nil if EOF is reached, t otherwise."
|
||||||
(or (verify-visited-file-modtime (current-buffer))
|
(vlfi-verify-size)
|
||||||
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name)))
|
|
||||||
(let ((read-more (< read-pos vlfi-file-size))
|
(let ((read-more (< read-pos vlfi-file-size))
|
||||||
(start-write-pos (point-min))
|
(start-write-pos (point-min))
|
||||||
(end-write-pos (point-max)))
|
(end-write-pos (point-max)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user