]> git.eshelyaron.com Git - sweep.git/commitdiff
ENHANCED: 'sweeprolog-find-predicate/module' improvements
authorEshel Yaron <me@eshelyaron.com>
Sun, 11 Jun 2023 17:56:40 +0000 (20:56 +0300)
committerEshel Yaron <me@eshelyaron.com>
Sun, 11 Jun 2023 17:56:40 +0000 (20:56 +0300)
Allow finding modules and predicates in another window with prefix
argument.  Also improve prompt for 'sweeprolog-find-predicate'.

* sweeprolog.el (sweeprolog-read-predicate-prompt): Remove trailing
colon and space.
(sweeprolog-predicate-visible-p-function): New user option.
(sweeprolog-read-predicate): Use it, and format PROMPT with predicate
at point as the default argument.
(sweeprolog-find-module)
(sweeprolog-find-predicate): Add optional argument OTHER-WINDOW.
(sweeprolog-describe-predicate): Adapt PROMPT argument passed to
'sweeprolog-read-predicate'.

* README.org (Finding Prolog Code): Expand.

README.org
sweeprolog.el

index 9a36bec76b7bc671281e733f1d0ac75bfbc22679..36471cdab98551f091b261a511ef4d8d56209542 100644 (file)
@@ -2368,24 +2368,47 @@ press ~C-c C-k~ (~kill-compilation~).
 _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:
@@ -2466,8 +2489,8 @@ accessed from anywhere with =C-c p t=, which invokes the command
 
 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]]        |
@@ -2479,7 +2502,7 @@ The full list of keybindings in ~sweeprolog-prefix-map~ is given below:
 | ~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]]   |
index 81b4c19fcb6e0f54f408b471596e7e1728cff5d2..aa4753098ca84ade2370dd80bc964e03b090a825 100644 (file)
@@ -236,9 +236,9 @@ the value of this option is used as its path."
   :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)
 
@@ -423,6 +423,24 @@ use `autoload/2' for all added directives."
   :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
@@ -1004,6 +1022,11 @@ Return a cons cell of the functor as a string and the arity."
       (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
@@ -1012,14 +1035,20 @@ default."
          (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))
@@ -1041,18 +1070,27 @@ default."
             (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
@@ -1163,7 +1201,8 @@ If OTHER-WINDOW is non-nil, find it in another window.
 
 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)
@@ -5084,11 +5123,7 @@ accordingly."
 ;;;###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)