Mercurial > hg > xemacs-beta
comparison lisp/utils/eldoc.el @ 24:4103f0995bd7 r19-15b95
Import from CVS: tag r19-15b95
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:51:03 +0200 |
parents | 8fc7fe29b841 |
children |
comparison
equal
deleted
inserted
replaced
23:0edd3412f124 | 24:4103f0995bd7 |
---|---|
5 ;; Author: Noah Friedman <friedman@prep.ai.mit.edu> | 5 ;; Author: Noah Friedman <friedman@prep.ai.mit.edu> |
6 ;; Maintainer: friedman@prep.ai.mit.edu | 6 ;; Maintainer: friedman@prep.ai.mit.edu |
7 ;; Keywords: extensions | 7 ;; Keywords: extensions |
8 ;; Created: 1995-10-06 | 8 ;; Created: 1995-10-06 |
9 | 9 |
10 ;; $Id: eldoc.el,v 1.1 1997/02/14 20:00:10 steve Exp $ | 10 ;; $Id: eldoc.el,v 1.2 1997/02/22 22:08:00 steve Exp $ |
11 | 11 |
12 ;; This file is part of GNU Emacs. | 12 ;; This file is part of GNU Emacs. |
13 | 13 |
14 ;; GNU Emacs is free software; you can redistribute it and/or modify | 14 ;; GNU Emacs is free software; you can redistribute it and/or modify |
15 ;; it under the terms of the GNU General Public License as published by | 15 ;; it under the terms of the GNU General Public License as published by |
41 ;; .emacs: | 41 ;; .emacs: |
42 ;; | 42 ;; |
43 ;; (autoload 'turn-on-eldoc-mode "eldoc" nil t) | 43 ;; (autoload 'turn-on-eldoc-mode "eldoc" nil t) |
44 ;; (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) | 44 ;; (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) |
45 ;; (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode) | 45 ;; (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode) |
46 ;; (add-hook 'ielm-mode-hook 'turn-on-eldoc-mode) | |
46 | 47 |
47 ;;; Code: | 48 ;;; Code: |
48 | 49 |
49 ;; Use idle timers if available in the version of emacs running. | 50 ;; Use idle timers if available in the version of emacs running. |
50 ;; Please don't change this to use `require'; this package works as-is in | 51 ;; Please don't change this to use `require'; this package works as-is in |
89 "Case to display argument names of functions, as a symbol. | 90 "Case to display argument names of functions, as a symbol. |
90 This has two preferred values: `upcase' or `downcase'. | 91 This has two preferred values: `upcase' or `downcase'. |
91 Actually, any name of a function which takes a string as an argument and | 92 Actually, any name of a function which takes a string as an argument and |
92 returns another string is acceptable.") | 93 returns another string is acceptable.") |
93 | 94 |
95 ;; No user options below here. | |
96 | |
94 (defvar eldoc-message-commands nil | 97 (defvar eldoc-message-commands nil |
95 "*Commands after which it is appropriate to print in the echo area. | 98 "Commands after which it is appropriate to print in the echo area. |
96 | 99 |
97 Eldoc does not try to print function arglists, etc. after just any command, | 100 Eldoc does not try to print function arglists, etc. after just any command, |
98 because some commands print their own messages in the echo area and these | 101 because some commands print their own messages in the echo area and these |
99 functions would instantly overwrite them. But self-insert-command as well | 102 functions would instantly overwrite them. But self-insert-command as well |
100 as most motion commands are good candidates. | 103 as most motion commands are good candidates. |
101 | 104 |
102 This variable contains an obarray of symbols; it is probably best to | 105 This variable contains an obarray of symbols; do not manipulate it |
103 manipulate this data structure with the commands `eldoc-add-command' and | 106 directly. Instead, use the functions `eldoc-add-command' and |
104 `eldoc-remove-command'.") | 107 `eldoc-remove-command'.") |
105 | 108 |
106 (cond ((null eldoc-message-commands) | 109 ;; This is used by eldoc-add-command to initialize eldoc-message-commands |
107 ;; If you increase the number of buckets, keep it a prime number. | 110 ;; as an obarray. |
108 (setq eldoc-message-commands (make-vector 31 0)) | 111 ;; If you increase the number of buckets, keep it a prime number. |
109 (let ((list '("self-insert-command" | 112 (defconst eldoc-message-commands-table-size 31) |
110 "next-" "previous-" | |
111 "forward-" "backward-" | |
112 "beginning-of-" "end-of-" | |
113 "goto-" | |
114 "recenter" | |
115 "scroll-" | |
116 "mouse-set-point")) | |
117 (syms nil)) | |
118 (while list | |
119 (setq syms (all-completions (car list) obarray 'fboundp)) | |
120 (setq list (cdr list)) | |
121 (while syms | |
122 (set (intern (car syms) eldoc-message-commands) t) | |
123 (setq syms (cdr syms))))))) | |
124 | 113 |
125 ;; Bookkeeping; the car contains the last symbol read from the buffer. | 114 ;; Bookkeeping; the car contains the last symbol read from the buffer. |
126 ;; The cdr contains the string last displayed in the echo area, so it can | 115 ;; The cdr contains the string last displayed in the echo area, so it can |
127 ;; be printed again if necessary without reconsing. | 116 ;; be printed again if necessary without reconsing. |
128 (defvar eldoc-last-data '(nil . nil)) | 117 (defvar eldoc-last-data '(nil . nil)) |
118 (defvar eldoc-last-message nil) | |
129 | 119 |
130 ;; Idle timers are supported in Emacs 19.31 and later. | 120 ;; Idle timers are supported in Emacs 19.31 and later. |
131 (defconst eldoc-use-idle-timer-p (fboundp 'run-with-idle-timer)) | 121 (defconst eldoc-use-idle-timer-p (fboundp 'run-with-idle-timer)) |
132 | 122 |
133 ;; eldoc's timer object, if using idle timers | 123 ;; eldoc's timer object, if using idle timers |
134 (defvar eldoc-timer nil) | 124 (defvar eldoc-timer nil) |
135 | 125 |
136 ;; idle time delay currently in use by timer. | 126 ;; idle time delay currently in use by timer. |
137 ;; This is used to determine if eldoc-idle-delay is changed by the user. | 127 ;; This is used to determine if eldoc-idle-delay is changed by the user. |
138 (defvar eldoc-current-idle-delay eldoc-idle-delay) | 128 (defvar eldoc-current-idle-delay eldoc-idle-delay) |
139 | |
140 ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages are | |
141 ;; recorded in a log. Do not put eldoc messages in that log since | |
142 ;; they are Legion. | |
143 (defmacro eldoc-message (&rest args) | |
144 (if (fboundp 'display-message) | |
145 ;; XEmacs 19.13 way of preventing log messages. | |
146 (list 'display-message '(quote no-log) (apply 'list 'format args)) | |
147 (list 'let (list (list 'message-log-max 'nil)) | |
148 (apply 'list 'message args)))) | |
149 | 129 |
150 | 130 |
151 ;;;###autoload | 131 ;;;###autoload |
152 (defun eldoc-mode (&optional prefix) | 132 (defun eldoc-mode (&optional prefix) |
153 "*Enable or disable eldoc mode. | 133 "*Enable or disable eldoc mode. |
156 If called interactively with no prefix argument, toggle current condition | 136 If called interactively with no prefix argument, toggle current condition |
157 of the mode. | 137 of the mode. |
158 If called with a positive or negative prefix argument, enable or disable | 138 If called with a positive or negative prefix argument, enable or disable |
159 the mode, respectively." | 139 the mode, respectively." |
160 (interactive "P") | 140 (interactive "P") |
161 | 141 (setq eldoc-last-message nil) |
162 (cond (eldoc-use-idle-timer-p | 142 (cond (eldoc-use-idle-timer-p |
163 (add-hook 'post-command-hook 'eldoc-schedule-timer)) | 143 (add-hook 'post-command-hook 'eldoc-schedule-timer) |
144 (add-hook 'pre-command-hook 'eldoc-pre-command-refresh-echo-area)) | |
164 (t | 145 (t |
165 ;; Use post-command-idle-hook if defined, otherwise use | 146 ;; Use post-command-idle-hook if defined, otherwise use |
166 ;; post-command-hook. The former is only proper to use in Emacs | 147 ;; post-command-hook. The former is only proper to use in Emacs |
167 ;; 19.30; that is the first version in which it appeared, but it | 148 ;; 19.30; that is the first version in which it appeared, but it |
168 ;; was obsolesced by idle timers in Emacs 19.31. | 149 ;; was obsolesced by idle timers in Emacs 19.31. |
169 (add-hook (if (boundp 'post-command-idle-hook) | 150 (add-hook (if (boundp 'post-command-idle-hook) |
170 'post-command-idle-hook | 151 'post-command-idle-hook |
171 'post-command-hook) | 152 'post-command-hook) |
172 'eldoc-print-current-symbol-info))) | 153 'eldoc-print-current-symbol-info) |
173 | 154 ;; quick and dirty hack for seeing if this is XEmacs |
155 (and (fboundp 'display-message) | |
156 (add-hook 'pre-command-hook | |
157 'eldoc-pre-command-refresh-echo-area)))) | |
174 (setq eldoc-mode (if prefix | 158 (setq eldoc-mode (if prefix |
175 (>= (prefix-numeric-value prefix) 0) | 159 (>= (prefix-numeric-value prefix) 0) |
176 (not eldoc-mode))) | 160 (not eldoc-mode))) |
177 | |
178 (and (interactive-p) | 161 (and (interactive-p) |
179 (if eldoc-mode | 162 (if eldoc-mode |
180 (message "eldoc-mode is enabled") | 163 (message "eldoc-mode is enabled") |
181 (message "eldoc-mode is disabled"))) | 164 (message "eldoc-mode is disabled"))) |
182 eldoc-mode) | 165 eldoc-mode) |
184 ;;;###autoload | 167 ;;;###autoload |
185 (defun turn-on-eldoc-mode () | 168 (defun turn-on-eldoc-mode () |
186 "Unequivocally turn on eldoc-mode (see variable documentation)." | 169 "Unequivocally turn on eldoc-mode (see variable documentation)." |
187 (interactive) | 170 (interactive) |
188 (eldoc-mode 1)) | 171 (eldoc-mode 1)) |
189 | |
190 (defun eldoc-add-command (cmd) | |
191 "Add COMMAND to the list of commands which causes function arg display. | |
192 If called interactively, completion on defined commands is available. | |
193 | |
194 When point is in a sexp, the function args are not reprinted in the echo | |
195 area after every possible interactive command because some of them print | |
196 their own messages in the echo area; the eldoc functions would instantly | |
197 overwrite them unless it is more restrained." | |
198 (interactive "CAdd function to eldoc message commands list: ") | |
199 (and (fboundp cmd) | |
200 (set (intern (symbol-name cmd) eldoc-message-commands) t))) | |
201 | |
202 (defun eldoc-remove-command (cmd) | |
203 "Remove COMMAND from the list of commands which causes function arg display. | |
204 If called interactively, completion matches only those functions currently | |
205 in the list. | |
206 | |
207 When point is in a sexp, the function args are not reprinted in the echo | |
208 area after every possible interactive command because some of them print | |
209 their own messages in the echo area; the eldoc functions would instantly | |
210 overwrite them unless it is more restrained." | |
211 (interactive (list (completing-read | |
212 "Remove function from eldoc message commands list: " | |
213 eldoc-message-commands 'boundp t))) | |
214 (and (symbolp cmd) | |
215 (setq cmd (symbol-name cmd))) | |
216 (if (fboundp 'unintern) | |
217 (unintern cmd eldoc-message-commands) | |
218 (let ((s (intern-soft cmd eldoc-message-commands))) | |
219 (and s | |
220 (makunbound s))))) | |
221 | 172 |
222 ;; Idle timers are part of Emacs 19.31 and later. | 173 ;; Idle timers are part of Emacs 19.31 and later. |
223 (defun eldoc-schedule-timer () | 174 (defun eldoc-schedule-timer () |
224 (or (and eldoc-timer | 175 (or (and eldoc-timer |
225 (memq eldoc-timer timer-idle-list)) | 176 (memq eldoc-timer timer-idle-list)) |
230 ;; If user has changed the idle delay, update the timer. | 181 ;; If user has changed the idle delay, update the timer. |
231 (cond ((not (= eldoc-idle-delay eldoc-current-idle-delay)) | 182 (cond ((not (= eldoc-idle-delay eldoc-current-idle-delay)) |
232 (setq eldoc-current-idle-delay eldoc-idle-delay) | 183 (setq eldoc-current-idle-delay eldoc-idle-delay) |
233 (timer-set-idle-time eldoc-timer eldoc-idle-delay t)))) | 184 (timer-set-idle-time eldoc-timer eldoc-idle-delay t)))) |
234 | 185 |
186 ;; This function goes on pre-command-hook for XEmacs or when using idle | |
187 ;; timers in Emacs. Motion commands clear the echo area for some reason, | |
188 ;; which make eldoc messages flicker or disappear just before motion | |
189 ;; begins. This function reprints the last eldoc message immediately | |
190 ;; before the next command executes, which does away with the flicker. | |
191 ;; This doesn't seem to be required for Emacs 19.28 and earlier. | |
192 (defun eldoc-pre-command-refresh-echo-area () | |
193 (and eldoc-last-message | |
194 (if (eldoc-display-message-no-interference-p) | |
195 (eldoc-message eldoc-last-message) | |
196 (setq eldoc-last-message nil)))) | |
197 | |
198 (defun eldoc-message (&rest args) | |
199 (let ((omessage eldoc-last-message)) | |
200 (cond ((eq (car args) eldoc-last-message)) | |
201 ((or (null args) | |
202 (null (car args))) | |
203 (setq eldoc-last-message nil)) | |
204 (t | |
205 (setq eldoc-last-message (apply 'format args)))) | |
206 ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages | |
207 ;; are recorded in a log. Do not put eldoc messages in that log since | |
208 ;; they are Legion. | |
209 (if (fboundp 'display-message) | |
210 ;; XEmacs 19.13 way of preventing log messages. | |
211 (if eldoc-last-message | |
212 (display-message 'no-log eldoc-last-message) | |
213 (and omessage | |
214 (clear-message 'no-log))) | |
215 (let ((message-log-max nil)) | |
216 (if eldoc-last-message | |
217 (message "%s" eldoc-last-message) | |
218 (and omessage | |
219 (message nil)))))) | |
220 eldoc-last-message) | |
221 | |
235 | 222 |
236 (defun eldoc-print-current-symbol-info () | 223 (defun eldoc-print-current-symbol-info () |
237 (and eldoc-mode | 224 (and (eldoc-display-message-p) |
238 (not executing-kbd-macro) | 225 (let ((current-symbol (eldoc-current-symbol)) |
239 | 226 (current-fnsym (eldoc-fnsym-in-current-sexp))) |
240 ;; Having this mode operate in an active minibuffer makes it | 227 (or (cond ((eq current-symbol current-fnsym) |
241 ;; impossible to see what you're doing. | 228 (or (eldoc-print-fnsym-args current-fnsym) |
242 (not (eq (selected-window) (minibuffer-window))) | 229 (eldoc-print-var-docstring current-symbol))) |
243 | 230 (t |
231 (or (eldoc-print-var-docstring current-symbol) | |
232 (eldoc-print-fnsym-args current-fnsym)))) | |
233 (eldoc-message nil))))) | |
234 | |
235 ;; Decide whether now is a good time to display a message. | |
236 (defun eldoc-display-message-p () | |
237 (and (eldoc-display-message-no-interference-p) | |
244 (cond (eldoc-use-idle-timer-p | 238 (cond (eldoc-use-idle-timer-p |
245 (and (symbolp last-command) | 239 ;; If this-command is non-nil while running via an idle |
240 ;; timer, we're still in the middle of executing a command, | |
241 ;; e.g. a query-replace where it would be annoying to | |
242 ;; overwrite the echo area. | |
243 (and (not this-command) | |
244 (symbolp last-command) | |
246 (intern-soft (symbol-name last-command) | 245 (intern-soft (symbol-name last-command) |
247 eldoc-message-commands))) | 246 eldoc-message-commands))) |
248 (t | 247 (t |
249 ;; If we don't have idle timers, this function is | 248 ;; If we don't have idle timers, this function is |
250 ;; running on post-command-hook directly; that means the | 249 ;; running on post-command-hook directly; that means the |
251 ;; user's last command is still on `this-command', and we | 250 ;; user's last command is still on `this-command', and we |
252 ;; must wait briefly for input to see whether to do display. | 251 ;; must wait briefly for input to see whether to do display. |
253 (and (symbolp this-command) | 252 (and (symbolp this-command) |
254 (intern-soft (symbol-name this-command) | 253 (intern-soft (symbol-name this-command) |
255 eldoc-message-commands) | 254 eldoc-message-commands) |
256 (sit-for eldoc-idle-delay)))) | 255 (sit-for eldoc-idle-delay)))))) |
257 | 256 |
258 (let ((current-symbol (eldoc-current-symbol)) | 257 (defun eldoc-display-message-no-interference-p () |
259 (current-fnsym (eldoc-fnsym-in-current-sexp))) | 258 (and eldoc-mode |
260 (cond ((eq current-symbol current-fnsym) | 259 (not executing-kbd-macro) |
261 (eldoc-print-fnsym-args current-fnsym)) | 260 ;; Having this mode operate in an active minibuffer/echo area causes |
262 (t | 261 ;; interference with what's going on there. |
263 (or (eldoc-print-var-docstring current-symbol) | 262 (not cursor-in-echo-area) |
264 (eldoc-print-fnsym-args current-fnsym))))))) | 263 (not (eq (selected-window) (minibuffer-window))))) |
265 | 264 |
266 (defun eldoc-print-fnsym-args (&optional symbol) | 265 (defun eldoc-print-fnsym-args (sym) |
267 (interactive) | 266 (interactive) |
268 (let ((sym (or symbol (eldoc-fnsym-in-current-sexp))) | 267 (let ((args nil)) |
269 (args nil)) | 268 (cond ((not (and sym |
270 (cond ((not (and (symbolp sym) | 269 (symbolp sym) |
271 (fboundp sym)))) | 270 (fboundp sym)))) |
272 ((eq sym (car eldoc-last-data)) | 271 ((eq sym (car eldoc-last-data)) |
273 (setq args (cdr eldoc-last-data))) | 272 (setq args (cdr eldoc-last-data))) |
274 ((subrp (eldoc-symbol-function sym)) | 273 ((subrp (eldoc-symbol-function sym)) |
275 (setq args (or (eldoc-function-argstring-from-docstring sym) | 274 (setq args (or (eldoc-function-argstring-from-docstring sym) |
282 (setcdr eldoc-last-data args))) | 281 (setcdr eldoc-last-data args))) |
283 (and args | 282 (and args |
284 (eldoc-message "%s: %s" sym args)))) | 283 (eldoc-message "%s: %s" sym args)))) |
285 | 284 |
286 (defun eldoc-fnsym-in-current-sexp () | 285 (defun eldoc-fnsym-in-current-sexp () |
287 (let* ((p (point)) | 286 (let ((p (point))) |
288 (sym (progn | 287 (eldoc-beginning-of-sexp) |
289 (while (and (eldoc-forward-sexp-safe -1) | 288 (prog1 |
290 (> (point) (point-min)))) | 289 ;; Don't do anything if current word is inside a string. |
291 (cond ((or (= (point) (point-min)) | 290 (if (= (or (char-after (1- (point))) 0) ?\") |
292 (memq (or (char-after (point)) 0) | 291 nil |
293 '(?\( ?\")) | 292 (eldoc-current-symbol)) |
294 ;; If we hit a quotation mark before a paren, we | 293 (goto-char p)))) |
295 ;; are inside a specific string, not a list of | 294 |
296 ;; symbols. | 295 (defun eldoc-beginning-of-sexp () |
297 (eq (or (char-after (1- (point))) 0) ?\")) | 296 (let ((parse-sexp-ignore-comments t)) |
298 nil) | 297 (condition-case err |
299 (t (condition-case nil | 298 (while (progn |
300 (read (current-buffer)) | 299 (forward-sexp -1) |
301 (error nil))))))) | 300 (or (= (or (char-after (1- (point)))) ?\") |
302 (goto-char p) | 301 (> (point) (point-min))))) |
303 (and (symbolp sym) | 302 (error nil)))) |
304 sym))) | 303 |
304 ;; returns nil unless current word is an interned symbol. | |
305 (defun eldoc-current-symbol () | |
306 (let ((c (char-after (point)))) | |
307 (and c | |
308 (memq (char-syntax c) '(?w ?_)) | |
309 (intern-soft (current-word))))) | |
310 | |
311 ;; Do indirect function resolution if possible. | |
312 (defun eldoc-symbol-function (fsym) | |
313 (let ((defn (and (fboundp fsym) | |
314 (symbol-function fsym)))) | |
315 (and (symbolp defn) | |
316 (condition-case err | |
317 (setq defn (indirect-function fsym)) | |
318 (error (setq defn nil)))) | |
319 defn)) | |
305 | 320 |
306 (defun eldoc-function-argstring (fn) | 321 (defun eldoc-function-argstring (fn) |
307 (let* ((prelim-def (eldoc-symbol-function fn)) | 322 (let* ((prelim-def (eldoc-symbol-function fn)) |
308 (def (if (eq (car-safe prelim-def) 'macro) | 323 (def (if (eq (car-safe prelim-def) 'macro) |
309 (cdr prelim-def) | 324 (cdr prelim-def) |
337 (funcall eldoc-argument-case s)))) | 352 (funcall eldoc-argument-case s)))) |
338 arglist)))) | 353 arglist)))) |
339 (concat "(" (mapconcat 'identity arglist " ") ")")) | 354 (concat "(" (mapconcat 'identity arglist " ") ")")) |
340 | 355 |
341 | 356 |
342 (defun eldoc-print-var-docstring (&optional sym) | 357 (defun eldoc-print-var-docstring (sym) |
343 (or sym (setq sym (eldoc-current-symbol))) | |
344 (eldoc-print-docstring sym (documentation-property | 358 (eldoc-print-docstring sym (documentation-property |
345 sym 'variable-documentation t))) | 359 sym 'variable-documentation t))) |
346 | 360 |
347 ;; Print the brief (one-line) documentation string for the symbol. | 361 ;; Print the brief (one-line) documentation string for the symbol. |
348 (defun eldoc-print-docstring (symbol doc) | 362 (defun eldoc-print-docstring (symbol doc) |
461 ;; This finds the argstring for `start-process'. Any others? | 475 ;; This finds the argstring for `start-process'. Any others? |
462 (list (function (lambda (doc fn) | 476 (list (function (lambda (doc fn) |
463 (string-match "^Args are +\\([^\n]+\\)$" doc))) | 477 (string-match "^Args are +\\([^\n]+\\)$" doc))) |
464 (function (lambda (doc) | 478 (function (lambda (doc) |
465 (substring doc (match-beginning 1) (match-end 1))))) | 479 (substring doc (match-beginning 1) (match-end 1))))) |
480 | |
481 ;; These subrs don't have arglists in their docstrings. | |
482 ;; This is cheating. | |
483 (list (function (lambda (doc fn) | |
484 (memq fn '(and or list + -)))) | |
485 (function (lambda (doc) | |
486 ;; The value nil is a placeholder; otherwise, the | |
487 ;; following string may be compiled as a docstring, | |
488 ;; and not a return value for the function. | |
489 ;; In interpreted lisp form they are | |
490 ;; indistinguishable; it only matters for compiled | |
491 ;; forms. | |
492 nil | |
493 "&rest args"))) | |
466 )) | 494 )) |
467 | 495 |
468 (defun eldoc-function-argstring-from-docstring (fn) | 496 (defun eldoc-function-argstring-from-docstring (fn) |
469 (let ((docstring (documentation fn 'raw)) | 497 (let ((docstring (documentation fn 'raw)) |
470 (table eldoc-function-argstring-from-docstring-method-table) | 498 (table eldoc-function-argstring-from-docstring-method-table) |
495 (eldoc-function-argstring-format (nreverse doclist)))) | 523 (eldoc-function-argstring-format (nreverse doclist)))) |
496 (t | 524 (t |
497 (concat "(" (funcall eldoc-argument-case doc) ")")))))) | 525 (concat "(" (funcall eldoc-argument-case doc) ")")))))) |
498 | 526 |
499 | 527 |
500 ;; forward-sexp calls scan-sexps, which returns an error if it hits the | 528 ;; When point is in a sexp, the function args are not reprinted in the echo |
501 ;; beginning or end of the sexp. This returns nil instead. | 529 ;; area after every possible interactive command because some of them print |
502 (defun eldoc-forward-sexp-safe (&optional count) | 530 ;; their own messages in the echo area; the eldoc functions would instantly |
503 "Move forward across one balanced expression (sexp). | 531 ;; overwrite them unless it is more restrained. |
504 With argument, do it that many times. Negative arg -COUNT means | 532 ;; These functions do display-command table management. |
505 move backward across COUNT balanced expressions. | 533 |
506 Return distance in buffer moved, or nil." | 534 (defun eldoc-add-command (&rest cmds) |
507 (or count (setq count 1)) | 535 (or eldoc-message-commands |
508 (condition-case err | 536 (setq eldoc-message-commands |
509 (- (- (point) (progn | 537 (make-vector eldoc-message-commands-table-size 0))) |
510 (let ((parse-sexp-ignore-comments t)) | 538 |
511 (forward-sexp count)) | 539 (let (name sym) |
512 (point)))) | 540 (while cmds |
513 (error nil))) | 541 (setq name (car cmds)) |
514 | 542 (setq cmds (cdr cmds)) |
515 ;; Do indirect function resolution if possible. | 543 |
516 (defun eldoc-symbol-function (fsym) | 544 (cond ((symbolp name) |
517 (let ((defn (and (fboundp fsym) | 545 (setq sym name) |
518 (symbol-function fsym)))) | 546 (setq name (symbol-name sym))) |
519 (and (symbolp defn) | 547 ((stringp name) |
520 (condition-case err | 548 (setq sym (intern-soft name)))) |
521 (setq defn (indirect-function fsym)) | 549 |
522 (error (setq defn nil)))) | 550 (and (symbolp sym) |
523 defn)) | 551 (fboundp sym) |
524 | 552 (set (intern name eldoc-message-commands) t))))) |
525 (defun eldoc-current-symbol () | 553 |
526 (let ((c (char-after (point)))) | 554 (defun eldoc-add-command-completions (&rest names) |
527 (and c | 555 (while names |
528 (memq (char-syntax c) '(?w ?_)) | 556 (apply 'eldoc-add-command |
529 (intern-soft (current-word))))) | 557 (all-completions (car names) obarray 'fboundp)) |
558 (setq names (cdr names)))) | |
559 | |
560 (defun eldoc-remove-command (&rest cmds) | |
561 (let (name) | |
562 (while cmds | |
563 (setq name (car cmds)) | |
564 (setq cmds (cdr cmds)) | |
565 | |
566 (and (symbolp name) | |
567 (setq name (symbol-name name))) | |
568 | |
569 (if (fboundp 'unintern) | |
570 (unintern name eldoc-message-commands) | |
571 (let ((s (intern-soft name eldoc-message-commands))) | |
572 (and s | |
573 (makunbound s))))))) | |
574 | |
575 (defun eldoc-remove-command-completions (&rest names) | |
576 (while names | |
577 (apply 'eldoc-remove-command | |
578 (all-completions (car names) eldoc-message-commands)) | |
579 (setq names (cdr names)))) | |
580 | |
581 ;; Prime the command list. | |
582 (eldoc-add-command-completions | |
583 "backward-" "beginning-of-" "delete-other-windows" "delete-window" | |
584 "end-of-" "forward-" "goto-" "mouse-set-point" "next-" "other-window" | |
585 "previous-" "recenter" "scroll-" "self-insert-command" "split-window-") | |
530 | 586 |
531 (provide 'eldoc) | 587 (provide 'eldoc) |
532 | 588 |
533 ;;; eldoc.el ends here | 589 ;;; eldoc.el ends here |