summaryrefslogtreecommitdiff
path: root/apt-utils.el
diff options
context:
space:
mode:
authorpsg <>2005-06-02 14:33:33 +0000
committerpsg <>2005-06-02 14:33:33 +0000
commit895a7897f2c62cc79c43088e71599dcc7b4f739a (patch)
treed770db5cc807d370ed2378d49b4af7e26e141d99 /apt-utils.el
parentd6a51fc8f14a351ad0c4d367b8df77914be38317 (diff)
debian-el:
apt-utils.el: "apt-utils-show-package is broken", thanks to Thamer Mahmoud for reporting it and to Matt Hodges for fixing it in a new upstream version (Closes: #302888).
Diffstat (limited to 'apt-utils.el')
-rw-r--r--apt-utils.el902
1 files changed, 584 insertions, 318 deletions
diff --git a/apt-utils.el b/apt-utils.el
index a168721..bb5354b 100644
--- a/apt-utils.el
+++ b/apt-utils.el
@@ -1,6 +1,6 @@
;;; apt-utils.el --- Emacs interface to APT (Debian package management)
-;;; Copyright (C) 2002, 2003, 2004 Matthew P. Hodges
+;;; Copyright (C) 2002, 2003, 2004, 2005 Matthew P. Hodges
;; Author: Matthew P. Hodges <MPHodges@member.fsf.org>
;; $Id$
@@ -17,12 +17,12 @@
;;; Commentary:
;;
-;; Package to interface Emacs with APT. Start things off using e.g.:
+;; Package to interface Emacs with APT. Start things off using e.g.:
;; M-x apt-utils-show-package RET emacs21 RET
;;
;; Other packages (dependencies, conflicts etc.) can be navigated
;; using apt-utils-{next,previous}-package,
-;; apt-utils-choose-package-link or apt-utils-follow-link. Return to
+;; apt-utils-choose-package-link or apt-utils-follow-link. Return to
;; the previous package with apt-utils-view-previous-package.
;; ChangeLog and README files for the current package can easily be
;; accessed with, for example, apt-utils-view-changelog.
@@ -36,6 +36,10 @@
;;; Code:
+(defconst apt-utils-version "2.4.0"
+ "Version number of this package.")
+
+(require 'browse-url)
(require 'jka-compr)
(cond
@@ -52,7 +56,7 @@
(defgroup apt-utils nil
"Emacs interface to APT (Debian package management)."
:group 'tools
- :link '(url-link "http://www.tc.bham.ac.uk/~matt/published/Public/AptUtilsEl.html"))
+ :link '(url-link "http://mph-emacs-pkgs.alioth.debian.org/AptUtilsEl.html"))
(defcustom apt-utils-fill-packages t
"*Fill APT package names if t."
@@ -72,9 +76,10 @@
(defcustom apt-utils-automatic-update 'ask
"*Controls automatic rebuilding of APT package lists.
-If t always rebuilt when `apt-utils-timestamped-file' is newer than
-`apt-utils-package-list-update-time'. If equal to the symbol ask,
-ask the user about the update. If nil, never update automatically."
+If t always rebuilt when `apt-utils-timestamped-file' is newer
+than the timestamp stored in `apt-utils-package-list-built'. If
+equal to the symbol ask, ask the user about the update. If nil,
+never update automatically."
:group 'apt-utils
:type '(choice (const :tag "Always update automatically" t)
(const :tag "Ask user about update" ask)
@@ -85,20 +90,56 @@ ask the user about the update. If nil, never update automatically."
:group 'apt-utils
:type '(repeat string))
-(defcustom apt-utils-mode-name-update nil
- "*String indicating that package lists need updating."
- :group 'apt-utils
- :type 'string)
-
(defcustom apt-utils-kill-buffer-confirmation-function 'yes-or-no-p
"Function called before killing any buffers.
-Used by `apt-utils-kill-other-window-buffers'."
+The function is called with one argument, which is a prompt.
+Suitable non-nil values include `yes-or-no-p', `y-or-n-p' and
+`ignore'."
:group 'apt-utils
:type '(choice (const :tag "Kill buffers only after yes or no query" yes-or-no-p)
(const :tag "Kill buffers only after y or n query" y-or-n-p)
(const :tag "Never kill buffers" ignore)
(const :tag "Kill buffers without confirmation" nil)))
+(defcustom apt-utils-search-split-regexp "\\s-*&&\\s-*"
+ "Regular expression used to split multiple search terms.
+See `apt-utils-search' and `apt-utils-search-names-only'."
+ :group 'apt-utils
+ :type 'regexp)
+
+(defcustom apt-utils-web-browse-debian-changelog-url
+ "http://packages.debian.org/changelogs/pool/main/%d/%s/%s_%v/changelog"
+ "Template URL for Debian ChangeLog files.
+See `apt-utils-web-format-url'."
+ :group 'apt-utils
+ :type 'string)
+
+(defcustom apt-utils-web-browse-bug-reports-url
+ "http://bugs.debian.org/%p"
+ "Template URL for Debian bug reports.
+See `apt-utils-web-format-url'."
+ :group 'apt-utils
+ :type 'string)
+
+(defcustom apt-utils-web-browse-copyright-url
+ "http://packages.debian.org/changelogs/pool/main/%d/%s/%s_%v/%p.copyright"
+ "Template URL for Debian copyright files.
+See `apt-utils-web-format-url'."
+ :group 'apt-utils
+ :type 'string)
+
+(defcustom apt-utils-web-browse-versions-url
+ "http://packages.debian.org/%p"
+ "Template URL for Debian version information.
+See `apt-utils-web-format-url'."
+ :group 'apt-utils
+ :type 'string)
+
+(defcustom apt-utils-show-package-hooks nil
+ "Hooks to be run after presenting package information."
+ :group 'apt-utils
+ :type 'hook)
+
;; Faces
(defface apt-utils-normal-package-face
@@ -165,20 +206,20 @@ Used by `apt-utils-kill-other-window-buffers'."
(defvar apt-utils-grep-dctrl-program "/usr/bin/grep-dctrl"
"Location of the grep-dctrl program.")
-(defvar apt-utils-grep-dctrl-file-list
- (directory-files "/var/lib/apt/lists" t "_Packages")
- "List of files searched by `apt-utils-search-grep-dctrl'.")
+(defvar apt-utils-grep-dctrl-file-directory "/var/lib/apt/lists"
+ "Directory used by `apt-utils-search-grep-dctrl'.
+See also `apt-utils-grep-dctrl-file-list'.")
-(defvar apt-utils-completion-table nil
- "List of packages known to APT; used by `completing-read'.
-Only generated if `apt-utils-completing-read-hashtable-p' is
-nil.")
+(defvar apt-utils-grep-dctrl-file-list nil
+ "List of files searched by `apt-utils-search-grep-dctrl'.
+If no list is specified, this is computed on demand from files in
+`apt-utils-grep-dctrl-file-directory'.")
-(defvar apt-utils-package-hashtable nil
+(defvar apt-utils-package-list nil
"Hash table containing APT packages types.")
-(defvar apt-utils-package-lists-built nil
- "Whether or not APT package lists are built.")
+(defvar apt-utils-package-list-built nil
+ "If non-nil, a timestamp for the APT package list data.")
(defvar apt-utils-package-history nil
"History of packages for each `apt-utils-mode' buffer.")
@@ -190,16 +231,13 @@ nil.")
(defvar apt-utils-buffer-positions nil
"Cache of positions associated with package history.
-These are stored in a hash table. See also
+These are stored in a hash table. See also
`apt-utils-package-history'")
(make-variable-buffer-local 'apt-utils-buffer-positions)
(defvar apt-utils-dired-buffer nil
"Keep track of dired buffer.")
-(defvar apt-utils-package-list-update-time nil
- "The time that `apt-utils-build-package-lists' was last done.")
-
(defvar apt-utils-automatic-update-asked nil
"Non-nil if user already asked about updating package lists.")
@@ -213,39 +251,31 @@ These are stored in a hash table. See also
(string-match "XEmacs\\|Lucid" (emacs-version)))
"True if we are using apt-utils under XEmacs.")
-(if apt-utils-xemacs-p
- (progn
- (defalias 'apt-utils-line-end-position 'point-at-eol))
- (defalias 'apt-utils-line-end-position 'line-end-position))
-
;; Other version-dependent configuration
+(defalias 'apt-utils-line-end-position
+ (cond
+ ((fboundp 'line-end-position) 'line-end-position)
+ ((fboundp 'point-at-eol) 'point-at-eol)))
+
(defconst apt-utils-completing-read-hashtable-p
- (and (not apt-utils-xemacs-p)
- (or
- ;; Next released version after 21.3 will support this
- (and
- (>= emacs-major-version 21)
- (>= emacs-minor-version 4))
- (>= emacs-major-version 22)
- ;; As will the current pretest
- (string-match "\\..*\\..*\\." emacs-version)))
+ ;; I think this is a valid way to check this feature...
+ (condition-case nil
+ (or (all-completions "" (make-hash-table)) t)
+ (error nil))
"Non-nil if `completing-read' supports hash table as input.")
(defconst apt-utils-face-property
- (cond
- ((and (not apt-utils-xemacs-p)
- (or
- ;; Next released version after 21.3 will support this
- (and
- (>= emacs-major-version 21)
- (>= emacs-minor-version 4))
- (>= emacs-major-version 22)
- ;; As will the current pretest
- (string-match "\\..*\\..*\\." emacs-version)))
- 'font-lock-face)
- (t
- 'face))
+ (if (with-temp-buffer
+ ;; We have to rename to something without a leading space,
+ ;; otherwise font-lock-mode won't get activated.
+ (rename-buffer "*test-font-lock*")
+ (font-lock-mode 1)
+ (and (boundp 'char-property-alias-alist)
+ (member 'font-lock-face
+ (assoc 'face char-property-alias-alist))))
+ 'font-lock-face
+ 'face)
"Use font-lock-face if `add-text-properties' supports it.
Otherwise, just use face.")
@@ -268,25 +298,26 @@ Otherwise, just use face.")
;; Commands and functions
;;;###autoload
-(defun apt-utils-show-package ()
+(defun apt-utils-show-package (&optional new-session)
"Show information for a Debian package.
-A selection of known packages is presented. See `apt-utils-mode'
-for more detailed help."
- (interactive)
- (apt-utils-show-package-1 t))
+A selection of known packages is presented. See `apt-utils-mode'
+for more detailed help. If NEW-SESSION is non-nil, generate a
+new `apt-utils-mode' buffer."
+ (interactive "P")
+ (apt-utils-show-package-1 t nil new-session))
(defun apt-utils-show-package-1 (&optional interactive package-spec new-session)
"Present Debian package information in a dedicated buffer.
If INTERACTIVE is non-nil, then we have been called
interactively (or from a keyboard macro) via
-`apt-utils-show-package'. Hence, reset the history of visited
+`apt-utils-show-package'. Hence, reset the history of visited
packages.
If PACKAGE-SPEC is specified, this can either be a string (the
name of the package) or a list, where the car of the list is the
name of the package, and the cdr is the package type; if not
-specified, a package name is prompted for. If NEW-SESSION is
+specified, a package name is prompted for. If NEW-SESSION is
non-nil, generate a new `apt-utils-mode' buffer."
(apt-utils-check-package-lists)
(let (package type)
@@ -304,7 +335,8 @@ non-nil, generate a new `apt-utils-mode' buffer."
(cond
(new-session
(set-buffer (generate-new-buffer "*APT package info*"))
- (apt-utils-mode))
+ (apt-utils-mode)
+ (apt-utils-update-mode-name))
((eq major-mode 'apt-utils-mode)
;; do nothing
)
@@ -337,13 +369,15 @@ non-nil, generate a new `apt-utils-mode' buffer."
((equal type 'search)
(insert (format "Debian package search for %s\n\n" package))
(apply 'call-process apt-utils-apt-cache-program nil '(t nil) nil
- "search" "--" (split-string package "&&"))
+ "search" "--"
+ (split-string package apt-utils-search-split-regexp))
(apt-utils-add-search-links 'search))
;; Search for names only
((equal type 'search-names-only)
(insert (format "Debian package search (names only) for %s\n\n" package))
(apply 'call-process apt-utils-apt-cache-program nil '(t nil) nil
- "search" "--names-only" "--" (split-string package "&&"))
+ "search" "--names-only" "--"
+ (split-string package apt-utils-search-split-regexp))
(apt-utils-add-search-links 'search-names-only))
;; Search for file names
((equal type 'search-file-names)
@@ -364,11 +398,12 @@ non-nil, generate a new `apt-utils-mode' buffer."
;; or when choosing new packages with apt-utils-follow-link or
;; apt-utils-choose-package-link.
(goto-char (point-min))
- (set-window-start (display-buffer (current-buffer)) (point-min))))
+ (set-window-start (display-buffer (current-buffer)) (point-min)))
+ (run-hooks 'apt-utils-show-package-hooks))
(defun apt-utils-list-package-files ()
"List the files associated with the current package.
-The list appears in a `dired-mode' buffer. Only works for
+The list appears in a `dired-mode' buffer. Only works for
installed packages; uses `apt-utils-dpkg-program'."
(interactive)
(let ((package (caar apt-utils-package-history))
@@ -389,63 +424,76 @@ installed packages; uses `apt-utils-dpkg-program'."
(t
(message "No files associated for type: %s." type)))))
-(defun apt-utils-get-package-files (package &optional filter)
+(defun apt-utils-get-package-files (package &optional filter installed)
"Return a list of files belonging to package PACKAGE.
With optional argument FILTER, return files matching this regular
-expression."
+expression.
+
+With non-nil INSTALLED, return t if package is installed,
+otherwise nil."
(let (files)
- (with-temp-buffer
- (call-process apt-utils-dpkg-program nil t nil "-L" package)
- ;; Check for files
- (cond
- ((or (search-backward "does not contain any files" nil t)
- (search-backward "not installed" nil t)))
- (t
- (goto-char (point-min))
- (insert "(setq files '(\n")
- (while (re-search-forward "^\\(.+\\)$" nil t)
- (replace-match "\"\\1\""))
- (insert "))")
- (eval-buffer)
- ;; Keep regular files or top directory (for dired)
- (setq files
- (delq nil
- (mapcar (lambda (elt)
- (if (and (or (file-regular-p elt)
- (string-equal "/." elt))
- (string-match (or filter ".") elt))
- elt
- nil))
- files))))))
- files))
+ (catch 'installed
+ (with-temp-buffer
+ (call-process apt-utils-dpkg-program nil t nil "-L" package)
+ ;; Check for files
+ (cond
+ ((or (search-backward "does not contain any files" nil t)
+ (search-backward "not installed" nil t)
+ ;; dlocate returns nothing for uninstalled packages
+ (or (zerop (buffer-size))))
+ (when installed
+ (throw 'installed nil)))
+ (installed
+ (throw 'installed t))
+ (t
+ (setq files (split-string (buffer-string) "\n"))
+ ;; Keep regular files or top directory (for dired)
+ (setq files
+ (delq nil
+ (mapcar (lambda (elt)
+ (if (and (or (file-regular-p elt)
+ (string-equal "/." elt))
+ (string-match (or filter ".") elt))
+ elt
+ nil))
+ files))))))
+ files)))
+
+(defun apt-utils-current-package-installed-p ()
+ "Return non-nil if the current-package is installed."
+ (apt-utils-get-package-files (caar apt-utils-package-history) nil t))
;;;###autoload
(defun apt-utils-search ()
"Search Debian packages for regular expression.
-To search for multiple patterns use a string like \"foo&&bar\"."
+To search for multiple patterns use a string like \"foo && bar\".
+The regular expression used to split the
+terms (`apt-utils-search-split-regexp') is customisable."
(interactive)
- (apt-utils-search-internal 'search))
+ (apt-utils-search-internal 'search
+ "Search packages for regexp: "))
(defun apt-utils-search-names-only ()
"Search Debian package names for regular expression.
-To search for multiple patterns use a string like \"foo&&bar\"."
+To search for multiple patterns use a string like \"foo && bar\".
+The regular expression used to split the
+terms (`apt-utils-search-split-regexp') is customisable."
(interactive)
- (apt-utils-search-internal 'search-names-only))
+ (apt-utils-search-internal 'search-names-only
+ "Search package names for regexp: "))
(defun apt-utils-search-file-names ()
"Search Debian file names for string."
(interactive)
- (apt-utils-search-internal 'search-file-names))
+ (apt-utils-search-internal 'search-file-names
+ "Search file names for string: "))
-(defun apt-utils-search-internal (type)
+(defun apt-utils-search-internal (type prompt)
"Search Debian packages for regular expression or string.
-The type of search is specified by TYPE."
+The type of search is specified by TYPE, the prompt for the
+search is specified by PROMPT."
(apt-utils-check-package-lists)
- (let ((regexp (read-from-minibuffer
- (cond ((eq type 'search-file-names)
- "Search file names for string: ")
- (t
- "Search packages for regexp: ")))))
+ (let ((regexp (read-from-minibuffer prompt)))
;; Set up the buffer
(cond
((eq major-mode 'apt-utils-mode)
@@ -469,11 +517,13 @@ The type of search is specified by TYPE."
(cond
((eq type 'search)
(apply 'call-process apt-utils-apt-cache-program nil '(t nil) nil
- "search" "--" (split-string regexp "&&"))
+ "search" "--"
+ (split-string regexp apt-utils-search-split-regexp))
(setq apt-utils-package-history (cons (cons regexp 'search) nil)))
((eq type 'search-names-only)
(apply 'call-process apt-utils-apt-cache-program nil '(t nil) nil
- "search" "--names-only" "--" (split-string regexp "&&"))
+ "search" "--names-only" "--"
+ (split-string regexp apt-utils-search-split-regexp))
(setq apt-utils-package-history (cons (cons regexp 'search-names-only) nil)))
((eq type 'search-file-names)
@@ -517,8 +567,10 @@ The type of search is specified by TYPE."
(let ((inhibit-read-only t))
(erase-buffer)
;; Construct argument list (need to keep this)
- (setq args (append apt-utils-grep-dctrl-args (list regexp fields show)
- apt-utils-grep-dctrl-file-list))
+ (setq args (append (list regexp fields show) apt-utils-grep-dctrl-args
+ (or apt-utils-grep-dctrl-file-list
+ (directory-files apt-utils-grep-dctrl-file-directory
+ t "_Packages"))))
(insert (format "grep-dctrl search for %s\n\n"
(mapconcat
(lambda (elt)
@@ -570,7 +622,6 @@ Use PROMPT for `completing-read'."
(defun apt-utils-toggle-package-info ()
"Toggle between package and showpkg info for normal packages."
(interactive)
- (apt-utils-check-package-lists)
(unless (equal major-mode 'apt-utils-mode)
(error "Not in APT utils buffer"))
(let ((package (caar apt-utils-package-history))
@@ -595,36 +646,43 @@ Use PROMPT for `completing-read'."
(set-window-start (selected-window) (cadr posns)))
((equal type 'virtual)
(message "Cannot toggle info for virtual packages."))
- ((or (equal type 'search)
- (equal type 'search-names-only)
- (equal type 'search-file-names)
- (equal type 'search-grep-dctrl))
+ ((memq type '(search search-names-only
+ search-file-names
+ search-grep-dctrl))
(message "Cannot toggle info for searches.")))))
+(defun apt-utils-normal-package-p ()
+ "Return non-nil if the current package is a normal package.
+That is, not a normal-showpkg, search or a virtual package."
+ (eq (cdar apt-utils-package-history) 'normal))
+
+(defun apt-utils-toggle-package-p ()
+ "Return non-nil if we can toggle between package and showpkg.
+See also `apt-utils-toggle-package-info'."
+ (memq (cdar apt-utils-package-history) '(normal normal-showpkg)))
+
(defun apt-utils-check-package-lists ()
"Determine whether package lists need rebuilding."
+ (apt-utils-update-mode-name)
(cond
- ((null apt-utils-package-lists-built)
- (apt-utils-build-package-lists))
- ((and (apt-utils-time-less-p apt-utils-package-list-update-time
- (nth 5 (file-attributes apt-utils-timestamped-file)))
+ ((null apt-utils-package-list-built)
+ (apt-utils-build-package-list))
+ ((and (apt-utils-packages-needs-update)
;; Only act for non-nil apt-utils-automatic-update
apt-utils-automatic-update
(cond
((eq apt-utils-automatic-update t))
((eq apt-utils-automatic-update 'ask)
(unless apt-utils-automatic-update-asked
- (when (eq major-mode 'apt-utils-mode)
- (setq mode-name (concat "APT utils" apt-utils-mode-name-update)))
(setq apt-utils-automatic-update-asked t)
(yes-or-no-p
"APT package lists may be out of date. Update them? ")))))
- (apt-utils-build-package-lists t))))
+ (apt-utils-build-package-list t))))
;; Find ChangeLog files
(defun apt-utils-view-changelog ()
- "Find ChangeLog for current package."
+ "Find ChangeLog for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -632,24 +690,26 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-changelog-file package)))))
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-changelog-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No ChangeLog file found for %s." package))))))
-(defun apt-utils-view-changelog-file (package)
- "Find ChangeLog file for PACKAGE."
+(defun apt-utils-changelog-file (&optional package)
+ "Find ChangeLog file for PACKAGE or the current package."
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/" package)
'("CHANGELOG" "ChangeLog" "Changelog" "changelog")
'("" ".gz"))))
- (if file
- (apt-utils-view-file file)
- (message "No ChangeLog file found for %s." package))))
+ file))
;; Find Debian ChangeLog files
(defun apt-utils-view-debian-changelog ()
- "Find Debian ChangeLog for current package."
+ "Find Debian ChangeLog for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -657,24 +717,26 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-debian-changelog-file package)))))
-
-(defun apt-utils-view-debian-changelog-file (package)
- "Find Debian ChangeLog file for PACKAGE."
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-debian-changelog-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No Debian ChangeLog file found for %s." package))))))
+
+(defun apt-utils-debian-changelog-file (&optional package)
+ "Find Debian ChangeLog file for PACKAGE or the current package. "
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/" package)
'("changelog.Debian")
'(".gz"))))
- (if file
- (apt-utils-view-file file)
- (message "No Debian ChangeLog file found for %s." package))))
+ file))
;; Find NEWS files
(defun apt-utils-view-news ()
- "Find NEWS for current package."
+ "Find NEWS for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -682,24 +744,26 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-news-file package)))))
-
-(defun apt-utils-view-news-file (package)
- "Find NEWS file for PACKAGE."
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-news-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No NEWS file found for %s." package))))))
+
+(defun apt-utils-news-file (&optional package)
+ "Find NEWS file for PACKAGE or the current package."
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/" package)
'("NEWS")
'("" ".gz"))))
- (if file
- (apt-utils-view-file file)
- (message "No NEWS file found for %s." package))))
+ file))
;; Find Debian NEWS files
(defun apt-utils-view-debian-news ()
- "Find Debian NEWS for current package."
+ "Find Debian NEWS for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -707,24 +771,26 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-debian-news-file package)))))
-
-(defun apt-utils-view-debian-news-file (package)
- "Find Debian NEWS file for PACKAGE."
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-debian-news-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No Debian NEWS file found for %s." package))))))
+
+(defun apt-utils-debian-news-file (&optional package)
+ "Find Debian NEWS file for PACKAGE or the current package."
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/" package)
'("NEWS.Debian")
'(".gz"))))
- (if file
- (apt-utils-view-file file)
- (message "No Debian NEWS file found for %s." package))))
+ file))
;; Find README files
(defun apt-utils-view-readme ()
- "Find README for current package."
+ "Find README for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -732,24 +798,26 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-readme-file package)))))
-
-(defun apt-utils-view-readme-file (package)
- "Find README file for PACKAGE."
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-readme-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No README file found for %s." package))))))
+
+(defun apt-utils-readme-file (&optional package)
+ "Find README file for PACKAGE or the current package."
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/" package)
- '("README")
+ '("README" "readme")
'("" ".gz"))))
- (if file
- (apt-utils-view-file file)
- (message "No README file found for %s." package))))
+ file))
;; Find Debian README files
(defun apt-utils-view-debian-readme ()
- "Find Debian README for current package."
+ "Find Debian README for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -757,24 +825,26 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-debian-readme-file package)))))
-
-(defun apt-utils-view-debian-readme-file (package)
- "Find Debian README file for PACKAGE."
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-debian-readme-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No Debian README file found for %s." package))))))
+
+(defun apt-utils-debian-readme-file (&optional package)
+ "Find Debian README file for PACKAGE or the current package."
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/" package)
'("README.Debian" "README.debian")
'("" ".gz"))))
- (if file
- (apt-utils-view-file file)
- (message "No Debian README file found for %s." package))))
+ file))
;; Find copyright files
(defun apt-utils-view-copyright ()
- "Find copyright file for current package."
+ "Find copyright file for the current package."
(interactive)
(cond
((not (equal major-mode 'apt-utils-mode))
@@ -782,19 +852,21 @@ Use PROMPT for `completing-read'."
((not (equal (cdar apt-utils-package-history) 'normal))
(message "Not a normal package."))
(t
- (let ((package (caar apt-utils-package-history)))
- (apt-utils-view-copyright-file package)))))
-
-(defun apt-utils-view-copyright-file (package)
- "Find copyright file for PACKAGE."
+ (let* ((package (caar apt-utils-package-history))
+ (file (apt-utils-copyright-file package)))
+ (if file
+ (apt-utils-view-file file)
+ (message "No copyright file found for %s." package))))))
+
+(defun apt-utils-copyright-file (&optional package)
+ "Find copyright file for PACKAGE or the current package."
+ (unless package (setq package (caar apt-utils-package-history)))
(let ((file
(apt-utils-find-readable-file
(format "/usr/share/doc/%s/copyright" package)
'("")
'(""))))
- (if file
- (apt-utils-view-file file)
- (message "No copyright file found for %s." package))))
+ file))
(defun apt-utils-view-man-page ()
"View man page for the current package.
@@ -839,6 +911,39 @@ offer a choice."
(woman-find-file chosen)
(manual-entry chosen)))))))
+(defun apt-utils-view-emacs-startup-file ()
+ "View Emacs startup file for the current package.
+If there is more than one file associated with the package, offer
+a choice."
+ (interactive)
+ (cond
+ ((not (equal major-mode 'apt-utils-mode))
+ (message "Not in APT utils buffer."))
+ ((not (equal (cdar apt-utils-package-history) 'normal))
+ (message "Not a normal package."))
+ (t
+ (let ((package (caar apt-utils-package-history))
+ chosen files table)
+ (setq files (apt-utils-get-package-files package
+ "^/etc/emacs/site-start.d/.*"))
+ (cond
+ ((null files)
+ (message "No Emacs startup files found for %s." package))
+ ((not (cdr files))
+ (setq chosen (car files)))
+ (t
+ (setq table (mapcar
+ (lambda (file)
+ (cons file file))
+ files))
+ (setq chosen
+ (cdr (assoc
+ (let ((completion-ignore-case t))
+ (completing-read "Choose Emacs startup file: " table nil t))
+ table)))))
+ (when chosen
+ (apt-utils-view-file chosen))))))
+
;; File-related utility functions
(defun apt-utils-find-readable-file (dir prefixes suffixes)
@@ -885,12 +990,15 @@ Argument EVENT is a mouse event."
(let (package)
(save-selected-window
(mouse-set-point event)
- (setq package
- (cadr
- (member 'apt-package (text-properties-at
- (point)))))
+ (setq package (apt-utils-package-at-point))
(apt-utils-follow-link-internal package nil))))
+(defun apt-utils-package-at-point ()
+ "Return name of package at point, if any."
+ (cadr
+ (member 'apt-package (text-properties-at
+ (point)))))
+
(defun apt-utils-follow-link-internal (package new-session)
"Follow hyperlink for PACKAGE.
With non-nil NEW-SESSION, follow link in a new buffer."
@@ -924,6 +1032,11 @@ With non-nil NEW-SESSION, follow link in a new buffer."
(setq apt-utils-package-history (cdr apt-utils-package-history)))
(message "No further package history.")))
+(defun apt-utils-previous-package-p ()
+ "Return non-nil if there is a previous entry in the package history.
+See also `apt-utils-package-history'."
+ (cdr apt-utils-package-history))
+
;; Adapted from widget-move
(defun apt-utils-next-package (&optional arg)
@@ -934,10 +1047,10 @@ ARG may be negative to move backward."
(error "Not in APT utils buffer"))
(cond
;; No links
- ((null apt-utils-current-links)
+ ((= (hash-table-count apt-utils-current-links) 0)
(message "No package links."))
;; One link
- ((= (length apt-utils-current-links) 1)
+ ((= (hash-table-count apt-utils-current-links) 1)
(goto-char (point-min))
(goto-char (next-single-property-change (point)
'apt-package)))
@@ -994,70 +1107,72 @@ With non-nil NEW-SESSION, follow link in a new buffer."
(defun apt-utils-choose-package-link-internal (new-session)
"Choose a Debian package from a list of links.
With non-nil NEW-SESSION, follow link in a new buffer."
- (unless (equal major-mode 'apt-utils-mode)
+ (cond
+ ((not (equal major-mode 'apt-utils-mode))
(error "Not in APT utils buffer"))
- (let ((package
- (completing-read "Choose related Debian package: "
- (mapcar (lambda (elt)
- (cons elt elt))
- apt-utils-current-links) nil t)))
- (when (> (length package) 0)
- (unless new-session
- (apt-utils-update-buffer-positions 'forward))
- (apt-utils-show-package-1 nil package new-session)
- (unless new-session
- (setq apt-utils-package-history
- (cons (cons package (apt-utils-package-type package))
- apt-utils-package-history))))))
-
-(defun apt-utils-build-package-lists (&optional force)
+ ((= (hash-table-count apt-utils-current-links) 0)
+ (message "No package links."))
+ (t
+ (let ((package
+ (completing-read "Choose related Debian package: "
+ (cond
+ (apt-utils-completing-read-hashtable-p
+ apt-utils-current-links)
+ (t
+ (apt-utils-build-completion-table
+ apt-utils-current-links)))
+ nil t)))
+ (when (> (length package) 0)
+ (unless new-session
+ (apt-utils-update-buffer-positions 'forward))
+ (apt-utils-show-package-1 nil package new-session)
+ (unless new-session
+ (setq apt-utils-package-history
+ (cons (cons package (apt-utils-package-type package))
+ apt-utils-package-history))))))))
+
+(defun apt-utils-build-package-list (&optional force)
"Build list of Debian packages known to APT.
With optional argument FORCE, rebuild the packages lists even if
-they are defined. When package lists are not up-to-date, this is
+they are defined. When package lists are not up-to-date, this is
indicated in `mode-name'."
- (when (or force (null apt-utils-package-lists-built))
+ (when (or force (null apt-utils-package-list-built))
(unwind-protect
(progn
- (setq apt-utils-package-lists-built nil
- apt-utils-package-list-update-time nil
- apt-utils-automatic-update-asked nil
- apt-utils-completion-table nil)
+ (setq apt-utils-package-list-built nil
+ apt-utils-automatic-update-asked nil)
(message "Building Debian package lists...")
;; Hash table listing package types
- (if (hash-table-p apt-utils-package-hashtable)
- (clrhash apt-utils-package-hashtable)
- (setq apt-utils-package-hashtable (make-hash-table :test 'equal)))
+ (if (hash-table-p apt-utils-package-list)
+ (clrhash apt-utils-package-list)
+ (setq apt-utils-package-list (make-hash-table :test 'equal)))
;; All packages except virtual ones
(with-temp-buffer
;; Virtual and normal packages
(call-process apt-utils-apt-cache-program nil '(t nil) nil "pkgnames")
(mapcar (lambda (elt)
- (apt-utils-puthash elt 'virtual apt-utils-package-hashtable))
- (split-string (buffer-string)))
+ (apt-utils-puthash elt 'virtual apt-utils-package-list))
+ (split-string (buffer-string) "\n"))
;; Normal packages
(erase-buffer)
(call-process apt-utils-apt-cache-program nil '(t nil) nil "pkgnames"
"-o" "APT::Cache::AllNames=0")
(mapcar (lambda (elt)
- (apt-utils-puthash elt 'normal apt-utils-package-hashtable))
- (split-string (buffer-string))))
+ (apt-utils-puthash elt 'normal apt-utils-package-list))
+ (split-string (buffer-string) "\n")))
(message "Building Debian package lists...done.")
- (setq apt-utils-package-lists-built t
- apt-utils-package-list-update-time
- (nth 5 (file-attributes apt-utils-timestamped-file)))
- (when (eq major-mode 'apt-utils-mode)
- (setq mode-name "APT utils")))
- (unless apt-utils-package-lists-built
+ (setq apt-utils-package-list-built (current-time))
+ (apt-utils-update-mode-name))
+ (unless apt-utils-package-list-built
(message "Building Debian package lists...interrupted.")
- (when (eq major-mode 'apt-utils-mode)
- (setq mode-name (concat "APT utils" apt-utils-mode-name-update)))
- (if (hash-table-p apt-utils-package-hashtable)
- (clrhash apt-utils-package-hashtable))))))
+ (apt-utils-update-mode-name)
+ (if (hash-table-p apt-utils-package-list)
+ (clrhash apt-utils-package-list))))))
(defun apt-utils-rebuild-package-lists ()
"Rebuild the APT package lists."
(interactive)
- (apt-utils-build-package-lists t))
+ (apt-utils-build-package-list t))
(defun apt-utils-choose-package ()
"Choose a Debian package name."
@@ -1065,26 +1180,25 @@ indicated in `mode-name'."
(and (eq major-mode 'apt-utils-mode)
(cadr (member 'apt-package
(text-properties-at (point)))))))
+ (when (eq package 'broken) (setq package nil))
(completing-read "Choose Debian package: "
(cond
(apt-utils-completing-read-hashtable-p
- apt-utils-package-hashtable)
+ apt-utils-package-list)
(t
- (or apt-utils-completion-table
- (apt-utils-build-completion-table))))
+ (apt-utils-build-completion-table
+ apt-utils-package-list)))
nil t package)))
-(defun apt-utils-build-completion-table ()
- "Build completion table for packages.
-See `apt-utils-completion-table'."
+(defun apt-utils-build-completion-table (hash)
+ "Build completion table for packages using keys of hashtable HASH. "
(with-temp-buffer
(maphash (lambda (key value)
(insert key "\n"))
- apt-utils-package-hashtable)
- (setq apt-utils-completion-table
- (mapcar (lambda (elt)
- (list elt))
- (split-string (buffer-string))))))
+ hash)
+ (mapcar (lambda (elt)
+ (list elt))
+ (split-string (buffer-string) "\n"))))
;; Add hyperlinks
@@ -1094,7 +1208,9 @@ See `apt-utils-completion-table'."
"Pre-Depends" "Provides" "Recommends" "Replaces"
"Suggests"))
match)
- (setq apt-utils-current-links nil)
+ (if (hash-table-p apt-utils-current-links)
+ (clrhash apt-utils-current-links)
+ (setq apt-utils-current-links (make-hash-table :test 'equal)))
(goto-char (point-min))
(while (re-search-forward "^\\([^ \n:]+\\):\\( \\|$\\)"
(point-max) t)
@@ -1151,10 +1267,8 @@ See `apt-utils-completion-table'."
(when (equal (char-before) ?\ )
(delete-char -1)) ; trailing whitespace
(insert "\n" (make-string (+ 2 (length match)) ? )))
- ;; Store list of unique package links
- (unless (member package apt-utils-current-links)
- (setq apt-utils-current-links
- (cons package apt-utils-current-links)))
+ ;; Store package links
+ (apt-utils-puthash package nil apt-utils-current-links)
(forward-char length)
(skip-chars-forward ", |\n")
(setq packages (cdr packages)))))
@@ -1180,7 +1294,9 @@ See `apt-utils-completion-table'."
(let ((keywords '("Reverse Depends" "Reverse Provides"))
(inhibit-read-only t)
start end regexp face link)
- (setq apt-utils-current-links nil)
+ (if (hash-table-p apt-utils-current-links)
+ (clrhash apt-utils-current-links)
+ (setq apt-utils-current-links (make-hash-table :test 'equal)))
(while keywords
(setq regexp (concat "^" (car keywords) ": "))
(goto-char (point-min))
@@ -1199,10 +1315,8 @@ See `apt-utils-completion-table'."
(when (or (looking-at "^\\s-+\\(.*\\),")
(looking-at "^\\(.*\\) "))
(setq link (match-string 1))
- ;; Store list of unique package links
- (unless (member link apt-utils-current-links)
- (setq apt-utils-current-links
- (cons link apt-utils-current-links)))
+ ;; Store package links
+ (apt-utils-puthash link nil apt-utils-current-links)
(cond
((equal (apt-utils-package-type link t) 'normal)
(setq face 'apt-utils-normal-package-face))
@@ -1223,7 +1337,9 @@ See `apt-utils-completion-table'."
The type of search is specified by TYPE."
(let ((inhibit-read-only t)
face link regexp)
- (setq apt-utils-current-links nil)
+ (if (hash-table-p apt-utils-current-links)
+ (clrhash apt-utils-current-links)
+ (setq apt-utils-current-links (make-hash-table :test 'equal)))
(goto-char (point-min))
(forward-line 2) ; Move past header
(cond
@@ -1237,10 +1353,8 @@ The type of search is specified by TYPE."
(setq regexp"^\\([^ ]+\\) - ")))
(while (re-search-forward regexp (point-max) t)
(setq link (match-string 1))
- ;; Store list of unique package links
- (unless (member link apt-utils-current-links)
- (setq apt-utils-current-links
- (cons link apt-utils-current-links)))
+ ;; Store package links
+ (apt-utils-puthash link nil apt-utils-current-links)
(cond
((equal (apt-utils-package-type link t) 'normal)
(setq face 'apt-utils-normal-package-face))
@@ -1263,7 +1377,7 @@ The type of search is specified by TYPE."
"Return what type of package PACKAGE is.
With optional argument NO-ERROR, don't flag an error for unknown
packages."
- (or (gethash package apt-utils-package-hashtable)
+ (or (gethash package apt-utils-package-list)
(cond
(no-error
nil)
@@ -1302,8 +1416,8 @@ packages."
(defun apt-utils-kill-buffer ()
"Kill this `apt-utils-mode' buffer.
-Also clean up `apt-utils-package-hashtable' and
-`apt-utils-completion-table' using `apt-utils-cleanup'."
+Also clean up `apt-utils-package-list' using
+`apt-utils-cleanup'."
(interactive)
(unless (equal major-mode 'apt-utils-mode)
(error "Not in APT utils buffer"))
@@ -1312,17 +1426,15 @@ Also clean up `apt-utils-package-hashtable' and
(defun apt-utils-cleanup ()
"Clean up lists used by `apt-utils-mode'.
-Specifically, nullify `apt-utils-package-hashtable' and
-`apt-utils-completion-table'. Only do this if there are no
-buffers left in `apt-utils-mode'."
+Specifically, nullify `apt-utils-package-list'. Only do this if
+there are no buffers left in `apt-utils-mode'."
(unless (memq 'apt-utils-mode
(mapcar (lambda (b)
(with-current-buffer b
major-mode))
(buffer-list)))
- (clrhash apt-utils-package-hashtable)
- (setq apt-utils-completion-table nil
- apt-utils-package-lists-built nil)))
+ (clrhash apt-utils-package-list)
+ (setq apt-utils-package-list-built nil)))
(defun apt-utils-describe-package ()
"Describe package at point."
@@ -1337,8 +1449,8 @@ customisation options."
(unless (eq major-mode 'apt-utils-mode)
(error "Not in APT utils buffer"))
(when (or (null apt-utils-kill-buffer-confirmation-function)
- (apply apt-utils-kill-buffer-confirmation-function
- (list "Kill buffers in other windows? ")))
+ (funcall apt-utils-kill-buffer-confirmation-function
+ "Kill buffers in other windows? "))
(let ((buffer-list
(delq (current-buffer)
(mapcar #'window-buffer (window-list)))))
@@ -1465,6 +1577,106 @@ TYPE can be forward, backward, or toggle."
(and (= (car t1) (car t2))
(< (nth 1 t1) (nth 1 t2)))))
+(defun apt-utils-web-browse-debian-changelog ()
+ "Browse web version of Debian ChangeLog file for the current package."
+ (interactive)
+ (apt-utils-web-browse-url
+ apt-utils-web-browse-debian-changelog-url))
+
+(defun apt-utils-web-browse-bug-reports ()
+ "Browse Debian bug reports for the current package."
+ (interactive)
+ (apt-utils-web-browse-url
+ apt-utils-web-browse-bug-reports-url))
+
+(defun apt-utils-web-browse-copyright ()
+ "Browse web version of Debian copyright file for the current package."
+ (interactive)
+ (apt-utils-web-browse-url
+ apt-utils-web-browse-copyright-url))
+
+(defun apt-utils-web-browse-versions ()
+ "Browse web version information for the current package."
+ (interactive)
+ (apt-utils-web-browse-url
+ apt-utils-web-browse-versions-url))
+
+(defun apt-utils-web-browse-url (url)
+ "Browse Debian-related URL.
+The URL can contain tokens that need formatting (see
+`apt-utils-web-format-url')."
+ (cond
+ ((not (equal major-mode 'apt-utils-mode))
+ (message "Not in APT utils buffer."))
+ ((not (memq (cdar apt-utils-package-history) '(normal normal-showpkg)))
+ (message "Not a normal package."))
+ (t
+ (browse-url (apt-utils-web-format-url url)))))
+
+(defun apt-utils-web-format-url (url)
+ "Format and return Debian URL.
+The tokens that can be replaced are:
+ %d: pool directory
+ %s: source package name
+ %p: package name
+ %v: package version."
+ (let ((buffer (current-buffer))
+ (package (caar apt-utils-package-history))
+ (type (cdar apt-utils-package-history))
+ char source-package version)
+ (save-excursion ; for normal package type
+ (with-temp-buffer
+ (cond
+ ((eq type 'normal)
+ (set-buffer buffer))
+ ((eq type 'normal-showpkg)
+ (call-process apt-utils-apt-cache-program nil '(t nil) nil "show" package)))
+ (goto-char (point-min))
+ (if (re-search-forward "^Source: \\(.*\\)$" (point-max) t)
+ (setq source-package (match-string 1))
+ (setq source-package package))
+ (goto-char (point-min))
+ (re-search-forward "^Version: \\([0-9]:\\)?\\(.*\\)$" (point-max))
+ (setq version (match-string 2))))
+ ;; Format the URL
+ (while (string-match "%\\(.\\)" url)
+ (setq char (string-to-char (match-string 1 url)))
+ (setq url (apt-utils-replace-regexp-in-string
+ (match-string 0 url)
+ (cond
+ ((eq char ?d)
+ (substring source-package 0
+ (if (string-match "^lib[a-z]"
+ source-package)
+ 4 1)))
+ ((eq char ?s) source-package)
+ ((eq char ?p) package)
+ ((eq char ?v) version)
+ (t
+ (error "Unrecognized token (%%%c) in URL: %s" char url)))
+ url))))
+ url)
+
+(defun apt-utils-packages-needs-update ()
+ "Return t if `apt-utils' package lists needs updating."
+ (or (not apt-utils-package-list-built)
+ (apt-utils-time-less-p apt-utils-package-list-built
+ (nth 5 (file-attributes apt-utils-timestamped-file)))))
+
+(defun apt-utils-update-mode-name ()
+ "Update `mode-name' for all buffers in `apt-utils-mode'."
+ (let* ((need-update (apt-utils-packages-needs-update))
+ (update-string
+ (and need-update
+ (substitute-command-keys
+ ": update using \\<apt-utils-mode-map>\\[apt-utils-rebuild-package-lists]")))
+ (name (concat "APT utils" update-string)))
+ (mapc (lambda (b)
+ (with-current-buffer b
+ (when (eq major-mode 'apt-utils-mode)
+ (setq mode-name name))))
+ (buffer-list))))
+
;; Mode settings
(defvar apt-utils-mode-map
@@ -1474,31 +1686,36 @@ TYPE can be forward, backward, or toggle."
(define-key map (kbd "<") 'apt-utils-view-previous-package)
(define-key map (kbd ">") 'apt-utils-choose-package-link)
(define-key map (kbd "?") 'describe-mode)
- (define-key map (kbd "C") 'apt-utils-view-debian-changelog)
(define-key map (kbd "DEL") 'scroll-down)
(define-key map (kbd "M-TAB") 'apt-utils-previous-package)
- (define-key map (kbd "N") 'apt-utils-view-debian-news)
(define-key map (kbd "Q") 'apt-utils-kill-buffer)
- (define-key map (kbd "R") 'apt-utils-view-debian-readme)
(define-key map (kbd "RET") 'apt-utils-follow-link)
- (define-key map (kbd "S") 'apt-utils-search)
+ (define-key map (kbd "S s") 'apt-utils-search)
+ (define-key map (kbd "S f") 'apt-utils-search-file-names)
+ (define-key map (kbd "S g") 'apt-utils-search-grep-dctrl)
+ (define-key map (kbd "S n") 'apt-utils-search-names-only)
(define-key map (kbd "SPC") 'scroll-up)
(define-key map (kbd "TAB") 'apt-utils-next-package)
- (define-key map (kbd "c") 'apt-utils-view-changelog)
+ (define-key map (kbd "b C") 'apt-utils-web-browse-debian-changelog)
+ (define-key map (kbd "b b") 'apt-utils-web-browse-bug-reports)
+ (define-key map (kbd "b l") 'apt-utils-web-browse-copyright)
+ (define-key map (kbd "b v") 'apt-utils-web-browse-versions)
(define-key map (kbd "d") 'apt-utils-describe-package)
- (define-key map (kbd "f") 'apt-utils-search-file-names)
- (define-key map (kbd "g") 'apt-utils-search-grep-dctrl)
- (define-key map (kbd "i") 'apt-utils-view-copyright)
(when (fboundp 'window-list)
(define-key map (kbd "k") 'apt-utils-kill-other-window-buffers))
(define-key map (kbd "l") 'apt-utils-list-package-files)
- (define-key map (kbd "m") 'apt-utils-view-man-page)
- (define-key map (kbd "n") 'apt-utils-view-news)
- (define-key map (kbd "o") 'apt-utils-search-names-only)
(define-key map (kbd "q") 'apt-utils-quit)
- (define-key map (kbd "r") 'apt-utils-view-readme)
(define-key map (kbd "s") 'apt-utils-show-package)
(define-key map (kbd "t") 'apt-utils-toggle-package-info)
+ (define-key map (kbd "v C") 'apt-utils-view-debian-changelog)
+ (define-key map (kbd "v R") 'apt-utils-view-debian-readme)
+ (define-key map (kbd "v N") 'apt-utils-view-debian-news)
+ (define-key map (kbd "v c") 'apt-utils-view-changelog)
+ (define-key map (kbd "v e") 'apt-utils-view-emacs-startup-file)
+ (define-key map (kbd "v l") 'apt-utils-view-copyright)
+ (define-key map (kbd "v m") 'apt-utils-view-man-page)
+ (define-key map (kbd "v n") 'apt-utils-view-news)
+ (define-key map (kbd "v r") 'apt-utils-view-readme)
(define-key map [(shift iso-lefttab)] 'apt-utils-previous-package)
(define-key map [(shift tab)] 'apt-utils-previous-package)
(define-key map
@@ -1507,11 +1724,6 @@ TYPE can be forward, backward, or toggle."
map)
"Keymap for apt-utils mode.")
-(unless apt-utils-mode-name-update
- (setq apt-utils-mode-name-update
- (substitute-command-keys
- ": update using \\<apt-utils-mode-map>\\[apt-utils-rebuild-package-lists]")))
-
;; Menus
(defvar apt-utils-menu nil
@@ -1520,33 +1732,62 @@ TYPE can be forward, backward, or toggle."
(when (fboundp 'easy-menu-define)
(easy-menu-define apt-utils-menu apt-utils-mode-map "Apt Utils Menu"
- '("Apt Utils"
- "---"
+ `("Apt Utils"
["Show Package" apt-utils-show-package t]
- ["Toggle Package Info" apt-utils-toggle-package-info t]
- ["View Previous Package" apt-utils-view-previous-package t]
- ["Choose Package Link" apt-utils-choose-package-link t]
- ["Next Package" apt-utils-next-package t]
- ["Previous Package" apt-utils-previous-package t]
- ["Follow Link" apt-utils-follow-link t]
- ["List Package Files" apt-utils-list-package-files t]
- "---"
- ["Search" apt-utils-search t]
- ["Search (names only)" apt-utils-search-names-only t]
- ["Search (file names)" apt-utils-search-file-names t]
- ["Search (grep-dctrl)" apt-utils-search-grep-dctrl t]
- "---"
- ["View ChangeLog" apt-utils-view-changelog t]
- ["View Debian ChangeLog" apt-utils-view-debian-changelog t]
- ["View README" apt-utils-view-readme t]
- ["View Debian README" apt-utils-view-debian-readme t]
- ["View NEWS" apt-utils-view-news t]
- ["View Debian NEWS" apt-utils-view-debian-news t]
- ["View copyright" apt-utils-view-copyright t]
- ["View man page" apt-utils-view-man-page t]
- "---"
+ ["Toggle Package Info" apt-utils-toggle-package-info
+ (apt-utils-toggle-package-p)]
+ ["View Previous Package" apt-utils-view-previous-package
+ (apt-utils-previous-package-p)]
+ ["Choose Package Link" apt-utils-choose-package-link
+ (> (hash-table-count apt-utils-current-links) 0)]
+ ["Next Package Link" apt-utils-next-package
+ (> (hash-table-count apt-utils-current-links) 0)]
+ ["Previous Package Link" apt-utils-previous-package
+ (> (hash-table-count apt-utils-current-links) 0)]
+ ["Follow Link at Point" apt-utils-follow-link
+ (apt-utils-package-at-point)]
+ ["List Package Files (dired)" apt-utils-list-package-files
+ (apt-utils-current-package-installed-p)]
["Rebuild Package Lists" apt-utils-rebuild-package-lists t]
"---"
+ ("Search"
+ ["Package Descriptions" apt-utils-search t]
+ ["Package Names" apt-utils-search-names-only t]
+ ["Installed Files" apt-utils-search-file-names t]
+ ["Grep-Dctrl" apt-utils-search-grep-dctrl t])
+ ("View Files"
+ ,@(list (if apt-utils-xemacs-p
+ :included
+ :active)
+ '(apt-utils-current-package-installed-p))
+ ["ChangeLog" apt-utils-view-changelog
+ (apt-utils-changelog-file)]
+ ["Debian ChangeLog" apt-utils-view-debian-changelog
+ (apt-utils-debian-changelog-file)]
+ ["README" apt-utils-view-readme
+ (apt-utils-readme-file)]
+ ["Debian README" apt-utils-view-debian-readme
+ (apt-utils-debian-readme-file)]
+ ["NEWS" apt-utils-view-news
+ (apt-utils-news-file)]
+ ["Debian NEWS" apt-utils-view-debian-news
+ (apt-utils-debian-news-file)]
+ ["Copyright" apt-utils-view-copyright
+ (apt-utils-copyright-file)]
+ "---"
+ ["Man Page" apt-utils-view-man-page
+ (apt-utils-current-package-installed-p)])
+ ("Browse URL"
+ ,@(list (if apt-utils-xemacs-p
+ :included
+ :active)
+ '(apt-utils-toggle-package-p))
+ ["Debian ChangeLog" apt-utils-web-browse-debian-changelog t]
+ ["Bug Reports" apt-utils-web-browse-bug-reports t]
+ ["Copyright" apt-utils-web-browse-copyright t]
+ ["Package Versions" apt-utils-web-browse-versions t])
+ "---"
+ ["Help" describe-mode t]
["Quit" apt-utils-quit t]
["Kill Buffer" apt-utils-kill-buffer t])))
@@ -1560,35 +1801,47 @@ Start things off with, for example:
Other packages (dependencies, conflicts etc.) can be navigated
using:
+ \\[apt-utils-toggle-package-info] toggle package and showpkg information
+ \\[apt-utils-view-previous-package] show the previous package from history
+ \\[apt-utils-choose-package-link] choose next package from current links
\\[apt-utils-next-package] move to next package link
\\[apt-utils-previous-package] move to previous package link
- \\[apt-utils-choose-package-link] choose next package from current links
\\[apt-utils-follow-link] show package for the link at point
- \\[apt-utils-view-previous-package] show the previous package from history
- \\[apt-utils-toggle-package-info] toggle package and showpkg information
+ \\[apt-utils-list-package-files] list package files (in a `dired' buffer)
+
+Confirmation will be requested before updating the list of known
+packages. The update can be started at any time with
+\\[apt-utils-rebuild-package-lists].
+
+Package searches can be performed using:
+
+ \\[apt-utils-search] search for regular expression in package names and descriptions
+ \\[apt-utils-search-names-only] search for regular expression in package names
+ \\[apt-utils-search-file-names] search for string in filenames
+ \\[apt-utils-search-grep-dctrl] search for regular expression in selected package fields
+ (using the grep-dctrl program)
Files associated with installed packages can be accessed using:
- \\[apt-utils-list-package-files] list package files (in a `dired' buffer)
\\[apt-utils-view-changelog] view ChangeLog file
\\[apt-utils-view-debian-changelog] view Debian ChangeLog file
\\[apt-utils-view-readme] view README file
\\[apt-utils-view-debian-readme] view Debian ChangeLog file
\\[apt-utils-view-news] view NEWS file
\\[apt-utils-view-debian-news] view Debian NEWS file
- \\[apt-utils-view-copyright] view copyright file
+ \\[apt-utils-view-copyright] view copyright (licence) file
\\[apt-utils-view-man-page] view man page
-Package searchs can be performed using:
+Web locations can be visited using:
- \\[apt-utils-search] search for regular expression in package names and descriptions
- \\[apt-utils-search-names-only] search for regular expression in package names
- \\[apt-utils-search-grep-dctrl] search for regular expression in selected package fields
- \\[apt-utils-search-file-names] search for string in filenames
+ \\[apt-utils-web-browse-debian-changelog] browse Debian ChangeLog URL
+ \\[apt-utils-web-browse-bug-reports] browse bug report URL
+ \\[apt-utils-web-browse-copyright] browse copyright (licence) URL
+ \\[apt-utils-web-browse-versions] browse package versions URL
A history of navigated packages is maintained when package links
are followed using `apt-utils-choose-package-link' or
-`apt-utils-follow-link'. This history is reset when
+`apt-utils-follow-link'. This history is reset when
`apt-utils-show-package' or any of the search commands is used.
Key definitions:
@@ -1605,6 +1858,19 @@ Key definitions:
(easy-menu-add apt-utils-menu))
(run-hooks 'apt-utils-mode-hook))
+;; Debugging
+
+(defun apt-utils-trace-all ()
+ (require 'trace)
+ (let ((buffer (get-buffer-create "*APT Utils Trace*")))
+ (buffer-disable-undo buffer)
+ (all-completions "apt-utils" obarray
+ (lambda (sym)
+ (and (fboundp sym)
+ (not (memq (car-safe (symbol-function sym))
+ '(autoload macro)))
+ (trace-function-background sym buffer))))))
+
(provide 'apt-utils)
;;; apt-utils.el ends here