Fix compilation of xmenu.c and unexcoff.c, clean up MSDOS source files.
[bpt/emacs.git] / lisp / finder.el
index cb51217..b7eccf3 100644 (file)
@@ -1,7 +1,7 @@
 ;;; finder.el --- topic & keyword-based code finder
 
 ;; Copyright (C) 1992, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
-;;   2006, 2007, 2008  Free Software Foundation, Inc.
+;;   2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
 ;; Created: 16 Jun 1992
 
 ;; This mode uses the Keywords library header to provide code-finding
 ;; services by keyword.
-;;
-;; Things to do:
-;;    1. Support multiple keywords per search.  This could be extremely hairy;
-;; there doesn't seem to be any way to get completing-read to exit on
-;; an EOL with no substring pending, which is what we'd want to end the loop.
-;;    2. Search by string in synopsis line?
-;;    3. Function to check finder-package-info for unknown keywords.
 
 ;;; Code:
 
     (tex       . "supporting code for the TeX formatter")
     (tools     . "programming tools")
     (unix      . "front-ends/assistants for, or emulators of, UNIX-like features")
-;; Not a custom group and not currently useful.
-;;    (vms     . "support code for vms")
+    (vc                . "version control")
     (wp                . "word processing")
     ))
 
 (defvar finder-mode-map
-  (let ((map (make-sparse-keymap)))
+  (let ((map (make-sparse-keymap))
+       (menu-map (make-sparse-keymap "Finder")))
     (define-key map " "        'finder-select)
     (define-key map "f"        'finder-select)
     (define-key map [follow-link] 'mouse-face)
     (define-key map "p" 'previous-line)
     (define-key map "q"        'finder-exit)
     (define-key map "d"        'finder-list-keywords)
+
+    (define-key map [menu-bar finder-mode]
+      (cons "Finder" menu-map))
+    (define-key menu-map [finder-exit]
+      '(menu-item "Quit" finder-exit
+                 :help "Exit Finder mode"))
+    (define-key menu-map [finder-summary]
+      '(menu-item "Summary" finder-summary
+                 :help "Summary item on current line in a finder buffer"))
+    (define-key menu-map [finder-list-keywords]
+      '(menu-item "List keywords" finder-list-keywords
+                 :help "Display descriptions of the keywords in the Finder buffer"))
+    (define-key menu-map [finder-select]
+      '(menu-item "Select" finder-select
+                 :help "Select item on current line in a finder buffer"))
     map))
 
 (defvar finder-mode-syntax-table
@@ -143,7 +151,7 @@ no arguments compiles from `load-path'."
     (setq buffer-undo-list t)
     (erase-buffer)
     (insert (autoload-rubric generated-finder-keywords-file
-                             "keyword-to-package mapping"))
+                             "keyword-to-package mapping" t))
     (search-backward "\f")
     (insert "(setq finder-package-info '(\n")
     (let (processed summary keywords)
@@ -168,7 +176,7 @@ no arguments compiles from `load-path'."
                            f)))
                 (prin1 summary (current-buffer))
                 (insert "\n        ")
-                (princ keywords (current-buffer))
+                (prin1 (mapcar 'intern keywords) (current-buffer))
                 (insert ")\n")))
            (directory-files d nil
                              ;; Allow compressed files also.  FIXME:
@@ -216,6 +224,29 @@ no arguments compiles from `load-path'."
      '(mouse-face highlight
                  help-echo finder-help-echo))))
 
+(defun finder-unknown-keywords ()
+  "Return an alist of unknown keywords and number of their occurences.
+Unknown are keywords that are present in `finder-package-info'
+but absent in `finder-known-keywords'."
+  (let ((unknown-keywords-hash (make-hash-table)))
+    ;; Prepare a hash where key is a keyword
+    ;; and value is the number of keyword occurences.
+    (mapc (lambda (package)
+           (mapc (lambda (keyword)
+                   (unless (assq keyword finder-known-keywords)
+                     (puthash keyword
+                              (1+ (gethash keyword unknown-keywords-hash 0))
+                              unknown-keywords-hash)))
+                 (nth 2 package)))
+         finder-package-info)
+    ;; Make an alist from the hash and sort by the keyword name.
+    (sort (let (unknown-keywords-list)
+           (maphash (lambda (key value)
+                      (push (cons key value) unknown-keywords-list))
+                    unknown-keywords-hash)
+           unknown-keywords-list)
+         (lambda (a b) (string< (car a) (car b))))))
+
 ;;;###autoload
 (defun finder-list-keywords ()
   "Display descriptions of the keywords in the Finder buffer."
@@ -288,7 +319,6 @@ FILE should be in a form suitable for passing to `locate-library'."
     (or str (error "Can't find any Commentary section"))
     ;; This used to use *Finder* but that would clobber the
     ;; directory of categories.
-    (delete-other-windows)
     (pop-to-buffer "*Finder-package*")
     (setq buffer-read-only nil
           buffer-undo-list t)
@@ -335,8 +365,7 @@ FILE should be in a form suitable for passing to `locate-library'."
 (defun finder-mouse-select (event)
   "Select item in a finder buffer with the mouse."
   (interactive "e")
-  (save-excursion
-    (set-buffer (window-buffer (posn-window (event-start event))))
+  (with-current-buffer (window-buffer (posn-window (event-start event)))
     (goto-char (posn-point (event-start event)))
     (finder-select)))