From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: npostavs@users.sourceforge.net Newsgroups: gmane.emacs.bugs Subject: bug#26894: 25.1, 26.0.50; =?UTF-8?Q?=E2=80=98eshell/which=E2=80=99?= abuses =?UTF-8?Q?=E2=80=98describe-function=E2=80=99?= Date: Sat, 03 Jun 2017 22:50:58 -0400 Message-ID: <871sr01n59.fsf@users.sourceforge.net> References: <87d1belsvn.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1496544620 27406 195.159.176.226 (4 Jun 2017 02:50:20 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 4 Jun 2017 02:50:20 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2.50 (gnu/linux) Cc: 26894@debbugs.gnu.org To: Dmitry Alexandrov <321942@gmail.com> Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Jun 04 04:50:12 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dHLcK-0006ff-0T for geb-bug-gnu-emacs@m.gmane.org; Sun, 04 Jun 2017 04:50:12 +0200 Original-Received: from localhost ([::1]:55582 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dHLcP-0000fn-9r for geb-bug-gnu-emacs@m.gmane.org; Sat, 03 Jun 2017 22:50:17 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45947) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dHLcF-0000dv-Fx for bug-gnu-emacs@gnu.org; Sat, 03 Jun 2017 22:50:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dHLcA-0002q1-DA for bug-gnu-emacs@gnu.org; Sat, 03 Jun 2017 22:50:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:51759) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dHLcA-0002pg-7t for bug-gnu-emacs@gnu.org; Sat, 03 Jun 2017 22:50:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dHLc9-0002CP-QV for bug-gnu-emacs@gnu.org; Sat, 03 Jun 2017 22:50:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: npostavs@users.sourceforge.net Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 04 Jun 2017 02:50:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 26894 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 26894-submit@debbugs.gnu.org id=B26894.14965445708405 (code B ref 26894); Sun, 04 Jun 2017 02:50:01 +0000 Original-Received: (at 26894) by debbugs.gnu.org; 4 Jun 2017 02:49:30 +0000 Original-Received: from localhost ([127.0.0.1]:54436 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dHLbd-0002BQ-Vq for submit@debbugs.gnu.org; Sat, 03 Jun 2017 22:49:30 -0400 Original-Received: from mail-it0-f48.google.com ([209.85.214.48]:35699) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dHLbb-0002B4-Bj; Sat, 03 Jun 2017 22:49:27 -0400 Original-Received: by mail-it0-f48.google.com with SMTP id m62so36419203itc.0; Sat, 03 Jun 2017 19:49:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=rWt39OzVwJqVWdWqOPhoMJk6QuRS6gAnupl/jeLkk6I=; b=QJ2swFBwigc3w8ZVa45YRVSwwlqMz0mFQGASLN7d9QSxtLG0DNmWaA7yhDw3Jcdi20 g1PGN7y2cGACcQMk/BoPMkzyuG4wOTRelb81+A/LazeaPYvZIl+ZFqNhWaEVZedOauBM qGAZkV4aHY/0N8sIBm70+h3lvwTsrZ16BK094Jc9UtHIyKe3bvnSJhEDyOJXJ/eUB2jZ mZEneuWY4AhhwexKuGTecTluGltK5/wEXEmDvwUMg8v75OE8UVvbDyH2Mqcz0EUbp/Bu //EWftYN4k6++iCXVvg1cSUulqijTZepzVMr4Wf2keeqlJYU8sIJtubmXJr9WqzwZbSf 5hOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=rWt39OzVwJqVWdWqOPhoMJk6QuRS6gAnupl/jeLkk6I=; b=fhJitnQHVOjkFFMmP/z93SPZixRJBQ3inyh4b0Vk4jxqKj0HysEPqJ5aD63L/PSSKR pZK5eZ/BHYLZQuKhw8Jfc7jpV8XhHgTc0QH01/w+M8CTUuMiqt2z4vpRv5j2zJLK5mj0 fyI7S/EkizS4bg212OIJPS4qvw/685DC2iuDwsCGilYFgIkEGOlt6OK5yBzcuAHH0eAR eg0HKA0ofRfr/DxeY4AKcLcwxbhjZ6BOrLlM7UPylTkpf0d7e7rwBxghuKuNxcvz7oIp dGCR8+nhCqRh8VACxAkgJFSjTUR2nS3GZ2kiesqZYSTszW1K6xr6EDBA6Elie/Ehv+xE uxaw== X-Gm-Message-State: AODbwcBU4W3ydpwg6/GyaAlTrGY29IXRD7i2JJMu54Hqt4QF+pemhgLf nNZys88qFBUlyZ3t X-Received: by 10.36.57.137 with SMTP id l131mr6584047ita.61.1496544561604; Sat, 03 Jun 2017 19:49:21 -0700 (PDT) Original-Received: from zony ([45.2.7.65]) by smtp.googlemail.com with ESMTPSA id z191sm12131232iod.59.2017.06.03.19.49.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 03 Jun 2017 19:49:20 -0700 (PDT) In-Reply-To: <87d1belsvn.fsf@gmail.com> (Dmitry Alexandrov's message of "Fri, 12 May 2017 05:18:52 +0300") 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: 208.118.235.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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:133240 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable tags 26894 patch quit Dmitry Alexandrov <321942@gmail.com> writes: > =E2=80=98eshell/which=E2=80=99 in its part, that locates built-in command= s (=E2=80=98$ which > which=E2=80=99 for example) and elisp functions in general, looks like a = dirty > hack [0]: it calls interactive =E2=80=98describe-function=E2=80=99 comman= d and parses > *Help* buffer. Yeah, that's not great. Here's a patch. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=v1-0001-Don-t-read-eshell-which-output-from-Help-buffer-B.patch Content-Description: patch >From d4e1da8e3384c67a91c0466a0a5b60f543195b81 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 3 Jun 2017 22:15:19 -0400 Subject: [PATCH v1] Don't read eshell/which output from *Help* buffer (Bug#26894) * lisp/help-fns.el (help-fns--analyse-function) (describe-function-header): New functions, extracted from describe-function-1. (describe-function-1): Use them. * lisp/eshell/esh-cmd.el (eshell/which): Use `describe-function-header' instead of `describe-function-1'. --- lisp/eshell/esh-cmd.el | 31 ++++++--------- lisp/help-fns.el | 103 +++++++++++++++++++++++++++---------------------- 2 files changed, 69 insertions(+), 65 deletions(-) diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 86e7b83c28..91e41b7224 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1148,6 +1148,8 @@ (defun eshell-do-eval (form &optional synchronous-p) ;; command invocation +(declare-function describe-function-header "help-fns") + (defun eshell/which (command &rest names) "Identify the COMMAND, and where it is located." (dolist (name (cons command names)) @@ -1164,25 +1166,16 @@ (defun eshell/which (command &rest names) (concat name " is an alias, defined as \"" (cadr alias) "\""))) (unless program - (setq program (eshell-search-path name)) - (let* ((esym (eshell-find-alias-function name)) - (sym (or esym (intern-soft name)))) - (if (and (or esym (and sym (fboundp sym))) - (or eshell-prefer-lisp-functions (not direct))) - (let ((desc (let ((inhibit-redisplay t)) - (save-window-excursion - (prog1 - (describe-function sym) - (message nil)))))) - (setq desc (if desc (substring desc 0 - (1- (or (string-match "\n" desc) - (length desc)))) - ;; This should not happen. - (format "%s is defined, \ -but no documentation was found" name))) - (if (buffer-live-p (get-buffer "*Help*")) - (kill-buffer "*Help*")) - (setq program (or desc name)))))) + (setq program + (let* ((esym (eshell-find-alias-function name)) + (sym (or esym (intern-soft name)))) + (if (and (or esym (and sym (fboundp sym))) + (or eshell-prefer-lisp-functions (not direct))) + (require 'help-fns) + (or (with-output-to-string + (describe-function-header sym)) + name) + (eshell-search-path name))))) (if (not program) (eshell-error (format "which: no %s in (%s)\n" name (getenv "PATH"))) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 2c635ffa50..fd1dec19bf 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -560,8 +560,9 @@ (defun help-fns-short-filename (filename) (setq short rel)))) short)) -;;;###autoload -(defun describe-function-1 (function) +(defun help-fns--analyse-function (function) + "Return information about FUNCTION. +Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." (let* ((advised (and (symbolp function) (featurep 'nadvice) (advice--p (advice--symbol-function function)))) @@ -594,22 +595,24 @@ (defun describe-function-1 (function) (setq f (symbol-function f))) f)) ((subrp def) (intern (subr-name def))) - (t def))) - (sig-key (if (subrp def) - (indirect-function real-def) - real-def)) - (file-name (find-lisp-object-file-name function (if aliased 'defun - def))) - (pt1 (with-current-buffer (help-buffer) (point))) - (beg (if (and (or (byte-code-function-p def) - (keymapp def) - (memq (car-safe def) '(macro lambda closure))) - (stringp file-name) - (help-fns--autoloaded-p function file-name)) - (if (commandp def) - "an interactive autoloaded " - "an autoloaded ") - (if (commandp def) "an interactive " "a ")))) + (t def)))) + (list real-function def aliased real-def))) + +(defun describe-function-header (function) + "Print a line describing FUNCTION to `standard-output'." + (pcase-let* ((`(,_real-function ,def ,aliased ,real-def) + (help-fns--analyse-function function)) + (file-name (find-lisp-object-file-name function (if aliased 'defun + def))) + (beg (if (and (or (byte-code-function-p def) + (keymapp def) + (memq (car-safe def) '(macro lambda closure))) + (stringp file-name) + (help-fns--autoloaded-p function file-name)) + (if (commandp def) + "an interactive autoloaded " + "an autoloaded ") + (if (commandp def) "an interactive " "a ")))) ;; Print what kind of function-like object FUNCTION is. (princ (cond ((or (stringp def) (vectorp def)) @@ -676,34 +679,42 @@ (defun describe-function-1 (function) (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) (help-xref-button 1 'help-function-def function file-name)))) - (princ ".") - (with-current-buffer (help-buffer) - (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point)) - (point))) - (terpri)(terpri) - - (let ((doc-raw (documentation function t)) - (key-bindings-buffer (current-buffer))) - - ;; If the function is autoloaded, and its docstring has - ;; key substitution constructs, load the library. - (and (autoloadp real-def) doc-raw - help-enable-auto-load - (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" doc-raw) - (autoload-do-load real-def)) - - (help-fns--key-bindings function) - (with-current-buffer standard-output - (let ((doc (help-fns--signature function doc-raw sig-key - real-function key-bindings-buffer))) - (run-hook-with-args 'help-fns-describe-function-functions function) - (insert "\n" - (or doc "Not documented.")) - ;; Avoid asking the user annoying questions if she decides - ;; to save the help buffer, when her locale's codeset - ;; isn't UTF-8. - (unless (memq text-quoting-style '(straight grave)) - (set-buffer-file-coding-system 'utf-8)))))))) + (princ ".")))) + +;;;###autoload +(defun describe-function-1 (function) + (let ((pt1 (with-current-buffer (help-buffer) (point)))) + (describe-function-header function) + (with-current-buffer (help-buffer) + (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point)) + (point)))) + (terpri)(terpri) + + (let ((doc-raw (documentation function t)) + (key-bindings-buffer (current-buffer))) + + ;; If the function is autoloaded, and its docstring has + ;; key substitution constructs, load the library. + (and (autoloadp real-def) doc-raw + help-enable-auto-load + (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" doc-raw) + (autoload-do-load real-def)) + + (help-fns--key-bindings function) + (with-current-buffer standard-output + (pcase-let* ((`(,real-function ,def ,_aliased ,real-def) + (help-fns--analyse-function function)) + (doc (help-fns--signature + function doc-raw + (if (subrp def) (indirect-function real-def) real-def) + real-function key-bindings-buffer))) + (run-hook-with-args 'help-fns-describe-function-functions function) + (insert "\n" (or doc "Not documented."))) + ;; Avoid asking the user annoying questions if she decides + ;; to save the help buffer, when her locale's codeset + ;; isn't UTF-8. + (unless (memq text-quoting-style '(straight grave)) + (set-buffer-file-coding-system 'utf-8))))) ;; Add defaults to `help-fns-describe-function-functions'. (add-hook 'help-fns-describe-function-functions #'help-fns--obsolete) -- 2.11.1 --=-=-=--