From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Mark Oteiza Newsgroups: gmane.emacs.bugs Subject: bug#28257: 26.0.50; [PATCH] expose eldoc functions in a hook Date: Fri, 14 Feb 2020 17:54:15 -0500 Message-ID: <20200214225415.GA3947@holos.localdomain> References: <87ziakwifi.fsf@holos> <87val88l0d.fsf@users.sourceforge.net> <20170828031104.GA15524@holos.localdomain> <87shgb89q1.fsf@users.sourceforge.net> <20170830015017.GA28668@holos.localdomain> <87wohasikq.fsf@gmail.com> <20190626140303.quhh4psgvd3aneyr@logos.localdomain> <20200126234731.GA12794@holos.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="96778"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Lars Ingebrigtsen , npostavs@users.sourceforge.net, Noam Postavsky , 28257@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Feb 14 23:55:15 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j2jre-000P2c-Oz for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 14 Feb 2020 23:55:14 +0100 Original-Received: from localhost ([::1]:46442 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j2jrd-0001Eu-RL for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 14 Feb 2020 17:55:13 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:46549) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j2jrV-0001ET-0M for bug-gnu-emacs@gnu.org; Fri, 14 Feb 2020 17:55:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j2jrS-0006oz-U9 for bug-gnu-emacs@gnu.org; Fri, 14 Feb 2020 17:55:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:57129) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1j2jrS-0006oo-Ew for bug-gnu-emacs@gnu.org; Fri, 14 Feb 2020 17:55:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1j2jrS-0000uj-Db for bug-gnu-emacs@gnu.org; Fri, 14 Feb 2020 17:55:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Mark Oteiza Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 14 Feb 2020 22:55:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 28257 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 28257-submit@debbugs.gnu.org id=B28257.15817208663461 (code B ref 28257); Fri, 14 Feb 2020 22:55:02 +0000 Original-Received: (at 28257) by debbugs.gnu.org; 14 Feb 2020 22:54:26 +0000 Original-Received: from localhost ([127.0.0.1]:34869 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j2jqr-0000tl-FX for submit@debbugs.gnu.org; Fri, 14 Feb 2020 17:54:26 -0500 Original-Received: from mail-qk1-f196.google.com ([209.85.222.196]:33137) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j2jqp-0000tX-65 for 28257@debbugs.gnu.org; Fri, 14 Feb 2020 17:54:24 -0500 Original-Received: by mail-qk1-f196.google.com with SMTP id h4so10862856qkm.0 for <28257@debbugs.gnu.org>; Fri, 14 Feb 2020 14:54:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=udel-edu.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=OJE1/iyFFXa0/LqIBnE6jQcca9B3ZgWwCZ+Z8os/PAs=; b=Zv0KaXPav1uhW0kjKIfsyRSgzUbYjB5wXYmrqDnq00WyzkP17TBr67XyYGFoMDqQ+B lLn1rMZ+XAFEb+Ex2TOUMzmS25NTP3DLGrAs3XscGFGw8e/aBEDjjzjST4uWwl3JHhfS qbxQ75dS9pWGzsGoW7fOExwoMAxVFymLREwohCTx9WCcFVmS0dq0xRodukKi70TPhIPA rQLy96Aa+lsMNv/2j+RODdOuXjMnomla8Ust+BB8HU+ntmZ9yRcKfQJG8qdghMoE+F5W E/ElHN92Hx7tnnCqrCbeDKroqA9d34Gv+RG+ydMzTjRgaujZePgHyAL1mDzeNdc1c1hE o1bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=OJE1/iyFFXa0/LqIBnE6jQcca9B3ZgWwCZ+Z8os/PAs=; b=noowkUq/i3EGpnTaEz6wRWvFGFZCo2Dxlz1F1s0Tk65RvZP5T1kP8rGBmUfQEAmpko p+Aou27XYkhpvcuVwjl61NPn9L5fjKmBLXnPXgbqsuXM/mUjsRBkbJnpY+3KK8PzjT9g A2XMMxO+aoaWD0IPXSqs3TprZ387FSXS+xxHOaROjMwj7yQnTrOUUKHPm4sJi+zQeP7D LrCPYSz9aKL/UoIoKWWUZyerMMOnFkzQrE+24yD0MUAqRBeyEtRThN5dKviVndvJVHNS mgOhchNri440tST6cN4RGypkyoyuJZiMrD2lm6QfCOX5dqGeMWNwUuVW3nLQAw2yMm3y wyfA== X-Gm-Message-State: APjAAAX7rS5npnGyoCruKsklYSDXfZcqxVv0GK15ioBuIH6Ei8bOLdnV X5Ts+V7qqDBJPy+SNXLxwwnA9w== X-Google-Smtp-Source: APXvYqygqx2rsOGA4mCyMSEW+z32a0qlYdaJq6c0jiDXuuNwnUj38ABXd2nbpl2D/CIm3u3GQ93wPw== X-Received: by 2002:a05:620a:b06:: with SMTP id t6mr4961747qkg.373.1581720857174; Fri, 14 Feb 2020 14:54:17 -0800 (PST) Original-Received: from holos.localdomain (c-69-251-56-176.hsd1.md.comcast.net. [69.251.56.176]) by smtp.gmail.com with ESMTPSA id g84sm4163799qke.129.2020.02.14.14.54.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 14:54:16 -0800 (PST) Content-Disposition: inline In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:176070 Archived-At: Thanks Noam and Stefan for the catches. New patch below. On 14/02/20 at 09:50am, Stefan Monnier wrote: > > +*** 'eldoc-documentation-function' is now a custom variable. > > I think this should be expanded to clarify that packages should stop > using this var and use `eldoc-documentation-functions` instead. > > <...snip...> doc/emacs/programs.texi | 24 ++++++++++++-- etc/NEWS | 12 +++++++ lisp/emacs-lisp/eldoc.el | 75 ++++++++++++++++++++++++++++++++++---------- lisp/hexl.el | 6 ++-- lisp/ielm.el | 4 +-- lisp/progmodes/cfengine.el | 15 +++++---- lisp/progmodes/elisp-mode.el | 4 +-- lisp/progmodes/octave.el | 3 +- lisp/progmodes/python.el | 6 ++-- 9 files changed, 113 insertions(+), 36 deletions(-) diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index 683374c615..8e2a22b2ff 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -1269,9 +1269,27 @@ Lisp Doc for a function, it shows the argument list, and for a variable it shows the first line of the variable's documentation string. To toggle Eldoc mode, type @kbd{M-x eldoc-mode}. There's also a Global -Eldoc mode, which is turned on by default, and affects buffers, such -as @samp{*scratch*}, whose major mode is Emacs Lisp or Lisp -Interaction (@w{@kbd{M-x global-eldoc-mode}} to turn it off globally). +Eldoc mode, which is turned on by default, and affects buffers whose +major mode sets the variables described below. Use @w{@kbd{M-x +global-eldoc-mode}} to turn it off globally. + +@vindex eldoc-documentation-function +@vindex eldoc-documentation-functions + These variables can be used to configure ElDoc mode: + +@table @code +@item eldoc-documentation-function +This variable holds the function which is used to retrieve +documentation for the item at point from the functions in the hook +@code{eldoc-documentation-functions}. By default, +@code{eldoc-documentation-function} returns the first documentation +string produced by the @code{eldoc-documentation-functions} hook. + +@item eldoc-documentation-functions +This abnormal hook holds documentation functions. It acts as a +collection of backends for ElDoc. This is what modes should use to +register their documentation functions with ElDoc. +@end table @node Hideshow @section Hideshow minor mode diff --git a/etc/NEWS b/etc/NEWS index b0e17c7c03..793be515c5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -120,6 +120,18 @@ To revert to the previous behaviour, unconditionally aborts the current edebug instrumentation with the supplied error message. ++++ +** ElDoc + +*** New hook 'eldoc-documentation-functions' to be used for registering +doc string functions. This makes the results of all doc string +functions accessible to the user through the existing single function hook +'eldoc-documentation-function'. + +*** 'eldoc-documentation-function' is now a custom variable. +Modes should use the new hook instead of this variable to register +their backends. + ** Tramp +++ diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 7a7b8ec164..d96e569fca 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -40,9 +40,9 @@ ;; (add-hook 'ielm-mode-hook 'eldoc-mode) ;; (add-hook 'eval-expression-minibuffer-setup-hook 'eldoc-mode) -;; Major modes for other languages may use ElDoc by defining an -;; appropriate function as the buffer-local value of -;; `eldoc-documentation-function'. +;; Major modes for other languages may use ElDoc by adding an +;; appropriate function to the buffer-local value of +;; `eldoc-documentation-functions'. ;;; Code: @@ -222,8 +222,8 @@ global-eldoc-mode (defun eldoc--eval-expression-setup () ;; Setup `eldoc', similar to `emacs-lisp-mode'. FIXME: Call ;; `emacs-lisp-mode' itself? - (add-function :before-until (local 'eldoc-documentation-function) - #'elisp-eldoc-documentation-function) + (add-hook 'eldoc-documentation-functions + #'elisp-eldoc-documentation-function nil t) (eldoc-mode +1)) ;;;###autoload @@ -235,7 +235,11 @@ turn-on-eldoc-mode (defun eldoc--supported-p () "Non-nil if an ElDoc function is set for this buffer." - (not (memq eldoc-documentation-function '(nil ignore)))) + (let ((hook 'eldoc-documentation-functions)) + (and (not (memq eldoc-documentation-function '(nil ignore))) + (or (and (local-variable-p hook) + (buffer-local-value hook (current-buffer))) + (default-value hook))))) (defun eldoc-schedule-timer () @@ -347,8 +351,46 @@ eldoc-display-message-no-interference-p (not (or executing-kbd-macro (bound-and-true-p edebug-active)))) -;;;###autoload -(defvar eldoc-documentation-function #'ignore +(defvar eldoc-documentation-functions nil + "Hook for functions to call to return doc string. +Each function should accept no arguments and return a one-line +string for displaying doc about a function etc. appropriate to +the context around point. It should return nil if there's no doc +appropriate for the context. Typically doc is returned if point +is on a function-like name or in its arg list. + +Major modes should modify this hook locally, for example: + (add-hook \\='eldoc-documentation-functions #\\='foo-mode-eldoc nil t) +so that the global value (i.e. the default value of the hook) is +taken into account if the major mode specific function does not +return any documentation.") + +(defun eldoc-documentation-default () + "Show first doc string for item at point. +Default value for `eldoc-documentation-function'." + (let ((res (run-hook-with-args-until-success 'eldoc-documentation-functions))) + (when res + (if eldoc-echo-area-use-multiline-p res + (truncate-string-to-width + res (1- (window-width (minibuffer-window)))))))) + +(defun eldoc-documentation-compose () + "Show multiple doc string results at once. +Meant as a value for `eldoc-documentation-function'." + (let (res) + (run-hook-wrapped + 'eldoc-documentation-functions + (lambda (f) + (let ((str (funcall f))) + (when str (push str res)) + nil))) + (when res + (setq res (mapconcat #'identity (nreverse res) ", ")) + (if eldoc-echo-area-use-multiline-p res + (truncate-string-to-width + res (1- (window-width (minibuffer-window)))))))) + +(defcustom eldoc-documentation-function #'eldoc-documentation-default "Function to call to return doc string. The function of no args should return a one-line string for displaying doc about a function etc. appropriate to the context around point. @@ -359,14 +401,12 @@ eldoc-documentation-function The result is used as is, so the function must explicitly handle the variables `eldoc-argument-case' and `eldoc-echo-area-use-multiline-p', and the face `eldoc-highlight-function-argument', if they are to have any -effect. - -Major modes should modify this variable using `add-function', for example: - (add-function :before-until (local \\='eldoc-documentation-function) - #\\='foo-mode-eldoc-function) -so that the global documentation function (i.e. the default value of the -variable) is taken into account if the major mode specific function does not -return any documentation.") +effect." + :link '(info-link "(emacs) Lisp Doc") + :type '(radio (function-item eldoc-documentation-default) + (function-item eldoc-documentation-compose) + (function :tag "Other function")) + :group 'eldoc) (defun eldoc-print-current-symbol-info () "Print the text produced by `eldoc-documentation-function'." @@ -381,7 +421,8 @@ eldoc-print-current-symbol-info ;; Only keep looking for the info as long as the user hasn't ;; requested our attention. This also locally disables inhibit-quit. (while-no-input - (eldoc-message (funcall eldoc-documentation-function))))))) + (let ((fun eldoc-documentation-function)) + (when fun (eldoc-message (funcall fun))))))))) ;; If the entire line cannot fit in the echo area, the symbol name may be ;; truncated or eliminated entirely from the output to make room for the diff --git a/lisp/hexl.el b/lisp/hexl.el index 58518e7416..cf7118f208 100644 --- a/lisp/hexl.el +++ b/lisp/hexl.el @@ -367,8 +367,8 @@ hexl-mode (add-hook 'change-major-mode-hook #'hexl-maybe-dehexlify-buffer nil t) ;; Set a callback function for eldoc. - (add-function :before-until (local 'eldoc-documentation-function) - #'hexl-print-current-point-info) + (add-hook 'eldoc-documentation-functions + #'hexl-print-current-point-info nil t) (eldoc-add-command-completions "hexl-") (eldoc-remove-command "hexl-save-buffer" "hexl-current-address") @@ -455,6 +455,8 @@ hexl-revert-buffer-function ;; 2. reset change-major-mode-hook in case that `hexl-mode' ;; previously added hexl-maybe-dehexlify-buffer to it. (remove-hook 'change-major-mode-hook #'hexl-maybe-dehexlify-buffer t) + (remove-hook 'eldoc-documentation-functions + #'hexl-print-current-point-info t) (setq major-mode 'fundamental-mode) (hexl-mode))) diff --git a/lisp/ielm.el b/lisp/ielm.el index 41675c011d..fc06ebfa2d 100644 --- a/lisp/ielm.el +++ b/lisp/ielm.el @@ -541,8 +541,8 @@ inferior-emacs-lisp-mode (set (make-local-variable 'completion-at-point-functions) '(comint-replace-by-expanded-history ielm-complete-filename elisp-completion-at-point)) - (add-function :before-until (local 'eldoc-documentation-function) - #'elisp-eldoc-documentation-function) + (add-hook 'eldoc-documentation-functions + #'elisp-eldoc-documentation-function nil t) (set (make-local-variable 'ielm-prompt-internal) ielm-prompt) (set (make-local-variable 'comint-prompt-read-only) ielm-prompt-read-only) (setq comint-get-old-input 'ielm-get-old-input) diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index 9ddb2ab2bb..a94a6666bb 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el @@ -1390,12 +1390,15 @@ cfengine3-mode (when buffer-file-name (shell-quote-argument buffer-file-name))))) - ;; For emacs < 25.1 where `eldoc-documentation-function' defaults to - ;; nil. - (or eldoc-documentation-function - (setq-local eldoc-documentation-function #'ignore)) - (add-function :before-until (local 'eldoc-documentation-function) - #'cfengine3-documentation-function) + (if (boundp 'eldoc-documentation-functions) + (add-hook 'eldoc-documentation-functions + #'cfengine3-documentation-function nil t) + ;; For emacs < 25.1 where `eldoc-documentation-function' defaults + ;; to nil. + (or eldoc-documentation-function + (setq-local eldoc-documentation-function #'ignore)) + (add-function :before-until (local 'eldoc-documentation-function) + #'cfengine3-documentation-function)) (add-hook 'completion-at-point-functions #'cfengine3-completion-function nil t) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 2617a6e4cc..813b628bc3 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -250,8 +250,8 @@ emacs-lisp-mode (add-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-text-pairs)) (setq-local electric-quote-string t) (setq imenu-case-fold-search nil) - (add-function :before-until (local 'eldoc-documentation-function) - #'elisp-eldoc-documentation-function) + (add-hook 'eldoc-documentation-functions + #'elisp-eldoc-documentation-function nil t) (add-hook 'xref-backend-functions #'elisp--xref-backend nil t) (setq-local project-vc-external-roots-function #'elisp-load-path-roots) (add-hook 'completion-at-point-functions diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 9e03956254..352c1810d1 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -619,8 +619,7 @@ octave-mode (add-hook 'before-save-hook 'octave-sync-function-file-names nil t) (setq-local beginning-of-defun-function 'octave-beginning-of-defun) (and octave-font-lock-texinfo-comment (octave-font-lock-texinfo-comment)) - (add-function :before-until (local 'eldoc-documentation-function) - 'octave-eldoc-function) + (add-hook 'eldoc-documentation-functions 'octave-eldoc-function nil t) (easy-menu-add octave-mode-menu)) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index a2d85d0bef..67383b3415 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -5544,8 +5544,10 @@ python-mode ;; Emacs<25 (set (make-local-variable 'eldoc-documentation-function) #'python-eldoc-function) - (add-function :before-until (local 'eldoc-documentation-function) - #'python-eldoc-function)) + (if (boundp 'eldoc-documentation-functions) + (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t) + (add-function :before-until (local 'eldoc-documentation-function) + #'python-eldoc-function))) (add-to-list 'hs-special-modes-alist