aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2007-07-12 01:51:52 +0000
committerStefan Monnier2007-07-12 01:51:52 +0000
commit1bed504abe704d9ddb2b6a68c86b8569ed05860e (patch)
tree5fc71692afe900b955d66d9cf0a029e7ea538956
parentd8b180437fc649520fae0afea113590224948fc9 (diff)
downloademacs-1bed504abe704d9ddb2b6a68c86b8569ed05860e.tar.gz
emacs-1bed504abe704d9ddb2b6a68c86b8569ed05860e.zip
(eldoc-last-data): Revise documentation.
(eldoc-print-current-symbol-info): Adjust for changed helper function signatures. (eldoc-get-fnsym-args-string): Add `args' argument. Use new `eldoc-highlight-function-argument'. (eldoc-highlight-function-argument): New function. (eldoc-get-var-docstring): Format documentation with `font-lock-variable-name-face'. (eldoc-docstring-format-sym-doc): Add `face' argument and apply it where suited. (eldoc-fnsym-in-current-sexp): Return a list with argument index. (eldoc-beginning-of-sexp): Return number of skipped sexps.
-rw-r--r--lisp/ChangeLog19
-rw-r--r--lisp/emacs-lisp/eldoc.el120
2 files changed, 109 insertions, 30 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b4ca74d8198..69c7f3fb0be 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,18 @@
12007-07-12 Paul Pogonyshev <pogonyshev@gmx.net>
2
3 * emacs-lisp/eldoc.el (eldoc-last-data): Revise documentation.
4 (eldoc-print-current-symbol-info): Adjust for changed helper
5 function signatures.
6 (eldoc-get-fnsym-args-string): Add `args' argument. Use new
7 `eldoc-highlight-function-argument'.
8 (eldoc-highlight-function-argument): New function.
9 (eldoc-get-var-docstring): Format documentation with
10 `font-lock-variable-name-face'.
11 (eldoc-docstring-format-sym-doc): Add `face' argument and apply it
12 where suited.
13 (eldoc-fnsym-in-current-sexp): Return a list with argument index.
14 (eldoc-beginning-of-sexp): Return number of skipped sexps.
15
12007-07-11 Michael Albinus <michael.albinus@gmx.de> 162007-07-11 Michael Albinus <michael.albinus@gmx.de>
2 17
3 * progmodes/compile.el (compilation-start): `start-process' must 18 * progmodes/compile.el (compilation-start): `start-process' must
@@ -45,6 +60,10 @@
45 60
462007-07-10 Stefan Monnier <monnier@iro.umontreal.ca> 612007-07-10 Stefan Monnier <monnier@iro.umontreal.ca>
47 62
63 * emacs-lisp/autoload.el (autoload-generate-file-autoloads): Be careful
64 with EOLs when generating MD5 checksums.
65
66
48 * follow.el: Don't change the global map from the follow-mode-map 67 * follow.el: Don't change the global map from the follow-mode-map
49 defvar, but from the toplevel. Use easy-menu to unify the Emacs and 68 defvar, but from the toplevel. Use easy-menu to unify the Emacs and
50 XEmacs code. 69 XEmacs code.
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 85b150b6ae5..37e2eb351f2 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -124,8 +124,8 @@ directly. Instead, use `eldoc-add-command' and `eldoc-remove-command'.")
124(defconst eldoc-last-data (make-vector 3 nil) 124(defconst eldoc-last-data (make-vector 3 nil)
125 "Bookkeeping; elements are as follows: 125 "Bookkeeping; elements are as follows:
126 0 - contains the last symbol read from the buffer. 126 0 - contains the last symbol read from the buffer.
127 1 - contains the string last displayed in the echo area for that 127 1 - contains the string last displayed in the echo area for variables,
128 symbol, so it can be printed again if necessary without reconsing. 128 or argument string for functions.
129 2 - 'function if function args, 'variable if variable documentation.") 129 2 - 'function if function args, 'variable if variable documentation.")
130(defvar eldoc-last-message nil) 130(defvar eldoc-last-message nil)
131 131
@@ -249,12 +249,16 @@ Emacs Lisp mode) that support Eldoc.")
249 (let* ((current-symbol (eldoc-current-symbol)) 249 (let* ((current-symbol (eldoc-current-symbol))
250 (current-fnsym (eldoc-fnsym-in-current-sexp)) 250 (current-fnsym (eldoc-fnsym-in-current-sexp))
251 (doc (cond 251 (doc (cond
252 ((eq current-symbol current-fnsym) 252 ((null current-fnsym)
253 (or (eldoc-get-fnsym-args-string current-fnsym) 253 nil)
254 ((eq current-symbol (car current-fnsym))
255 (or (apply 'eldoc-get-fnsym-args-string
256 current-fnsym)
254 (eldoc-get-var-docstring current-symbol))) 257 (eldoc-get-var-docstring current-symbol)))
255 (t 258 (t
256 (or (eldoc-get-var-docstring current-symbol) 259 (or (eldoc-get-var-docstring current-symbol)
257 (eldoc-get-fnsym-args-string current-fnsym)))))) 260 (apply 'eldoc-get-fnsym-args-string
261 current-fnsym))))))
258 (eldoc-message doc)))) 262 (eldoc-message doc))))
259 ;; This is run from post-command-hook or some idle timer thing, 263 ;; This is run from post-command-hook or some idle timer thing,
260 ;; so we need to be careful that errors aren't ignored. 264 ;; so we need to be careful that errors aren't ignored.
@@ -263,24 +267,62 @@ Emacs Lisp mode) that support Eldoc.")
263;; Return a string containing the function parameter list, or 1-line 267;; Return a string containing the function parameter list, or 1-line
264;; docstring if function is a subr and no arglist is obtainable from the 268;; docstring if function is a subr and no arglist is obtainable from the
265;; docstring or elsewhere. 269;; docstring or elsewhere.
266(defun eldoc-get-fnsym-args-string (sym) 270(defun eldoc-get-fnsym-args-string (sym argument-index)
267 (let ((args nil) 271 (let ((args nil)
268 (doc nil)) 272 (doc nil))
269 (cond ((not (and sym (symbolp sym) (fboundp sym)))) 273 (cond ((not (and sym (symbolp sym) (fboundp sym))))
270 ((and (eq sym (aref eldoc-last-data 0)) 274 ((and (eq sym (aref eldoc-last-data 0))
271 (eq 'function (aref eldoc-last-data 2))) 275 (eq 'function (aref eldoc-last-data 2)))
272 (setq doc (aref eldoc-last-data 1))) 276 (setq args (aref eldoc-last-data 1)))
273 ((setq doc (help-split-fundoc (documentation sym t) sym)) 277 ((setq doc (help-split-fundoc (documentation sym t) sym))
274 (setq args (car doc)) 278 (setq args (car doc))
275 (string-match "\\`[^ )]* ?" args) 279 (string-match "\\`[^ )]* ?" args)
276 (setq args (concat "(" (substring args (match-end 0))))) 280 (setq args (concat "(" (substring args (match-end 0))))
281 (eldoc-last-data-store sym args 'function))
277 (t 282 (t
278 (setq args (eldoc-function-argstring sym)))) 283 (setq args (eldoc-function-argstring sym))))
279 (cond (args 284 (when args
280 (setq doc (eldoc-docstring-format-sym-doc sym args)) 285 (setq doc (eldoc-highlight-function-argument sym args argument-index)))
281 (eldoc-last-data-store sym doc 'function)))
282 doc)) 286 doc))
283 287
288;; Highlight argument INDEX in ARGS list for SYM.
289(defun eldoc-highlight-function-argument (sym args index)
290 (let ((start nil)
291 (end 0)
292 (argument-face 'bold))
293 ;; Find the current argument in the argument string. We need to
294 ;; handle `&rest' and informal `...' properly.
295 ;;
296 ;; FIXME: What to do with optional arguments, like in
297 ;; (defun NAME ARGLIST [DOCSTRING] BODY...) case?
298 ;; The problem is there is no robust way to determine if
299 ;; the current argument is indeed a docstring.
300 (while (>= index 1)
301 (if (string-match "[^ ()]+" args end)
302 (progn
303 (setq start (match-beginning 0)
304 end (match-end 0))
305 (let ((argument (match-string 0 args)))
306 (cond ((string= argument "&rest")
307 ;; All the rest arguments are the same.
308 (setq index 1))
309 ((string= argument "&optional"))
310 ((string-match "\\.\\.\\.$" argument)
311 (setq index 0))
312 (t
313 (setq index (1- index))))))
314 (setq end (length args)
315 start (1- end)
316 argument-face 'font-lock-warning-face
317 index 0)))
318 (let ((doc args))
319 (when start
320 (setq doc (copy-sequence args))
321 (add-text-properties start end (list 'face argument-face) doc))
322 (setq doc (eldoc-docstring-format-sym-doc
323 sym doc 'font-lock-function-name-face))
324 doc)))
325
284;; Return a string containing a brief (one-line) documentation string for 326;; Return a string containing a brief (one-line) documentation string for
285;; the variable. 327;; the variable.
286(defun eldoc-get-var-docstring (sym) 328(defun eldoc-get-var-docstring (sym)
@@ -292,7 +334,8 @@ Emacs Lisp mode) that support Eldoc.")
292 (let ((doc (documentation-property sym 'variable-documentation t))) 334 (let ((doc (documentation-property sym 'variable-documentation t)))
293 (cond (doc 335 (cond (doc
294 (setq doc (eldoc-docstring-format-sym-doc 336 (setq doc (eldoc-docstring-format-sym-doc
295 sym (eldoc-docstring-first-line doc))) 337 sym (eldoc-docstring-first-line doc)
338 'font-lock-variable-name-face))
296 (eldoc-last-data-store sym doc 'variable))) 339 (eldoc-last-data-store sym doc 'variable)))
297 doc))))) 340 doc)))))
298 341
@@ -316,7 +359,7 @@ Emacs Lisp mode) that support Eldoc.")
316;; If the entire line cannot fit in the echo area, the symbol name may be 359;; If the entire line cannot fit in the echo area, the symbol name may be
317;; truncated or eliminated entirely from the output to make room for the 360;; truncated or eliminated entirely from the output to make room for the
318;; description. 361;; description.
319(defun eldoc-docstring-format-sym-doc (sym doc) 362(defun eldoc-docstring-format-sym-doc (sym doc face)
320 (save-match-data 363 (save-match-data
321 (let* ((name (symbol-name sym)) 364 (let* ((name (symbol-name sym))
322 (ea-multi eldoc-echo-area-use-multiline-p) 365 (ea-multi eldoc-echo-area-use-multiline-p)
@@ -328,7 +371,7 @@ Emacs Lisp mode) that support Eldoc.")
328 (cond ((or (<= strip 0) 371 (cond ((or (<= strip 0)
329 (eq ea-multi t) 372 (eq ea-multi t)
330 (and ea-multi (> (length doc) ea-width))) 373 (and ea-multi (> (length doc) ea-width)))
331 (format "%s: %s" sym doc)) 374 (format "%s: %s" (propertize name 'face face) doc))
332 ((> (length doc) ea-width) 375 ((> (length doc) ea-width)
333 (substring (format "%s" doc) 0 ea-width)) 376 (substring (format "%s" doc) 0 ea-width))
334 ((>= strip (length name)) 377 ((>= strip (length name))
@@ -338,27 +381,44 @@ Emacs Lisp mode) that support Eldoc.")
338 ;; than the beginning, since the former is more likely 381 ;; than the beginning, since the former is more likely
339 ;; to be unique given package namespace conventions. 382 ;; to be unique given package namespace conventions.
340 (setq name (substring name strip)) 383 (setq name (substring name strip))
341 (format "%s: %s" name doc)))))) 384 (format "%s: %s" (propertize name 'face face) doc))))))
342 385
343 386
387;; Return a list of current function name and argument index.
344(defun eldoc-fnsym-in-current-sexp () 388(defun eldoc-fnsym-in-current-sexp ()
345 (let ((p (point))) 389 (save-excursion
346 (eldoc-beginning-of-sexp) 390 (let ((argument-index (1- (eldoc-beginning-of-sexp))))
347 (prog1 391 ;; If we are at the beginning of function name, this will be -1.
348 ;; Don't do anything if current word is inside a string. 392 (when (< argument-index 0)
349 (if (= (or (char-after (1- (point))) 0) ?\") 393 (setq argument-index 0))
350 nil 394 ;; Don't do anything if current word is inside a string.
351 (eldoc-current-symbol)) 395 (if (= (or (char-after (1- (point))) 0) ?\")
352 (goto-char p)))) 396 nil
353 397 (list (eldoc-current-symbol) argument-index)))))
398
399;; Move to the beginnig of current sexp. Return the number of nested
400;; sexp the point was over or after.
354(defun eldoc-beginning-of-sexp () 401(defun eldoc-beginning-of-sexp ()
355 (let ((parse-sexp-ignore-comments t)) 402 (let ((parse-sexp-ignore-comments t)
403 (num-skipped-sexps 0))
356 (condition-case err 404 (condition-case err
357 (while (progn 405 (progn
358 (forward-sexp -1) 406 ;; First account for the case the point is directly over a
359 (or (= (char-before) ?\") 407 ;; beginning of a nested sexp.
360 (> (point) (point-min))))) 408 (condition-case err
361 (error nil)))) 409 (let ((p (point)))
410 (forward-sexp -1)
411 (forward-sexp 1)
412 (when (< (point) p)
413 (setq num-skipped-sexps 1)))
414 (error))
415 (while
416 (let ((p (point)))
417 (forward-sexp -1)
418 (when (< (point) p)
419 (setq num-skipped-sexps (1+ num-skipped-sexps))))))
420 (error))
421 num-skipped-sexps))
362 422
363;; returns nil unless current word is an interned symbol. 423;; returns nil unless current word is an interned symbol.
364(defun eldoc-current-symbol () 424(defun eldoc-current-symbol ()