unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#18048: 24.3.92; [patch] eldoc improvements
@ 2014-07-18  5:46 Thierry Volpiatto
  2014-07-19  3:07 ` Stefan Monnier
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-18  5:46 UTC (permalink / raw)
  To: 18048


Here a little patch that add two improvements to eldoc:

1) Allow adding manually informations to a symbol for eldoc:
   When a symbol use (&rest args), we want sometimes more meaningful infos
   on ARGS, this can be added with `put'.
e.g
(defun foo (&rest args)
  "Eval each ARG in ARGS like setq"
  [...])
(put 'foo 'eldoc "([VAR VALUE]...)")

Now when I use `foo' function I have in eldoc:
(foo ([VAR VALUE]...))

2) Better handling of "..." in eldoc highlighting:
Actually when using `setq', highlighting is correct when setting one
symbol: 
(setq foo 1)
When cursor is on foo we have in eldoc: (setq ([SYM VAL]...))
                                               ^^^^ 
And when cursor is on 1 (setq ([SYM VAL]...))
                                    ^^^^^^^
When setting more than one symbol e.g
(setq foo 1 bar 2)
After 1 eldoc highlighting stay on second arg:
(setq ([SYM VAL]...))
            ^^^^^^^
With this patch highlighting come back on first arg (SYM)

diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index c64ec52..19962d5 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -349,8 +349,9 @@ or elsewhere, return a 1-line docstring.  Calls the functions
 former calls `eldoc-argument-case'; the latter gives the
 function name `font-lock-function-name-face', and optionally
 highlights argument number INDEX."
-  (let (args doc advertised)
-    (cond ((not (and sym (symbolp sym) (fboundp sym))))
+  (let (args doc advertised (prop (get sym 'eldoc)))
+    (cond (prop (setq doc prop))
+          ((not (and sym (symbolp sym) (fboundp sym))))
 	  ((and (eq sym (aref eldoc-last-data 0))
 		(eq 'function (aref eldoc-last-data 2)))
 	   (setq doc (aref eldoc-last-data 1)))
@@ -400,7 +401,9 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
 		     ;; All the rest arguments are the same.
 		     (setq index 1))
 		    ((string= argument "&optional"))
-		    ((string-match-p "\\.\\.\\.$" argument)
+		    ((or (string-match-p "\\.\\.\\.$" argument)
+                         (and (string-match-p "\\.\\.\\.)?$" args)
+                              (> index 1) (oddp index)))
 		     (setq index 0))
 		    (t
 		     (setq index (1- index))))))




In GNU Emacs 24.3.92.6 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.8)
 of 2014-07-15 on dell-14z
Windowing system distributor `The X.Org Foundation', version 11.0.11501000
System Description:	Ubuntu 14.04 LTS

Configured using:
 `configure --without-toolkit-scroll-bars --without-gconf
 --without-gsettings'

Important settings:
  value of $LANG: fr_FR.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  psession-mode: t
  golden-ratio-mode: t
  winner-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  auto-image-file-mode: t
  eldoc-in-minibuffer-mode: t
  show-paren-mode: t
  display-time-mode: t
  recentf-mode: t
  savehist-mode: t
  eldoc-mode: t
  minibuffer-depth-indicate-mode: t
  helm-mode: t
  helm-descbinds-mode: t
  shell-dirtrack-mode: t
  helm-adaptive-mode: t
  helm-match-plugin-mode: t
  helm-occur-match-plugin-mode: t
  tooltip-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
<f11> s c <left> <right> <up> <up> M-e <down> <down> 
<right> <right> <right> <right> <right> <right> <right> 
<right> <right> <right> <right> <right> <right> <right> 
<right> <right> <up> <left> <left> <left> <left> <left> 
<left> <left> <left> <left> <left> <left> <left> <right> 
<right> <right> <backspace> <backspace> <backspace> 
<backspace> SPC 3 <left> <right> <right> M-x r e p 
o r t <return>

Recent messages:
Restoring buffers...78%
Setting up indent for shell type bash
Indentation variables are now local.
Indentation setup for shell type bash
Setting up indent for shell type sh
Indentation variables are now local.
Indentation setup for shell type sh
Restoring buffers...done
"([VAR VALUE]...)"
Auto-saving...

Load-path shadows:
~/elisp/auctex/lpath hides ~/elisp/emacs-wget/lpath
/usr/local/share/emacs/24.3.92/lisp/emacs-lisp/tq hides ~/elisp/emms/lisp/tq

Features:
(shadow epa-mail mule-util emacsbug helm-command cc-langs rst
markdown-mode sh-script smie executable make-mode vc-rcs js json moz
imenu cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align
cc-engine cc-vars cc-defs vc-git naquadah-theme em-unix em-script
em-prompt em-ls em-hist em-pred em-glob em-dirs em-cmpl em-basic
em-banner em-alias align-let git-gutter server psession golden-ratio
winner undo-tree diff slime-xref-browser slime-banner slime-tramp
slime-asdf slime-fancy slime-trace-dialog slime-fontifying-fu
slime-package-fu slime-references slime-compiler-notes-tree
slime-scratch slime-presentations bridge slime-fuzzy slime-fancy-trace
slime-fancy-inspector slime-c-p-c slime-editing-commands slime-autodoc
slime-repl elp slime-parse slime gud apropos etags arc-mode archive-mode
hyperspec image-file xdvi-search preview-latex tex-site auto-loads
pcomplete-extension pcmpl-unix pcmpl-gnu em-term term disp-table ehelp
helm-ipython helm-elisp helm-eval python eldoc-eval warnings whitespace
paren time recentf tree-widget savehist mu4e-config org-mu4e helm-mu
mu4e-contrib mu4e mu4e-speedbar speedbar sb-image ezimage dframe
mu4e-main mu4e-view mu4e-headers mu4e-compose mu4e-draft mu4e-actions
ido rfc2368 mu4e-mark mu4e-message html2text mu4e-proc mu4e-utils
mu4e-lists mu4e-about mu4e-vars mu4e-meta gnus-dired nnir gnus-sum
gnus-group gnus-undo nnmail mail-source gnus-start gnus-spec gnus-int
gnus-range gnus-win nnoo config-w3m w3m-search w3m doc-view jka-compr
image-mode timezone w3m-hist w3m-fb bookmark-w3m w3m-ems w3m-ccl ccl
w3m-favicon w3m-image w3m-proc w3m-util w3m-load smtpmail-async smtpmail
sendmail dired-async iterator lacarte iedit-rect iedit iedit-lib
smallurl mm-url gnus gnus-ems nnheader wid-edit rectangle-utils rect
ledger-config ledger esh-var esh-io esh-cmd esh-opt esh-ext esh-proc
eldoc esh-groups eshell esh-module esh-mode esh-arg esh-util tv-utils
async pcvs vc-cvs pcvs-parse pcvs-info pcvs-defs pcvs-util ewoc mb-depth
cl-info slime-autoloads esh-toggle flymake no-word htmlize cl
dired-extension emms-mpd-config emms-playlist-limit emms-volume
emms-volume-amixer emms-i18n emms-history emms-score emms-stream-info
emms-metaplaylist-mode emms-bookmarks emms-cue emms-mode-line-icon
emms-browser sort emms-playlist-sort emms-last-played emms-player-xine
emms-player-mpd tq emms-playing-time emms-lyrics emms-url hl-line
emms-tag-editor emms-mark emms-mode-line emms-cache emms-info-ogginfo
emms-info-mp3info emms-playlist-mode emms-player-vlc emms-player-mplayer
emms-info emms-streams later-do emms-source-playlist emms-source-file
emms-player-simple emms-setup emms emms-compat org-config-thierry ob-sh
org-crypt cal-china lunar solar cal-dst cal-bahai cal-islam cal-hebrew
holidays hol-loaddefs appt diary-lib diary-loaddefs
org-annotation-helper addressbook-bookmark message rfc822 mml mml-sec
mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev mail-utils gmm-utils mailheader firefox-protocol
bookmark-firefox-handler bookmark-extensions org org-macro org-footnote
org-pcomplete org-list org-faces org-entities noutline outline
easy-mmode org-version ob-emacs-lisp ob ob-tangle org-src ob-ref ob-lob
ob-table ob-keys ob-exp ob-comint ob-core ob-eval org-compat org-macs
org-loaddefs find-func cal-menu calendar cal-loaddefs init-helm-thierry
helm-mode helm-dictionary helm-ls-git helm-descbinds helm-ls-hg
helm-files image-dired tramp tramp-compat tramp-loaddefs trampver shell
pcomplete format-spec dired-x dired-aux ffap thingatpt helm-buffers
helm-elscreen helm-tags helm-bookmark helm-adaptive helm-info helm-net
browse-url xml url url-proxy url-privacy url-expand url-methods
url-history url-cookie url-domsuf url-util url-parse url-vars mailcap
helm-plugin bookmark pp helm-help helm-match-plugin helm-grep wgrep-helm
wgrep helm-regexp grep helm-external helm-utils dired compile comint
ansi-color ring helm-locate helm cl-macs gv vc vc-dispatcher helm-config
helm-aliases epa-file epa derived epg epg-config auth-source eieio
byte-opt bytecomp byte-compile cconv eieio-core gnus-util mm-util
mail-prsvr password-cache package time-date avoid cus-start cus-load
w3m-wget info easymenu edmacro kmacro advice help-fns net-utils
cl-loaddefs cl-lib tooltip electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel x-win x-dnd tool-bar dnd fontset image regexp-opt
fringe tabulated-list newcomment lisp-mode prog-mode register page
menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock font-lock
syntax facemenu font-core frame cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
case-table epa-hook jka-cmpr-hook help simple abbrev minibuffer nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process dbusbind
gfilenotify dynamic-setting font-render-setting move-toolbar gtk
x-toolkit x multi-tty emacs)

Memory information:
((conses 16 536201 35503)
 (symbols 48 56357 9)
 (miscs 40 627 671)
 (strings 32 139699 18835)
 (string-bytes 1 4218847)
 (vectors 16 49691)
 (vector-slots 8 885428 24463)
 (floats 8 2130 170)
 (intervals 56 2486 0)
 (buffers 960 108)
 (heap 1024 42632 3181))
-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-18  5:46 bug#18048: 24.3.92; [patch] eldoc improvements Thierry Volpiatto
@ 2014-07-19  3:07 ` Stefan Monnier
  2014-07-19  5:25   ` Thierry Volpiatto
                     ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Stefan Monnier @ 2014-07-19  3:07 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: 18048

> (defun foo (&rest args)
>   "Eval each ARG in ARGS like setq"
>   [...])
> (put 'foo 'eldoc "([VAR VALUE]...)")

You can use

   (defun foo (&rest args)
     "Eval each ARG in ARGS like setq.

   (fn [VAR VALUE]...)"
     [...])

Instead.

> 2) Better handling of "..." in eldoc highlighting:
> Actually when using `setq', highlighting is correct when setting one
> symbol: 
> (setq foo 1)
> When cursor is on foo we have in eldoc: (setq ([SYM VAL]...))
>                                                ^^^^ 
> And when cursor is on 1 (setq ([SYM VAL]...))
>                                     ^^^^^^^
> When setting more than one symbol e.g
> (setq foo 1 bar 2)
> After 1 eldoc highlighting stay on second arg:
> (setq ([SYM VAL]...))
>             ^^^^^^^
> With this patch highlighting come back on first arg (SYM)

This part looks OK, feel free to install into trunk.


        Stefan





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-19  3:07 ` Stefan Monnier
@ 2014-07-19  5:25   ` Thierry Volpiatto
  2014-07-19  5:46   ` Thierry Volpiatto
  2014-07-19  8:11   ` Thierry Volpiatto
  2 siblings, 0 replies; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-19  5:25 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048


Stefan Monnier <monnier@iro.umontreal.ca> writes:

> You can use
>
>    (defun foo (&rest args)
>      "Eval each ARG in ARGS like setq.
>
>    (fn [VAR VALUE]...)"
>      [...])
>
> Instead.

This is not working.

> This part looks OK, feel free to install into trunk.

I can't do that, please do it.

Thanks.

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-19  3:07 ` Stefan Monnier
  2014-07-19  5:25   ` Thierry Volpiatto
@ 2014-07-19  5:46   ` Thierry Volpiatto
  2014-07-19  8:11   ` Thierry Volpiatto
  2 siblings, 0 replies; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-19  5:46 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048


Stefan Monnier <monnier@iro.umontreal.ca> writes:

> You can use
>
>    (defun foo (&rest args)
>      "Eval each ARG in ARGS like setq.
>
>    (fn [VAR VALUE]...)"
>      [...])
>
> Instead.

Ok I got it, your example above is not working, but like this yes:

(defun foo (&rest args)
  "Eval each ARG in ARGS like setq.

\(fn VAR VALUE...)"
  nil)

Is this documented somewhere ?

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-19  3:07 ` Stefan Monnier
  2014-07-19  5:25   ` Thierry Volpiatto
  2014-07-19  5:46   ` Thierry Volpiatto
@ 2014-07-19  8:11   ` Thierry Volpiatto
  2014-07-19 17:01     ` Stefan Monnier
  2 siblings, 1 reply; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-19  8:11 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048


Also the words &key and &allow-other-keys are upcased.

diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index c64ec52..85c40b6 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -551,12 +551,15 @@ ARGLIST is either a string, or a list of strings or symbols."
 
 (defun eldoc-function-argstring-format (argstring)
   "Apply `eldoc-argument-case' to each word in ARGSTRING.
-The words \"&rest\", \"&optional\" are returned unchanged."
-  (mapconcat (lambda (s)
-	       (if (string-match-p "\\`(?&\\(?:optional\\|rest\\))?\\'" s)
-		   s
-		 (funcall eldoc-argument-case s)))
-	     (split-string argstring) " "))
+The words \"&rest\", \"&optional\", \"&key\" and \"&allow-other-keys\"
+are returned unchanged."
+  (mapconcat
+   (lambda (s)
+     (if (string-match-p
+          "\\`(?&\\(?:optional\\|rest\\|key\\|allow-other-keys\\))?\\'" s)
+         s
+       (funcall eldoc-argument-case s)))
+   (split-string argstring) " "))


-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-19  8:11   ` Thierry Volpiatto
@ 2014-07-19 17:01     ` Stefan Monnier
  2014-07-21  7:24       ` Thierry Volpiatto
  2014-07-21 12:27       ` Thierry Volpiatto
  0 siblings, 2 replies; 13+ messages in thread
From: Stefan Monnier @ 2014-07-19 17:01 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: 18048

> Also the words &key and &allow-other-keys are upcased.

Hmm... this eldoc code reminds me of similar code in help-fns.el.
Can you take a look at it and see if we could consolidate them?


        Stefan





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-19 17:01     ` Stefan Monnier
@ 2014-07-21  7:24       ` Thierry Volpiatto
  2014-08-18 19:32         ` Stefan Monnier
  2014-07-21 12:27       ` Thierry Volpiatto
  1 sibling, 1 reply; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-21  7:24 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048


Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Also the words &key and &allow-other-keys are upcased.
>
> Hmm... this eldoc code reminds me of similar code in help-fns.el.
> Can you take a look at it and see if we could consolidate them?

I didn't find in help-fns.el, but in help.el I found
`help-function-arglist' which is used by eldoc.

diff --git a/lisp/help.el b/lisp/help.el
index fa2a4f2..8bd5fd0 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1294,7 +1294,7 @@ the same names as used in the original source code, when possible."
               (unless (and (symbolp arg)
                            (let ((name (symbol-name arg)))
                              (if (eq (aref name 0) ?&)
-                                 (memq arg '(&rest &optional))
+                                 (memq arg '(&rest &optional &key &allow-other-keys))
                                (not (string-match "\\." name)))))
                 (setq valid nil)))
             (when valid arglist)))

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-19 17:01     ` Stefan Monnier
  2014-07-21  7:24       ` Thierry Volpiatto
@ 2014-07-21 12:27       ` Thierry Volpiatto
  2014-07-21 15:13         ` Thierry Volpiatto
  1 sibling, 1 reply; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-21 12:27 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048


And also "&key" highlighting is not supported by eldoc, I could end up
soon which a patch for this too if interested (it is indeed nearly
finished), let me know.

e.g (cursor at "!")

(defun foo (a b &key c d e f))

(foo 1 2 :e !3 :c 4 :f 5 :d 6)

=> eldoc: (foo: (A B &key C D E F)) 
                              ^  
-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-21 12:27       ` Thierry Volpiatto
@ 2014-07-21 15:13         ` Thierry Volpiatto
  2014-07-22  6:16           ` Thierry Volpiatto
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-21 15:13 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048


Here all changes done on eldoc.el:

1) Fix highlighting args in setq or similar &rest args.
2) Fix highlighting cl keyword args with &key.
3) Don't upcase &key and &allow-other-keys.

Changes from master to working directory
1 file changed, 36 insertions(+), 9 deletions(-)
 lisp/emacs-lisp/eldoc.el | 45 ++++++++++++++++++++++++++++++++++++---------

	Modified   lisp/emacs-lisp/eldoc.el
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 7102b55..9959f57 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -388,6 +388,27 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
     ;;        (defun NAME ARGLIST [DOCSTRING] BODY...) case?
     ;;        The problem is there is no robust way to determine if
     ;;        the current argument is indeed a docstring.
+    (when (string-match "&key" args)
+      (let* (case-fold-search
+             (cur-w (current-word))
+             (args-lst (mapcar (lambda (x)
+                                 (replace-regexp-in-string
+                                  "\\`[(]\\|[)]\\'" "" x))
+                               (split-string args)))
+             (args-lst-ak (member "&key" args-lst))
+             (limit (save-excursion
+                      (when (re-search-backward (symbol-name sym) nil t)
+                        (match-end 0))))
+             (cur-a (if (string-match ":\\([^ ()]*\\)" cur-w)
+                        (substring cur-w 1)
+                      (save-excursion
+                        (if (re-search-backward ":\\([^ ()\n]*\\)" limit t)
+                            (match-string 1)
+                          cur-w)))))
+        (when (member (upcase cur-a) args-lst-ak)
+          (setq index nil
+                start (string-match (upcase cur-a) args)
+                end   (match-end 0)))))
     (while (and index (>= index 1))
       (if (string-match "[^ ()]+" args end)
 	  (progn
@@ -398,8 +419,11 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
 		     ;; All the rest arguments are the same.
 		     (setq index 1))
 		    ((string= argument "&optional"))
-		    ((string-match-p "\\.\\.\\.$" argument)
-		     (setq index 0))
+                    ((string= argument "&allow-other-keys"))
+		    ((or (string-match-p "\\.\\.\\.$" argument)
+                         (and (string-match-p "\\.\\.\\.)?$" args)
+                              (> index 1) (oddp index)))
+                     (setq index 0))
 		    (t
 		     (setq index (1- index))))))
 	(setq end           (length args)
@@ -548,13 +572,16 @@ ARGLIST is either a string, or a list of strings or symbols."
       (format "(%s)" arglist)))
 
 (defun eldoc-function-argstring-format (argstring)
-  "Apply `eldoc-argument-case' to each word in ARGSTRING.
-The words \"&rest\", \"&optional\" are returned unchanged."
-  (mapconcat (lambda (s)
-	       (if (string-match-p "\\`(?&\\(?:optional\\|rest\\))?\\'" s)
-		   s
-		 (funcall eldoc-argument-case s)))
-	     (split-string argstring) " "))
+    "Apply `eldoc-argument-case' to each word in ARGSTRING.
+The words \"&rest\", \"&optional\", \"&key\" and \"&allow-other-keys\"
+are returned unchanged."
+    (mapconcat
+     (lambda (s)
+       (if (string-match-p
+            "\\`(?&\\(?:optional\\|rest\\|key\\|allow-other-keys\\))?\\'" s)
+           s
+         (funcall eldoc-argument-case s)))
+     (split-string argstring) " "))
 
 \f
 ;; When point is in a sexp, the function args are not reprinted in the echo


-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-21 15:13         ` Thierry Volpiatto
@ 2014-07-22  6:16           ` Thierry Volpiatto
  0 siblings, 0 replies; 13+ messages in thread
From: Thierry Volpiatto @ 2014-07-22  6:16 UTC (permalink / raw)
  To: 18048


Here the last version of previous patch simplified and with some
comments.


Changes from master to working directory
1 file changed, 42 insertions(+), 10 deletions(-)
 lisp/emacs-lisp/eldoc.el | 52 ++++++++++++++++++++++++++++++++++++++----------

	Modified   lisp/emacs-lisp/eldoc.el
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 7102b55..744dea7 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -388,6 +388,30 @@ In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
     ;;        (defun NAME ARGLIST [DOCSTRING] BODY...) case?
     ;;        The problem is there is no robust way to determine if
     ;;        the current argument is indeed a docstring.
+
+    ;; When `&key' is used finding position based on `index'
+    ;; would be wrong, so find the arg at point and determine
+    ;; position in ARGS based on this current arg.
+    (when (string-match "&key" args)
+      (let* (case-fold-search
+             (cur-w (current-word))
+             (limit (save-excursion
+                      (when (re-search-backward (symbol-name sym) nil t)
+                        (match-end 0))))
+             (cur-a (if (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)))))
+    ;; Handle now positional arguments.
     (while (and index (>= index 1))
       (if (string-match "[^ ()]+" args end)
 	  (progn
@@ -397,9 +421,14 @@ 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"))
-		    ((string-match-p "\\.\\.\\.$" argument)
-		     (setq index 0))
+		    ((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)
+                              (> index 1) (oddp index)))
+                     (setq index 0))
 		    (t
 		     (setq index (1- index))))))
 	(setq end           (length args)
@@ -548,13 +577,16 @@ ARGLIST is either a string, or a list of strings or symbols."
       (format "(%s)" arglist)))
 
 (defun eldoc-function-argstring-format (argstring)
-  "Apply `eldoc-argument-case' to each word in ARGSTRING.
-The words \"&rest\", \"&optional\" are returned unchanged."
-  (mapconcat (lambda (s)
-	       (if (string-match-p "\\`(?&\\(?:optional\\|rest\\))?\\'" s)
-		   s
-		 (funcall eldoc-argument-case s)))
-	     (split-string argstring) " "))
+    "Apply `eldoc-argument-case' to each word in ARGSTRING.
+The words \"&rest\", \"&optional\", \"&key\" and \"&allow-other-keys\"
+are returned unchanged."
+    (mapconcat
+     (lambda (s)
+       (if (string-match-p
+            "\\`(?&\\(?:optional\\|rest\\|key\\|allow-other-keys\\))?\\'" s)
+           s
+         (funcall eldoc-argument-case s)))
+     (split-string argstring) " "))
 
 \f
 ;; When point is in a sexp, the function args are not reprinted in the echo


-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 






^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-07-21  7:24       ` Thierry Volpiatto
@ 2014-08-18 19:32         ` Stefan Monnier
  2014-08-19  5:39           ` Thierry Volpiatto
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Monnier @ 2014-08-18 19:32 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: 18048-done

> I didn't find in help-fns.el, but in help.el I found
> `help-function-arglist' which is used by eldoc.

Hmm... no, this one does something different, so it definitely shouldn't
skip &key and other CLisms.

I installed a completely different patch in eldoc which uses
help-make-usage so that the appearance is "as good as C-h f".
This gives us "always upcase" arguments already, so there's no need to
upcase them manually afterwards.

So I also removed support for eldoc-argument-case, which is kind of
a pain to implement properly.

I also installed your &key handling patch, thanks.


        Stefan





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-08-18 19:32         ` Stefan Monnier
@ 2014-08-19  5:39           ` Thierry Volpiatto
  2014-09-04 14:50             ` Stefan Monnier
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Volpiatto @ 2014-08-19  5:39 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 18048-done


Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

> I also installed your &key handling patch, thanks.

Thanks, however this patch doesn't handle things like:

--8<---------------cut here---------------start------------->8---
(define-ibuffer-op 1 2 "" :interactive t :mark 'foo :dangerous t :modifier-p t (foo))
                                                                               ^^^^^
or

(cl-multiple-value-bind (a b c) '(1 2 3) (+ a b c))
--8<---------------cut here---------------end--------------->8---

This patch is fixing it:

diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 0b8304a..c2d3c98 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -371,7 +371,11 @@ or elsewhere, return a 1-line docstring."
 In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
   (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 +389,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,13 +446,16 @@ 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)
-                              (> index 1) (cl-oddp index)))
+		    ((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) (oddp index)))
                      (setq index 0))
 		    (t
 		     (setq index (1- index))))))

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 





^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#18048: 24.3.92; [patch] eldoc improvements
  2014-08-19  5:39           ` Thierry Volpiatto
@ 2014-09-04 14:50             ` Stefan Monnier
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Monnier @ 2014-09-04 14:50 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: 18048-done

>> I also installed your &key handling patch, thanks.
> Thanks, however this patch doesn't handle things like:

> --8<---------------cut here---------------start------------->8---
> (define-ibuffer-op 1 2 "" :interactive t :mark 'foo :dangerous t :modifier-p t (foo))

Thanks, installed.  I added two FIXMEs, there: the code is rather
unwieldy now.


        Stefan





^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-09-04 14:50 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-18  5:46 bug#18048: 24.3.92; [patch] eldoc improvements Thierry Volpiatto
2014-07-19  3:07 ` Stefan Monnier
2014-07-19  5:25   ` Thierry Volpiatto
2014-07-19  5:46   ` Thierry Volpiatto
2014-07-19  8:11   ` Thierry Volpiatto
2014-07-19 17:01     ` Stefan Monnier
2014-07-21  7:24       ` Thierry Volpiatto
2014-08-18 19:32         ` Stefan Monnier
2014-08-19  5:39           ` Thierry Volpiatto
2014-09-04 14:50             ` Stefan Monnier
2014-07-21 12:27       ` Thierry Volpiatto
2014-07-21 15:13         ` Thierry Volpiatto
2014-07-22  6:16           ` Thierry Volpiatto

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).