diff options
| author | Thierry Volpiatto | 2014-08-18 15:28:40 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-08-18 15:28:40 -0400 |
| commit | 2e7d4343e96fe3937140464f05bc8ff760da8e16 (patch) | |
| tree | 257d02e6731760a3100833b877f83c4c59f0aa6b | |
| parent | a8626b7ec10c36440c2801e0433bb122e331b3e8 (diff) | |
| download | emacs-2e7d4343e96fe3937140464f05bc8ff760da8e16.tar.gz emacs-2e7d4343e96fe3937140464f05bc8ff760da8e16.zip | |
* lisp/emacs-lisp/eldoc.el (eldoc-highlight-function-argument): Add support
for &key args.
* emacs-lisp/eldoc.el (eldoc-argument-case): Obsolete and change default.
(eldoc-function-argstring-format): Remove.
(eldoc-function-argstring): Always return upcase args.
Use help-make-usage. Don't add parens.
(eldoc-get-fnsym-args-string): Don't obey eldoc-argument-case since
it's too late to do it right (bug#18048).
| -rw-r--r-- | lisp/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eldoc.el | 84 |
2 files changed, 58 insertions, 40 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1ee5ca6a3b7..78fe9456891 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2014-08-18 Thierry Volpiatto <thierry.volpiatto@gmail.com> | ||
| 2 | |||
| 3 | * emacs-lisp/eldoc.el (eldoc-highlight-function-argument): Add support | ||
| 4 | for &key args (bug#18048). | ||
| 5 | |||
| 6 | 2014-08-18 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 7 | |||
| 8 | * emacs-lisp/eldoc.el (eldoc-argument-case): Obsolete and change default. | ||
| 9 | (eldoc-function-argstring-format): Remove. | ||
| 10 | (eldoc-function-argstring): Always return upcase args. | ||
| 11 | Use help-make-usage. Don't add parens. | ||
| 12 | (eldoc-get-fnsym-args-string): Don't obey eldoc-argument-case since | ||
| 13 | it's too late to do it right (bug#18048). | ||
| 14 | |||
| 1 | 2014-08-18 Eli Zaretskii <eliz@gnu.org> | 15 | 2014-08-18 Eli Zaretskii <eliz@gnu.org> |
| 2 | 16 | ||
| 3 | * scroll-bar.el (scroll-bar-horizontal-drag-1) | 17 | * scroll-bar.el (scroll-bar-horizontal-drag-1) |
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 7102b5549eb..0b8304af29f 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | ;;; Code: | 48 | ;;; Code: |
| 49 | 49 | ||
| 50 | (require 'help-fns) ;For fundoc-usage handling functions. | 50 | (require 'help-fns) ;For fundoc-usage handling functions. |
| 51 | (require 'cl-lib) | ||
| 51 | 52 | ||
| 52 | (defgroup eldoc nil | 53 | (defgroup eldoc nil |
| 53 | "Show function arglist or variable docstring in echo area." | 54 | "Show function arglist or variable docstring in echo area." |
| @@ -75,7 +76,7 @@ Changing the value requires toggling `eldoc-mode'." | |||
| 75 | :type '(choice string (const :tag "None" nil)) | 76 | :type '(choice string (const :tag "None" nil)) |
| 76 | :group 'eldoc) | 77 | :group 'eldoc) |
| 77 | 78 | ||
| 78 | (defcustom eldoc-argument-case 'upcase | 79 | (defcustom eldoc-argument-case #'identity |
| 79 | "Case to display argument names of functions, as a symbol. | 80 | "Case to display argument names of functions, as a symbol. |
| 80 | This has two preferred values: `upcase' or `downcase'. | 81 | This has two preferred values: `upcase' or `downcase'. |
| 81 | Actually, any name of a function which takes a string as an argument and | 82 | Actually, any name of a function which takes a string as an argument and |
| @@ -87,6 +88,7 @@ has no effect, unless the function handles it explicitly." | |||
| 87 | (function-item downcase) | 88 | (function-item downcase) |
| 88 | function) | 89 | function) |
| 89 | :group 'eldoc) | 90 | :group 'eldoc) |
| 91 | (make-obsolete-variable 'eldoc-argument-case nil "24.5") | ||
| 90 | 92 | ||
| 91 | (defcustom eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit | 93 | (defcustom eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit |
| 92 | "Allow long ElDoc messages to resize echo area display. | 94 | "Allow long ElDoc messages to resize echo area display. |
| @@ -341,12 +343,7 @@ Emacs Lisp mode) that support ElDoc.") | |||
| 341 | (defun eldoc-get-fnsym-args-string (sym &optional index) | 343 | (defun eldoc-get-fnsym-args-string (sym &optional index) |
| 342 | "Return a string containing the parameter list of the function SYM. | 344 | "Return a string containing the parameter list of the function SYM. |
| 343 | If SYM is a subr and no arglist is obtainable from the docstring | 345 | If SYM is a subr and no arglist is obtainable from the docstring |
| 344 | or elsewhere, return a 1-line docstring. Calls the functions | 346 | or elsewhere, return a 1-line docstring." |
| 345 | `eldoc-function-argstring-format' and | ||
| 346 | `eldoc-highlight-function-argument' to format the result. The | ||
| 347 | former calls `eldoc-argument-case'; the latter gives the | ||
| 348 | function name `font-lock-function-name-face', and optionally | ||
| 349 | highlights argument number INDEX." | ||
| 350 | (let (args doc advertised) | 347 | (let (args doc advertised) |
| 351 | (cond ((not (and sym (symbolp sym) (fboundp sym)))) | 348 | (cond ((not (and sym (symbolp sym) (fboundp sym)))) |
| 352 | ((and (eq sym (aref eldoc-last-data 0)) | 349 | ((and (eq sym (aref eldoc-last-data 0)) |
| @@ -356,12 +353,7 @@ highlights argument number INDEX." | |||
| 356 | advertised-signature-table t))) | 353 | advertised-signature-table t))) |
| 357 | (setq args advertised)) | 354 | (setq args advertised)) |
| 358 | ((setq doc (help-split-fundoc (documentation sym t) sym)) | 355 | ((setq doc (help-split-fundoc (documentation sym t) sym)) |
| 359 | (setq args (car doc)) | 356 | (setq args (car doc))) |
| 360 | ;; Remove any enclosing (), since e-function-argstring adds them. | ||
| 361 | (string-match "\\`[^ )]* ?" args) | ||
| 362 | (setq args (substring args (match-end 0))) | ||
| 363 | (if (string-match-p ")\\'" args) | ||
| 364 | (setq args (substring args 0 -1)))) | ||
| 365 | (t | 357 | (t |
| 366 | (setq args (help-function-arglist sym)))) | 358 | (setq args (help-function-arglist sym)))) |
| 367 | (if args | 359 | (if args |
| @@ -372,8 +364,7 @@ highlights argument number INDEX." | |||
| 372 | (setq args doc)) ; use stored value | 364 | (setq args doc)) ; use stored value |
| 373 | ;; Change case, highlight, truncate. | 365 | ;; Change case, highlight, truncate. |
| 374 | (if args | 366 | (if args |
| 375 | (eldoc-highlight-function-argument | 367 | (eldoc-highlight-function-argument sym args index)))) |
| 376 | sym (eldoc-function-argstring-format args) index)))) | ||
| 377 | 368 | ||
| 378 | (defun eldoc-highlight-function-argument (sym args index) | 369 | (defun eldoc-highlight-function-argument (sym args index) |
| 379 | "Highlight argument INDEX in ARGS list for function SYM. | 370 | "Highlight argument INDEX in ARGS list for function SYM. |
| @@ -388,6 +379,30 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'." | |||
| 388 | ;; (defun NAME ARGLIST [DOCSTRING] BODY...) case? | 379 | ;; (defun NAME ARGLIST [DOCSTRING] BODY...) case? |
| 389 | ;; The problem is there is no robust way to determine if | 380 | ;; The problem is there is no robust way to determine if |
| 390 | ;; the current argument is indeed a docstring. | 381 | ;; the current argument is indeed a docstring. |
| 382 | |||
| 383 | ;; When `&key' is used finding position based on `index' | ||
| 384 | ;; would be wrong, so find the arg at point and determine | ||
| 385 | ;; position in ARGS based on this current arg. | ||
| 386 | (when (string-match "&key" args) | ||
| 387 | (let* (case-fold-search | ||
| 388 | (cur-w (current-word)) | ||
| 389 | (limit (save-excursion | ||
| 390 | (when (re-search-backward (symbol-name sym) nil t) | ||
| 391 | (match-end 0)))) | ||
| 392 | (cur-a (if (string-match ":\\([^ ()]*\\)" cur-w) | ||
| 393 | (substring cur-w 1) | ||
| 394 | (save-excursion | ||
| 395 | (when (re-search-backward ":\\([^ ()\n]*\\)" limit t) | ||
| 396 | (match-string 1)))))) | ||
| 397 | ;; If `cur-a' is nil probably cursor is on a positional arg | ||
| 398 | ;; before `&key', in this case, exit this block and determine | ||
| 399 | ;; position with `index'. | ||
| 400 | (when (and cur-a | ||
| 401 | (string-match (concat "\\_<" (upcase cur-a) "\\_>") args)) | ||
| 402 | (setq index nil ; Skip next block based on positional args. | ||
| 403 | start (match-beginning 0) | ||
| 404 | end (match-end 0))))) | ||
| 405 | ;; Handle now positional arguments. | ||
| 391 | (while (and index (>= index 1)) | 406 | (while (and index (>= index 1)) |
| 392 | (if (string-match "[^ ()]+" args end) | 407 | (if (string-match "[^ ()]+" args end) |
| 393 | (progn | 408 | (progn |
| @@ -397,9 +412,14 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'." | |||
| 397 | (cond ((string= argument "&rest") | 412 | (cond ((string= argument "&rest") |
| 398 | ;; All the rest arguments are the same. | 413 | ;; All the rest arguments are the same. |
| 399 | (setq index 1)) | 414 | (setq index 1)) |
| 400 | ((string= argument "&optional")) | 415 | ((string= argument "&optional")) ; Skip. |
| 401 | ((string-match-p "\\.\\.\\.$" argument) | 416 | ((string= argument "&allow-other-keys")) ; Skip. |
| 402 | (setq index 0)) | 417 | ;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc... |
| 418 | ;; like in `setq'. | ||
| 419 | ((or (string-match-p "\\.\\.\\.$" argument) | ||
| 420 | (and (string-match-p "\\.\\.\\.)?$" args) | ||
| 421 | (> index 1) (cl-oddp index))) | ||
| 422 | (setq index 0)) | ||
| 403 | (t | 423 | (t |
| 404 | (setq index (1- index)))))) | 424 | (setq index (1- index)))))) |
| 405 | (setq end (length args) | 425 | (setq end (length args) |
| @@ -533,28 +553,12 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'." | |||
| 533 | (defun eldoc-function-argstring (arglist) | 553 | (defun eldoc-function-argstring (arglist) |
| 534 | "Return ARGLIST as a string enclosed by (). | 554 | "Return ARGLIST as a string enclosed by (). |
| 535 | ARGLIST is either a string, or a list of strings or symbols." | 555 | ARGLIST is either a string, or a list of strings or symbols." |
| 536 | (cond ((stringp arglist)) | 556 | (let ((str (cond ((stringp arglist) arglist) |
| 537 | ((not (listp arglist)) | 557 | ((not (listp arglist)) nil) |
| 538 | (setq arglist nil)) | 558 | (t (format "%S" (help-make-usage 'toto arglist)))))) |
| 539 | ((symbolp (car arglist)) | 559 | (if (and str (string-match "\\`([^ ]+ ?" str)) |
| 540 | (setq arglist | 560 | (replace-match "(" t t str) |
| 541 | (mapconcat (lambda (s) (symbol-name s)) | 561 | str))) |
| 542 | arglist " "))) | ||
| 543 | ((stringp (car arglist)) | ||
| 544 | (setq arglist | ||
| 545 | (mapconcat (lambda (s) s) | ||
| 546 | arglist " ")))) | ||
| 547 | (if arglist | ||
| 548 | (format "(%s)" arglist))) | ||
| 549 | |||
| 550 | (defun eldoc-function-argstring-format (argstring) | ||
| 551 | "Apply `eldoc-argument-case' to each word in ARGSTRING. | ||
| 552 | The words \"&rest\", \"&optional\" are returned unchanged." | ||
| 553 | (mapconcat (lambda (s) | ||
| 554 | (if (string-match-p "\\`(?&\\(?:optional\\|rest\\))?\\'" s) | ||
| 555 | s | ||
| 556 | (funcall eldoc-argument-case s))) | ||
| 557 | (split-string argstring) " ")) | ||
| 558 | 562 | ||
| 559 | 563 | ||
| 560 | ;; When point is in a sexp, the function args are not reprinted in the echo | 564 | ;; When point is in a sexp, the function args are not reprinted in the echo |