[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/sweeprolog f807eea272: ENHANCED: teach sweep to jump to C
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/sweeprolog f807eea272: ENHANCED: teach sweep to jump to C code for built-in predicates |
Date: |
Wed, 19 Oct 2022 02:59:24 -0400 (EDT) |
branch: elpa/sweeprolog
commit f807eea272426b269228ed01b2e6fac84e642c5a
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>
ENHANCED: teach sweep to jump to C code for built-in predicates
* sweeprolog.el:
- sweeprolog-swipl-sources: new user option.
- sweeprolog-native-predicate-location: new function.
- sweeprolog-predicate-location: use it.
- README.org: Built-in Native Predicates: new section.
---
NEWS.org | 18 +++++++++++++
README.org | 38 ++++++++++++++++++++++++++
sweeprolog.el | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 137 insertions(+), 6 deletions(-)
diff --git a/NEWS.org b/NEWS.org
index 40f95e6fb7..4f589361af 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -11,6 +11,24 @@ SWI-Prolog in Emacs.
For further details, please consult the manual:
<https://eshelyaron.com/sweep.html>.
+
+* Version 0.7.1 on 2022-10-19
+
+** Jumping to source works also for built-in predicates defined in C
+
+~sweep~ now knows how to find and jump to the definitions of native
+built-in SWI-Prolog predicates defined in C, under the condition that
+the user has the SWI-Prolog sources checked out locally.
+
+See ~C-h v sweeprolog-swipl-sources~ and the new section "Built-in
+Native Predicates" in the manual for more information about this
+feature.
+
+** Fixes and improvements to ~sweeprolog-describe-predicate~
+
+This version fixes some compatibility issues with Emacs versions prior
+to 29 in ~sweeprolog-describe-predicate~. Reported by Jan Wielemaker.
+
* Version 0.7.0 on 2022-10-17
** New command ~sweeprolog-describe-predicate~
diff --git a/README.org b/README.org
index 711748ca88..28fc8cf995 100644
--- a/README.org
+++ b/README.org
@@ -1108,6 +1108,44 @@ For example, typing =C-x C-f library(pldoc/doc_man)=
will open the
source of the =pldoc_man= module from the Prolog library, and likewise
=C-x C-f pack(.)= will open the Prolog packages directory.
+** Built-in Native Predicates
+:PROPERTIES:
+:CUSTOM_ID: goto-c-predicates
+:DESCRIPTION: Finding and jumping to definitions of built-in SWI-Prolog
predicates defined in C
+:END:
+
+#+CINDEX: native built-in predicates
+Some of the built-in predicates provided by SWI-Prolog, such as ~is/2~,
+are implemented in C and included as native functions in the
+SWI-Prolog runtime. It is sometimes useful to examine the
+implementation of such native built-in predicates by reading its
+definition in the SWI-Prolog C sources. ~sweep~ knows about SWI-Prolog
+native built-ins, and can find and jump to their definitions in C when
+the user has the SWI-Prolog sources checked out locally.
+
+#+VINDEX: sweeprolog-swipl-sources
+The way ~sweep~ locates the SWI-Prolog sources depends on the user
+option ~sweeprolog-swipl-sources~. When customized to a string, it is
+taken to be the path to the root directory of the SWI-Prolog source
+code. If instead ~sweeprolog-swipl-sources~ is set to ~t~ (the default),
+~sweep~ will try to locate a local checkout of the SWI-Prolog sources
+automatically among known project root directories provided by Emacs'
+built-in ~project-known-project-roots~ from =project.el= (see
[[info:emacs#Projects][Projects in
+the Emacs manual]] for more information about =project.el= projects).
+Lastly, setting ~sweeprolog-swipl-sources~ to ~nil~ disables searching for
+definitions of native built-ins.
+
+With ~sweeprolog-swipl-sources~ set, the provided commands for finding
+predicate definitions operate seamlessly on native built-ins to
+display their C definitions in ~c-mode~ buffers (see [[info:ccmode#Top][the
Emacs CC Mode
+manual]] for information about working with C code in Emacs). These
+commands include:
+- ~M-x sweeprolog-find-predicate~,
+- ~M-.~ (~xref-find-definitions~) in ~sweeprolog-mode~ buffers (see
+ [[#sweeprolog-xref][Definitions and references]]), and
+- ~s~ (~help-view-source~) in the =*Help*= buffer produced by ~M-x
+ sweeprolog-describe-predicate~ (see [[#prolog-help][Prolog Help]]).
+
* Quick access to sweep commands
:PROPERTIES:
:CUSTOM_ID: quick-command-access
diff --git a/sweeprolog.el b/sweeprolog.el
index 4d326472f0..3c1d9d7be7 100644
--- a/sweeprolog.el
+++ b/sweeprolog.el
@@ -6,8 +6,8 @@
;; Maintainer: Eshel Yaron <~eshel/dev@lists.sr.ht>
;; Keywords: prolog languages extensions
;; URL: https://git.sr.ht/~eshel/sweep
-;; Package-Version: 0.7.0
-;; Package-Requires: ((emacs "28"))
+;; Package-Version: 0.7.1
+;; Package-Requires: ((emacs "28.1"))
;; This file is NOT part of GNU Emacs.
@@ -40,6 +40,24 @@
"SWI-Prolog Embedded in Emacs."
:group 'prolog)
+(defcustom sweeprolog-swipl-sources t
+ "Location of the SWI-Prolog source code root directory.
+
+When non-nil, the function `sweeprolog-predicate-location' will
+attempt to find the C defintions of SWI-Prolog native built-in
+predicates.
+
+The value of this option can be a string, in which case it should
+be a path to the SWI-Prolog source code root directory. Any
+other non-nil value instructs `sweeprolog-predicate-location' to
+try and find the SWI-Prolog sources among known project roots
+obtained from `project-known-project-roots', which see."
+ :package-version '((sweeprolog . "0.4.6"))
+ :type '(choice (const :tag "Detect" t)
+ (string :tag "Manual")
+ (const :tag "Disable" nil))
+ :group 'sweeprolog)
+
(defcustom sweeprolog-module-header-comment-skeleton ?\n
"Additional content for the topmost comment in module headers.
@@ -415,6 +433,7 @@ Otherwise set ARGS to nil."
(interactive
(and
current-prefix-arg
+ (fboundp 'split-string-shell-command)
(split-string-shell-command (read-string "swipl arguments: "))))
(when-let ((top-levels (seq-filter (lambda (buffer)
(eq 'sweeprolog-top-level-mode
@@ -464,13 +483,68 @@ When non-nil, only predicates whose name contains PREFIX
are returned."
(when (sweeprolog-true-p sol)
(cdr sol))))
+(defun sweeprolog--mfn-to-functor-arity (mfn)
+ (let ((functor-arity (split-string (car (reverse (split-string mfn ":")))
"/")))
+ (cons (car functor-arity)
+ (string-to-number (cadr functor-arity)))))
+
+(defun sweeprolog--swipl-source-directory ()
+ (when sweeprolog-swipl-sources
+ (if (stringp sweeprolog-swipl-sources)
+ sweeprolog-swipl-sources
+ (when (fboundp 'project-known-project-roots)
+ (car (seq-filter
+ (lambda (root)
+ (member (car
+ (reverse
+ (seq-filter
+ (lambda (s)
+ (not (string-empty-p s)))
+ (file-name-split root))))
+ '("swipl" "swipl-devel")))
+ (project-known-project-roots)))))))
+
+(defun sweeprolog-native-predicate-location (mfn)
+ (let ((functor-arity (sweeprolog--mfn-to-functor-arity mfn)))
+ (when-let ((default-directory (sweeprolog--swipl-source-directory))
+ (match
+ (car (xref-matches-in-files
+ (rx (or "PRED_IMPL" "FRG")
+ (zero-or-more whitespace)
+ "(\""
+ (zero-or-more whitespace)
+ (literal (car functor-arity))
+ "\""
+ (zero-or-more whitespace)
+ ","
+ (zero-or-more whitespace)
+ (literal (number-to-string (cdr functor-arity))))
+ (project-files (project-current)
+ (list (expand-file-name "src"
+
default-directory))))))
+ (location (if (fboundp 'xref-match-item-location)
+ (xref-match-item-location match)
+ (xref-item-location match))))
+ (if (fboundp 'xref-file-location-file)
+ (cons (xref-file-location-file location)
+ (xref-file-location-line location))
+ (with-slots ((file file)
+ (line line))
+ location
+ (cons file line))))))
+
(defun sweeprolog-predicate-location (mfn)
- "Return the source location where the predicate MFN is defined."
+ "Return the source location where the predicate MFN is defined.
+
+For native built-in predicates, the behavior of this function
+depends on the value of the user option
+`sweeprolog-swipl-sources', which see."
(sweeprolog-open-query "user" "sweep" "sweep_predicate_location" mfn)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
- (when (sweeprolog-true-p sol)
- (cdr sol))))
+ (if (sweeprolog-true-p sol)
+ (cdr sol)
+ (sweeprolog-native-predicate-location mfn))))
(defun sweeprolog-predicate-apropos (pattern)
"Return a list of predicates whose name resembeles PATTERN."
@@ -2788,7 +2862,8 @@ if-then-else constructs in SWI-Prolog."
nil
(font-lock-fontify-region-function .
sweeprolog-colourise-some-terms)))
(when sweeprolog-enable-eldoc
- (setq-local eldoc-documentation-strategy #'eldoc-documentation-default)
+ (when (fboundp 'eldoc-documentation-default)
+ (setq-local eldoc-documentation-strategy #'eldoc-documentation-default))
(add-hook 'eldoc-documentation-functions #'sweeprolog-predicate-modes-doc
nil t))
(when sweeprolog-enable-flymake
(add-hook 'flymake-diagnostic-functions #'sweeprolog-diagnostic-function
nil t)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [nongnu] elpa/sweeprolog f807eea272: ENHANCED: teach sweep to jump to C code for built-in predicates,
ELPA Syncer <=