diff options
| author | Stefan Monnier | 2007-07-12 01:51:52 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2007-07-12 01:51:52 +0000 |
| commit | 1bed504abe704d9ddb2b6a68c86b8569ed05860e (patch) | |
| tree | 5fc71692afe900b955d66d9cf0a029e7ea538956 | |
| parent | d8b180437fc649520fae0afea113590224948fc9 (diff) | |
| download | emacs-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/ChangeLog | 19 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eldoc.el | 120 |
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 @@ | |||
| 1 | 2007-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 | |||
| 1 | 2007-07-11 Michael Albinus <michael.albinus@gmx.de> | 16 | 2007-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 | ||
| 46 | 2007-07-10 Stefan Monnier <monnier@iro.umontreal.ca> | 61 | 2007-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 () |