view lisp/url/url-history.el @ 83548:c71725faff1a

Merged from emacs@sv.gnu.org. Last-minute emacsclient rewrites be damned! Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-490 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-491 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-492 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-493 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-494 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-495 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-496 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-497 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-498 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-499 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-500 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-501 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-502 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-503 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-504 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-505 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-506 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-507 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-508 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-509 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-510 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-511 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-512 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-513 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-514 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-515 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-516 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-517 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-518 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-519 Update from CVS: etc/TUTORIAL.cn: Updated. * emacs@sv.gnu.org/emacs--devo--0--patch-520 Merge from erc--emacs--22 * emacs@sv.gnu.org/emacs--devo--0--patch-521 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-522 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-523 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-524 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-525 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-526 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-527 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-528 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-529 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-530 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-531 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-532 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-533 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-534 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-535 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-161 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-162 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-163 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-164 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-165 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-166 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-167 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-168 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-169 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-170 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-588
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 03 Dec 2006 15:03:30 +0000
parents 55e22205ba88
children b8d9a391daf3
line wrap: on
line source

;;; url-history.el --- Global history tracking for URL package

;; Copyright (C) 1996, 1997, 1998, 1999, 2004,
;;   2005, 2006 Free Software Foundation, Inc.

;; Keywords: comm, data, processes, hypermedia

;; This file is part of GNU Emacs.
;;
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;;; Code:

;; This can get a recursive require.
;;(require 'url)
(eval-when-compile (require 'cl))
(require 'url-parse)
(autoload 'url-do-setup "url")

(defgroup url-history nil
  "History variables in the URL package."
  :prefix "url-history"
  :group 'url)

(defcustom url-history-track nil
  "*Controls whether to keep a list of all the URLs being visited.
If non-nil, the URL package will keep track of all the URLs visited.
If set to t, then the list is saved to disk at the end of each Emacs
session."
  :set #'(lambda (var val)
	   (set-default var val)
	   (and (bound-and-true-p url-setup-done)
		(url-history-setup-save-timer)))
  :type '(choice (const :tag "off" nil)
		 (const :tag "on" t)
		 (const :tag "within session" 'session))
  :group 'url-history)

(defcustom url-history-file nil
  "*The global history file for the URL package.
This file contains a list of all the URLs you have visited.  This file
is parsed at startup and used to provide URL completion."
  :type '(choice (const :tag "Default" :value nil) file)
  :group 'url-history)

(defcustom url-history-save-interval 3600
  "*The number of seconds between automatic saves of the history list.
Default is 1 hour.  Note that if you change this variable outside of
the `customize' interface after `url-do-setup' has been run, you need
to run the `url-history-setup-save-timer' function manually."
  :set #'(lambda (var val)
	   (set-default var val)
	   (if (bound-and-true-p url-setup-done)
	       (url-history-setup-save-timer)))
  :type 'integer
  :group 'url-history)

(defvar url-history-timer nil)

(defvar url-history-changed-since-last-save nil
  "Whether the history list has changed since the last save operation.")

(defvar url-history-hash-table (make-hash-table :size 31 :test 'equal)
  "Hash table for global history completion.")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun url-history-setup-save-timer ()
  "Reset the history list timer."
  (interactive)
  (ignore-errors
   (cancel-timer url-history-timer))
  (setq url-history-timer nil)
  (if (and (eq url-history-track t) url-history-save-interval)
      (setq url-history-timer (run-at-time url-history-save-interval
					   url-history-save-interval
					   'url-history-save-history))))

(defun url-history-parse-history (&optional fname)
  "Parse a history file stored in FNAME."
  ;; Parse out the mosaic global history file for completions, etc.
  (or fname (setq fname (expand-file-name url-history-file)))
  (cond
   ((not (file-exists-p fname))
    ;; It's completely normal for this file not to exist, so don't complain.
    ;; (message "%s does not exist." fname)
    )
   ((not (file-readable-p fname))
    (message "%s is unreadable." fname))
   (t
    (condition-case nil
	(load fname nil t)
      (error (message "Could not load %s" fname))))))

(defun url-history-update-url (url time)
  (setq url-history-changed-since-last-save t)
  (puthash (if (vectorp url) (url-recreate-url url) url) time
           url-history-hash-table))

(defun url-history-save-history (&optional fname)
  "Write the global history file into `url-history-file'.
The type of data written is determined by what is in the file to begin
with.  If the type of storage cannot be determined, then prompt the
user for what type to save as."
  (interactive)
  (or fname (setq fname (expand-file-name url-history-file)))
  (unless (file-directory-p (file-name-directory fname))
    (ignore-errors (make-directory (file-name-directory fname))))
  (cond
   ((not url-history-changed-since-last-save) nil)
   ((not (file-writable-p fname))
    (message "%s is unwritable." fname))
   (t
    (let ((make-backup-files nil)
	  (version-control nil)
	  (require-final-newline t))
      (with-current-buffer (get-buffer-create " *url-tmp*")
	(erase-buffer)
	(let ((count 0))
	  (maphash (lambda (key value)
                     (while (string-match "[\r\n]+" key)
                       (setq key (concat (substring key 0 (match-beginning 0))
                                         (substring key (match-end 0) nil))))
                     (setq count (1+ count))
                     (insert "(puthash \"" key "\""
                             (if (not (stringp value)) " '" "")
                             (prin1-to-string value)
                             " url-history-hash-table)\n"))
                   url-history-hash-table)
          ;; We used to add this in the file, but it just makes the code
          ;; more complex with no benefit.  Worse: it makes it harder to
          ;; preserve preexisting history when loading the history file.
	  ;; (goto-char (point-min))
	  ;; (insert (format
	  ;;          "(setq url-history-hash-table (make-hash-table :size %d :test 'equal))\n"
	  ;;          (/ count 4)))
	  ;; (goto-char (point-max))
	  (insert "\n")
	  (write-file fname))
	(kill-buffer (current-buffer))))))
  (setq url-history-changed-since-last-save nil))

(defun url-have-visited-url (url)
  (url-do-setup)
  (gethash url url-history-hash-table nil))

(defun url-completion-function (string predicate function)
  ;; Completion function to complete urls from the history.
  ;; This is obsolete since we can now pass the hash-table directly as a
  ;; completion table.
  (url-do-setup)
  (cond
   ((eq function nil)
    (let ((list nil))
      (maphash (lambda (key val) (push key list))
               url-history-hash-table)
      ;; Not sure why we bother reversing the list.  --Stef
      (try-completion string (nreverse list) predicate)))
   ((eq function t)
    (let ((stub (concat "\\`" (regexp-quote string)))
	  (retval nil))
      (maphash
       (lambda (url time)
         (if (string-match stub url) (push url retval)))
       url-history-hash-table)
      retval))
   ((eq function 'lambda)
    (and (gethash string url-history-hash-table) t))
   (t
    (error "url-completion-function very confused"))))

(provide 'url-history)

;; arch-tag: fbbbaf63-db36-4e88-bc9f-2939aa93afb2
;;; url-history.el ends here