Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.0 KiB

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