* url-handlers.el (file-remote-p): Add handler.
[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)
8c8b8430
SM
31(require 'url-parse)
32(autoload 'url-do-setup "url")
33
34(defgroup url-history nil
7e1f4bf5 35 "History variables in the URL package."
8c8b8430
SM
36 :prefix "url-history"
37 :group 'url)
38
39(defcustom url-history-track nil
1942d6cc
RS
40 "*Controls whether to keep a list of all the URLs being visited.
41If non-nil, the URL package will keep track of all the URLs visited.
7e1f4bf5 42If set to t, then the list is saved to disk at the end of each Emacs
8c8b8430 43session."
1942d6cc
RS
44 :set #'(lambda (var val)
45 (set-default var val)
23dec9cb 46 (and (bound-and-true-p url-setup-done)
1942d6cc
RS
47 (url-history-setup-save-timer)))
48 :type '(choice (const :tag "off" nil)
49 (const :tag "on" t)
50 (const :tag "within session" 'session))
8c8b8430
SM
51 :group 'url-history)
52
53(defcustom url-history-file nil
54 "*The global history file for the URL package.
55This file contains a list of all the URLs you have visited. This file
56is parsed at startup and used to provide URL completion."
57 :type '(choice (const :tag "Default" :value nil) file)
58 :group 'url-history)
59
60(defcustom url-history-save-interval 3600
61 "*The number of seconds between automatic saves of the history list.
62Default is 1 hour. Note that if you change this variable outside of
63the `customize' interface after `url-do-setup' has been run, you need
64to run the `url-history-setup-save-timer' function manually."
8553120c
RS
65 :set #'(lambda (var val)
66 (set-default var val)
67 (if (bound-and-true-p url-setup-done)
68 (url-history-setup-save-timer)))
8c8b8430
SM
69 :type 'integer
70 :group 'url-history)
71
72(defvar url-history-timer nil)
73
8c8b8430
SM
74(defvar url-history-changed-since-last-save nil
75 "Whether the history list has changed since the last save operation.")
76
176c99dc 77(defvar url-history-hash-table (make-hash-table :size 31 :test 'equal)
8c8b8430
SM
78 "Hash table for global history completion.")
79
80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ad8c3ee0 81
8c8b8430
SM
82(defun url-history-setup-save-timer ()
83 "Reset the history list timer."
84 (interactive)
d87fefad
GM
85 (condition-case nil
86 (cancel-timer url-history-timer)
87 (error nil))
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
9824ded5
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)
9824ded5
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.
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))
8c8b8430 154 (insert "\n")
9824ded5
GM
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