[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch: make eldoc indicate current argument

From: Tom Tromey
Subject: Patch: make eldoc indicate current argument
Date: Wed, 27 Jun 2007 11:04:08 -0600
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.990 (gnu/linux)

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

* 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.


2007-06-27  Tom Tromey  <address@hidden>

        * 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)))
                           (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)))))
 ;; 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)))
         ;; Don't do anything if current word is inside a string.
         (if (= (or (char-after (1- (point))) 0) ?\")
-          (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 ()

reply via email to

[Prev in Thread] Current Thread [Next in Thread]