Add 2008 to copyright years.
[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;;
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
8c0ee52a 12;; the Free Software Foundation; either version 3, or (at your option)
ad8c3ee0
SM
13;; any later version.
14;;
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.
19;;
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to the
4fc5845f
LK
22;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, USA.
ad8c3ee0
SM
24
25;;; Commentary:
26
27;;; Code:
8c8b8430
SM
28
29;; This can get a recursive require.
30;;(require 'url)
31(eval-when-compile (require 'cl))
32(require 'url-parse)
33(autoload 'url-do-setup "url")
34
35(defgroup url-history nil
7e1f4bf5 36 "History variables in the URL package."
8c8b8430
SM
37 :prefix "url-history"
38 :group 'url)
39
40(defcustom url-history-track nil
1942d6cc
RS
41 "*Controls whether to keep a list of all the URLs being visited.
42If non-nil, the URL package will keep track of all the URLs visited.
7e1f4bf5 43If set to t, then the list is saved to disk at the end of each Emacs
8c8b8430 44session."
1942d6cc
RS
45 :set #'(lambda (var val)
46 (set-default var val)
23dec9cb 47 (and (bound-and-true-p url-setup-done)
1942d6cc
RS
48 (url-history-setup-save-timer)))
49 :type '(choice (const :tag "off" nil)
50 (const :tag "on" t)
51 (const :tag "within session" 'session))
8c8b8430
SM
52 :group 'url-history)
53
54(defcustom url-history-file nil
55 "*The global history file for the URL package.
56This file contains a list of all the URLs you have visited. This file
57is 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.
63Default is 1 hour. Note that if you change this variable outside of
64the `customize' interface after `url-do-setup' has been run, you need
65to run the `url-history-setup-save-timer' function manually."
8553120c
RS
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)))
8c8b8430
SM
70 :type 'integer
71 :group 'url-history)
72
73(defvar url-history-timer nil)
74
8c8b8430
SM
75(defvar url-history-changed-since-last-save nil
76 "Whether the history list has changed since the last save operation.")
77
176c99dc 78(defvar url-history-hash-table (make-hash-table :size 31 :test 'equal)
8c8b8430
SM
79 "Hash table for global history completion.")
80
81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ad8c3ee0 82
8c8b8430
SM
83(defun url-history-setup-save-timer ()
84 "Reset the history list timer."
85 (interactive)
e2a0329a 86 (ignore-errors
8553120c 87 (cancel-timer url-history-timer))
ad8c3ee0 88 (setq url-history-timer nil)
1942d6cc 89 (if (and (eq url-history-track t) url-history-save-interval)
8553120c
RS
90 (setq url-history-timer (run-at-time url-history-save-interval
91 url-history-save-interval
92 'url-history-save-history))))
8c8b8430 93
8c8b8430
SM
94(defun url-history-parse-history (&optional fname)
95 "Parse a history file stored in FNAME."
96 ;; Parse out the mosaic global history file for completions, etc.
97 (or fname (setq fname (expand-file-name url-history-file)))
98 (cond
99 ((not (file-exists-p fname))
ce0c92e1
SM
100 ;; It's completely normal for this file not to exist, so don't complain.
101 ;; (message "%s does not exist." fname)
102 )
8c8b8430
SM
103 ((not (file-readable-p fname))
104 (message "%s is unreadable." fname))
105 (t
106 (condition-case nil
107 (load fname nil t)
176c99dc 108 (error (message "Could not load %s" fname))))))
8c8b8430
SM
109
110(defun url-history-update-url (url time)
111 (setq url-history-changed-since-last-save t)
176c99dc
SM
112 (puthash (if (vectorp url) (url-recreate-url url) url) time
113 url-history-hash-table))
8c8b8430 114
57f44ca4
GM
115(autoload 'url-make-private-file "url-util")
116
8c8b8430
SM
117(defun url-history-save-history (&optional fname)
118 "Write the global history file into `url-history-file'.
119The type of data written is determined by what is in the file to begin
120with. If the type of storage cannot be determined, then prompt the
121user for what type to save as."
122 (interactive)
57f44ca4
GM
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)
176c99dc
SM
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 ;; We used to add this in the file, but it just makes the code
147 ;; more complex with no benefit. Worse: it makes it harder to
148 ;; preserve preexisting history when loading the history file.
57f44ca4
GM
149 ;; (goto-char (point-min))
150 ;; (insert (format
151 ;; "(setq url-history-hash-table (make-hash-table :size %d :test 'equal))\n"
152 ;; (/ count 4)))
153 ;; (goto-char (point-max))
154 (insert "\n")
155 (write-file fname)))
156 (setq url-history-changed-since-last-save nil))))
8c8b8430
SM
157
158(defun url-have-visited-url (url)
159 (url-do-setup)
176c99dc 160 (gethash url url-history-hash-table nil))
8c8b8430
SM
161
162(defun url-completion-function (string predicate function)
176c99dc
SM
163 ;; Completion function to complete urls from the history.
164 ;; This is obsolete since we can now pass the hash-table directly as a
165 ;; completion table.
8c8b8430
SM
166 (url-do-setup)
167 (cond
168 ((eq function nil)
169 (let ((list nil))
176c99dc
SM
170 (maphash (lambda (key val) (push key list))
171 url-history-hash-table)
172 ;; Not sure why we bother reversing the list. --Stef
8c8b8430
SM
173 (try-completion string (nreverse list) predicate)))
174 ((eq function t)
176c99dc 175 (let ((stub (concat "\\`" (regexp-quote string)))
8c8b8430
SM
176 (retval nil))
177 (maphash
176c99dc
SM
178 (lambda (url time)
179 (if (string-match stub url) (push url retval)))
8c8b8430
SM
180 url-history-hash-table)
181 retval))
182 ((eq function 'lambda)
176c99dc 183 (and (gethash string url-history-hash-table) t))
8c8b8430 184 (t
e2a0329a 185 (error "url-completion-function very confused"))))
8c8b8430
SM
186
187(provide 'url-history)
e5566bd5 188
ad8c3ee0
SM
189;; arch-tag: fbbbaf63-db36-4e88-bc9f-2939aa93afb2
190;;; url-history.el ends here