| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
(eval-when-compile (require 'cl)) |
|---|
| 32 |
(require 'url-parse) |
|---|
| 33 |
(autoload 'url-do-setup "url") |
|---|
| 34 |
|
|---|
| 35 |
(defgroup url-history nil |
|---|
| 36 |
"History variables in the URL package." |
|---|
| 37 |
:prefix "url-history" |
|---|
| 38 |
:group 'url) |
|---|
| 39 |
|
|---|
| 40 |
(defcustom url-history-track nil |
|---|
| 41 |
"*Controls whether to keep a list of all the URLs being visited. |
|---|
| 42 |
If non-nil, the URL package will keep track of all the URLs visited. |
|---|
| 43 |
If set to t, then the list is saved to disk at the end of each Emacs |
|---|
| 44 |
session." |
|---|
| 45 |
:set #'(lambda (var val) |
|---|
| 46 |
(set-default var val) |
|---|
| 47 |
(and (bound-and-true-p url-setup-done) |
|---|
| 48 |
(url-history-setup-save-timer))) |
|---|
| 49 |
:type '(choice (const :tag "off" nil) |
|---|
| 50 |
(const :tag "on" t) |
|---|
| 51 |
(const :tag "within session" 'session)) |
|---|
| 52 |
:group 'url-history) |
|---|
| 53 |
|
|---|
| 54 |
(defcustom url-history-file nil |
|---|
| 55 |
"*The global history file for the URL package. |
|---|
| 56 |
This file contains a list of all the URLs you have visited. This file |
|---|
| 57 |
is parsed at startup and used to provide URL completion." |
|---|
| 58 |
:type '(choice (const :tag "Default" :value nil) file) |
|---|
| 59 |
:group 'url-history) |
|---|
| 60 |
|
|---|
| 61 |
(defcustom url-history-save-interval 3600 |
|---|
| 62 |
"*The number of seconds between automatic saves of the history list. |
|---|
| 63 |
Default is 1 hour. Note that if you change this variable outside of |
|---|
| 64 |
the `customize' interface after `url-do-setup' has been run, you need |
|---|
| 65 |
to run the `url-history-setup-save-timer' function manually." |
|---|
| 66 |
:set #'(lambda (var val) |
|---|
| 67 |
(set-default var val) |
|---|
| 68 |
(if (bound-and-true-p url-setup-done) |
|---|
| 69 |
(url-history-setup-save-timer))) |
|---|
| 70 |
:type 'integer |
|---|
| 71 |
:group 'url-history) |
|---|
| 72 |
|
|---|
| 73 |
(defvar url-history-timer nil) |
|---|
| 74 |
|
|---|
| 75 |
(defvar url-history-changed-since-last-save nil |
|---|
| 76 |
"Whether the history list has changed since the last save operation.") |
|---|
| 77 |
|
|---|
| 78 |
(defvar url-history-hash-table (make-hash-table :size 31 :test 'equal) |
|---|
| 79 |
"Hash table for global history completion.") |
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
(defun url-history-setup-save-timer () |
|---|
| 84 |
"Reset the history list timer." |
|---|
| 85 |
(interactive) |
|---|
| 86 |
(ignore-errors |
|---|
| 87 |
(cancel-timer url-history-timer)) |
|---|
| 88 |
(setq url-history-timer nil) |
|---|
| 89 |
(if (and (eq url-history-track t) url-history-save-interval) |
|---|
| 90 |
(setq url-history-timer (run-at-time url-history-save-interval |
|---|
| 91 |
url-history-save-interval |
|---|
| 92 |
'url-history-save-history)))) |
|---|
| 93 |
|
|---|
| 94 |
(defun url-history-parse-history (&optional fname) |
|---|
| 95 |
"Parse a history file stored in FNAME." |
|---|
| 96 |
|
|---|
| 97 |
(or fname (setq fname (expand-file-name url-history-file))) |
|---|
| 98 |
(cond |
|---|
| 99 |
((not (file-exists-p fname)) |
|---|
| 100 |
|
|---|
| 101 |
|
|---|
| 102 |
) |
|---|
| 103 |
((not (file-readable-p fname)) |
|---|
| 104 |
(message "%s is unreadable." fname)) |
|---|
| 105 |
(t |
|---|
| 106 |
(condition-case nil |
|---|
| 107 |
(load fname nil t) |
|---|
| 108 |
(error (message "Could not load %s" fname)))))) |
|---|
| 109 |
|
|---|
| 110 |
(defun url-history-update-url (url time) |
|---|
| 111 |
(setq url-history-changed-since-last-save t) |
|---|
| 112 |
(puthash (if (vectorp url) (url-recreate-url url) url) time |
|---|
| 113 |
url-history-hash-table)) |
|---|
| 114 |
|
|---|
| 115 |
(autoload 'url-make-private-file "url-util") |
|---|
| 116 |
|
|---|
| 117 |
(defun url-history-save-history (&optional fname) |
|---|
| 118 |
"Write the global history file into `url-history-file'. |
|---|
| 119 |
The type of data written is determined by what is in the file to begin |
|---|
| 120 |
with. If the type of storage cannot be determined, then prompt the |
|---|
| 121 |
user for what type to save as." |
|---|
| 122 |
(interactive) |
|---|
| 123 |
(when url-history-changed-since-last-save |
|---|
| 124 |
(or fname (setq fname (expand-file-name url-history-file))) |
|---|
| 125 |
(if (condition-case nil |
|---|
| 126 |
(progn |
|---|
| 127 |
(url-make-private-file fname) |
|---|
| 128 |
nil) |
|---|
| 129 |
(error t)) |
|---|
| 130 |
(message "Error accessing history file `%s'" fname) |
|---|
| 131 |
(let ((make-backup-files nil) |
|---|
| 132 |
(version-control nil) |
|---|
| 133 |
(require-final-newline t) |
|---|
| 134 |
(count 0)) |
|---|
| 135 |
(with-temp-buffer |
|---|
| 136 |
(maphash (lambda (key value) |
|---|
| 137 |
(while (string-match "[\r\n]+" key) |
|---|
| 138 |
(setq key (concat (substring key 0 (match-beginning 0)) |
|---|
| 139 |
(substring key (match-end 0) nil)))) |
|---|
| 140 |
(setq count (1+ count)) |
|---|
| 141 |
(insert "(puthash \"" key "\"" |
|---|
| 142 |
(if (not (stringp value)) " '" "") |
|---|
| 143 |
(prin1-to-string value) |
|---|
| 144 |
" url-history-hash-table)\n")) |
|---|
| 145 |
url-history-hash-table) |
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 |
|
|---|
| 151 |
|
|---|
| 152 |
|
|---|
| 153 |
|
|---|
| 154 |
(insert "\n") |
|---|
| 155 |
(write-file fname))) |
|---|
| 156 |
(setq url-history-changed-since-last-save nil)))) |
|---|
| 157 |
|
|---|
| 158 |
(defun url-have-visited-url (url) |
|---|
| 159 |
(url-do-setup) |
|---|
| 160 |
(gethash url url-history-hash-table nil)) |
|---|
| 161 |
|
|---|
| 162 |
(defun url-completion-function (string predicate function) |
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 |
|
|---|
| 166 |
(url-do-setup) |
|---|
| 167 |
(cond |
|---|
| 168 |
((eq function nil) |
|---|
| 169 |
(let ((list nil)) |
|---|
| 170 |
(maphash (lambda (key val) (push key list)) |
|---|
| 171 |
url-history-hash-table) |
|---|
| 172 |
|
|---|
| 173 |
(try-completion string (nreverse list) predicate))) |
|---|
| 174 |
((eq function t) |
|---|
| 175 |
(let ((stub (concat "\\`" (regexp-quote string))) |
|---|
| 176 |
(retval nil)) |
|---|
| 177 |
(maphash |
|---|
| 178 |
(lambda (url time) |
|---|
| 179 |
(if (string-match stub url) (push url retval))) |
|---|
| 180 |
url-history-hash-table) |
|---|
| 181 |
retval)) |
|---|
| 182 |
((eq function 'lambda) |
|---|
| 183 |
(and (gethash string url-history-hash-table) t)) |
|---|
| 184 |
(t |
|---|
| 185 |
(error "url-completion-function very confused")))) |
|---|
| 186 |
|
|---|
| 187 |
(provide 'url-history) |
|---|
| 188 |
|
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 |
|
|---|