* lisp/emacs-lisp/eldoc.el (eldoc-highlight-function-argument): Handle the
case where we're currently providing part of the &rest arg after some &key args, as in define-ibuffer-op. Fixes: debbugs:18048
This commit is contained in:
parent
baff67fcd5
commit
e77bcfa34d
2 changed files with 62 additions and 16 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2014-09-04 Thierry Volpiatto <thierry.volpiatto@gmail.com>
|
||||||
|
|
||||||
|
* emacs-lisp/eldoc.el (eldoc-highlight-function-argument): Handle the
|
||||||
|
case where we're currently providing part of the &rest arg after some
|
||||||
|
&key args, as in define-ibuffer-op (bug#18048).
|
||||||
|
|
||||||
2014-09-03 Stefan Monnier <monnier@iro.umontreal.ca>
|
2014-09-03 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||||
|
|
||||||
* progmodes/which-func.el (which-func-ff-hook): Obey pre-existing
|
* progmodes/which-func.el (which-func-ff-hook): Obey pre-existing
|
||||||
|
|
|
@ -369,9 +369,16 @@ or elsewhere, return a 1-line docstring."
|
||||||
(defun eldoc-highlight-function-argument (sym args index)
|
(defun eldoc-highlight-function-argument (sym args index)
|
||||||
"Highlight argument INDEX in ARGS list for function SYM.
|
"Highlight argument INDEX in ARGS list for function SYM.
|
||||||
In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
|
In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
|
||||||
|
;; FIXME: This should probably work on the list representation of `args'
|
||||||
|
;; rather than its string representation.
|
||||||
|
;; FIXME: This function is much too long, we need to split it up!
|
||||||
(let ((start nil)
|
(let ((start nil)
|
||||||
(end 0)
|
(end 0)
|
||||||
(argument-face 'eldoc-highlight-function-argument))
|
(argument-face 'eldoc-highlight-function-argument)
|
||||||
|
(args-lst (mapcar (lambda (x)
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\\`[(]\\|[)]\\'" "" x))
|
||||||
|
(split-string args))))
|
||||||
;; Find the current argument in the argument string. We need to
|
;; Find the current argument in the argument string. We need to
|
||||||
;; handle `&rest' and informal `...' properly.
|
;; handle `&rest' and informal `...' properly.
|
||||||
;;
|
;;
|
||||||
|
@ -385,23 +392,53 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
|
||||||
;; position in ARGS based on this current arg.
|
;; position in ARGS based on this current arg.
|
||||||
(when (string-match "&key" args)
|
(when (string-match "&key" args)
|
||||||
(let* (case-fold-search
|
(let* (case-fold-search
|
||||||
|
key-have-value
|
||||||
|
(sym-name (symbol-name sym))
|
||||||
(cur-w (current-word))
|
(cur-w (current-word))
|
||||||
|
(args-lst-ak (cdr (member "&key" args-lst)))
|
||||||
(limit (save-excursion
|
(limit (save-excursion
|
||||||
(when (re-search-backward (symbol-name sym) nil t)
|
(when (re-search-backward sym-name nil t)
|
||||||
(match-end 0))))
|
(match-end 0))))
|
||||||
(cur-a (if (string-match ":\\([^ ()]*\\)" cur-w)
|
(cur-a (if (and cur-w (string-match ":\\([^ ()]*\\)" cur-w))
|
||||||
(substring cur-w 1)
|
(substring cur-w 1)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(when (re-search-backward ":\\([^ ()\n]*\\)" limit t)
|
(let (split)
|
||||||
(match-string 1))))))
|
(when (re-search-backward ":\\([^()\n]*\\)" limit t)
|
||||||
;; If `cur-a' is nil probably cursor is on a positional arg
|
(setq split (split-string (match-string 1) " " t))
|
||||||
;; before `&key', in this case, exit this block and determine
|
(prog1 (car split)
|
||||||
;; position with `index'.
|
(when (cdr split)
|
||||||
(when (and cur-a
|
(setq key-have-value t))))))))
|
||||||
(string-match (concat "\\_<" (upcase cur-a) "\\_>") args))
|
;; If `cur-a' is not one of `args-lst-ak'
|
||||||
(setq index nil ; Skip next block based on positional args.
|
;; assume user is entering an unknow key
|
||||||
start (match-beginning 0)
|
;; referenced in last position in signature.
|
||||||
end (match-end 0)))))
|
(other-key-arg (and (stringp cur-a)
|
||||||
|
args-lst-ak
|
||||||
|
(not (member (upcase cur-a) args-lst-ak))
|
||||||
|
(upcase (car (last args-lst-ak))))))
|
||||||
|
(unless (string= cur-w sym-name)
|
||||||
|
;; The last keyword have already a value
|
||||||
|
;; i.e :foo a b and cursor is at b.
|
||||||
|
;; If signature have also `&rest'
|
||||||
|
;; (assume it is after the `&key' section)
|
||||||
|
;; go to the arg after `&rest'.
|
||||||
|
(if (and key-have-value
|
||||||
|
(save-excursion
|
||||||
|
(not (re-search-forward ":.*" (point-at-eol) t)))
|
||||||
|
(string-match "&rest \\([^ ()]*\\)" args))
|
||||||
|
(setq index nil ; Skip next block based on positional args.
|
||||||
|
start (match-beginning 1)
|
||||||
|
end (match-end 1))
|
||||||
|
;; If `cur-a' is nil probably cursor is on a positional arg
|
||||||
|
;; before `&key', in this case, exit this block and determine
|
||||||
|
;; position with `index'.
|
||||||
|
(when (and cur-a ; A keyword arg (dot removed) or nil.
|
||||||
|
(or (string-match
|
||||||
|
(concat "\\_<" (upcase cur-a) "\\_>") args)
|
||||||
|
(string-match
|
||||||
|
(concat "\\_<" other-key-arg "\\_>") args)))
|
||||||
|
(setq index nil ; Skip next block based on positional args.
|
||||||
|
start (match-beginning 0)
|
||||||
|
end (match-end 0)))))))
|
||||||
;; Handle now positional arguments.
|
;; Handle now positional arguments.
|
||||||
(while (and index (>= index 1))
|
(while (and index (>= index 1))
|
||||||
(if (string-match "[^ ()]+" args end)
|
(if (string-match "[^ ()]+" args end)
|
||||||
|
@ -412,12 +449,15 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
|
||||||
(cond ((string= argument "&rest")
|
(cond ((string= argument "&rest")
|
||||||
;; All the rest arguments are the same.
|
;; All the rest arguments are the same.
|
||||||
(setq index 1))
|
(setq index 1))
|
||||||
((string= argument "&optional")) ; Skip.
|
((string= argument "&optional")) ; Skip.
|
||||||
((string= argument "&allow-other-keys")) ; Skip.
|
((string= argument "&allow-other-keys")) ; Skip.
|
||||||
;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc...
|
;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc...
|
||||||
;; like in `setq'.
|
;; like in `setq'.
|
||||||
((or (string-match-p "\\.\\.\\.$" argument)
|
((or (and (string-match-p "\\.\\.\\.$" argument)
|
||||||
(and (string-match-p "\\.\\.\\.)?$" args)
|
(string= argument (car (last args-lst))))
|
||||||
|
(and (string-match-p "\\.\\.\\.$"
|
||||||
|
(substring args 1 (1- (length args))))
|
||||||
|
(= (length (remove "..." args-lst)) 2)
|
||||||
(> index 1) (cl-oddp index)))
|
(> index 1) (cl-oddp index)))
|
||||||
(setq index 0))
|
(setq index 0))
|
||||||
(t
|
(t
|
||||||
|
|
Loading…
Add table
Reference in a new issue