config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

pdf-history.el (5239B)


      1 ;;; pdf-history.el --- A simple stack-based history in PDF buffers. -*- lexical-binding: t -*-
      2 
      3 ;; Copyright (C) 2013, 2014  Andreas Politz
      4 
      5 ;; Author: Andreas Politz <politza@fh-trier.de>
      6 ;; Keywords: files, multimedia
      7 
      8 ;; This program is free software; you can redistribute it and/or modify
      9 ;; it under the terms of the GNU General Public License as published by
     10 ;; the Free Software Foundation, either version 3 of the License, or
     11 ;; (at your option) any later version.
     12 
     13 ;; This program is distributed in the hope that it will be useful,
     14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 ;; GNU General Public License for more details.
     17 
     18 ;; You should have received a copy of the GNU General Public License
     19 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
     20 
     21 ;;; Commentary:
     22 ;;
     23 
     24 (require 'pdf-view)
     25 (require 'pdf-util)
     26 
     27 ;;; Code:
     28 
     29 (defgroup pdf-history nil
     30   "A simple stack-based history."
     31   :group 'pdf-tools)
     32 
     33 (defvar-local pdf-history-stack nil
     34   "The stack of history items.")
     35 
     36 (defvar-local pdf-history-index nil
     37   "The current index into the `pdf-history-stack'.")
     38 
     39 (defvar pdf-history-minor-mode-map
     40   (let ((kmap (make-sparse-keymap)))
     41     (define-key kmap (kbd "B") #'pdf-history-backward)
     42     (define-key kmap (kbd "N") #'pdf-history-forward)
     43     (define-key kmap (kbd "l") #'pdf-history-backward)
     44     (define-key kmap (kbd "r") #'pdf-history-forward)
     45     kmap)
     46   "Keymap used in `pdf-history-minor-mode'.")
     47 
     48 ;;;###autoload
     49 (define-minor-mode pdf-history-minor-mode
     50   "Keep a history of previously visited pages.
     51 
     52 This is a simple stack-based history.  Turning the page or
     53 following a link pushes the left-behind page on the stack, which
     54 may be navigated with the following keys.
     55 
     56 \\{pdf-history-minor-mode-map}"
     57   :group 'pdf-history
     58   (pdf-util-assert-pdf-buffer)
     59   (pdf-history-clear)
     60   (cond
     61    (pdf-history-minor-mode
     62     (pdf-history-push)
     63     (add-hook 'pdf-view-after-change-page-hook
     64               #'pdf-history-before-change-page-hook nil t))
     65    (t
     66     (remove-hook 'pdf-view-after-change-page-hook
     67                  #'pdf-history-before-change-page-hook t))))
     68 
     69 (defun pdf-history-before-change-page-hook ()
     70   "Push a history item, before leaving this page."
     71   (when (and pdf-history-minor-mode
     72              (not (bound-and-true-p pdf-isearch-active-mode))
     73              (pdf-view-current-page))
     74     (pdf-history-push)))
     75 
     76 (defun pdf-history-push ()
     77   "Push the current page on the stack.
     78 
     79 This function does nothing, if current stack item already
     80 represents the current page."
     81   (interactive)
     82   (let ((item (pdf-history-create-item)))
     83     (unless (and pdf-history-stack
     84                  (equal (nth pdf-history-index
     85                              pdf-history-stack) item))
     86       (setq pdf-history-stack
     87             (last pdf-history-stack
     88                   (- (length pdf-history-stack)
     89                      pdf-history-index))
     90             pdf-history-index 0)
     91       (push item pdf-history-stack))))
     92 
     93 (defun pdf-history-clear ()
     94   "Remove all history items."
     95   (interactive)
     96   (setq pdf-history-stack nil
     97         pdf-history-index 0)
     98   (pdf-history-push))
     99 
    100 (defun pdf-history-create-item ()
    101   "Create a history item representing the current page."
    102   (list
    103    (pdf-view-current-page)))
    104 
    105 (defun pdf-history-beginning-of-history-p ()
    106   "Return t, if at the beginning of the history."
    107   (= pdf-history-index 0))
    108 
    109 (defun pdf-history-end-of-history-p ()
    110   "Return t, if at the end of the history."
    111   (= pdf-history-index
    112      (1- (length pdf-history-stack))))
    113 
    114 (defun pdf-history-backward (n)
    115   "Go N times backward in the history."
    116   (interactive "p")
    117   (cond
    118    ((and (> n 0)
    119          (pdf-history-end-of-history-p))
    120     (error "End of history"))
    121    ((and (< n 0)
    122          (pdf-history-beginning-of-history-p))
    123     (error "Beginning of history"))
    124    ((/= n 0)
    125     (let ((i (min (max 0 (+ pdf-history-index n))
    126                   (1- (length pdf-history-stack)))))
    127       (prog1
    128           (- (+ pdf-history-index n) i)
    129         (pdf-history-goto i))))
    130    (t 0)))
    131 
    132 (defun pdf-history-forward (n)
    133   "Go N times forward in the history."
    134   (interactive "p")
    135   (pdf-history-backward (- n)))
    136 
    137 (defun pdf-history-goto (n)
    138   "Go to item N in the history."
    139   (interactive "p")
    140   (when (null pdf-history-stack)
    141     (error "The history is empty"))
    142   (cond
    143    ((>= n (length pdf-history-stack))
    144     (error "End of history"))
    145    ((< n 0)
    146     (error "Beginning of history"))
    147    (t
    148     (setq pdf-history-index n)
    149     (pdf-view-goto-page
    150      (car (nth n pdf-history-stack))))))
    151 
    152 (defun pdf-history-debug ()
    153   "Visualize the history in the header-line."
    154   (interactive)
    155   (setq header-line-format
    156         '(:eval
    157           (let ((pages (mapcar 'car pdf-history-stack))
    158                 (index pdf-history-index)
    159                 header)
    160             (dotimes (i (length pages))
    161               (push (propertize
    162                      (format "%s" (nth i pages))
    163                      'face
    164                      (and (= i index) 'match))
    165                     header))
    166             (concat
    167              "(" (format "%d" index) ")  "
    168              (mapconcat 'identity (nreverse header) " | "))))))
    169 
    170 (provide 'pdf-history)
    171 
    172 ;;; pdf-history.el ends here