diff options
| author | Stefan Monnier | 2002-11-19 23:32:54 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-11-19 23:32:54 +0000 |
| commit | a2dff4d3d37616aacf39c1ab5508316c4bc95ff4 (patch) | |
| tree | 6ba517f546a35de37411e61338d20c85a26f7673 | |
| parent | def9389aaa944e1b3b7fe41868af7d4f7b7c23e2 (diff) | |
| download | emacs-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.el | 187 |
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 |