1
0
mirror of https://github.com/m00natic/vlfi.git synced 2025-11-18 07:45:40 +00:00

6 Commits
0.7 ... 0.8

Author SHA1 Message Date
Andrey Kotlarski
54927afb8f Update README and bump version. 2013-04-16 15:56:10 +03:00
Andrey Kotlarski
f14ef6ce9e Usability improvements to vlfi-occur. 2013-04-16 15:51:30 +03:00
Andrey Kotlarski
1dcd12288b Use overlays for number indicators. 2013-04-16 15:38:36 +03:00
Andrey Kotlarski
641ff4b961 First feature complete version of vlfi-occur. 2013-04-16 14:44:34 +03:00
Andrey Kotlarski
681d3d94fc Add vlfi-occur-mode. 2013-04-16 12:25:06 +03:00
Andrey Kotlarski
ba439de0f6 Initial generation of vlfi-occur results. 2013-04-16 02:16:03 +03:00
2 changed files with 187 additions and 14 deletions

View File

@@ -4,14 +4,15 @@ 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
memory that is to be used for operations on the file.
This is a fork that builds on the bare bones GNU ELPA vlf.el. It adds
the following improvements:
This mode builds on the bare bones GNU ELPA vlf.el. It adds the
following improvements:
- proper dealing with Unicode
- regular expression search on whole file (in constant memory
determined by current batch size)
- chunk editing (if size has changed, saving is done in constant
memory determined by current batch size)
- occur like indexing
- options to jump to beginning, end or arbitrary file chunk
- ability to jump/insert given number of batches at once
- newly added content is acknowledged if file has changed size

196
vlfi.el
View File

@@ -2,7 +2,7 @@
;; Copyright (C) 2006, 2012, 2013 Free Software Foundation, Inc.
;; Version: 0.7
;; Version: 0.8
;; Keywords: large files, utilities
;; Authors: 2006 Mathias Dahl <mathias.dahl@gmail.com>
;; 2012 Sam Steingold <sds@gnu.org>
@@ -62,6 +62,7 @@
(vlfi-change-batch-size t)))
(define-key map "s" 'vlfi-re-search-forward)
(define-key map "r" 'vlfi-re-search-backward)
(define-key map "o" 'vlfi-occur)
(define-key map "[" 'vlfi-beginning-of-file)
(define-key map "]" 'vlfi-end-of-file)
(define-key map "e" 'vlfi-edit-mode)
@@ -374,12 +375,12 @@ Return number of bytes moved back for this to happen."
(match-start-pos (+ vlfi-start-pos (position-bytes (point))))
(match-end-pos match-start-pos)
(to-find count)
(search-reporter (make-progress-reporter
(concat "Searching for " regexp "...")
(if backward
(- vlfi-file-size vlfi-end-pos)
vlfi-start-pos)
vlfi-file-size))
(reporter (make-progress-reporter
(concat "Searching for " regexp "...")
(if backward
(- vlfi-file-size vlfi-end-pos)
vlfi-start-pos)
vlfi-file-size))
(batch-step (/ vlfi-batch-size 8))) ; amount of chunk overlap
(unwind-protect
(catch 'end-of-file
@@ -412,8 +413,8 @@ Return number of bytes moved back for this to happen."
(point-max))
(point-max)))
(progress-reporter-update
search-reporter (- vlfi-file-size
vlfi-start-pos)))))
reporter (- vlfi-file-size
vlfi-start-pos)))))
(while (not (zerop to-find))
(cond ((re-search-forward regexp nil t)
(setq to-find (1- to-find)
@@ -438,9 +439,9 @@ Return number of bytes moved back for this to happen."
vlfi-start-pos))
(point-max))
(point-min)))
(progress-reporter-update search-reporter
(progress-reporter-update reporter
vlfi-end-pos)))))
(progress-reporter-done search-reporter))
(progress-reporter-done reporter))
(if backward
(vlfi-goto-match match-chunk-start match-chunk-end
match-end-pos match-start-pos
@@ -475,7 +476,7 @@ successful. Return nil if nothing found."
(- match-pos-start
vlfi-start-pos))
match-end)))
(overlay-put overlay 'face 'region)
(overlay-put overlay 'face 'match)
(unless success
(goto-char match-end)
(message "Moved to the %d match which is last"
@@ -518,6 +519,177 @@ Search is performed chunk by chunk in `vlfi-batch-size' memory."
(vlfi-move-to-chunk start-pos end-pos)
(goto-char pos)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; occur
(defvar vlfi-occur-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "n" 'vlfi-occur-next-match)
(define-key map "p" 'vlfi-occur-prev-match)
(define-key map "\C-m" 'vlfi-occur-visit)
(define-key map [mouse-1] 'vlfi-occur-visit)
map)
"Keymap for command `vlfi-occur-mode'.")
(define-derived-mode vlfi-occur-mode special-mode "VLFI[occur]"
"Major mode for showing occur matches of VLFI opened files.")
(defun vlfi-occur-next-match ()
"Move cursor to next match."
(interactive)
(if (eq (get-char-property (point) 'face) 'match)
(goto-char (next-single-property-change (point) 'face)))
(goto-char (or (text-property-any (point) (point-max) 'face 'match)
(text-property-any (point-min) (point)
'face 'match))))
(defun vlfi-occur-prev-match ()
"Move cursor to previous match."
(interactive)
(if (eq (get-char-property (point) 'face) 'match)
(goto-char (previous-single-property-change (point) 'face)))
(while (not (eq (get-char-property (point) 'face) 'match))
(goto-char (or (previous-single-property-change (point) 'face)
(point-max)))))
(defun vlfi-occur-visit (&optional event)
"Visit current `vlfi-occur' link in a vlfi buffer.
The same for mouse EVENT."
(interactive (list last-nonmenu-event))
(when event
(switch-to-buffer (window-buffer (posn-window (event-end event))))
(goto-char (posn-point (event-end event))))
(let* ((pos (point))
(pos-relative (- pos (line-beginning-position) 1))
(file (get-char-property pos 'file)))
(if file
(let ((chunk-start (get-char-property pos 'chunk-start))
(chunk-end (get-char-property pos 'chunk-end))
(buffer (get-char-property pos 'buffer))
(match-pos (or (get-char-property pos 'match-pos)
(+ (get-char-property pos 'line-pos)
pos-relative))))
(unless (buffer-live-p buffer)
(let ((occur-buffer (current-buffer)))
(setq buffer (vlfi file))
(switch-to-buffer occur-buffer)))
(pop-to-buffer buffer)
(vlfi-move-to-chunk chunk-start chunk-end)
(set-buffer buffer)
(goto-char match-pos)))))
(defun vlfi-occur (regexp)
"Make occur style index for REGEXP."
(interactive (list (read-regexp "List lines matching regexp"
(if regexp-history
(car regexp-history)))))
(let ((start-pos vlfi-start-pos)
(end-pos vlfi-end-pos)
(pos (point)))
(vlfi-beginning-of-file)
(goto-char (point-min))
(vlfi-build-occur regexp)
(vlfi-move-to-chunk start-pos end-pos)
(goto-char pos)))
(defun vlfi-build-occur (regexp)
"Build occur style index for REGEXP."
(let ((line 1)
(last-match-line 0)
(last-line-pos (point-min))
(file buffer-file-name)
(total-matches 0)
(match-end-pos (+ vlfi-start-pos (position-bytes (point))))
(occur-buffer (generate-new-buffer
(concat "*VLFI-occur " (file-name-nondirectory
buffer-file-name)
"*")))
(line-regexp (concat "\\(?5:[\n\C-m]\\)\\|\\(?10:"
regexp "\\)"))
(batch-step (/ vlfi-batch-size 8))
(reporter (make-progress-reporter
(concat "Building index for " regexp "...")
vlfi-start-pos vlfi-file-size)))
(unwind-protect
(progn
(while (/= vlfi-end-pos vlfi-file-size)
(if (re-search-forward line-regexp nil t)
(progn
(setq match-end-pos (+ vlfi-start-pos
(position-bytes
(match-end 0))))
(if (match-string 5)
(setq line (1+ line)
last-line-pos (point))
(let* ((chunk-start vlfi-start-pos)
(chunk-end vlfi-end-pos)
(vlfi-buffer (current-buffer))
(line-pos (line-beginning-position))
(line-text (buffer-substring
line-pos (line-end-position))))
(with-current-buffer occur-buffer
(unless (= line last-match-line)
(insert "\n:")
(let* ((overlay-pos (1- (point)))
(overlay (make-overlay
overlay-pos
(1+ overlay-pos))))
(overlay-put overlay 'before-string
(propertize
(number-to-string line)
'face 'shadow)))
(insert (propertize line-text
'file file
'buffer vlfi-buffer
'chunk-start chunk-start
'chunk-end chunk-end
'mouse-face '(highlight)
'line-pos line-pos
'help-echo
(format "Move to line %d"
line))))
(setq last-match-line line
total-matches (1+ total-matches))
(let ((line-start (+ (line-beginning-position)
1))
(match-pos (match-beginning 10)))
(add-text-properties
(+ line-start match-pos (- last-line-pos))
(+ line-start (match-end 10)
(- last-line-pos))
(list 'face 'match 'match-pos match-pos
'help-echo
(format "Move to match %d"
total-matches))))))))
(let ((batch-move (- vlfi-end-pos batch-step)))
(vlfi-move-to-batch (if (< batch-move match-end-pos)
match-end-pos
batch-move) t))
(goto-char (if (< vlfi-start-pos match-end-pos)
(or (byte-to-position (- match-end-pos
vlfi-start-pos))
(point-min))
(point-min)))
(setq last-match-line 0
last-line-pos (point-min))
(progress-reporter-update reporter vlfi-end-pos)))
(progress-reporter-done reporter))
(if (zerop total-matches)
(progn (with-current-buffer occur-buffer
(set-buffer-modified-p nil))
(kill-buffer occur-buffer)
(message "No matches for \"%s\"" regexp))
(with-current-buffer occur-buffer
(goto-char (point-min))
(insert (propertize
(format "%d matches from %d lines for \"%s\" \
in file: %s" total-matches line regexp file)
'face 'underline))
(set-buffer-modified-p nil)
(forward-char)
(vlfi-occur-mode))
(display-buffer occur-buffer)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; editing