Commit e77bcfa3 authored by Thierry Volpiatto's avatar Thierry Volpiatto Committed by Stefan Monnier
Browse files

* 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
parent baff67fc
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>
 
* 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)
"Highlight argument INDEX in ARGS list for function SYM.
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)
(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
;; 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.
(when (string-match "&key" args)
(let* (case-fold-search
key-have-value
(sym-name (symbol-name sym))
(cur-w (current-word))
(args-lst-ak (cdr (member "&key" args-lst)))
(limit (save-excursion
(when (re-search-backward (symbol-name sym) nil t)
(when (re-search-backward sym-name nil t)
(match-end 0))))
(cur-a (if (string-match ":\\([^ ()]*\\)" cur-w)
(cur-a (if (and cur-w (string-match ":\\([^ ()]*\\)" cur-w))
(substring cur-w 1)
(save-excursion
(when (re-search-backward ":\\([^ ()\n]*\\)" limit t)
(match-string 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
(string-match (concat "\\_<" (upcase cur-a) "\\_>") args))
(setq index nil ; Skip next block based on positional args.
start (match-beginning 0)
end (match-end 0)))))
(let (split)
(when (re-search-backward ":\\([^()\n]*\\)" limit t)
(setq split (split-string (match-string 1) " " t))
(prog1 (car split)
(when (cdr split)
(setq key-have-value t))))))))
;; If `cur-a' is not one of `args-lst-ak'
;; assume user is entering an unknow key
;; referenced in last position in signature.
(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.
(while (and index (>= index 1))
(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")
;; All the rest arguments are the same.
(setq index 1))
((string= argument "&optional")) ; Skip.
((string= argument "&optional")) ; Skip.
((string= argument "&allow-other-keys")) ; Skip.
;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc...
;; like in `setq'.
((or (string-match-p "\\.\\.\\.$" argument)
(and (string-match-p "\\.\\.\\.)?$" args)
((or (and (string-match-p "\\.\\.\\.$" argument)
(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)))
(setq index 0))
(t
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment