From 3139de3e6c228327456dc24157f23389400b5639 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Sat, 3 Sep 2022 11:47:03 +0300 Subject: [PATCH] ENHANCED: prompt for buffer name in sweep-top-level with C-u --- README.org | 49 ++++++++++++++++++++++++++++++++++++++++++------- sweep.el | 41 ++++++++++++++++++++++++++++++----------- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/README.org b/README.org index 8cff877..87f0ee3 100644 --- a/README.org +++ b/README.org @@ -24,10 +24,21 @@ embedded SWI-Prolog runtime inside of Emacs. :CUSTOM_ID: overview :END: -=sweep= is an embedding of SWI-Prolog in Emacs. It uses the C -interfaces of both SWI-Prolog and Emacs Lisp to create a dynamically -loaded Emacs module that contains the SWI-Prolog runtime. As such, -=sweep= has parts written in C, in Prolog and in Emacs Lisp. +=sweep= is an embedding of SWI-Prolog in Emacs. It provides an +interface for executing Prolog queries and consuming their results +from Emacs Lisp (see [[Querying Prolog]]). =sweep= further builds on top of +this interface and on top of the standard Emacs facilities to provide +advanced features for developing SWI-Prolog programs in Emacs. + +** High-level architecture +:PROPERTIES: +:CUSTOM_ID: high-level-architecture +:END: + +both SWI-Prolog and Emacs Lisp to create a dynamically loaded Emacs +module that contains the SWI-Prolog runtime. As such, =sweep= has parts +written in C, in Prolog and in Emacs Lisp. + The different parts of =sweep= are structured as follows: @@ -250,7 +261,6 @@ Prolog terms to Elisp objects]]) and passed as a sole argument to the invoked Elisp function. The =sweep_funcall/2= variant invokes the Elisp function without any arguments. - * The Prolog top-level :PROPERTIES: :CUSTOM_ID: prolog-top-level @@ -272,17 +282,25 @@ buffer inherits the features present in other =comint-mode= derivatives, most of which are described in [[info:emacs#Shell Mode][the Emacs manual]]. ** Multiple top-levels +:PROPERTIES: +:CUSTOM_ID: multiple-top-levels +:END: Any number of top-levels can be created and used concurrently, each in its own buffer. If a top-level buffer already exists, =sweep-top-level= will simply open it by default. To create another one or more -top-level buffers, run the command =C-x x u= (or =M-x rename-uniquely=) in -the buffer called =*sweep-top-level*= and then run =M-x sweep-top-level= +top-level buffers, run =sweep-top-level= with a prefix argument +(i.e. =C-u M-x sweep-top-level-mode=) to choose a different buffer name. +Alternatively, run the command =C-x x u= (or =M-x rename-uniquely=) in the +buffer called =*sweep-top-level*= and then run =M-x sweep-top-level= again. This will change the name of the original top-level buffer to something like =*sweep-top-level*<2>= and allow the new top-level to claim the buffer name =*sweep-top-level*=. ** Completion in the top-level +:PROPERTIES: +:CUSTOM_ID: completion-in-top-level +:END: The =sweep-top-level-mode=, enabled in the =sweep= top-level buffer, integrates with the standard Emacs symbol completion mechanism to @@ -318,6 +336,23 @@ or upgrade a SWI-Prolog =pack=. When selecting a =pack= to install, the completion candidates are annotated with description and the version of each package. +* Quick access to =sweep= commands +:PROPERTIES: +:CUSTOM_ID: quick-command-access +:END: + +#+VINDEX: sweep-prefix-map +=sweep= defines a keymap called =sweep-prefix-map= which provides +keybinding for several useful =sweep= commands. By default, +=sweep-prefix-map= itself is not bound to any key. To bind it globally +to a prefix key, e.g. =C-c p=, use: + +#+begin_src emacs-lisp + (keymap-global-set "C-c p" sweep-prefix-map) +#+end_src + +As an example, with the above binding the =sweep= top-level can be +access from anywhere with =C-c p t=. * Indices :PROPERTIES: diff --git a/sweep.el b/sweep.el index 4d53003..bd1d33e 100644 --- a/sweep.el +++ b/sweep.el @@ -49,6 +49,12 @@ :type 'string :group 'sweep) +(defcustom sweep-top-level-display-action nil + "Display action used for displaying the `sweep-top-level' buffer." + :package-version '((sweep . "0.1.0")) + :type 'function + :group 'sweep) + (defvar sweep-install-buffer-name "*Install sweep*" "Name of the buffer used for compiling sweep-module.") @@ -595,18 +601,31 @@ module name, F is a functor name and N is its arity." sol))))) ;;;###autoload -(defun sweep-top-level () - "Start an interactive Prolog top-level." - (interactive) - (let ((buf (get-buffer-create "*sweep-top-level*"))) - (with-current-buffer buf - (unless (eq major-mode 'sweep-top-level-mode) +(defun sweep-top-level (&optional buffer) + "Run a Prolog top-level in BUFFER. +If BUFFER is nil, a buffer called \"*sweep-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 'sweep-top-level-mode) + (null (get-buffer-process + (current-buffer)))) + (buffer-name) + (generate-new-buffer-name "*sweep-top-level*")))))) + (list buffer))) + (let ((buf (get-buffer-create (or buffer "*sweep-top-level*")))) + (with-current-buffer buf + (unless (eq major-mode 'sweep-top-level-mode) (sweep-top-level-mode))) - (make-comint-in-buffer "sweep-top-level" - buf - (cons "localhost" - sweep-prolog-server-port)) - (select-window (display-buffer buf)))) + (make-comint-in-buffer "sweep-top-level" + buf + (cons "localhost" + sweep-prolog-server-port)) + (pop-to-buffer buf sweep-top-level-display-action))) (defun sweep-top-level--post-self-insert-function () (when-let ((pend (cdr comint-last-prompt))) -- 2.39.2