Switch to recommended form of GPLv3 permissions notice.
[bpt/emacs.git] / lisp / url / url-history.el
CommitLineData
8c8b8430 1;;; url-history.el --- Global history tracking for URL package
ad8c3ee0 2
71ddfde5 3;; Copyright (C) 1996, 1997, 1998, 1999, 2004,
12dc447f 4;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
ad8c3ee0 5
8c8b8430
SM
6;; Keywords: comm, data, processes, hypermedia
7
ad8c3ee0
SM
8;; This file is part of GNU Emacs.
9;;
4936186e 10;; GNU Emacs is free software: you can redistribute it and/or modify
ad8c3ee0 11;; it under the terms of the GNU General Public License as published by
4936186e
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
ad8c3ee0
SM
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
4936186e 19
ad8c3ee0 20;; You should have received a copy of the GNU General Public License
4936186e 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
ad8c3ee0
SM
22
23;;; Commentary:
24
25;;; Code:
8c8b8430
SM
26
27;; This can get a recursive require.
28;;(require 'url)
8c8b8430
SM
29(require 'url-parse)
30(autoload 'url-do-setup "url")
31
32(defgroup url-history nil
7e1f4bf5 33 "History variables in the URL package."
8c8b8430
SM
34 :prefix "url-history"
35 :group 'url)
36
37(defcustom url-history-track nil
1942d6cc
RS
38 "*Controls whether to keep a list of all the URLs being visited.
39If non-nil, the URL package will keep track of all the URLs visited.
7e1f4bf5 40If set to t, then the list is saved to disk at the end of each Emacs
8c8b8430 41session."
1942d6cc
RS
42 :set #'(lambda (var val)
43 (set-default var val)
23dec9cb 44 (and (bound-and-true-p url-setup-done)
1942d6cc
RS
45 (url-history-setup-save-timer)))
46 :type '(choice (const :tag "off" nil)
47 (const :tag "on" t)
48 (const :tag "within session" 'session))
8c8b8430
SM
49 :group 'url-history)
50
51(defcustom url-history-file nil
52 "*The global history file for the URL package.
53This file contains a list of all the URLs you have visited. This file
54is parsed at startup and used to provide URL completion."
55 :type '(choice (const :tag "Default" :value nil) file)
56 :group 'url-history)
57
58(defcustom url-history-save-interval 3600
59 "*The number of seconds between automatic saves of the history list.
60Default is 1 hour. Note that if you change this variable outside of
61the `customize' interface after `url-do-setup' has been run, you need
62to run the `url-history-setup-save-timer' function manually."
8553120c
RS
63 :set #'(lambda (var val)
64 (set-default var val)
65 (if (bound-and-true-p url-setup-done)
66 (url-history-setup-save-timer)))
8c8b8430
SM
67 :type 'integer
68 :group 'url-history)
69
70(defvar url-history-timer nil)
71
8c8b8430
SM
72(defvar url-history-changed-since-last-save nil
73 "Whether the history list has changed since the last save operation.")
74
176c99dc 75(defvar url-history-hash-table (make-hash-table :size 31 :test 'equal)
8c8b8430
SM
76 "Hash table for global history completion.")
77
78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ad8c3ee0 79
8c8b8430
SM
80(defun url-history-setup-save-timer ()
81 "Reset the history list timer."
82 (interactive)
d87fefad
GM
83 (condition-case nil
84 (cancel-timer url-history-timer)
85 (error nil))
ad8c3ee0 86 (setq url-history-timer nil)
1942d6cc 87 (if (and (eq url-history-track t) url-history-save-interval)
8553120c
RS
88 (setq url-history-timer (run-at-time url-history-save-interval
89 url-history-save-interval
90 'url-history-save-history))))
8c8b8430 91
8c8b8430
SM
92(defun url-history-parse-history (&optional fname)
93 "Parse a history file stored in FNAME."
94 ;; Parse out the mosaic global history file for completions, etc.
95 (or fname (setq fname (expand-file-name url-history-file)))
96 (cond
97 ((not (file-exists-p fname))
ce0c92e1
SM
98 ;; It's completely normal for this file not to exist, so don't complain.
99 ;; (message "%s does not exist." fname)
100 )
8c8b8430
SM
101 ((not (file-readable-p fname))
102 (message "%s is unreadable." fname))
103 (t
104 (condition-case nil
105 (load fname nil t)
176c99dc 106 (error (message "Could not load %s" fname))))))
8c8b8430
SM
107
108(defun url-history-update-url (url time)
109 (setq url-history-changed-since-last-save t)
176c99dc
SM
110 (puthash (if (vectorp url) (url-recreate-url url) url) time
111 url-history-hash-table))
8c8b8430 112
9824ded5
GM
113(autoload 'url-make-private-file "url-util")
114
8c8b8430
SM
115(defun url-history-save-history (&optional fname)
116 "Write the global history file into `url-history-file'.
117The type of data written is determined by what is in the file to begin
118with. If the type of storage cannot be determined, then prompt the
119user for what type to save as."
120 (interactive)
9824ded5
GM
121 (when url-history-changed-since-last-save
122 (or fname (setq fname (expand-file-name url-history-file)))
123 (if (condition-case nil
124 (progn
125 (url-make-private-file fname)
126 nil)
127 (error t))
128 (message "Error accessing history file `%s'" fname)
129 (let ((make-backup-files nil)
130 (version-control nil)
131 (require-final-newline t)
132 (count 0))
133 (with-temp-buffer
134 (maphash (lambda (key value)
176c99dc
SM
135 (while (string-match "[\r\n]+" key)
136 (setq key (concat (substring key 0 (match-beginning 0))
137 (substring key (match-end 0) nil))))
138 (setq count (1+ count))
139 (insert "(puthash \"" key "\""
140 (if (not (stringp value)) " '" "")
141 (prin1-to-string value)
142 " url-history-hash-table)\n"))
143 url-history-hash-table)
144 ;; We used to add this in the file, but it just makes the code
145 ;; more complex with no benefit. Worse: it makes it harder to
146 ;; preserve preexisting history when loading the history file.
147 ;; (goto-char (point-min))
148 ;; (insert (format
149 ;; "(setq url-history-hash-table (make-hash-table :size %d :test 'equal))\n"
150 ;; (/ count 4)))
151 ;; (goto-char (point-max))
8c8b8430 152 (insert "\n")
9824ded5
GM
153 (write-file fname)))
154 (setq url-history-changed-since-last-save nil))))
8c8b8430
SM
155
156(defun url-have-visited-url (url)
157 (url-do-setup)
176c99dc 158 (gethash url url-history-hash-table nil))
8c8b8430
SM
159
160(defun url-completion-function (string predicate function)
176c99dc
SM
161 ;; Completion function to complete urls from the history.
162 ;; This is obsolete since we can now pass the hash-table directly as a
163 ;; completion table.
8c8b8430
SM
164 (url-do-setup)
165 (cond
166 ((eq function nil)
167 (let ((list nil))
176c99dc
SM
168 (maphash (lambda (key val) (push key list))
169 url-history-hash-table)
170 ;; Not sure why we bother reversing the list. --Stef
8c8b8430
SM
171 (try-completion string (nreverse list) predicate)))
172 ((eq function t)
176c99dc 173 (let ((stub (concat "\\`" (regexp-quote string)))
8c8b8430
SM
174 (retval nil))
175 (maphash
176c99dc
SM
176 (lambda (url time)
177 (if (string-match stub url) (push url retval)))
8c8b8430
SM
178 url-history-hash-table)
179 retval))
180 ((eq function 'lambda)
176c99dc 181 (and (gethash string url-history-hash-table) t))
8c8b8430 182 (t
e2a0329a 183 (error "url-completion-function very confused"))))
8c8b8430
SM
184
185(provide 'url-history)
e5566bd5 186
ad8c3ee0
SM
187;; arch-tag: fbbbaf63-db36-4e88-bc9f-2939aa93afb2
188;;; url-history.el ends here