]> git.eshelyaron.com Git - sweep.git/commitdiff
ADDED: command for sending a goal to top-level from any buffer
authorEshel Yaron <me@eshelyaron.com>
Thu, 12 Jan 2023 11:27:17 +0000 (13:27 +0200)
committerEshel Yaron <me@eshelyaron.com>
Thu, 12 Jan 2023 11:27:17 +0000 (13:27 +0200)
* sweeprolog.el (sweeprolog-top-level): extract buffer setup logic to...
(sweeprolog-top-level-buffer): new function.
(sweeprolog-top-level-send-string): new function, used by...
(sweeprolog-top-level-send-goal): new command, reads a goal from the
minibuffer and sends it to a Prolog top-level buffer.
(sweeprolog-mode-map): bind it to C-c C-q.
(sweeprolog-menu): add "Send Goal to Top-level" entry.
* README.org ("Sending Goals to the Top-level"): new manual section.

README.org
sweeprolog.el

index e94587a3aac9dfc4800d3f5e15a5f74216596a5f..4da79be64039d7456e202dfc4d5784af71f6ce57 100644 (file)
@@ -1599,6 +1599,26 @@ buffers, you can arrange for it to be enabled as part of the
 
 #+end_src
 
+** Sending Goals to the Top-level
+:PROPERTIES:
+:CUSTOM_ID: top-level-send-goal
+:DESCRIPTION: Commands for sending goals to the be executed in the Top-level
+:ALT_TITLE: Send to Top-level
+:END:
+
+#+FINDEX: sweeprolog-top-level-send-goal
+You can send a goal to execute in a Prolog top-level from any buffer
+with the command ~M-x sweeprolog-top-level-send-goal~.  This command
+prompts for a Prolog goal in the minibuffer, executes it in a
+top-level buffer and displays that buffer if it's not already visible.
+While inserting the goal in the minibuffer, you can use ~TAB~ (or ~C-i~)
+to get completion suggestions.
+
+In ~sweeprolog-mode~ buffers, you can invoke
+~sweeprolog-top-level-send-goal~ by typing ~C-c C-q~.  It also uses the
+goal at point (if any) as the "future history" for the goal prompt,
+which you can access with ~M-n~ in the minibuffer.
+
 * Finding Prolog code
 :PROPERTIES:
 :CUSTOM_ID: finding-prolog-code
index 44c060246c4a80685b1a2169bfaeb1b21f62dce6..14c8567bc2e667b9c889c2fd6ec52c4869059ada 100644 (file)
@@ -391,6 +391,7 @@ determinism specification, and the third is a summary line."
     (define-key map (kbd "C-c C-m") #'sweeprolog-insert-term-with-holes)
     (define-key map (kbd "C-c C-o") #'sweeprolog-find-file-at-point)
     (define-key map (kbd "C-c C-s") #'sweeprolog-term-search)
+    (define-key map (kbd "C-c C-q") #'sweeprolog-top-level-send-goal)
     (define-key map (kbd "C-c C-t") #'sweeprolog-top-level)
     (define-key map (kbd "C-c C-u") #'sweeprolog-update-dependencies)
     (define-key map (kbd "C-c C-`")
@@ -502,6 +503,7 @@ determinism specification, and the third is a summary line."
                       (and (derived-mode-p 'sweeprolog-top-level-mode)
                            sweeprolog-top-level-thread-id)))
                   (buffer-list)) ]
+    [ "Send Goal to Top-level" sweeprolog-top-level-send-goal t ]
     [ "Open Top-level Menu" sweeprolog-list-top-levels t ]
     "--"
     [ "Describe Predicate" sweeprolog-describe-predicate t ]
@@ -2443,41 +2445,73 @@ Interactively, PROJ is the prefix argument."
         (sweeprolog--query-once "sweep" "sweep_colourise_query"
                                 (cons query (marker-position beg)))))))
 
-;;;###autoload
-(defun sweeprolog-top-level (&optional buffer)
-  "Run a Prolog top-level in BUFFER.
-If BUFFER is nil, a buffer called \"*sweeprolog-top-level*\" is used
-by default.
-
-Interactively, a prefix arg means to prompt for BUFFER."
-  (interactive
-   (let* ((buffer
-           (and current-prefix-arg
-                (read-buffer "Top-level buffer: "
-                             (if (and (eq major-mode 'sweeprolog-top-level-mode)
-                                      (null (get-buffer-process
-                                             (current-buffer))))
-                                 (buffer-name)
-                               (generate-new-buffer-name "*sweeprolog-top-level*"))))))
-     (list buffer)))
-  (let ((buf (get-buffer-create (or buffer "*sweeprolog-top-level*"))))
-    (with-current-buffer buf
-      (unless (eq major-mode 'sweeprolog-top-level-mode)
-        (sweeprolog-top-level-mode)))
-    (unless sweeprolog-prolog-server-port
-      (sweeprolog-start-prolog-server))
-    (unless (sweeprolog--query-once "sweep" "sweep_accept_top_level_client"
-                                    (buffer-name buf))
-      (error "Failed to create new top-level!"))
-    (with-current-buffer buf
+(defun sweeprolog-top-level-buffer (&optional name)
+  "Return a Prolog top-level buffer named NAME.
+
+If NAME is nil, use the default name \"*sweeprolog-top-level*\".
+
+If the buffer already exists, ensure it is associated with a live
+top-level."
+  (unless sweeprolog-prolog-server-port
+    (sweeprolog-start-prolog-server))
+  (let ((buf (get-buffer-create (or name "*sweeprolog-top-level*"))))
+    (unless (process-live-p (get-buffer-process buf))
+      (with-current-buffer buf
+        (unless (eq major-mode 'sweeprolog-top-level-mode)
+          (sweeprolog-top-level-mode)))
+      (unless (sweeprolog--query-once "sweep" "sweep_accept_top_level_client"
+                                      (buffer-name buf))
+        (error "Failed to create new top-level!"))
       (make-comint-in-buffer "sweeprolog-top-level"
                              buf
                              (cons "localhost"
                                    sweeprolog-prolog-server-port))
       (unless comint-last-prompt
-        (accept-process-output (get-buffer-process (current-buffer)) 1))
+        (accept-process-output (get-buffer-process buf) 1))
       (sweeprolog-top-level--populate-thread-id))
-    (pop-to-buffer buf sweeprolog-top-level-display-action)))
+    buf))
+
+;;;###autoload
+(defun sweeprolog-top-level (&optional buffer-name)
+  "Run a Prolog top-level in a buffer.
+
+BUFFER-NAME is passed to `sweeprolog-top-level-buffer' to obtain
+an appropriate buffer.
+
+Interactively, a prefix argument means to prompt for BUFFER-NAME."
+  (interactive
+   (list (and current-prefix-arg
+              (read-buffer "Top-level buffer: "
+                           (if (and (eq major-mode 'sweeprolog-top-level-mode)
+                                    (null (get-buffer-process
+                                           (current-buffer))))
+                               (buffer-name)
+                             (generate-new-buffer-name "*sweeprolog-top-level*"))))))
+  (pop-to-buffer (sweeprolog-top-level-buffer buffer-name)
+                 sweeprolog-top-level-display-action))
+
+(defun sweeprolog-top-level-send-string (string &optional buffer)
+  "Send STRING to the top-level associated with BUFFER.
+
+If BUFFER is nil, use `sweeprolog-top-level-buffer' to obtain an
+appropriate buffer."
+  (comint-send-string (get-buffer-process
+                       (or buffer (sweeprolog-top-level-buffer)))
+                      string))
+
+;;;###autoload
+(defun sweeprolog-top-level-send-goal (goal)
+  "Send GOAL to a top-level buffer and display that buffer."
+  (interactive (list (sweeprolog-read-goal)))
+  (let ((goal (cond
+               ((string-match (rx "." (or white "\n") eos) goal)
+                goal)
+               ((string-match (rx "." eos) goal)
+                (concat goal "\n"))
+               (t (concat goal ".\n")))))
+    (let ((buffer (sweeprolog-top-level-buffer)))
+      (sweeprolog-top-level-send-string goal buffer)
+      (display-buffer buffer sweeprolog-top-level-display-action))))
 
 (defun sweeprolog-top-level--post-self-insert-function ()
   (when-let ((pend (cdr comint-last-prompt)))