aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2002-11-19 23:32:54 +0000
committerStefan Monnier2002-11-19 23:32:54 +0000
commita2dff4d3d37616aacf39c1ab5508316c4bc95ff4 (patch)
tree6ba517f546a35de37411e61338d20c85a26f7673
parentdef9389aaa944e1b3b7fe41868af7d4f7b7c23e2 (diff)
downloademacs-a2dff4d3d37616aacf39c1ab5508316c4bc95ff4.tar.gz
emacs-a2dff4d3d37616aacf39c1ab5508316c4bc95ff4.zip
(eldoc-print-current-symbol-info):
Turn errors into messages so they don't get ignored. (eldoc-get-fnsym-args-string): Use help-split-fundoc. (eldoc-beginning-of-sexp): Simplify. (eldoc-function-arglist): Remove. (eldoc-function-argstring): Use help-function-arglist instead. (eldoc-function-argstring-from-docstring-method-table) (eldoc-function-argstring-from-docstring): Remove.
-rw-r--r--lisp/emacs-lisp/eldoc.el187
1 files changed, 24 insertions, 163 deletions
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 042b93886cb..ea09720db24 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -7,7 +7,7 @@
7;; Keywords: extensions 7;; Keywords: extensions
8;; Created: 1995-10-06 8;; Created: 1995-10-06
9 9
10;; $Id: eldoc.el,v 1.19 2001/11/16 23:58:48 monnier Exp $ 10;; $Id: eldoc.el,v 1.20 2002/01/08 23:57:30 rms Exp $
11 11
12;; This file is part of GNU Emacs. 12;; This file is part of GNU Emacs.
13 13
@@ -47,6 +47,8 @@
47 47
48;;; Code: 48;;; Code:
49 49
50(require 'help-fns) ;For fundoc-usage handling functions.
51
50;; Use idle timers if available in the version of emacs running. 52;; Use idle timers if available in the version of emacs running.
51;; Please don't change this to use `require'; this package works 53;; Please don't change this to use `require'; this package works
52;; as-is in XEmacs 19.14 and later and I am striving to maintain 54;; as-is in XEmacs 19.14 and later and I am striving to maintain
@@ -283,16 +285,21 @@ With prefix ARG, turn ElDoc mode on if and only if ARG is positive."
283 285
284 286
285(defun eldoc-print-current-symbol-info () 287(defun eldoc-print-current-symbol-info ()
286 (and (eldoc-display-message-p) 288 (condition-case err
287 (let* ((current-symbol (eldoc-current-symbol)) 289 (and (eldoc-display-message-p)
288 (current-fnsym (eldoc-fnsym-in-current-sexp)) 290 (let* ((current-symbol (eldoc-current-symbol))
289 (doc (cond ((eq current-symbol current-fnsym) 291 (current-fnsym (eldoc-fnsym-in-current-sexp))
290 (or (eldoc-get-fnsym-args-string current-fnsym) 292 (doc (cond
291 (eldoc-get-var-docstring current-symbol))) 293 ((eq current-symbol current-fnsym)
292 (t 294 (or (eldoc-get-fnsym-args-string current-fnsym)
293 (or (eldoc-get-var-docstring current-symbol) 295 (eldoc-get-var-docstring current-symbol)))
294 (eldoc-get-fnsym-args-string current-fnsym)))))) 296 (t
295 (eldoc-message doc)))) 297 (or (eldoc-get-var-docstring current-symbol)
298 (eldoc-get-fnsym-args-string current-fnsym))))))
299 (eldoc-message doc)))
300 ;; This is run from post-command-hook or some idle timer thing,
301 ;; so we need to be careful that errors aren't ignored.
302 (error (message "eldoc error: %s" err))))
296 303
297;; Return a string containing the function parameter list, or 1-line 304;; Return a string containing the function parameter list, or 1-line
298;; docstring if function is a subr and no arglist is obtainable from the 305;; docstring if function is a subr and no arglist is obtainable from the
@@ -306,9 +313,10 @@ With prefix ARG, turn ElDoc mode on if and only if ARG is positive."
306 ((and (eq sym (aref eldoc-last-data 0)) 313 ((and (eq sym (aref eldoc-last-data 0))
307 (eq 'function (aref eldoc-last-data 2))) 314 (eq 'function (aref eldoc-last-data 2)))
308 (setq doc (aref eldoc-last-data 1))) 315 (setq doc (aref eldoc-last-data 1)))
309 ((subrp (eldoc-symbol-function sym)) 316 ((setq doc (help-split-fundoc (documentation sym t) sym))
310 (setq args (or (eldoc-function-argstring-from-docstring sym) 317 (setq args (car doc))
311 (eldoc-docstring-first-line (documentation sym t))))) 318 (string-match "\\`[^ )]* ?" args)
319 (setq args (concat "(" (substring args (match-end 0)))))
312 (t 320 (t
313 (setq args (eldoc-function-argstring sym)))) 321 (setq args (eldoc-function-argstring sym))))
314 (cond (args 322 (cond (args
@@ -391,7 +399,7 @@ With prefix ARG, turn ElDoc mode on if and only if ARG is positive."
391 (condition-case err 399 (condition-case err
392 (while (progn 400 (while (progn
393 (forward-sexp -1) 401 (forward-sexp -1)
394 (or (= (or (char-after (1- (point)))) ?\") 402 (or (= (char-before) ?\")
395 (> (point) (point-min))))) 403 (> (point) (point-min)))))
396 (error nil)))) 404 (error nil))))
397 405
@@ -412,24 +420,8 @@ With prefix ARG, turn ElDoc mode on if and only if ARG is positive."
412 (error (setq defn nil)))) 420 (error (setq defn nil))))
413 defn)) 421 defn))
414 422
415(defun eldoc-function-arglist (fn)
416 (let* ((prelim-def (eldoc-symbol-function fn))
417 (def (if (eq (car-safe prelim-def) 'macro)
418 (cdr prelim-def)
419 prelim-def))
420 (arglist (cond ((null def) nil)
421 ((byte-code-function-p def)
422 (cond ((fboundp 'compiled-function-arglist)
423 (funcall 'compiled-function-arglist def))
424 (t
425 (aref def 0))))
426 ((eq (car-safe def) 'lambda)
427 (nth 1 def))
428 (t t))))
429 arglist))
430
431(defun eldoc-function-argstring (fn) 423(defun eldoc-function-argstring (fn)
432 (eldoc-function-argstring-format (eldoc-function-arglist fn))) 424 (eldoc-function-argstring-format (help-function-arglist fn)))
433 425
434(defun eldoc-function-argstring-format (arglist) 426(defun eldoc-function-argstring-format (arglist)
435 (cond ((not (listp arglist)) 427 (cond ((not (listp arglist))
@@ -452,137 +444,6 @@ With prefix ARG, turn ElDoc mode on if and only if ARG is positive."
452 (concat "(" (mapconcat 'identity arglist " ") ")")) 444 (concat "(" (mapconcat 'identity arglist " ") ")"))
453 445
454 446
455;; Alist of predicate/action pairs.
456;; Each member of the list is a sublist consisting of a predicate function
457;; used to determine if the arglist for a function can be found using a
458;; certain pattern, and a function which returns the actual arglist from
459;; that docstring.
460;;
461;; The order in this table is significant, since later predicates may be
462;; more general than earlier ones.
463;;
464;; Compiler note for Emacs/XEmacs versions which support dynamic loading:
465;; these functions will be compiled to bytecode, but can't be lazy-loaded
466;; even if you set byte-compile-dynamic; to do that would require making
467;; them named top-level defuns, which is not particularly desirable either.
468(defvar eldoc-function-argstring-from-docstring-method-table
469 (list
470 ;; Try first searching for args starting with symbol name.
471 ;; This is to avoid matching parenthetical remarks in e.g. sit-for.
472 (list (function (lambda (doc fn)
473 (string-match (format "^(%s[^\n)]*)$" fn) doc)))
474 (function (lambda (doc)
475 ;; end does not include trailing ")" sequence.
476 (let ((end (- (match-end 0) 1)))
477 (if (string-match " +" doc (match-beginning 0))
478 (substring doc (match-end 0) end)
479 "")))))
480
481 ;; Try again not requiring this symbol name in the docstring.
482 ;; This will be the case when looking up aliases.
483 (list (function (lambda (doc fn)
484 ;; save-restriction has a pathological docstring in
485 ;; Emacs/XEmacs 19.
486 (and (not (eq fn 'save-restriction))
487 (string-match "^([^\n)]+)$" doc))))
488 (function (lambda (doc)
489 ;; end does not include trailing ")" sequence.
490 (let ((end (- (match-end 0) 1)))
491 (and (string-match " +" doc (match-beginning 0))
492 (substring doc (match-end 0) end))))))
493
494 ;; Emacs subr docstring style:
495 ;; (fn arg1 arg2 ...): description...
496 (list (function (lambda (doc fn)
497 (string-match "^([^\n)]+):" doc)))
498 (function (lambda (doc)
499 ;; end does not include trailing "):" sequence.
500 (let ((end (- (match-end 0) 2)))
501 (and (string-match " +" doc (match-beginning 0))
502 (substring doc (match-end 0) end))))))
503
504 ;; XEmacs subr docstring style:
505 ;; "arguments: (arg1 arg2 ...)
506 (list (function (lambda (doc fn)
507 (string-match "^arguments: (\\([^\n)]+\\))" doc)))
508 (function (lambda (doc)
509 ;; also skip leading paren, but the first word is
510 ;; actually an argument, not the function name.
511 (substring doc (match-beginning 1) (match-end 1)))))
512
513 ;; This finds the argstring for `condition-case'. Any others?
514 (list (function (lambda (doc fn)
515 (string-match
516 (format "^Usage looks like \\((%s[^\n)]*)\\)\\.$" fn)
517 doc)))
518 (function (lambda (doc)
519 ;; end does not include trailing ")" sequence.
520 (let ((end (- (match-end 1) 1)))
521 (and (string-match " +" doc (match-beginning 1))
522 (substring doc (match-end 0) end))))))
523
524 ;; This finds the argstring for `setq-default'. Any others?
525 (list (function (lambda (doc fn)
526 (string-match (format "^[ \t]+\\((%s[^\n)]*)\\)$" fn)
527 doc)))
528 (function (lambda (doc)
529 ;; end does not include trailing ")" sequence.
530 (let ((end (- (match-end 1) 1)))
531 (and (string-match " +" doc (match-beginning 1))
532 (substring doc (match-end 0) end))))))
533
534 ;; This finds the argstring for `start-process'. Any others?
535 (list (function (lambda (doc fn)
536 (string-match "^Args are +\\([^\n]+\\)$" doc)))
537 (function (lambda (doc)
538 (substring doc (match-beginning 1) (match-end 1)))))
539
540 ;; These common subrs don't have arglists in their docstrings. So cheat.
541 (list (function (lambda (doc fn)
542 (memq fn '(and or list + -))))
543 (function (lambda (doc)
544 ;; The value nil is a placeholder; otherwise, the
545 ;; following string may be compiled as a docstring,
546 ;; and not a return value for the function.
547 ;; In interpreted lisp form they are
548 ;; indistinguishable; it only matters for compiled
549 ;; forms.
550 nil
551 "&rest args")))
552 ))
553
554(defun eldoc-function-argstring-from-docstring (fn)
555 (let ((docstring (documentation fn 'raw))
556 (table eldoc-function-argstring-from-docstring-method-table)
557 (doc nil)
558 (doclist nil))
559 (save-match-data
560 (while table
561 (cond ((funcall (car (car table)) docstring fn)
562 (setq doc (funcall (car (cdr (car table))) docstring))
563 (setq table nil))
564 (t
565 (setq table (cdr table)))))
566
567 (cond ((not (stringp doc))
568 nil)
569 ((string-match "&" doc)
570 (let ((p 0)
571 (l (length doc)))
572 (while (< p l)
573 (cond ((string-match "[ \t\n]+" doc p)
574 (setq doclist
575 (cons (substring doc p (match-beginning 0))
576 doclist))
577 (setq p (match-end 0)))
578 (t
579 (setq doclist (cons (substring doc p) doclist))
580 (setq p l))))
581 (eldoc-function-argstring-format (nreverse doclist))))
582 (t
583 (concat "(" (funcall eldoc-argument-case doc) ")"))))))
584
585
586;; When point is in a sexp, the function args are not reprinted in the echo 447;; When point is in a sexp, the function args are not reprinted in the echo
587;; area after every possible interactive command because some of them print 448;; area after every possible interactive command because some of them print
588;; their own messages in the echo area; the eldoc functions would instantly 449;; their own messages in the echo area; the eldoc functions would instantly