_Compatibility note_: asynchronous queries use pipe processes that
require Emacs 28 or later and SWI-Prolog 9.1.4 or later.
-* Finding Prolog code
+* Finding Prolog Code
:PROPERTIES:
:CUSTOM_ID: finding-prolog-code
:DESCRIPTION: Commands for locating and opening Prolog files
:ALT_TITLE: Finding Prolog Code
:END:
-#+FINDEX: sweeprolog-find-module
-Sweep provides the command =M-x sweeprolog-find-module= for
-selecting and jumping to the source code of a loaded or auto-loadable
-Prolog module. Sweep integrates with Emacs's standard completion API
-to annotate candidate modules in the completion UI with their =PLDoc=
-description when available.
+The following commands let you find and jump to Prolog code from
+anywhere in Emacs:
+#+FINDEX: sweeprolog-find-module
+- Command: sweeprolog-find-module :: Prompt for a known Prolog module
+ and find its source code.
#+FINDEX: sweeprolog-find-predicate
-Along with =M-x sweeprolog-find-module=, Sweep provides the
-command =M-x sweeprolog-find-predicate= jumping to the definition a
-loaded or auto-loadable Prolog predicate.
+- Command: sweeprolog-find-predicate :: Prompt for a known Prolog
+ predicate and find its source code.
+
+~sweeprolog-find-module~ and ~sweeprolog-find-predicate~ prompt you for a
+Prolog identifier (respectively, a module name or a predicate indicator),
+and jump to its source definition. Sweep integrates with Emacs's standard
+completion API to annotate candidate modules in the completion UI with a
+summary line derived from their documentation, when available.
+
+By default, these commands use the current window to display the selected
+module or predicate. To have it in another window instead, invoke these
+commands with a prefix argument (e.g. ~C-u M-x sweeprolog-find-predicate~).
+
+#+FINDEX: sweeprolog-read-predicate
+#+VINDEX: sweeprolog-predicate-visible-p-function
+The command ~sweeprolog-find-predicate~ uses the function
+~sweeprolog-read-predicate~ for prompting you to insert a predicate
+indicator in the minibuffer. This is the standard function that Sweep
+commands use for this purpose, it provides completion candidates based on
+known predicates, and it uses the predicate at point, if any, as the
+default minibuffer argument. By default, ~sweeprolog-read-predicate~
+includes all predicates that Sweep knows about as completion candidates,
+except for predicate whose functor name begins with ~$~, because that's the
+convention in in SWI-Prolog for internal predicates that are usually of
+little interest to users. To include also these predicates as completion
+candidates, customize the user option
+~sweeprolog-predicate-visible-p-function~ to ~nil~.
** Prolog file specification expansion
:PROPERTIES:
The full list of keybindings in ~sweeprolog-prefix-map~ is given below:
-| Key | Command | Documentation |
-|-----+--------------------------------------+-----------------------------------|
+| Key | Command | Documentation |
+|-------+----------------------------------------+-----------------------------------|
| ~B~ | ~sweeprolog-list-breakpoints~ | [[#breakpoint-menu][Breakpoint Menu]] |
| ~F~ | ~sweeprolog-set-prolog-flag~ | [[*Setting Prolog flags][Setting Prolog Flags]] |
| ~P~ | ~sweeprolog-pack-install~ | [[*Installing Prolog packages][Installing Prolog packages]] |
| ~h m~ | ~sweeprolog-describe-module~ | [[*Prolog Help][Prolog Help]] |
| ~l~ | ~sweeprolog-load-buffer~ | [[#loading-buffers][Loading Buffers]] |
| ~m~ | ~sweeprolog-find-module~ | [[#finding-prolog-code][Finding Prolog Code]] |
-| ~p~ | ~sweeprolog-find-predicate~ | [[*Finding Prolog code][Finding Prolog Code]] |
+| ~p~ | ~sweeprolog-find-predicate~ | [[*Finding Prolog Code][Finding Prolog Code]] |
| ~q~ | ~sweeprolog-top-level-send-goal~ | [[#top-level-send-goal][Sending Goals to the Top-level]] |
| ~t~ | ~sweeprolog-top-level~ | [[#prolog-top-level][The Prolog Top-level]] |
| ~&~ | ~sweeprolog-async-goal~ | [[#async-query][Executing Prolog Asynchronously]] |
:type 'string
:group 'sweeprolog)
-(defcustom sweeprolog-read-predicate-prompt "Predicate: "
+(defcustom sweeprolog-read-predicate-prompt "Predicate"
"Prompt used for reading a Prolog predicate name from the minibuffer."
- :package-version '((sweeprolog . "0.1.0"))
+ :package-version '((sweeprolog . "0.19.1"))
:type 'string
:group 'sweeprolog)
:type 'boolean
:group 'sweeprolog)
+(defcustom sweeprolog-predicate-visible-p-function #'sweeprolog-predicate-non-hidden-p
+ "Controls how `sweeprolog-read-predicate' filters completion candidates.
+
+This affects commands that read a Prolog predicate indicator in
+the minibuffer, such as \\[sweeprolog-find-predicate]
+and \\[sweeprolog-describe-predicate].
+
+If non-nil, this is a function that takes a single string
+argument, and returns non-nil if that string should be included
+as a completion candidate (i.e. it is not hidden). If this
+user option is nil, all known predicates are provided as
+completion candidates."
+ :package-version '((sweeprolog "0.19.1"))
+ :type '(choice (const :tag "Include all predicates" nil)
+ (const :tag "Exclude internal hidden predicates"
+ sweeprolog-predicate-non-hidden-p)
+ (function :tag "Custom exclusion predicate")))
+
;;;; Keymaps
(defvar sweeprolog-mode-map
(cons functor
(or arity (read-number (concat functor "/")))))))
+(defun sweeprolog-predicate-non-hidden-p (pred)
+ "Return nil if PRED is an internal hidden predicate.
+These are predicates whose functor begin with $."
+ (not (string-match (rx ":'$") pred)))
+
(defun sweeprolog-read-predicate (&optional prompt)
"Read a Prolog predicate from the minibuffer with prompt PROMPT.
If PROMPT is nil, `sweeprolog-read-predicate-prompt' is used by
(completion-extra-properties
(list :annotation-function
(lambda (key)
- (let* ((val (cdr (assoc-string key col))))
- (if val
- (concat (make-string (- 64 (length key)) ? ) (car val))
- nil))))))
- (completing-read (or prompt sweeprolog-read-predicate-prompt)
- col nil nil nil
- 'sweeprolog-read-predicate-history
- (sweeprolog-identifier-at-point))))
+ (when-let ((val (alist-get key col nil nil #'string=)))
+ (concat (make-string (- 64 (length key)) ? ) val)))))
+ (default (sweeprolog-identifier-at-point)))
+ (completing-read
+ (concat (or prompt sweeprolog-read-predicate-prompt)
+ (when default
+ (concat " (default " default ")"))
+ ": ")
+ col
+ (when sweeprolog-predicate-visible-p-function
+ (lambda (cand)
+ (funcall sweeprolog-predicate-visible-p-function
+ (car cand))))
+ nil nil 'sweeprolog-read-predicate-history default)))
(defun sweeprolog-predicate-prefix-boundaries (&optional point)
(let ((case-fold-search nil))
(cons start (point))))))))
;;;###autoload
-(defun sweeprolog-find-predicate (mfa)
- "Jump to the definition of the Prolog predicate MFA.
-MFA should be a string of the form \"M:F/A\" or \"M:F//A\", where
-M is a Prolog module name, F is a functor and A is its arity."
- (interactive (list (sweeprolog-read-predicate)))
- (if-let ((loc (sweeprolog-predicate-location mfa)))
+(defun sweeprolog-find-predicate (pi &optional other-window)
+ "Jump to the definition of the Prolog predicate PI.
+
+PI should be a string of the form \"M:F/A\" or \"M:F//A\", where
+M is a Prolog module name, F is a functor and A is its arity.
+
+If OTHER-WINDOW is non-nil, find it in another window.
+
+Interactively, this command prompts for PI, and OTHER-WINDOW is
+the prefix argument."
+ (interactive (list (sweeprolog-read-predicate)
+ current-prefix-arg))
+ (if-let ((loc (sweeprolog-predicate-location pi)))
(let ((path (car loc))
(line (or (cdr loc) 1)))
- (find-file path)
+ (if other-window
+ (find-file-other-window path)
+ (find-file path))
(goto-char (point-min))
(forward-line (1- line)))
- (user-error "Unable to locate predicate %s" mfa)))
+ (user-error "Unable to locate predicate %s" pi)))
(defun sweeprolog--fragment-to-mfa (fragment buffer-module)
(pcase fragment
Interactively, OTHER-WINDOW is the prefix argument and this
command prompts for MOD."
- (interactive (list (sweeprolog-read-module-name)))
+ (interactive (list (sweeprolog-read-module-name)
+ current-prefix-arg))
(let ((file (sweeprolog-module-path mod)))
(if other-window
(find-file-other-window file)
;;;###autoload
(defun sweeprolog-describe-predicate (pred)
"Display the full documentation for PRED (a Prolog predicate)."
- (interactive (list (sweeprolog-read-predicate
- (concat "Describe predicate"
- (when-let ((def (sweeprolog-identifier-at-point)))
- (concat " (default " def ")"))
- ": "))))
+ (interactive (list (sweeprolog-read-predicate "Describe predicate")))
(sweeprolog--describe-predicate pred))
(defun sweeprolog--find-predicate-from-symbol (sym)