├── README.md └── pdf-view-restore.el /README.md: -------------------------------------------------------------------------------- 1 | # pdf-view-restore 2 | 3 | Support for opening last known pdf position in pdf-view-mode provided by [pdf-tools](https://github.com/politza/pdf-tools). 4 | 5 | To install, add the following: 6 | 7 | ```lisp 8 | (use-package pdf-view-restore 9 | :after pdf-tools 10 | :config 11 | (add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode)) 12 | ``` 13 | Once setup, pdf documents will automatically open to their last known page. 14 | 15 | By default, save information will be saved relative to the pdf document. If you 16 | do not want this behavior, add the following: 17 | 18 | ```lisp 19 | (setq pdf-view-restore-filename "~/.emacs.d/.pdf-view-restore") 20 | ``` 21 | 22 | Do note pdf documents with the same name will conflict with this setting, but you get 23 | the ability to move pdf documents around and still keeping the save information in sync. 24 | -------------------------------------------------------------------------------- /pdf-view-restore.el: -------------------------------------------------------------------------------- 1 | ;;; pdf-view-restore.el --- Support for opening last known pdf position in pdfview mode -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (c) 2019 Kevin Kim 4 | 5 | ;; Author: Kevin Kim 6 | ;; URL: https://github.com/007kevin/pdf-view-restore 7 | ;; Keywords: files convenience 8 | ;; Version: 0.1 9 | ;; Package-Requires: ((pdf-tools "0.90") (emacs "26.0")) 10 | 11 | ;; This file is NOT part of GNU Emacs. 12 | 13 | ;;; License: 14 | 15 | ;; This program is free software: you can redistribute it and/or modify 16 | ;; it under the terms of the GNU General Public License as published by 17 | ;; the Free Software Foundation, either version 3 of the License, or 18 | ;; (at your option) any later version. 19 | 20 | ;; This program is distributed in the hope that it will be useful, 21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | ;; GNU General Public License for more details. 24 | 25 | ;; You should have received a copy of the GNU General Public License 26 | ;; along with this program. If not, see . 27 | 28 | ;;; Commentary: 29 | ;; Support for saving and opening last known pdf position in pdfview mode. 30 | ;; Information will be saved relative to the pdf being viewed so ensure 31 | ;; `pdf-view-restore-filename' is in the same directory as the viewing pdf. 32 | ;; 33 | ;; To enable, add the following: 34 | ;; (add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode) 35 | 36 | ;;; Code: 37 | 38 | (require 'pdf-view) 39 | 40 | (defcustom pdf-view-restore-filename ".pdf-view-restore" 41 | "Filename to save the last known pdf position." 42 | :group 'pdf-view 43 | :type 'string) 44 | 45 | (defcustom use-file-base-name-flag t 46 | "Flag to control whether to use only the base name of file or to use full file path. Defaults to using base name. 47 | 48 | pdf-view-restore uses this setting to determine what to use as the key to search saved files. 49 | If set to t, only the base name is used. This will allow moving files while saving sync information. 50 | However, that may cause conflicts if you have many files with the same name. 51 | Setting to nil will use the full path but then you may lose information if you move files." 52 | :group 'pdf-view 53 | :type 'boolean) 54 | 55 | ;;;###autoload 56 | (define-minor-mode pdf-view-restore-mode 57 | "Automatically restore last known pdf position" 58 | :global nil 59 | (if (not pdf-view-restore-mode) 60 | (remove-hook 'pdf-view-after-change-page-hook 'pdf-view-restore-save) 61 | (pdf-view-restore) 62 | (add-hook 'pdf-view-after-change-page-hook 'pdf-view-restore-save nil t))) 63 | 64 | (defun pdf-view-restore () 65 | "Restore page." 66 | (when (derived-mode-p 'pdf-view-mode) 67 | ;; This buffer is in pdf-view-mode 68 | (let ((page (pdf-view-restore-get-page))) 69 | (when page (pdf-view-goto-page page))))) 70 | 71 | (defun pdf-view-restore-save () 72 | "Save restore information." 73 | (when (derived-mode-p 'pdf-view-mode) 74 | ;; This buffer is in pdf-view-mode 75 | (let ((page (pdf-view-current-page))) 76 | (pdf-view-restore-set-page page)))) 77 | 78 | (defun pdf-view-restore-get-page () 79 | "Return restore page." 80 | (let* ((alist (pdf-view-restore-unserialize)) 81 | (key (pdf-view-restore-key)) 82 | (val (cdr (assoc key alist)))) 83 | val)) 84 | 85 | (defun pdf-view-restore-set-page (page) 86 | "Save restore PAGE." 87 | (let ((alist (pdf-view-restore-unserialize)) 88 | (key (pdf-view-restore-key))) 89 | (setf (alist-get key alist nil nil 'equal) page) 90 | (pdf-view-restore-serialize alist))) 91 | 92 | (defun pdf-view-restore-key () 93 | "Key for storing data is based on filename." 94 | (if use-file-base-name-flag 95 | (file-name-base buffer-file-name) 96 | buffer-file-name)) 97 | 98 | ;;; Serialization 99 | (defun pdf-view-restore-serialize (data) 100 | "Serialize DATA to `pdf-view-restore-filename'. 101 | The saved data can be restored with `pdf-view-restore-unserialize'." 102 | (when (file-writable-p pdf-view-restore-filename) 103 | (with-temp-file pdf-view-restore-filename 104 | (insert (let (print-length) (prin1-to-string data)))))) 105 | 106 | (defun pdf-view-restore-unserialize () 107 | "Read data serialized by `pdf-view-restore-serialize' from `pdf-view-restore-filename'." 108 | (with-demoted-errors 109 | "Error during file deserialization: %S" 110 | (when (file-exists-p pdf-view-restore-filename) 111 | (with-temp-buffer 112 | (insert-file-contents pdf-view-restore-filename) 113 | ;; this will blow up if the contents of the file aren't 114 | ;; lisp data structures 115 | (read (buffer-string)))))) 116 | 117 | 118 | (provide 'pdf-view-restore) 119 | ;;; pdf-view-restore.el ends here 120 | --------------------------------------------------------------------------------