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, 24 Jun 2017 16:20:46 -0400 Message-ID: <87tw35p275.fsf@users.sourceforge.net> References: <87d1belsvn.fsf@gmail.com> <871sr01n59.fsf@users.sourceforge.net> <87shjgza55.fsf@users.sourceforge.net> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1498335620 1560 195.159.176.226 (24 Jun 2017 20:20:20 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 24 Jun 2017 20:20: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 Sat Jun 24 22:20: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 1dOrXO-0008Lc-2B for geb-bug-gnu-emacs@m.gmane.org; Sat, 24 Jun 2017 22:20:10 +0200 Original-Received: from localhost ([::1]:40356 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dOrXT-0002h5-9i for geb-bug-gnu-emacs@m.gmane.org; Sat, 24 Jun 2017 16:20:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37387) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dOrXL-0002di-SP for bug-gnu-emacs@gnu.org; Sat, 24 Jun 2017 16:20:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dOrXG-0003MG-Su for bug-gnu-emacs@gnu.org; Sat, 24 Jun 2017 16:20:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:33304) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dOrXG-0003M6-Mb for bug-gnu-emacs@gnu.org; Sat, 24 Jun 2017 16:20:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dOrXG-0001V6-6C for bug-gnu-emacs@gnu.org; Sat, 24 Jun 2017 16:20:02 -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: Sat, 24 Jun 2017 20:20:02 +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: patch Original-Received: via spool by 26894-submit@debbugs.gnu.org id=B26894.14983355585705 (code B ref 26894); Sat, 24 Jun 2017 20:20:02 +0000 Original-Received: (at 26894) by debbugs.gnu.org; 24 Jun 2017 20:19:18 +0000 Original-Received: from localhost ([127.0.0.1]:35981 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dOrWX-0001Tx-RL for submit@debbugs.gnu.org; Sat, 24 Jun 2017 16:19:18 -0400 Original-Received: from mail-it0-f48.google.com ([209.85.214.48]:36456) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dOrWV-0001Ti-9Y for 26894@debbugs.gnu.org; Sat, 24 Jun 2017 16:19:15 -0400 Original-Received: by mail-it0-f48.google.com with SMTP id m68so5273564ith.1 for <26894@debbugs.gnu.org>; Sat, 24 Jun 2017 13:19:15 -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=w5Mo5p/YjVKDqGavkEmrPBx/Sks6xlgc9NiGzObacp4=; b=EL27h/MWWLmqmKqm1iFulgB2QDk4ciZJdrlu3wwKo64zpigr1Aq4YAlIq4fgfksDMr uYKugqSkesCHWiQ3Cz5ZB2JIrW6+rWXiI9R+Y6Ib4t08GZflLs0vfXwUg4EKkyT1P182 uq4gVlTIsE5lGCfE0AONdyzuFy1oNsIC0d8GDSf9wqDvyD2sIFyI00OVePf6xxPpTMaB tohdqv5jALmCD2iB9Js5wls72vSiiMW+o8XHbhvZY9uIG0OAbzjOTLPazgfqkpBgsWd6 vPa5EiNlMLzf5S5P///YW1nNsytHPcwr2d0OoBPC0Q2N/Lo+ac7ztmo9AaSY7IkGol5D OElg== 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=w5Mo5p/YjVKDqGavkEmrPBx/Sks6xlgc9NiGzObacp4=; b=rYDI/+sYmIZFAV9gsLKJgvUkK0/VbxcG5OkXUQ7/lrnVARVIMwbzg09miXayphuiPo L+iOpIKIQKcumgvdlfD7GOellberNiSV8Y6KgsRmjrygx++fI7pt8DS155lz3E4OTdKU kPyvj8XduaVFlqNzslz2UG7C2Ikw9sooZ+qTA8GMQuZrgVf3rK4JzyihbLEK+6eT/jWe iBTtjFW2Hc0pzB+dYAtoXT5Ugjtx1f5+mAKGNfxsXxxEwHuVe7gxIUV/8Uh8vQ7aF16h OQnsbU8C8SqOR1/JjpeKKayNu9vCT+FR5Sj/MffibloLLmLxqhXxv4pYgSg2Ltgk/u2N bxVQ== X-Gm-Message-State: AKS2vOzlRQnQBQyXVJwxEms6Q5Mvs9D9DZ9sgagfoCpPSKkCG8CjdHZr jFCmn0zj8d9unNgY X-Received: by 10.36.127.208 with SMTP id r199mr14724585itc.110.1498335549694; Sat, 24 Jun 2017 13:19:09 -0700 (PDT) Original-Received: from zony ([45.2.7.65]) by smtp.googlemail.com with ESMTPSA id u186sm5287545ita.3.2017.06.24.13.19.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 24 Jun 2017 13:19:08 -0700 (PDT) In-Reply-To: <87shjgza55.fsf@users.sourceforge.net> (npostavs@users.sourceforge.net's message of "Sat, 03 Jun 2017 23:47:50 -0400") 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:133851 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable npostavs@users.sourceforge.net writes: > npostavs@users.sourceforge.net writes: > >> Dmitry Alexandrov <321942@gmail.com> writes: >> >>> =E2=80=98eshell/which=E2=80=99 in its part, that locates built-in comma= nds (=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 comm= and and parses >>> *Help* buffer. >> >> Yeah, that's not great. Here's a patch. > > Sorry, I sent a broken version, here's the right one. Um, 3rd time's the charm? --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=v3-0001-Don-t-read-eshell-which-output-from-Help-buffer-B.patch Content-Description: patch >From bb5022bb6dac31ee5a0b14b9b2764a2b61fbffb6 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 3 Jun 2017 22:15:19 -0400 Subject: [PATCH v3] Don't read eshell/which output from *Help* buffer (Bug#26894) * lisp/help-fns.el (help-fns--analyse-function) (help-fns-function-description-header): New functions, extracted from describe-function-1. (describe-function-1): Use them. * lisp/eshell/esh-cmd.el (eshell/which): Use `help-fns-function-description-header' instead of `describe-function-1'. --- lisp/eshell/esh-cmd.el | 32 +++++++-------- lisp/help-fns.el | 103 +++++++++++++++++++++++++++---------------------- 2 files changed, 70 insertions(+), 65 deletions(-) diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 86e7b83c28..2434220877 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 help-fns-function-description-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,17 @@ (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))) + (or (with-output-to-string + (require 'help-fns) + (princ (format "%s is " sym)) + (help-fns-function-description-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..32324ae3bc 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 help-fns-function-description-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)))) + (help-fns-function-description-header function) + (with-current-buffer (help-buffer) + (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point)) + (point)))) + (terpri)(terpri) + + (pcase-let ((`(,real-function ,def ,_aliased ,real-def) + (help-fns--analyse-function function)) + (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 + (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 --=-=-=--