From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Juanma Barranquero Newsgroups: gmane.emacs.devel Subject: Re: Improved help from minibuffer prompts Date: Sat, 01 May 2004 04:17:46 +0200 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <20040501034809.AEC7.LEKTU@mi.madritel.es> References: <20040430232000.AEC0.LEKTU@mi.madritel.es> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1083377992 2125 80.91.224.253 (1 May 2004 02:19:52 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 1 May 2004 02:19:52 +0000 (UTC) Cc: Stefan Monnier Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Sat May 01 04:19:43 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BJk6R-0007lS-00 for ; Sat, 01 May 2004 04:19:43 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BJk6Q-0001Dg-00 for ; Sat, 01 May 2004 04:19:42 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.30) id 1BJk5s-0002uZ-Pd for emacs-devel@quimby.gnus.org; Fri, 30 Apr 2004 22:19:08 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.30) id 1BJk5E-0002sb-0J for emacs-devel@gnu.org; Fri, 30 Apr 2004 22:18:28 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.30) id 1BJk4f-00026N-54 for emacs-devel@gnu.org; Fri, 30 Apr 2004 22:18:26 -0400 Original-Received: from [62.81.186.19] (helo=smtp09.retemail.es) by monty-python.gnu.org with esmtp (Exim 4.30) id 1BJk4e-00022a-GX for emacs-devel@gnu.org; Fri, 30 Apr 2004 22:17:52 -0400 Original-Received: from [127.0.0.1] ([213.37.34.18]) by smtp09.retemail.es (InterMail vM.5.01.05.32 201-253-122-126-132-20030307) with ESMTP id <20040501021750.FTBD25645.smtp09.retemail.es@[127.0.0.1]>; Sat, 1 May 2004 04:17:50 +0200 Original-To: emacs-devel@gnu.org In-Reply-To: X-Mailer: Becky! ver. 2.09.01 [en] X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:22476 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:22476 On 30 Apr 2004 18:49:42 -0400, Stefan Monnier wrote: > Instead, you could hook into describe-function-1 at the place where the > corresponding text is inserted, at which point you know exactly where that > text is, without needing any heuristic. I agree, in principle, and as I said that's what I first tried. The problem is, describe-function-1 is a big hairy function with a complex program flow. For starters, there's not a single place where help-split-fundoc is called inside describe-function-1, but two. There's also a call to help-make-usage, which, to add fun, does not return a string but a list which must be first converted. Additionally, describe-function-1 uses princ to output data to the current buffer, which must be changed to (with-current-buffer standard-output (insert...)) or otherwise the text attributes are lost... All in all, I really doubt the result is easier to understand or maintain. For example, there's a case I've been unable to test, the one corresponding to ((stringp arglist) arglist) in the cond, because I don't know of any such function. AFAICS, the benefits from doing it your way are small: - No heuristics to determine what's a usage doc and what's simply doc. OK, but the format of docs is something we control so we can be reasonably sure it's working, and we can always adapt help-highlight-arguments if necessary. - All functions that use describe-function-1 are automatically highlighted. The fact is that describe-function-1 is not a public function (it has no docstring and it's not included on the Emacs Lisp reference manual); it's only used in describe-function and describe-key. Adding my initial implementation to both is a matter of adding one line to describe-function and two lines to describe-key. I've included below a patch doing it your style (it's a bit weird because I've had to used diff -b to avoid the effects of a reindent of some code). I honestly don't find it more robust or better that the other implementation, but I'll be happy to pursue whatever one is deemed more acceptable. /L/e/k/t/u Index: help-fns.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v retrieving revision 1.40 diff -u -2 -b -r1.40 help-fns.el --- help-fns.el 29 Apr 2004 18:46:13 -0000 1.40 +++ help-fns.el 1 May 2004 01:59:08 -0000 @@ -131,4 +131,39 @@ ;; Functions +(defun help-do-arg-highlight (doc args) + (while args + (let ((arg (car args))) + (setq args (cdr args)) + (setq doc (replace-regexp-in-string (concat "\\<\\(" arg "\\)e?s?\\>") + (propertize arg 'face 'font-lock-variable-name-face) + doc)))) + doc) + +(defun help-highlight-arguments (usage &rest args) + (when usage + (let* ((case-fold-search nil) + (use (car usage)) + (doc (cdr usage)) + (next (not args))) + ;; Make a list of all arguments + (with-temp-buffer + (insert use) + (goto-char (point-min)) + ;; Make a list of all arguments + (while next + (if (not (re-search-forward " \\([\\[(]?\\)\\([^] &)\.]+\\)" nil t)) + (setq next nil) + (setq args (cons (match-string 2) args)) + (when (string= (match-string 1) "(") + ;; A pesky CL-style optional argument with default value, + ;; so let's skip over it + (search-backward "(") + (goto-char (scan-sexps (point) 1))))) + ;; Highlight aguments in the USE string + (setq use (help-do-arg-highlight (buffer-string) args))) + ;; Highlight arguments in the DOC string + (setq doc (and doc (help-do-arg-highlight doc args))) + (cons use doc)))) + ;;;###autoload (defun describe-function (function) @@ -353,10 +390,14 @@ (let* ((arglist (help-function-arglist def)) (doc (documentation function)) - (usage (help-split-fundoc doc function))) + (usage (help-highlight-arguments (help-split-fundoc doc function)))) ;; If definition is a keymap, skip arglist note. (unless (keymapp def) - (princ (cond + (with-current-buffer standard-output + (insert (cond (usage (setq doc (cdr usage)) (car usage)) - ((listp arglist) (help-make-usage function arglist)) + ((listp arglist) + (setq doc (help-highlight-arguments (cons (format "%s" (help-make-usage function arglist)) + doc))) + (prog1 (car doc) (setq doc (cdr doc)))) ((stringp arglist) arglist) ;; Maybe the arglist is in the docstring of the alias. @@ -367,10 +408,10 @@ (documentation fun) function))))) - usage) + (setq usage (help-highlight-arguments usage))) (car usage)) ((or (stringp def) (vectorp def)) (format "\nMacro: %s" (format-kbd-macro def))) - (t "[Missing arglist. Please make a bug report.]"))) + (t "[Missing arglist. Please make a bug report.]")))) (terpri)) (let ((obsolete (and @@ -387,5 +428,6 @@ (terpri))) (terpri) - (princ (or doc "Not documented."))))) + (with-current-buffer standard-output + (insert (or doc "Not documented."))))))