unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Mathias Dahl <mathias.dahl@gmail.com>
To: sds@gnu.org, emacs-devel@gnu.org
Cc: Stefan Monnier <monnier@iro.umontreal.ca>
Subject: Re: feature request: view part of file
Date: Thu, 14 Jun 2012 18:53:12 +0200	[thread overview]
Message-ID: <CABrcCQ4RQNVCyX4UaB_GuSTtX9_RGJc6RupyZQZagmsh3H5UXQ@mail.gmail.com> (raw)
In-Reply-To: <87d351uap6.fsf@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 1030 bytes --]

>
> > There's vlf.el.  I wish someone would take this on and develop it
> > further.
>
> Is it okay if I clean it up and put into the emacs tree, hooking up into
> the "really open this huge file" dialog?
>

Be my guest, do what you like with it. As you can read in the comment
section of the file I created vlf.el because I got kind of tired about
hearing that same question over and over again. I had no real *personal*
itch. Hence I got tired of it and kind of abandoned it after some
experiments.


> Do we have the papers for Mathias Dahl, the vlf author?
>

There should be papers for me from the time when Tumme/image-dired was
included in Emacs.

Attached you can find my latest local version of vlf.el (working state
unknown). The code should be quite clean. I get only one warning when byte
compiling and only two warnings with checkdoc.

It would feel nice if something "real" finally came out of it. The basic
mechanisms is quite simple. What Stefan mentions about hooking into isearch
sounds wicked cool :)

/Mathias

[-- Attachment #1.2: Type: text/html, Size: 1513 bytes --]

[-- Attachment #2: vlf.el --]
[-- Type: application/octet-stream, Size: 6715 bytes --]

;;; vlf.el --- View Large Files

;; Copyright (C) 2006  Mathias Dahl

;; Version: 0.1.2
;; Keywords: files, helpers, utilities
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
;; Maintainer: Mathias Dahl
;; URL: http://www.emacswiki.org/cgi-bin/wiki/VLF

;; 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
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:
;; 
;; After reading the Nth post on Gnu Emacs Help about Viewing Large
;; Files in Emacs, it itched so much that I decided to make a try.  It
;; helped quite a lot when Kevin Rodgers posted a snippet on how to
;; use `insert-file-contents' to extract part of a file.  At first I
;; made a try using head and tail and that worked too, but using
;; internal Emacs commands is nicer.  Here is the code to extract data
;; using head and tail in case someone wanna try that out in the
;; future:

;; (defun vlf-extract-part-of-file (file from to)
;;   "Returns bytes in FILE from FROM to TO."
;;   (let ((size (vlf-file-size file)))
;;     (if (or (> from size)
;;             (> to size))
;;         (error "From or to is larger that the file size"))
;;     (with-temp-buffer
;;       (shell-command
;;        (format "head --bytes %d %s | tail --bytes %d"
;; 	       to file (+ (- to from) 1)) t)
;;       (buffer-substring (point-min) (point-max)))))

;;; History:
;;
;; - Wed Jan 10 00:13:45 2007
;;
;;    First version created and released into the wild.
;;
;; - Wed Jan 10 18:58:47 2007
;;
;;    0.1.2
;;
;;    Added option to use external tools (head and tail) for
;;    extracting the data from the file.
;;
;;    Refactored buffer name format code into a new function.
;;
;;    Started to fiddle with float/integer conversions.
;;

;;; Bugs
;;
;; Probably some. Feel free to fix them :)

;;; Code:

(defgroup vlf nil
  "Browse large files in Emacs"
  :prefix "vlf-"
  :group 'files)

(defcustom vlf-batch-size 1000
  "Defines how large each batch of file data is."
  :type 'integer
  :group 'vlf)

(defcustom vlf-external-extraction nil
  "How to extract the data from a file.
`nil' means to use internal extraction, using
`insert-file-contents'. `t' means to use external `head' and
`tail' tools."
  :type 'boolean
  :group 'vlf)

(defvar vlf-current-start-pos 1
  "Keeps track of file position.")

(defvar vlf-current-batch-size nil
  "Keeps track of current batch size.")

(defvar vlf-current-file nil
  "File that is currently viewed.")

(defvar vlf-current-file-size 0
  "Size of current file.")

(defvar vlf-mode-map (make-sparse-keymap)
  "Keymap for `vlf-mode'.")

(defun vlf-define-keymap ()
  "Define keymap for `vlf-mode'."
  (define-key vlf-mode-map [next] 'vlf-next)
  (define-key vlf-mode-map [prior] 'vlf-prev)
  (define-key vlf-mode-map "q" 'vlf-quit))

(define-derived-mode vlf-mode
  fundamental-mode "vlf-mode"
  "Mode to browse large files in.
See `vlf' for details."
  (vlf-define-keymap)
  (toggle-read-only 1)
  (message "vlf-mode enabled"))

(defun vlf-file-size (file)
  "Get size of FILE."
  (nth 7 (file-attributes file)))

(defun vlf-quit ()
  "Quit vlf."
  (interactive)
  (kill-buffer (current-buffer)))

(defun vlf-extract-with-head-and-tail (file from to)
  "Returns bytes in FILE from FROM to TO."
  (let ((size (vlf-file-size file)))
    (if (or (> from size)
            (> to size))
        (error "From or to is larger that the file size"))
    (with-temp-buffer
      (shell-command
       (format "head --bytes %.0f \"%s\" | tail --bytes %.0f"
	       (float to) (expand-file-name file)
               (float (+ (- to from) 1))) t)
      (buffer-substring (point-min) (point-max)))))

(defun vlf-insert-batch ()
  "Insert current batch of data."
  (let* ((beg (1- vlf-current-start-pos))
        (end (+ beg vlf-current-batch-size)))
    (if vlf-external-extraction
        (insert
         (vlf-extract-with-head-and-tail
          vlf-current-file (1+ beg) end))
      (insert-file-contents
       vlf-current-file nil
       (floor beg) (floor end)))))

(defun vlf-format-buffer-name ()
  "Return format for vlf buffer name."
  (format "%s[%.0f,%.0f(%.0f)]"
          (file-name-nondirectory vlf-current-file)
          vlf-current-start-pos
          (1- (+ vlf-current-start-pos
                 vlf-current-batch-size))
          vlf-current-file-size))

(defun vlf-next ()
  "Display the next batch of file data."
  (interactive)
  (let ((inhibit-read-only t)
        left next-start-pos
        (size (vlf-file-size vlf-current-file)))
    (setq next-start-pos (float (+ vlf-current-start-pos
                                   vlf-batch-size)))
    (if (> next-start-pos size)
        (message "End of file")
      (setq vlf-current-batch-size
            vlf-batch-size
            vlf-current-start-pos next-start-pos
            left (1+ (- size vlf-current-start-pos)))     
      (if (< left vlf-current-batch-size)
          (setq vlf-current-batch-size left))
      (erase-buffer)
      (vlf-insert-batch)
      (rename-buffer
       (vlf-format-buffer-name)))))

(defun vlf-prev ()
  "Display the previous batch of file data."
  (interactive)
  (if (= 1 vlf-current-start-pos)
      (message "At beginning of file")
    (let ((inhibit-read-only t))
      (erase-buffer)
      (setq vlf-current-start-pos (- vlf-current-start-pos
                                     vlf-batch-size)
            vlf-current-batch-size vlf-batch-size)
      (vlf-insert-batch)
      (rename-buffer
       (vlf-format-buffer-name)))))

(defun vlf (file)
  "View a large file in Emacs FILE is the file to open.
Batches of the file data from FILE will be displayed in a
read-only buffer.  You can customize the amount of bytes to
display by customizing `vlf-batch-size'."
  (interactive "fFile to open: ")
  (setq vlf-current-file file
        vlf-current-start-pos 1
        vlf-current-file-size (vlf-file-size file)
        vlf-current-batch-size
        (1- (+ vlf-current-start-pos
               vlf-batch-size)))
  (switch-to-buffer
   (generate-new-buffer (vlf-format-buffer-name)))
  (erase-buffer)
  (vlf-insert-batch)
  (vlf-mode))

(provide 'vlf)

;;; vlf.el ends here

  reply	other threads:[~2012-06-14 16:53 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-13 20:52 feature request: view part of file Sam Steingold
2012-06-13 23:16 ` Stefan Monnier
2012-06-14 16:20   ` Sam Steingold
2012-06-14 16:53     ` Mathias Dahl [this message]
2012-06-14 17:32     ` Stephen J. Turnbull
2012-06-14 18:21       ` Paul Eggert
     [not found]     ` <jwvd3517qww.fsf-monnier+emacs@gnu.org>
     [not found]       ` <CABrcCQ5zDfB2tw9DRrwpCZmDqHPc+BB6W5w9ULNU95e_v4yyJw@mail.gmail.com>
     [not found]         ` <87395xu768.fsf@gnu.org>
     [not found]           ` <CABrcCQ6rpG9qhsCO+ZEpTiNqbQRtg-PBeb=q_B5F8YgrGxoWKA@mail.gmail.com>
     [not found]             ` <jwvvcit67sc.fsf-monnier+emacs@gnu.org>
2012-06-14 19:34               ` Sam Steingold
2012-06-14 21:29 ` Sam Steingold
2012-06-18 20:34   ` Štěpán Němec
2012-07-19 17:58     ` Samuel Bronson
2012-07-19 19:38       ` Stephen J. Turnbull
2012-08-04 11:58   ` Andrey Kotlarski
2013-01-18 23:30   ` Vitalie Spinu
2013-01-18 23:52     ` Vitalie Spinu
2013-01-19  6:54       ` Eli Zaretskii
2013-01-19 10:18         ` Paul Eggert
2013-01-19 10:51           ` Eli Zaretskii
2013-01-19 12:47             ` Paul Eggert
2013-01-19 13:47               ` Eli Zaretskii
2013-01-19 19:00                 ` Paul Eggert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CABrcCQ4RQNVCyX4UaB_GuSTtX9_RGJc6RupyZQZagmsh3H5UXQ@mail.gmail.com \
    --to=mathias.dahl@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=sds@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).