From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: storm@cua.dk (Kim F. Storm) Newsgroups: gmane.emacs.devel Subject: Apropos commands and regexps Date: 12 May 2002 02:57:20 +0200 Sender: emacs-devel-admin@gnu.org Message-ID: <5xg00y41zj.fsf@kfs2.cua.dk> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1021161462 6699 127.0.0.1 (11 May 2002 23:57:42 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sat, 11 May 2002 23:57:42 +0000 (UTC) Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 176gkA-0001jw-00 for ; Sun, 12 May 2002 01:57:42 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 176gty-00064t-00 for ; Sun, 12 May 2002 02:07:50 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 176gjo-0000hD-00; Sat, 11 May 2002 19:57:20 -0400 Original-Received: from fepb.post.tele.dk ([195.41.46.145]) by fencepost.gnu.org with smtp (Exim 3.34 #1 (Debian)) id 176gj8-0000g7-00 for ; Sat, 11 May 2002 19:56:38 -0400 Original-Received: from kfs2.cua.dk.cua.dk ([80.62.38.68]) by fepB.post.tele.dk (InterMail vM.4.01.03.23 201-229-121-123-20010418) with SMTP id <20020511235634.LSJQ19716.fepB.post.tele.dk@kfs2.cua.dk.cua.dk> for ; Sun, 12 May 2002 01:56:34 +0200 Original-To: emacs-devel@gnu.org Original-Lines: 136 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2.50 Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.9 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:3847 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:3847 I was thinking about the use of regexps in connection with the various apropos commands. We often advise new users to use e.g. C-h a or M-x apropos (also accessible through the Help menu). However, these commands prompts like this: Apropos command (regexp): which may be nonsense to some novice users. Wouldn't it be simpler (for a novice user -- and for advanced users too) to simply write one or more words (substrings) and then search for all combinations of those words (substrings) in the relevant list. E.g. C-h a open file RET would find any matching open.*file and file.*open BTW, this obvious example doesn't find `find-file' :-( Maybe we should have a defalias open-file -> find-file ? Of course, if the input is already a regexp (e.g. if it does not contain any spaces), it should be used directly. Below is a patch to show the concept: Index: apropos.el =================================================================== RCS file: /cvs/emacs/lisp/apropos.el,v retrieving revision 1.84 diff -c -r1.84 apropos.el *** apropos.el 4 May 2002 14:51:16 -0000 1.84 --- apropos.el 11 May 2002 23:55:10 -0000 *************** *** 122,127 **** --- 122,130 ---- (defvar apropos-regexp nil "Regexp used in current apropos run.") + (defvar apropos-orig-regexp nil + "Regexp as entered by user.") + (defvar apropos-files-scanned () "List of elc files already scanned in current run of `apropos-documentation'.") *************** *** 219,224 **** --- 222,245 ---- (and label button))) + (defun apropos-rewrite-regexp (regexp) + "Rewrite a list of words to a regexp matching all permutations. + If REGEXP is already a regexp, don't modify it." + (setq apropos-orig-regexp regexp) + (if (and (string-match " " regexp) + (string-equal (regexp-quote regexp) regexp)) + ;; We don't actually make a regexp matching all permutations. + ;; Instead, for e.g. "a b c", we make a regexp matching + ;; any combination of two or more words like this: + ;; (a|b|c).*(a|b|c) which may give some false matches, + ;; but as long as it also gives the right ones, that's ok. + (let ((words (split-string regexp "[ \t]+")) + res) + (dolist (w words) + (setq res (concat (or res "\\(") (if res "\\|" "") w))) + (concat res "\\).*" res "\\)")) + regexp)) + ;;;###autoload (define-derived-mode apropos-mode fundamental-mode "Apropos" "Major mode for following hyperlinks in output of apropos commands. *************** *** 262,267 **** --- 283,289 ---- "or function ") "(regexp): ")) current-prefix-arg)) + (setq apropos-regexp (apropos-rewrite-regexp apropos-regexp)) (let ((message (let ((standard-output (get-buffer-create "*Apropos*"))) (print-help-return-message 'identity)))) *************** *** 304,309 **** --- 326,332 ---- show unbound symbols and key bindings, which is a little more time-consuming. Returns list of symbols and documentation found." (interactive "sApropos symbol (regexp): \nP") + (setq apropos-regexp (apropos-rewrite-regexp apropos-regexp)) (setq apropos-accumulator (apropos-internal apropos-regexp (and (not do-all) *************** *** 371,376 **** --- 394,400 ---- at the function and at the names and values of properties. Returns list of symbols and values found." (interactive "sApropos value (regexp): \nP") + (setq apropos-regexp (apropos-rewrite-regexp apropos-regexp)) (or do-all (setq do-all apropos-do-all)) (setq apropos-accumulator ()) (let (f v p) *************** *** 397,402 **** --- 421,427 ---- bindings. Returns list of symbols and documentation found." (interactive "sApropos documentation (regexp): \nP") + (setq apropos-regexp (apropos-rewrite-regexp apropos-regexp)) (or do-all (setq do-all apropos-do-all)) (setq apropos-accumulator () apropos-files-scanned ()) (let ((standard-input (get-buffer-create " apropos-temp")) *************** *** 590,596 **** If SPACING is non-nil, it should be a string; separate items with that string." (if (null apropos-accumulator) ! (message "No apropos matches for `%s'" apropos-regexp) (setq apropos-accumulator (sort apropos-accumulator (lambda (a b) (string-lessp (car a) (car b))))) --- 615,621 ---- If SPACING is non-nil, it should be a string; separate items with that string." (if (null apropos-accumulator) ! (message "No apropos matches for `%s'" apropos-orig-regexp) (setq apropos-accumulator (sort apropos-accumulator (lambda (a b) (string-lessp (car a) (car b))))) -- Kim F. Storm http://www.cua.dk