m00natic pushed a commit to branch master in repository elpa. commit de361827d8f40ee471163a029c28e833f094869f Author: Andrey Kotlarski <m00nati...@gmail.com> Date: Sun Feb 23 17:33:35 2014 +0200
* packages/vlf: Version 1.5. Add hexl-mode integration and hook extensibility. * vlf.el: (vlf-before-batch-functions, vlf-after-batch-functions): New hooks. (vlf-mode): Play well with hexl-mode. Don't disable mode in case user has declined to reload whole file. (vlf-keep-alive, vlf-hexl-before, vlf-hexl-after): New functions. Use them in hooks. (vlf-hexl-save, vlf-hexl-scroll-up, vlf-hexl-scroll-down): New advices. * vlf-write.el (vlf-write): Run batch hooks. Check if tramp is loaded. * vlf-search.el (vlf-re-search, vlf-goto-line): Run batch hooks. Check if tramp is loaded. * vlf-occur.el (vlf-occur): Run batch hooks. (vlf-build-occur): Check if tramp is loaded. * vlf-integrate.el: Minor whitespace adjustment. * vlf-ediff.el: Enable lexical scoping. (vlf-ediff-next): Run batch hooks. Check if tramp is loaded. * vlf-base.el (vlf-before-chunk-update, vlf-after-chunk-update): New hooks. (vlf-move-to-chunk-1, vlf-move-to-chunk-2): Run them. (vlf-move-to-chunk-2): Delete undo info only in case it's not disabled. (vlf-insert-file-contents-1): Use insert-file-contents instead of manual decoding and remove position parameter. (vlf-insert-file-contents, vlf-adjust-start): Adjust calls. --- packages/vlf/vlf-base.el | 55 +++++++--------- packages/vlf/vlf-ediff.el | 21 ++++--- packages/vlf/vlf-integrate.el | 18 ++--- packages/vlf/vlf-occur.el | 11 +++- packages/vlf/vlf-search.el | 17 ++++-- packages/vlf/vlf-write.el | 70 +++++++++++---------- packages/vlf/vlf.el | 135 +++++++++++++++++++++++++++++++---------- 7 files changed, 202 insertions(+), 125 deletions(-) diff --git a/packages/vlf/vlf-base.el b/packages/vlf/vlf-base.el index 2a530f8..98b6831 100644 --- a/packages/vlf/vlf-base.el +++ b/packages/vlf/vlf-base.el @@ -27,17 +27,19 @@ ;;; Code: -(defgroup vlf nil - "View Large Files in Emacs." - :prefix "vlf-" - :group 'files) - (defcustom vlf-batch-size 1024 "Defines how large each batch of file data is (in bytes)." - :group 'vlf - :type 'integer) + :group 'vlf :type 'integer) (put 'vlf-batch-size 'permanent-local t) +(defcustom vlf-before-chunk-update nil + "Hook that runs before chunk update." + :group 'vlf :type 'hook) + +(defcustom vlf-after-chunk-update nil + "Hook that runs after chunk update." + :group 'vlf :type 'hook) + ;;; Keep track of file position. (defvar vlf-start-pos 0 "Absolute position of the visible chunk start.") @@ -142,6 +144,7 @@ bytes added to the end." ((or (and (<= start vlf-start-pos) (<= edit-end end)) (not modified) (y-or-n-p "Chunk modified, are you sure? ")) + (run-hooks 'vlf-before-chunk-update) (let ((shift-start 0) (shift-end 0)) (let ((pos (+ (position-bytes (point)) vlf-start-pos)) @@ -200,12 +203,14 @@ bytes added to the end." (setq vlf-start-pos start)) (set-buffer-modified-p modified) (set-visited-file-modtime) + (run-hooks 'vlf-after-chunk-update) (cons shift-start shift-end)))))) (defun vlf-move-to-chunk-2 (start end) "Unconditionally move to chunk enclosed by START END bytes. Return number of bytes moved back for proper decoding and number of bytes added to the end." + (run-hooks 'vlf-before-chunk-update) (vlf-verify-size t) (setq vlf-start-pos (max 0 start) vlf-end-pos (min end vlf-file-size)) @@ -221,14 +226,16 @@ bytes added to the end." (goto-char (or (byte-to-position (+ pos (car shifts))) (point-max))))) (set-buffer-modified-p nil) - (setq buffer-undo-list nil) + (or (eq buffer-undo-list t) + (setq buffer-undo-list nil)) + (run-hooks 'vlf-after-chunk-update) shifts)) (defun vlf-insert-file-contents (start end adjust-start adjust-end &optional position) "Adjust chunk at absolute START to END till content can be\ -properly decoded. ADJUST-START determines if trying to prepend bytes\ - to the beginning, ADJUST-END - append to the end. +properly decoded. ADJUST-START determines if trying to prepend bytes +to the beginning, ADJUST-END - append to the end. Use buffer POSITION as start if given. Return number of bytes moved back for proper decoding and number of bytes added to the end." @@ -245,7 +252,7 @@ bytes added to the end." (setq shift-start (vlf-adjust-start start safe-end position adjust-end) start (- start shift-start)) - (vlf-insert-file-contents-1 start safe-end position)) + (vlf-insert-file-contents-1 start safe-end)) (if adjust-end (setq shift-end (- (car (vlf-delete-region position start safe-end end @@ -254,23 +261,9 @@ bytes added to the end." end))) (cons shift-start shift-end))) -(defun vlf-insert-file-contents-1 (start end position) - "Extract decoded file bytes START to END at POSITION." - (let ((coding buffer-file-coding-system)) - (insert-file-contents-literally buffer-file-name nil start end) - (let ((coding-system-for-read coding)) - (decode-coding-inserted-region position (point-max) - buffer-file-name nil start end))) - (when (eq (detect-coding-region position (min (+ position - vlf-sample-size) - (point-max)) t) - 'no-conversion) - (delete-region position (point-max)) - (insert-file-contents-literally buffer-file-name nil start end) - (let ((coding-system-for-read nil)) - (decode-coding-inserted-region position (point-max) - buffer-file-name nil start end))) - (setq buffer-file-coding-system last-coding-system-used)) +(defun vlf-insert-file-contents-1 (start end) + "Extract decoded file bytes START to END." + (insert-file-contents buffer-file-name nil start end)) (defun vlf-adjust-start (start end position adjust-end) "Adjust chunk beginning at absolute START to END till content can\ @@ -283,8 +276,8 @@ Return number of bytes moved back for proper decoding." (strict (or (= sample-end vlf-file-size) (and (not adjust-end) (= sample-end end)))) (shift 0)) - (while (and (progn (vlf-insert-file-contents-1 - safe-start sample-end position) + (while (and (progn (vlf-insert-file-contents-1 safe-start + sample-end) (not (zerop safe-start))) (< shift 3) (let ((diff (- chunk-size @@ -304,7 +297,7 @@ Return number of bytes moved back for proper decoding." position t 'start))) (unless (= sample-end end) (delete-region position (point-max)) - (vlf-insert-file-contents-1 safe-start end position)) + (vlf-insert-file-contents-1 safe-start end)) (- start safe-start))) (defun vlf-delete-region (position start end border cut-point from-start diff --git a/packages/vlf/vlf-ediff.el b/packages/vlf/vlf-ediff.el index 51c8aec..2b7c63f 100644 --- a/packages/vlf/vlf-ediff.el +++ b/packages/vlf/vlf-ediff.el @@ -1,4 +1,4 @@ -;;; vlf-ediff.el --- VLF ediff functionality +;;; vlf-ediff.el --- VLF ediff functionality -*- lexical-binding: t -*- ;; Copyright (C) 2014 Free Software Foundation, Inc. @@ -154,6 +154,7 @@ beginning of difference list." governed by EDIFF-BUFFER. NEXT-FUNC is used to jump to the next logical chunks in case there is no difference at the current ones." (set-buffer buffer-A) + (run-hook-with-args 'vlf-before-batch-functions 'ediff) (setq buffer-A (current-buffer)) ;names change, so reference by buffer object (let ((end-A (= vlf-start-pos vlf-end-pos)) (chunk-A (cons vlf-start-pos vlf-end-pos)) @@ -163,9 +164,11 @@ logical chunks in case there is no difference at the current ones." (forward-p (eq next-func 'vlf-next-chunk))) (font-lock-mode 0) (set-buffer buffer-B) + (run-hook-with-args 'vlf-before-batch-functions 'ediff) (setq buffer-B (current-buffer) min-file-size (min min-file-size vlf-file-size)) - (let ((tramp-verbose (min 2 tramp-verbose)) + (let ((tramp-verbose (if (boundp 'tramp-verbose) + (min tramp-verbose 2))) (end-B (= vlf-start-pos vlf-end-pos)) (chunk-B (cons vlf-start-pos vlf-end-pos)) (font-lock-B font-lock-mode) @@ -222,12 +225,6 @@ logical chunks in case there is no difference at the current ones." (and (not end-A) (not end-B))) (vlf-ediff-refine buffer-A buffer-B))) (setq done t)) - (when font-lock-A - (set-buffer buffer-A) - (font-lock-mode 1)) - (when font-lock-B - (set-buffer buffer-B) - (font-lock-mode 1)) (unless done (set-buffer buffer-A) (set-buffer-modified-p nil) @@ -237,7 +234,13 @@ logical chunks in case there is no difference at the current ones." (vlf-move-to-chunk (car chunk-B) (cdr chunk-B)) (set-buffer ediff-buffer) (ediff-update-diffs) - (vlf-ediff-refine buffer-A buffer-B)))))) + (vlf-ediff-refine buffer-A buffer-B)) + (set-buffer buffer-A) + (if font-lock-A (font-lock-mode 1)) + (run-hook-with-args 'vlf-after-batch-functions 'ediff) + (set-buffer buffer-B) + (if font-lock-B (font-lock-mode 1)) + (run-hook-with-args 'vlf-after-batch-functions 'ediff))))) (defun vlf-ediff-refine (buffer-A buffer-B) "Try to minimize differences between BUFFER-A and BUFFER-B. diff --git a/packages/vlf/vlf-integrate.el b/packages/vlf/vlf-integrate.el index c072398..435ac45 100644 --- a/packages/vlf/vlf-integrate.el +++ b/packages/vlf/vlf-integrate.el @@ -26,10 +26,8 @@ ;;; Code: -(defgroup vlf nil - "View Large Files in Emacs." - :prefix "vlf-" - :group 'files) +(defgroup vlf nil "View Large Files in Emacs." + :prefix "vlf-" :group 'files) (defcustom vlf-application 'ask "Determines when `vlf' will be offered on opening files. @@ -37,18 +35,16 @@ Possible values are: nil to never use it; `ask' offer `vlf' when file size is beyond `large-file-warning-threshold'; `dont-ask' automatically use `vlf' for large files; `always' use `vlf' for all files." - :group 'vlf - :type '(radio (const :format "%v " nil) - (const :format "%v " ask) - (const :format "%v " dont-ask) - (const :format "%v" always))) + :group 'vlf :type '(radio (const :format "%v " nil) + (const :format "%v " ask) + (const :format "%v " dont-ask) + (const :format "%v" always))) (defcustom vlf-forbidden-modes-list '(archive-mode tar-mode jka-compr git-commit-mode image-mode doc-view-mode doc-view-mode-maybe ebrowse-tree-mode) "Major modes which VLF will not be automatically applied to." - :group 'vlf - :type '(list symbol)) + :group 'vlf :type '(list symbol)) (unless (fboundp 'file-size-human-readable) (defun file-size-human-readable (file-size) diff --git a/packages/vlf/vlf-occur.el b/packages/vlf/vlf-occur.el index 3b7be85..cea885e 100644 --- a/packages/vlf/vlf-occur.el +++ b/packages/vlf/vlf-occur.el @@ -131,8 +131,11 @@ Prematurely ending indexing will still show what's found so far." (set (make-local-variable 'vlf-batch-size) batch-size) (vlf-mode 1) (goto-char (point-min)) + (run-hook-with-args 'vlf-before-batch-functions 'occur) (vlf-with-undo-disabled - (vlf-build-occur regexp vlf-buffer)))) + (vlf-build-occur regexp vlf-buffer)) + (run-hook-with-args 'vlf-after-batch-functions 'occur))) + (run-hook-with-args 'vlf-before-batch-functions 'occur) (let ((start-pos vlf-start-pos) (end-pos vlf-end-pos) (pos (point))) @@ -141,11 +144,13 @@ Prematurely ending indexing will still show what's found so far." (goto-char (point-min)) (unwind-protect (vlf-build-occur regexp (current-buffer)) (vlf-move-to-chunk start-pos end-pos) - (goto-char pos)))))) + (goto-char pos)))) + (run-hook-with-args 'vlf-after-batch-functions 'occur))) (defun vlf-build-occur (regexp vlf-buffer) "Build occur style index for REGEXP over VLF-BUFFER." - (let ((tramp-verbose (min 2 tramp-verbose)) + (let ((tramp-verbose (if (boundp 'tramp-verbose) + (min tramp-verbose 2))) (case-fold-search t) (line 1) (last-match-line 0) diff --git a/packages/vlf/vlf-search.el b/packages/vlf/vlf-search.el index 8fa2ce4..0462cb2 100644 --- a/packages/vlf/vlf-search.el +++ b/packages/vlf/vlf-search.el @@ -34,7 +34,9 @@ BATCH-STEP is amount of overlap between successive chunks." (if (<= count 0) (error "Count must be positive")) - (let* ((tramp-verbose (min 2 tramp-verbose)) + (run-hook-with-args 'vlf-before-batch-functions 'search) + (let* ((tramp-verbose (if (boundp 'tramp-verbose) + (min tramp-verbose 2))) (case-fold-search t) (match-chunk-start vlf-start-pos) (match-chunk-end vlf-end-pos) @@ -118,13 +120,14 @@ BATCH-STEP is amount of overlap between successive chunks." count to-find) (vlf-goto-match match-chunk-start match-chunk-end match-start-pos match-end-pos - count to-find)))))) + count to-find)) + (run-hook-with-args 'vlf-after-batch-functions 'search))))) (defun vlf-goto-match (match-chunk-start match-chunk-end match-pos-start match-pos-end count to-find) - "Move to MATCH-CHUNK-START MATCH-CHUNK-END surrounding \ + "Move to MATCH-CHUNK-START MATCH-CHUNK-END surrounding\ MATCH-POS-START and MATCH-POS-END. According to COUNT and left TO-FIND, show if search has been successful. Return nil if nothing found." @@ -179,8 +182,10 @@ Search is performed chunk by chunk in `vlf-batch-size' memory." "Go to line N. If N is negative, count from the end of file." (interactive (if (vlf-no-modifications) (list (read-number "Go to line: ")))) + (run-hook-with-args 'vlf-before-batch-functions 'goto-line) (vlf-verify-size) - (let ((tramp-verbose (min 2 tramp-verbose)) + (let ((tramp-verbose (if (boundp 'tramp-verbose) + (min tramp-verbose 2))) (start-pos vlf-start-pos) (end-pos vlf-end-pos) (pos (point)) @@ -243,8 +248,10 @@ Search is performed chunk by chunk in `vlf-batch-size' memory." (unless success (vlf-with-undo-disabled (vlf-move-to-chunk-2 start-pos end-pos)) + (vlf-update-buffer-name) (goto-char pos) - (message "Unable to find line"))))) + (message "Unable to find line")) + (run-hook-with-args 'vlf-after-batch-functions 'goto-line)))) (provide 'vlf-search) diff --git a/packages/vlf/vlf-write.el b/packages/vlf/vlf-write.el index e8549a7..1c5db49 100644 --- a/packages/vlf/vlf-write.el +++ b/packages/vlf/vlf-write.el @@ -33,40 +33,42 @@ "Write current chunk to file. Always return true to disable save. If changing size of chunk, shift remaining file content." (interactive) - (and (buffer-modified-p) - (or (verify-visited-file-modtime (current-buffer)) - (y-or-n-p "File has changed since visited or saved. \ -Save anyway? ")) - (if (zerop vlf-file-size) ;new file - (progn - (write-region nil nil buffer-file-name vlf-start-pos t) - (setq vlf-file-size (vlf-get-file-size - buffer-file-truename) - vlf-end-pos vlf-file-size) - (vlf-update-buffer-name)) - (widen) - (let* ((region-length (length (encode-coding-region - (point-min) (point-max) - buffer-file-coding-system t))) - (size-change (- vlf-end-pos vlf-start-pos - region-length))) - (if (zerop size-change) - (write-region nil nil buffer-file-name vlf-start-pos t) - (let ((tramp-verbose (min 2 tramp-verbose)) - (pos (point)) - (font-lock font-lock-mode)) - (font-lock-mode 0) - (if (< 0 size-change) - (vlf-file-shift-back size-change) - (vlf-file-shift-forward (- size-change))) - (if font-lock (font-lock-mode 1)) - (vlf-move-to-chunk-2 vlf-start-pos - (if (< (- vlf-end-pos vlf-start-pos) - vlf-batch-size) - (+ vlf-start-pos vlf-batch-size) - vlf-end-pos)) - (vlf-update-buffer-name) - (goto-char pos)))))) + (when (and (buffer-modified-p) + (or (verify-visited-file-modtime (current-buffer)) + (y-or-n-p "File has changed since visited or saved.\ + Save anyway? "))) + (run-hook-with-args 'vlf-before-batch-functions 'write) + (if (zerop vlf-file-size) ;new file + (progn (write-region nil nil buffer-file-name vlf-start-pos t) + (setq vlf-file-size (vlf-get-file-size + buffer-file-truename) + vlf-end-pos vlf-file-size) + (vlf-update-buffer-name)) + (widen) + (let* ((region-length (length (encode-coding-region + (point-min) (point-max) + buffer-file-coding-system t))) + (size-change (- vlf-end-pos vlf-start-pos + region-length))) + (if (zerop size-change) + (write-region nil nil buffer-file-name vlf-start-pos t) + (let ((tramp-verbose (if (boundp 'tramp-verbose) + (min tramp-verbose 2))) + (pos (point)) + (font-lock font-lock-mode)) + (font-lock-mode 0) + (if (< 0 size-change) + (vlf-file-shift-back size-change) + (vlf-file-shift-forward (- size-change))) + (if font-lock (font-lock-mode 1)) + (vlf-move-to-chunk-2 vlf-start-pos + (if (< (- vlf-end-pos vlf-start-pos) + vlf-batch-size) + (+ vlf-start-pos vlf-batch-size) + vlf-end-pos)) + (vlf-update-buffer-name) + (goto-char pos))))) + (run-hook-with-args 'vlf-after-batch-functions 'write)) t) (defun vlf-file-shift-back (size-change) diff --git a/packages/vlf/vlf.el b/packages/vlf/vlf.el index 18f274b..f90b770 100644 --- a/packages/vlf/vlf.el +++ b/packages/vlf/vlf.el @@ -2,7 +2,7 @@ ;; Copyright (C) 2006, 2012-2014 Free Software Foundation, Inc. -;; Version: 1.4 +;; Version: 1.5 ;; Keywords: large files, utilities ;; Maintainer: Andrey Kotlarski <m00nati...@gmail.com> ;; Authors: 2006 Mathias Dahl <mathias.d...@gmail.com> @@ -39,6 +39,21 @@ ;;; Code: +(defgroup vlf nil "View Large Files in Emacs." + :prefix "vlf-" :group 'files) + +(defcustom vlf-before-batch-functions nil + "Hook that runs before multiple batch operations. +One argument is supplied that specifies current action. Possible +values are: `write', `ediff', `occur', `search', `goto-line'." + :group 'vlf :type 'hook) + +(defcustom vlf-after-batch-functions nil + "Hook that runs after multiple batch operations. +One argument is supplied that specifies current action. Possible +values are: `write', `ediff', `occur', `search', `goto-line'." + :group 'vlf :type 'hook) + (require 'vlf-base) (autoload 'vlf-write "vlf-write" "Write current chunk to file." t) @@ -86,37 +101,48 @@ (define-minor-mode vlf-mode "Mode to browse large files in." - :lighter " VLF" - :group 'vlf - :keymap vlf-prefix-map - (if vlf-mode - (progn - (set (make-local-variable 'require-final-newline) nil) - (add-hook 'write-file-functions 'vlf-write nil t) - (set (make-local-variable 'revert-buffer-function) - 'vlf-revert) - (make-local-variable 'vlf-batch-size) - (setq vlf-file-size (vlf-get-file-size buffer-file-truename) - vlf-start-pos 0 - vlf-end-pos 0) - (let* ((pos (position-bytes (point))) - (start (* (/ pos vlf-batch-size) vlf-batch-size))) - (goto-char (byte-to-position (- pos start))) - (vlf-move-to-batch start))) - (kill-local-variable 'revert-buffer-function) - (vlf-stop-follow) - (when (or (not large-file-warning-threshold) - (< vlf-file-size large-file-warning-threshold) - (y-or-n-p (format "Load whole file (%s)? " - (file-size-human-readable - vlf-file-size)))) - (kill-local-variable 'require-final-newline) - (remove-hook 'write-file-functions 'vlf-write t) - (let ((pos (+ vlf-start-pos (position-bytes (point))))) - (vlf-with-undo-disabled - (insert-file-contents buffer-file-name t nil nil t)) - (goto-char (byte-to-position pos))) - (rename-buffer (file-name-nondirectory buffer-file-name) t)))) + :lighter " VLF" :group 'vlf :keymap vlf-prefix-map + (cond (vlf-mode + (set (make-local-variable 'require-final-newline) nil) + (add-hook 'write-file-functions 'vlf-write nil t) + (set (make-local-variable 'revert-buffer-function) + 'vlf-revert) + (make-local-variable 'vlf-batch-size) + (setq vlf-file-size (vlf-get-file-size buffer-file-truename) + vlf-start-pos 0 + vlf-end-pos 0) + (let* ((pos (position-bytes (point))) + (start (* (/ pos vlf-batch-size) vlf-batch-size))) + (goto-char (byte-to-position (- pos start))) + (vlf-move-to-batch start)) + (add-hook 'after-change-major-mode-hook 'vlf-keep-alive t t) + (vlf-keep-alive)) + ((or (not large-file-warning-threshold) + (< vlf-file-size large-file-warning-threshold) + (y-or-n-p (format "Load whole file (%s)? " + (file-size-human-readable + vlf-file-size)))) + (kill-local-variable 'revert-buffer-function) + (vlf-stop-follow) + (kill-local-variable 'require-final-newline) + (remove-hook 'write-file-functions 'vlf-write t) + (remove-hook 'after-change-major-mode-hook + 'vlf-keep-alive t) + (let ((hexl (eq major-mode 'hexl-mode))) + (if hexl (hexl-mode-exit)) + (let ((pos (+ vlf-start-pos (position-bytes (point))))) + (vlf-with-undo-disabled + (insert-file-contents buffer-file-name t nil nil t)) + (goto-char (byte-to-position pos))) + (if hexl (hexl-mode))) + (rename-buffer (file-name-nondirectory buffer-file-name) t)) + (t (setq vlf-mode t)))) + +(defun vlf-keep-alive () + "Keep `vlf-mode' on major mode change." + (if (eq major-mode 'hexl-mode) + (set (make-local-variable 'revert-buffer-function) 'vlf-revert)) + (setq vlf-mode t)) ;;;###autoload (defun vlf (file) @@ -180,6 +206,51 @@ When prefix argument is negative (goto-char (point-max))) ad-do-it)) +;; hexl mode integration +(defun vlf-hexl-before (&optional operation) + "Temporarily disable `hexl-mode' for OPERATION." + (when (eq major-mode 'hexl-mode) + (hexl-mode-exit) + (set (make-local-variable 'vlf-restore-hexl-mode) operation))) + +(defun vlf-hexl-after (&optional operation) + "Re-enable `hexl-mode' if active before OPERATION." + (when (and (boundp 'vlf-restore-hexl-mode) + (eq vlf-restore-hexl-mode operation)) + (hexl-mode) + (kill-local-variable 'vlf-restore-hexl-mode))) + +(add-hook 'vlf-before-batch-functions 'vlf-hexl-before) +(add-hook 'vlf-after-batch-functions 'vlf-hexl-after) +(add-hook 'vlf-before-chunk-update 'vlf-hexl-before) +(add-hook 'vlf-after-chunk-update 'vlf-hexl-after) + +(eval-after-load "hexl" + '(progn + (defadvice hexl-save-buffer (around vlf-hexl-save + activate compile) + "Prevent hexl save if `vlf-mode' is active." + (if vlf-mode + (vlf-write) + ad-do-it)) + + (defadvice hexl-scroll-up (around vlf-hexl-scroll-up + activate compile) + "Slide to next batch if at end of buffer in `vlf-mode'." + (if (and vlf-mode (pos-visible-in-window-p (point-max)) + (or (not (numberp arg)) (< 0 arg))) + (progn (vlf-next-batch 1) + (goto-char (point-min))) + ad-do-it)) + + (defadvice hexl-scroll-down (around vlf-hexl-scroll-down + activate compile) + "Slide to previous batch if at beginning of buffer in `vlf-mode'." + (if (and vlf-mode (pos-visible-in-window-p (point-min))) + (progn (vlf-prev-batch 1) + (goto-char (point-max))) + ad-do-it)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; utilities