diff options
| author | Noah Friedman | 1998-09-19 02:15:26 +0000 |
|---|---|---|
| committer | Noah Friedman | 1998-09-19 02:15:26 +0000 |
| commit | 44faf981957e153483a535c9968f2b7b0e5654b0 (patch) | |
| tree | 3724655588ac80a399a98faaf11eee0168b03481 /lisp | |
| parent | d71de6f99e05b791244ea68e957bcbbbd2005a98 (diff) | |
| download | emacs-44faf981957e153483a535c9968f2b7b0e5654b0.tar.gz emacs-44faf981957e153483a535c9968f2b7b0e5654b0.zip | |
(eldoc-message): Check for 1-arg case, and store string in
eldoc-last-message without consing a new string.
Rearrange logic from nested if's into cond's.
(eldoc-print-fnsym-args): Renamed to eldoc-get-fnsym-args-string.
Do not print message; just return string.
(eldoc-get-var-docstring): Renamed from eldoc-print-var-docstring.
Do not print message; just return string.
Cache that string in eldoc-last-data.
(eldoc-last-data): Make into a vector.
(eldoc-get-fnsym-args-string): Use new data form of structure.
(eldoc-get-var-docstring): Here also.
(eldoc-last-data-store): New function.
(eldoc-get-fnsym-args-string): Use it.
(eldoc-get-var-docstring): Here also.
(eldoc-docstring-first-line): Minimize interim string consing.
Call substitute-command-keys on the result.
(eldoc-print-var-docstrings, eldoc-print-docstring,
eldoc-docstring-message): Functions removed.
(eldoc-docstring-format-sym-doc): New function, functionality ripped out of
eldoc-docstring-message.
(eldoc-get-fnsym-args-string, eldoc-get-var-docstring): Use it.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/eldoc.el | 230 |
1 files changed, 126 insertions, 104 deletions
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 1a2d3c7ee37..f294ddbfe8d 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | ;;; eldoc.el --- show function arglist or variable docstring in echo area | 1 | ;;; eldoc.el --- show function arglist or variable docstring in echo area |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Noah Friedman <friedman@prep.ai.mit.edu> | 5 | ;; Author: Noah Friedman <friedman@splode.com> |
| 6 | ;; Maintainer: friedman@prep.ai.mit.edu | 6 | ;; Maintainer: friedman@splode.com |
| 7 | ;; Keywords: extensions | 7 | ;; Keywords: extensions |
| 8 | ;; Created: 1995-10-06 | 8 | ;; Created: 1995-10-06 |
| 9 | 9 | ||
| 10 | ;; $Id: eldoc.el,v 1.13 1997/05/22 06:47:41 friedman Exp $ | 10 | ;; $Id: eldoc.el,v 1.14 1997/07/09 12:44:15 friedman Exp $ |
| 11 | 11 | ||
| 12 | ;; This file is part of GNU Emacs. | 12 | ;; This file is part of GNU Emacs. |
| 13 | 13 | ||
| @@ -123,10 +123,12 @@ returns another string is acceptable." | |||
| 123 | ;; Remember to keep it a prime number to improve hash performance. | 123 | ;; Remember to keep it a prime number to improve hash performance. |
| 124 | (defvar eldoc-message-commands-table-size 31) | 124 | (defvar eldoc-message-commands-table-size 31) |
| 125 | 125 | ||
| 126 | ;; Bookkeeping; the car contains the last symbol read from the buffer. | 126 | ;; Bookkeeping; elements are as follows: |
| 127 | ;; The cdr contains the string last displayed in the echo area, so it can | 127 | ;; 0 - contains the last symbol read from the buffer. |
| 128 | ;; be printed again if necessary without reconsing. | 128 | ;; 1 - contains the string last displayed in the echo area for that |
| 129 | (defvar eldoc-last-data (cons nil nil)) | 129 | ;; symbol, so it can be printed again if necessary without reconsing. |
| 130 | ;; 2 - 'function if function args, 'variable if variable documentation. | ||
| 131 | (defvar eldoc-last-data (make-vector 3 nil)) | ||
| 130 | (defvar eldoc-last-message nil) | 132 | (defvar eldoc-last-message nil) |
| 131 | 133 | ||
| 132 | ;; Idle timers are supported in Emacs 19.31 and later. | 134 | ;; Idle timers are supported in Emacs 19.31 and later. |
| @@ -182,6 +184,7 @@ the mode, respectively." | |||
| 182 | (interactive) | 184 | (interactive) |
| 183 | (eldoc-mode 1)) | 185 | (eldoc-mode 1)) |
| 184 | 186 | ||
| 187 | |||
| 185 | ;; Idle timers are part of Emacs 19.31 and later. | 188 | ;; Idle timers are part of Emacs 19.31 and later. |
| 186 | (defun eldoc-schedule-timer () | 189 | (defun eldoc-schedule-timer () |
| 187 | (or (and eldoc-timer | 190 | (or (and eldoc-timer |
| @@ -195,54 +198,48 @@ the mode, respectively." | |||
| 195 | (setq eldoc-current-idle-delay eldoc-idle-delay) | 198 | (setq eldoc-current-idle-delay eldoc-idle-delay) |
| 196 | (timer-set-idle-time eldoc-timer eldoc-idle-delay t)))) | 199 | (timer-set-idle-time eldoc-timer eldoc-idle-delay t)))) |
| 197 | 200 | ||
| 198 | ;; This function goes on pre-command-hook for XEmacs or when using idle | ||
| 199 | ;; timers in Emacs. Motion commands clear the echo area for some reason, | ||
| 200 | ;; which make eldoc messages flicker or disappear just before motion | ||
| 201 | ;; begins. This function reprints the last eldoc message immediately | ||
| 202 | ;; before the next command executes, which does away with the flicker. | ||
| 203 | ;; This doesn't seem to be required for Emacs 19.28 and earlier. | ||
| 204 | (defun eldoc-pre-command-refresh-echo-area () | ||
| 205 | (and eldoc-last-message | ||
| 206 | (if (eldoc-display-message-no-interference-p) | ||
| 207 | (eldoc-message eldoc-last-message) | ||
| 208 | (setq eldoc-last-message nil)))) | ||
| 209 | |||
| 210 | (defun eldoc-message (&rest args) | 201 | (defun eldoc-message (&rest args) |
| 211 | (let ((omessage eldoc-last-message)) | 202 | (let ((omessage eldoc-last-message)) |
| 212 | (cond ((eq (car args) eldoc-last-message)) | 203 | (cond ((eq (car args) eldoc-last-message)) |
| 213 | ((or (null args) | 204 | ((or (null args) |
| 214 | (null (car args))) | 205 | (null (car args))) |
| 215 | (setq eldoc-last-message nil)) | 206 | (setq eldoc-last-message nil)) |
| 207 | ;; If only one arg, no formatting to do so put it in | ||
| 208 | ;; eldoc-last-message so eq test above might succeed on | ||
| 209 | ;; subsequent calls. | ||
| 210 | ((null (cdr args)) | ||
| 211 | (setq eldoc-last-message (car args))) | ||
| 216 | (t | 212 | (t |
| 217 | (setq eldoc-last-message (apply 'format args)))) | 213 | (setq eldoc-last-message (apply 'format args)))) |
| 218 | ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages | 214 | ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages |
| 219 | ;; are recorded in a log. Do not put eldoc messages in that log since | 215 | ;; are recorded in a log. Do not put eldoc messages in that log since |
| 220 | ;; they are Legion. | 216 | ;; they are Legion. |
| 221 | (if (fboundp 'display-message) | 217 | (cond ((fboundp 'display-message) |
| 222 | ;; XEmacs 19.13 way of preventing log messages. | 218 | ;; XEmacs 19.13 way of preventing log messages. |
| 223 | (if eldoc-last-message | 219 | (cond (eldoc-last-message |
| 224 | (display-message 'no-log eldoc-last-message) | 220 | (display-message 'no-log eldoc-last-message)) |
| 225 | (and omessage | 221 | (omessage |
| 226 | (clear-message 'no-log))) | 222 | (clear-message 'no-log)))) |
| 227 | (let ((message-log-max nil)) | 223 | (t |
| 228 | (if eldoc-last-message | 224 | ;; Emacs way of preventing log messages. |
| 229 | (message "%s" eldoc-last-message) | 225 | (let ((message-log-max nil)) |
| 230 | (and omessage | 226 | (cond (eldoc-last-message |
| 231 | (message nil)))))) | 227 | (message "%s" eldoc-last-message)) |
| 228 | (omessage | ||
| 229 | (message nil))))))) | ||
| 232 | eldoc-last-message) | 230 | eldoc-last-message) |
| 233 | 231 | ||
| 234 | 232 | ;; This function goes on pre-command-hook for XEmacs or when using idle | |
| 235 | (defun eldoc-print-current-symbol-info () | 233 | ;; timers in Emacs. Motion commands clear the echo area for some reason, |
| 236 | (and (eldoc-display-message-p) | 234 | ;; which make eldoc messages flicker or disappear just before motion |
| 237 | (let ((current-symbol (eldoc-current-symbol)) | 235 | ;; begins. This function reprints the last eldoc message immediately |
| 238 | (current-fnsym (eldoc-fnsym-in-current-sexp))) | 236 | ;; before the next command executes, which does away with the flicker. |
| 239 | (or (cond ((eq current-symbol current-fnsym) | 237 | ;; This doesn't seem to be required for Emacs 19.28 and earlier. |
| 240 | (or (eldoc-print-fnsym-args current-fnsym) | 238 | (defun eldoc-pre-command-refresh-echo-area () |
| 241 | (eldoc-print-var-docstring current-symbol))) | 239 | (and eldoc-last-message |
| 242 | (t | 240 | (if (eldoc-display-message-no-interference-p) |
| 243 | (or (eldoc-print-var-docstring current-symbol) | 241 | (eldoc-message eldoc-last-message) |
| 244 | (eldoc-print-fnsym-args current-fnsym)))) | 242 | (setq eldoc-last-message nil)))) |
| 245 | (eldoc-message nil))))) | ||
| 246 | 243 | ||
| 247 | ;; Decide whether now is a good time to display a message. | 244 | ;; Decide whether now is a good time to display a message. |
| 248 | (defun eldoc-display-message-p () | 245 | (defun eldoc-display-message-p () |
| @@ -274,26 +271,98 @@ the mode, respectively." | |||
| 274 | (not cursor-in-echo-area) | 271 | (not cursor-in-echo-area) |
| 275 | (not (eq (selected-window) (minibuffer-window))))) | 272 | (not (eq (selected-window) (minibuffer-window))))) |
| 276 | 273 | ||
| 277 | (defun eldoc-print-fnsym-args (sym) | 274 | |
| 278 | (interactive) | 275 | (defun eldoc-print-current-symbol-info () |
| 279 | (let ((args nil)) | 276 | (and (eldoc-display-message-p) |
| 277 | (let* ((current-symbol (eldoc-current-symbol)) | ||
| 278 | (current-fnsym (eldoc-fnsym-in-current-sexp)) | ||
| 279 | (doc (cond ((eq current-symbol current-fnsym) | ||
| 280 | (or (eldoc-get-fnsym-args-string current-fnsym) | ||
| 281 | (eldoc-get-var-docstring current-symbol))) | ||
| 282 | (t | ||
| 283 | (or (eldoc-get-var-docstring current-symbol) | ||
| 284 | (eldoc-get-fnsym-args-string current-fnsym)))))) | ||
| 285 | (eldoc-message doc)))) | ||
| 286 | |||
| 287 | ;; Return a string containing the function parameter list, or 1-line | ||
| 288 | ;; docstring if function is a subr and no arglist is obtainable from the | ||
| 289 | ;; docstring or elsewhere. | ||
| 290 | (defun eldoc-get-fnsym-args-string (sym) | ||
| 291 | (let ((args nil) | ||
| 292 | (doc nil)) | ||
| 280 | (cond ((not (and sym | 293 | (cond ((not (and sym |
| 281 | (symbolp sym) | 294 | (symbolp sym) |
| 282 | (fboundp sym)))) | 295 | (fboundp sym)))) |
| 283 | ((eq sym (car eldoc-last-data)) | 296 | ((and (eq sym (aref eldoc-last-data 0)) |
| 284 | (setq args (cdr eldoc-last-data))) | 297 | (eq 'function (aref eldoc-last-data 2))) |
| 298 | (setq doc (aref eldoc-last-data 1))) | ||
| 285 | ((subrp (eldoc-symbol-function sym)) | 299 | ((subrp (eldoc-symbol-function sym)) |
| 286 | (setq args (or (eldoc-function-argstring-from-docstring sym) | 300 | (setq args (or (eldoc-function-argstring-from-docstring sym) |
| 287 | (eldoc-docstring-first-line (documentation sym t)))) | 301 | (eldoc-docstring-first-line (documentation sym t))))) |
| 288 | (setcar eldoc-last-data sym) | ||
| 289 | (setcdr eldoc-last-data args)) | ||
| 290 | (t | 302 | (t |
| 291 | (setq args (eldoc-function-argstring sym)) | 303 | (setq args (eldoc-function-argstring sym)))) |
| 292 | (setcar eldoc-last-data sym) | 304 | (cond (args |
| 293 | (setcdr eldoc-last-data args))) | 305 | (setq doc (eldoc-docstring-format-sym-doc sym args)) |
| 294 | (and args | 306 | (eldoc-last-data-store sym doc 'function))) |
| 295 | (eldoc-message "%s: %s" sym args)))) | 307 | doc)) |
| 308 | |||
| 309 | ;; Return a string containing a brief (one-line) documentation string for | ||
| 310 | ;; the variable. | ||
| 311 | (defun eldoc-get-var-docstring (sym) | ||
| 312 | (cond ((and (eq sym (aref eldoc-last-data 0)) | ||
| 313 | (eq 'variable (aref eldoc-last-data 2))) | ||
| 314 | (aref eldoc-last-data 1)) | ||
| 315 | (t | ||
| 316 | (let ((doc (documentation-property sym 'variable-documentation t))) | ||
| 317 | (cond (doc | ||
| 318 | (setq doc (eldoc-docstring-format-sym-doc | ||
| 319 | sym (eldoc-docstring-first-line doc))) | ||
| 320 | (eldoc-last-data-store sym doc 'variable))) | ||
| 321 | doc)))) | ||
| 322 | |||
| 323 | (defun eldoc-last-data-store (symbol doc type) | ||
| 324 | (aset eldoc-last-data 0 symbol) | ||
| 325 | (aset eldoc-last-data 1 doc) | ||
| 326 | (aset eldoc-last-data 2 type)) | ||
| 327 | |||
| 328 | ;; Note that any leading `*' in the docstring (which indicates the variable | ||
| 329 | ;; is a user option) is removed. | ||
| 330 | (defun eldoc-docstring-first-line (doc) | ||
| 331 | (and (stringp doc) | ||
| 332 | (substitute-command-keys | ||
| 333 | (save-match-data | ||
| 334 | (let ((start (if (string-match "^\\*" doc) (match-end 0) 0))) | ||
| 335 | (cond ((string-match "\n" doc) | ||
| 336 | (substring doc start (match-beginning 0))) | ||
| 337 | ((zerop start) doc) | ||
| 338 | (t (substring doc start)))))))) | ||
| 339 | |||
| 340 | ;; If the entire line cannot fit in the echo area, the symbol name may be | ||
| 341 | ;; truncated or eliminated entirely from the output to make room for the | ||
| 342 | ;; description. | ||
| 343 | (defun eldoc-docstring-format-sym-doc (sym doc) | ||
| 344 | (save-match-data | ||
| 345 | (let* ((name (symbol-name sym)) | ||
| 346 | (doclen (+ (length name) (length ": ") (length doc))) | ||
| 347 | ;; Subtract 1 from window width since emacs seems not to write | ||
| 348 | ;; any chars to the last column, at least for some terminal types. | ||
| 349 | (strip (- doclen (1- (window-width (minibuffer-window)))))) | ||
| 350 | (cond ((> strip 0) | ||
| 351 | (let* ((len (length name))) | ||
| 352 | (cond ((>= strip len) | ||
| 353 | (format "%s" doc)) | ||
| 354 | (t | ||
| 355 | ;;(setq name (substring name 0 (- len strip))) | ||
| 356 | ;; | ||
| 357 | ;; Show the end of the partial symbol name, rather | ||
| 358 | ;; than the beginning, since the former is more likely | ||
| 359 | ;; to be unique given package namespace conventions. | ||
| 360 | (setq name (substring name strip)) | ||
| 361 | (format "%s: %s" name doc))))) | ||
| 362 | (t | ||
| 363 | (format "%s: %s" sym doc)))))) | ||
| 296 | 364 | ||
| 365 | |||
| 297 | (defun eldoc-fnsym-in-current-sexp () | 366 | (defun eldoc-fnsym-in-current-sexp () |
| 298 | (let ((p (point))) | 367 | (let ((p (point))) |
| 299 | (eldoc-beginning-of-sexp) | 368 | (eldoc-beginning-of-sexp) |
| @@ -366,54 +435,6 @@ the mode, respectively." | |||
| 366 | (concat "(" (mapconcat 'identity arglist " ") ")")) | 435 | (concat "(" (mapconcat 'identity arglist " ") ")")) |
| 367 | 436 | ||
| 368 | 437 | ||
| 369 | (defun eldoc-print-var-docstring (sym) | ||
| 370 | (eldoc-print-docstring sym (documentation-property | ||
| 371 | sym 'variable-documentation t))) | ||
| 372 | |||
| 373 | ;; Print the brief (one-line) documentation string for the symbol. | ||
| 374 | (defun eldoc-print-docstring (symbol doc) | ||
| 375 | (and doc | ||
| 376 | (eldoc-message "%s" (eldoc-docstring-message symbol doc)))) | ||
| 377 | |||
| 378 | ;; If the entire line cannot fit in the echo area, the variable name may be | ||
| 379 | ;; truncated or eliminated entirely from the output to make room. | ||
| 380 | ;; Any leading `*' in the docstring (which indicates the variable is a user | ||
| 381 | ;; option) is not printed." | ||
| 382 | (defun eldoc-docstring-message (symbol doc) | ||
| 383 | (and doc | ||
| 384 | (let ((name (symbol-name symbol))) | ||
| 385 | (setq doc (eldoc-docstring-first-line doc)) | ||
| 386 | (save-match-data | ||
| 387 | (let* ((doclen (+ (length name) (length ": ") (length doc))) | ||
| 388 | ;; Subtract 1 from window width since emacs seems not to | ||
| 389 | ;; write any chars to the last column, at least for some | ||
| 390 | ;; terminal types. | ||
| 391 | (strip (- doclen (1- (window-width (minibuffer-window)))))) | ||
| 392 | (cond ((> strip 0) | ||
| 393 | (let* ((len (length name))) | ||
| 394 | (cond ((>= strip len) | ||
| 395 | (format "%s" doc)) | ||
| 396 | (t | ||
| 397 | ;;(setq name (substring name 0 (- len strip))) | ||
| 398 | ;; | ||
| 399 | ;; Show the end of the partial variable name, | ||
| 400 | ;; rather than the beginning, since the former | ||
| 401 | ;; is more likely to be unique given package | ||
| 402 | ;; namespace conventions. | ||
| 403 | (setq name (substring name strip)) | ||
| 404 | (format "%s: %s" name doc))))) | ||
| 405 | (t | ||
| 406 | (format "%s: %s" symbol doc)))))))) | ||
| 407 | |||
| 408 | (defun eldoc-docstring-first-line (doc) | ||
| 409 | (save-match-data | ||
| 410 | (and (string-match "\n" doc) | ||
| 411 | (setq doc (substring doc 0 (match-beginning 0)))) | ||
| 412 | (and (string-match "^\\*" doc) | ||
| 413 | (setq doc (substring doc 1)))) | ||
| 414 | doc) | ||
| 415 | |||
| 416 | |||
| 417 | ;; Alist of predicate/action pairs. | 438 | ;; Alist of predicate/action pairs. |
| 418 | ;; Each member of the list is a sublist consisting of a predicate function | 439 | ;; Each member of the list is a sublist consisting of a predicate function |
| 419 | ;; used to determine if the arglist for a function can be found using a | 440 | ;; used to determine if the arglist for a function can be found using a |
| @@ -598,6 +619,7 @@ the mode, respectively." | |||
| 598 | (all-completions (car names) eldoc-message-commands)) | 619 | (all-completions (car names) eldoc-message-commands)) |
| 599 | (setq names (cdr names)))) | 620 | (setq names (cdr names)))) |
| 600 | 621 | ||
| 622 | |||
| 601 | ;; Prime the command list. | 623 | ;; Prime the command list. |
| 602 | (eldoc-add-command-completions | 624 | (eldoc-add-command-completions |
| 603 | "backward-" "beginning-of-" "delete-other-windows" "delete-window" | 625 | "backward-" "beginning-of-" "delete-other-windows" "delete-window" |