From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Arthur Miller Newsgroups: gmane.emacs.devel Subject: Re: Path & Demo: Source View in Help Buffers Date: Wed, 22 Sep 2021 15:42:11 +0200 Message-ID: References: <87o88kj2oz.fsf@gnu.org> <87k0j8j0v3.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32834"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Tassilo Horn Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Sep 22 15:44:04 2021 Return-path: Envelope-to: ged-emacs-devel@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 1mT2Xa-0008Hv-39 for ged-emacs-devel@m.gmane-mx.org; Wed, 22 Sep 2021 15:44:03 +0200 Original-Received: from localhost ([::1]:38338 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mT2XX-0001HM-TD for ged-emacs-devel@m.gmane-mx.org; Wed, 22 Sep 2021 09:43:59 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56758) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mT2Vx-0000NP-Tg for emacs-devel@gnu.org; Wed, 22 Sep 2021 09:42:21 -0400 Original-Received: from mail-oln040092072051.outbound.protection.outlook.com ([40.92.72.51]:27182 helo=EUR03-VE1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mT2Vu-0007pT-53; Wed, 22 Sep 2021 09:42:21 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NRoUWRYlSCNkJrU2qgT0MtvnBCU7u631FaTKmMBtwSmtUQ8y2R3VM0nV6BNeEoMU878+3TAktwYRb3xqkYIppkv6osuUUejne2JaO5DW1m0nj7VsZZOWVbV49wHcXt7koOCYOWpTAfK9Pr9YLkXm2huAsX3Ql/qTpdS6i8N5Yuw4qa97Z1uCMCrps9IKxbrfFfD1fzKg3pUYTJFEE8JkwhyXtyXw8o025lmA8OqN6FejDYL80qqzQ4MHUGxFOE0AiXT0El7tcrZg0idF8ItseYpHCCSoEMgmpxey6OobK2OEsNarS7McRCulU7BGDOBZpxOheDJZTOFfTN/KOp6mDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=hlP70Ngv2Pei8de0uJpxtJZQzcquinNRX4ld93Nlq0E=; b=E4zoDU/esS2SGRwyXqNVPu4GVVr2R6TJbmmjZHCWxrhWwG3ZMiX59tD3zeEneXLSFk0690kkFx5/nswx04oNO7aBiknfOrbtN1CSf2qFr1ZRHcKJoo4MsV7skEU3L4Lei9IQWPCOQz3nHwJcBJgkhKQeiMaou3+eJ5vE4PeKSbGOURzhbW7lWXr/VrfBJdO8ZoCLldmcgbhVxd0Xhfqi+9UX+gu66TE+2zgPmBQvTpyACm1bV1VTUZmZoNRX5cCTiEyQ0dCTIC11EZdB0XGEjqrZsT5z3cbJhIlfxBeJYPASzkCr/YPZFE6mVNt9MDVJZsEy+X4SYMJJaGgHVg4NIQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=live.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hlP70Ngv2Pei8de0uJpxtJZQzcquinNRX4ld93Nlq0E=; b=kJOTrYVlT8uw3WL/vD2OwBDChHeWIFNCG2gX+Gi9ndnucy+yW5BTjw6CIfAZPfAkNqH2qD8meHa2M7c8Ndac901bW4Mio80eVeOylYbxag18oUOdukCwjeY9T4iHX2kkGeh8xDsE1bpMeQHzsP0wAFiTfsEgEcr3sudOozG2Mrdu2Ke+tmDuQPmSw2i3VWAPY8SH8XM9V+9RbFe2KQrlTm3Bv5NmY3+v4I+teVUxgmw9de2ITrOPG+e24DOjpJHYBM+jCUjJctq6SjEvOyFGeps09jSQEgeWPyEpfyCJOVDs6RBeCSpLAwT5f9y62hy+HXYA+ewi4NYTVIEvZOQqVA== Original-Received: from DB9PR09MB4986.eurprd09.prod.outlook.com (2603:10a6:10:2a9::19) by DU2PR09MB5231.eurprd09.prod.outlook.com (2603:10a6:10:23a::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4500.18; Wed, 22 Sep 2021 13:42:12 +0000 Original-Received: from DB9PR09MB4986.eurprd09.prod.outlook.com ([fe80::80be:d528:d357:5d3a]) by DB9PR09MB4986.eurprd09.prod.outlook.com ([fe80::80be:d528:d357:5d3a%9]) with mapi id 15.20.4523.018; Wed, 22 Sep 2021 13:42:12 +0000 In-Reply-To: <87k0j8j0v3.fsf@gnu.org> (Tassilo Horn's message of "Wed, 22 Sep 2021 13:32:57 +0200") X-TMN: [wx+R4rULgjlK+sYqh2vOUnXSUqOoDoQq] X-ClientProxiedBy: AM6P194CA0033.EURP194.PROD.OUTLOOK.COM (2603:10a6:209:90::46) To DB9PR09MB4986.eurprd09.prod.outlook.com (2603:10a6:10:2a9::19) X-Microsoft-Original-Message-ID: <874kacwwuk.fsf@live.com> X-MS-Exchange-MessageSentRepresentingType: 1 Original-Received: from pascal.homepc (81.232.177.30) by AM6P194CA0033.EURP194.PROD.OUTLOOK.COM (2603:10a6:209:90::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13 via Frontend Transport; Wed, 22 Sep 2021 13:42:12 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a717d6b5-beac-4974-52bd-08d97dcec812 X-MS-TrafficTypeDiagnostic: DU2PR09MB5231: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: to+J7Wnrzfu1cgffkIACQMLtG0ri+h7F/XimvELh62PYM1vPqTqrld+GmTElaH3ApP9QMS9IvIW7JIGVKtS4gTwjpPIqWdSmVeCWVddu1oHYbZTX7uxxqyJ3198gCv8T5zMbotGgoNWwplZFZgxYPKFlOCb1S+yFwp70jxmRj6HTUhMQZLamTJyJDnE1CO2BLAwhyw2CuXHubcje51H54jRUdUKHf6rCJNGYHGnPYWsz2Hur46lsng89h5A7yfFqInMBLilySkmGXBE1rdsWZCKFB4QSIMk4pdFdeoXdOAAIxFyEDt1jHHC7Chl1+n42rWuiI9I04VvO26B+RQyIfcB1UQ91/LPtn6SlwpxAWIL6t6Tgj/5YzYN+meahOub21Z9zk5PE1Dl+sLmhekNhrp5TL7B+tMp4Ppeq0q6CDUt0yhCl3wrc6k5XYr6r/ves X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: LHE7wJ6hmxqGOzVgy0BD2T3n3QrPQnD+aEVaU1XPEbJdI+L/rJE7gDnf0Riac6TcL84kW/RgznJjOT/zTS5v7s7+8R5masKgheXjEtKh6SMvT2Nof0XqpPhb6s0r0xPN9Dz0R/92KNWmhu/GDWib0w== X-OriginatorOrg: sct-15-20-3174-20-msonline-outlook-72e6e.templateTenant X-MS-Exchange-CrossTenant-Network-Message-Id: a717d6b5-beac-4974-52bd-08d97dcec812 X-MS-Exchange-CrossTenant-AuthSource: DB9PR09MB4986.eurprd09.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Sep 2021 13:42:12.8351 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU2PR09MB5231 Received-SPF: pass client-ip=40.92.72.51; envelope-from=arthur.miller@live.com; helo=EUR03-VE1-obe.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, MSGID_FROM_MTA_HEADER=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:275317 Archived-At: --=-=-= Content-Type: text/plain Tassilo Horn writes: > Arthur Miller writes: > >>> Out of curiosity, why do you have fboundp-checks for font-lock-ensure >>> in the code? That's always true, isn't it? >> >> I don't know. Since font-lock has all its stuff abstracted into buffer >> local function variables, I am not sure if I can count it is not nil? > > But it's no buffer-local variable, it's a function. If you have emacs > 25.1 upwards, you have `font-lock-ensure'. > >> If I can I would gladly remove the check. I appreciate advice, I am >> not so familiar with all the details of everything. > > I think that's a common check for 3rd-party packages which want to keep > supporting emacs 24. But since you are hacking emacs core, there's no > need for that unless the function/variable is only defined if some > configure option is given or some lib is available. But none of the > latter applies to font-lock.el. > Yes, I have tested now, it works fine. I did even som minor refactoring. Don't know if anyone else cares at all, anyway here is updated patch. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Display-source-code-in-help-mode-buffers.patch >From 63f6f0a9806c8326b8913f5d6856d841c019b4d0 Mon Sep 17 00:00:00 2001 From: Arthur Miller Date: Wed, 22 Sep 2021 15:33:56 +0200 Subject: [PATCH] Display source code in 'help-mode' buffers * lisp/help-mode.el (help-mode-inline-source): New option. (help--fetch-c-src): New function. (help--fetch-lisp-src): New function. (help--insert-source): New function. (help--remove-source): New function. (help--toggle-source-view): New function. (help-source-view): New button. (help-make-xrefs): Check for 'help-mode-inline-source' and call 'help--insert-source' to perform insertion when possible. --- lisp/help-mode.el | 152 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 5 deletions(-) diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 551cf7e1a3..dc6a532c63 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -149,6 +149,16 @@ help-mode-hook "Hook run by `help-mode'." :type 'hook :group 'help) + +(defcustom help-mode-inline-source nil + "Display inlined source code in `help-mode' buffers. + +When enabled the source code of a symbol currently shown in the +help-buffer will be displayed inlined in the help buffer, if the +source code for the symbol is available." + :type 'boolean + :group 'help + :version "28.1") ;; Button types used by help @@ -367,6 +377,11 @@ 'help-news (view-buffer-other-window (find-file-noselect file)) (goto-char pos)) 'help-echo (purecopy "mouse-2, RET: show corresponding NEWS announcement")) + +(define-button-type 'help-source-view + :supertype 'help-xref + 'help-function #'help-toggle-source-view + 'help-echo (purecopy "mouse-2, RET: toggle source view in help-buffer")) (defvar bookmark-make-record-function) (defvar help-mode--current-data nil) @@ -503,6 +518,102 @@ describe-symbol-backends and a frame), inserts the description of that symbol in the current buffer and returns that text as well.") +(defun help--fetch-c-src (symbol type file) + "Find C source code for a Lisp SYMBOL in a FILE. + +symbol - the symbol to find. +type - the type as obtained by 'describe-*' functions. +file - the source file to search in." + (let (src beg) + (setq file (expand-file-name file source-directory)) + (when (file-readable-p file) + (with-temp-buffer + (insert-file-contents-literally file) + (delay-mode-hooks (funcall 'c-mode)) + (goto-char (point-min)) + (unless type + ;; Either or both an alias and its target might be advised. + (setq symbol (find-function-advised-original + (indirect-function + (find-function-advised-original symbol))))) + (when (re-search-forward + (if type + (concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\"" + (regexp-quote (symbol-name symbol)) + "\"") + (concat "DEFUN[ \t\n]*([ \t\n]*\"" + (regexp-quote (subr-name (advice--cd*r symbol))) + "\"")) + nil t) + (if type + (and (re-search-backward "DEFVAR" nil t) + (setq beg (point)) + (re-search-forward ");$" nil t)) + (and (re-search-backward "DEFUN" nil t) + (setq beg (point)) + (re-search-forward ")[\n\s\t\r]*{") + (re-search-forward "^}[\n\s\t\r]+"))) + (narrow-to-region beg (point)) + (with-no-warnings (font-lock-fontify-buffer)) + (setq src (buffer-string))))) + src)) + +(defun help--fetch-lisp-src (symbol type file) + "Find emacs-lisp source code for a Lisp SYMBOL in a FILE. + +symbol - the symbol to find. +type - the type as obtained by 'describe-*' functions. +file - the source file to search in." + (let (src pos) + (when file + (setq file (or file (find-lisp-object-file-name symbol type)))) + (with-temp-buffer + (insert-file-contents file) + (delay-mode-hooks (funcall 'emacs-lisp-mode)) + (setq pos (cdr (find-function-search-for-symbol symbol type file))) + (when pos + (goto-char pos) + (forward-sexp) + (narrow-to-region pos (point)) + (with-no-warnings (font-lock-fontify-buffer)) + (setq src (buffer-string)))) + src)) + +(defun help--insert-source () + "Fnd and insert source for the current symbol into the help-mode +buffer." + (with-silent-modifications + (with-current-buffer (help-buffer) + (save-excursion + (let* ((file (plist-get help-mode--current-data :file)) + (type (plist-get help-mode--current-data :type)) + (sym (plist-get help-mode--current-data :symbol)) + (src "Source code not available.")) + (require 'find-func) + (when (eq file 'C-source) + (setq file (help-C-file-name (indirect-function sym) 'fun))) + (setq src (if (string-suffix-p ".c" file) + (help--fetch-c-src sym type file) + (help--fetch-lisp-src sym type file))) + (goto-char (point-max)) + (let ((end (point))) + (when (search-backward "View Source Code:" nil t) + (delete-region (point) end) + (help-insert-xref-button "Hide Source Code:" 'help-source-view) + (insert (concat "\n" src "\n"))))))))) + +(defun help--remove-source () + "Remove source code from the help buffer when present." + (with-current-buffer (help-buffer) + (with-silent-modifications + (save-excursion + (goto-char (point-max)) + (let ((end (point))) + (when (search-backward "Hide Source Code:" nil t) + (delete-region (point) end) + (help-insert-xref-button + "View Source Code:" 'help-source-view))))))) + ;;;###autoload (defun help-make-xrefs (&optional buffer) "Parse and hyperlink documentation cross-references in the given BUFFER. @@ -664,7 +775,25 @@ help-make-xrefs (help-insert-xref-button help-forward-label 'help-forward (current-buffer))) (when (or help-xref-stack help-xref-forward-stack) - (insert "\n"))) + (insert "\n")) + (insert "\n") + ;; get source string if needed and available + ;; describe-symbol does not produce 'current-data' plist + (unless help-mode--current-data + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "\\.\\(el\\|c\\)" nil t) + (goto-char (- (point) 2)) + (let ((props (get-text-property (point) 'help-args))) + (when props + (setq help-mode--current-data + (list :symbol (nth 0 props) + :file (nth 1 props)))))))) + (if help-mode-inline-source + (progn + (insert "View Source Code:") ;; just a little hack + (help--insert-source)) + (help-insert-xref-button "View Source Code:" 'help-source-view))) (set-buffer-modified-p old-modified))))) ;;;###autoload @@ -819,10 +948,23 @@ help-do-xref (append args (list (generate-new-buffer-name "*info*"))) args)))) -;; The doc string is meant to explain what buttons do. -(defun help-follow-mouse () - "Follow the cross-reference that you click on." - (declare (obsolete nil "28.1")) +(defun help-toggle-source-view () + "Toggle source code display in help buffer for the current symbol." + (interactive) + (when (get-buffer-window (help-buffer)) + (with-current-buffer (help-buffer) + (unless (plist-get help-mode--current-data :file) + (error "Source file for the current help item is not defined")) + (save-excursion + (goto-char (point-min)) + (if (search-forward "Hide Source Code:" nil t) + (help--remove-source) + (help--insert-source)))))) + + ;; The doc string is meant to explain what buttons do. + (defun help-follow-mouse () + "Follow the cross-reference that you click on." + (declare (obsolete nil "28.1")) (interactive) (error "No cross-reference here")) -- 2.33.0 --=-=-=--