From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tom Tromey Newsgroups: gmane.emacs.devel Subject: Patch: make eldoc indicate current argument Date: Wed, 27 Jun 2007 11:04:08 -0600 Message-ID: Reply-To: tromey@redhat.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1182965063 12676 80.91.229.12 (27 Jun 2007 17:24:23 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 27 Jun 2007 17:24:23 +0000 (UTC) To: Emacs Hackers Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Jun 27 19:24:21 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1I3bFX-0007m9-3E for ged-emacs-devel@m.gmane.org; Wed, 27 Jun 2007 19:24:15 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1I3bFW-0003kg-HE for ged-emacs-devel@m.gmane.org; Wed, 27 Jun 2007 13:24:14 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1I3bF4-0003TJ-Cx for emacs-devel@gnu.org; Wed, 27 Jun 2007 13:23:46 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1I3bF2-0003Sv-Tu for emacs-devel@gnu.org; Wed, 27 Jun 2007 13:23:46 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1I3bF2-0003Ss-Ph for emacs-devel@gnu.org; Wed, 27 Jun 2007 13:23:44 -0400 Original-Received: from mx1.redhat.com ([66.187.233.31]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1I3bF2-0008Vp-Fh for emacs-devel@gnu.org; Wed, 27 Jun 2007 13:23:44 -0400 Original-Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l5RHNh1H024139 for ; Wed, 27 Jun 2007 13:23:43 -0400 Original-Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l5RHNh2K012251 for ; Wed, 27 Jun 2007 13:23:43 -0400 Original-Received: from opsy.redhat.com (ton.toronto.redhat.com [172.16.14.15]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l5RHNgXA005828; Wed, 27 Jun 2007 13:23:42 -0400 Original-Received: by opsy.redhat.com (Postfix, from userid 500) id 3684C3786E5; Wed, 27 Jun 2007 11:04:08 -0600 (MDT) X-Attribution: Tom User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.990 (gnu/linux) X-detected-kernel: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:73932 Archived-At: This patch changes eldoc so that the current argument is highlighted in bold. This is something Eclipse does and I've found it nice to use there. Note that "current" generally means "argument after point" -- this yields the nicest results when typing in new forms, since if you pause you will see what comes next. This patch isn't perfect. There are a few improvements that could be made. However, IMO it is good enough without these. * Emacs formats documentation inconsistently. Some functions use &optional and &rest in their description. Some use "..." appended to an argument name, e.g. "CLAUSES...". And, some use "..." as a standalone argument name (see 'when'). This patch doesn't attempt to deal with all these cases properly. * If the documentation comments had a bit more structure, this could also show the description of the current argument, say as a tooltip. I don't think there is a reliable way to extract this information at present. * It might be nice to show the eldoc just after typing space, without a pause. Currently you must pause briefly to see where you are in the argument list. Tom 2007-06-27 Tom Tromey * emacs-lisp/eldoc.el (eldoc-beginning-of-sexp): Return number of sexps skipped. (eldoc-fnsym-in-current-sexp): Return cons including number of sexps skipped. (eldoc-get-fnsym-args-string): Added 'index' argument. Fontify current argument. (eldoc-print-current-symbol-info): Update. Index: lisp/emacs-lisp/eldoc.el =================================================================== RCS file: /sources/emacs/emacs/lisp/emacs-lisp/eldoc.el,v retrieving revision 1.42 diff -u -r1.42 eldoc.el --- lisp/emacs-lisp/eldoc.el 7 May 2007 01:09:35 -0000 1.42 +++ lisp/emacs-lisp/eldoc.el 27 Jun 2007 17:02:32 -0000 @@ -247,14 +247,18 @@ (if eldoc-documentation-function (eldoc-message (funcall eldoc-documentation-function)) (let* ((current-symbol (eldoc-current-symbol)) - (current-fnsym (eldoc-fnsym-in-current-sexp)) + (sexp-pair (eldoc-fnsym-in-current-sexp)) + (current-fnsym (cdr sexp-pair)) + (current-arg (car sexp-pair)) (doc (cond ((eq current-symbol current-fnsym) - (or (eldoc-get-fnsym-args-string current-fnsym) + (or (eldoc-get-fnsym-args-string current-fnsym + current-arg) (eldoc-get-var-docstring current-symbol))) (t (or (eldoc-get-var-docstring current-symbol) - (eldoc-get-fnsym-args-string current-fnsym)))))) + (eldoc-get-fnsym-args-string current-fnsym + current-arg)))))) (eldoc-message doc)))) ;; This is run from post-command-hook or some idle timer thing, ;; so we need to be careful that errors aren't ignored. @@ -263,7 +267,7 @@ ;; Return a string containing the function parameter list, or 1-line ;; docstring if function is a subr and no arglist is obtainable from the ;; docstring or elsewhere. -(defun eldoc-get-fnsym-args-string (sym) +(defun eldoc-get-fnsym-args-string (sym index) (let ((args nil) (doc nil)) (cond ((not (and sym (symbolp sym) (fboundp sym)))) @@ -279,6 +283,20 @@ (cond (args (setq doc (eldoc-docstring-format-sym-doc sym args)) (eldoc-last-data-store sym doc 'function))) + (when (and doc (> index 0)) + (save-match-data + ;; Perhaps this should recognize argument names that have + ;; trailing "..."s (see 'cond') or standalone "..."s (see + ;; 'when'). Or, maybe Emacs should more strictly follow a + ;; convention. And, perhaps this should use a different + ;; highlight if there are now many actual arguments. + (let ((rx (concat "[(]\\(?:&optional \\|&rest \\)?\\(?:[^ ]* \\(?:&optional \\|&rest \\)?\\)\\{" + (int-to-string (1- index)) + "\\}\\([^ ]*\\)[ )]"))) + (when (string-match rx doc) + (setq doc (substring doc 0)) + (put-text-property (match-beginning 1) (match-end 1) 'face 'bold + doc))))) doc)) ;; Return a string containing a brief (one-line) documentation string for @@ -342,23 +360,27 @@ (defun eldoc-fnsym-in-current-sexp () - (let ((p (point))) - (eldoc-beginning-of-sexp) + (let* ((p (point)) + (n-sexps (eldoc-beginning-of-sexp))) (prog1 ;; Don't do anything if current word is inside a string. (if (= (or (char-after (1- (point))) 0) ?\") nil - (eldoc-current-symbol)) + (cons n-sexps (eldoc-current-symbol))) (goto-char p)))) (defun eldoc-beginning-of-sexp () - (let ((parse-sexp-ignore-comments t)) + (let ((parse-sexp-ignore-comments t) + (count 0)) (condition-case err - (while (progn - (forward-sexp -1) - (or (= (char-before) ?\") - (> (point) (point-min))))) - (error nil)))) + (progn + (while (progn + (forward-sexp -1) + (setq count (1+ count)) + (or (= (char-before) ?\") + (> (point) (point-min))))) + count) + (error count)))) ;; returns nil unless current word is an interned symbol. (defun eldoc-current-symbol ()