[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/sweeprolog 0bb2a103bb 1/2: ADDED: command for inserting ex
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/sweeprolog 0bb2a103bb 1/2: ADDED: command for inserting example usage comments |
Date: |
Tue, 30 May 2023 16:02:37 -0400 (EDT) |
branch: elpa/sweeprolog
commit 0bb2a103bb5e279024fe385702484eb92bd35cb6
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>
ADDED: command for inserting example usage comments
* sweeprolog.el (sweeprolog-top-level-example-mode): New minor mode.
(sweeprolog-make-example-usage-comment): New command.
(sweeprolog-mode-map): Bind it.
* README.org (Example Usage Comments): New section.
---
README.org | 36 +++++++++++++++++++++++++++
sweeprolog.el | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 115 insertions(+)
diff --git a/README.org b/README.org
index 286463297a..6d43662cd5 100644
--- a/README.org
+++ b/README.org
@@ -1511,6 +1511,42 @@ documented in [[info:emacs#Text][Commands for Human
Languages]], which see.
For more information about =PlDoc= and source documentation in
SWI-Prolog, see
[[https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/pldoc.html%27)][the
PlDoc manual]].
+** Example Usage Comments
+:PROPERTIES:
+:CUSTOM_ID: usage-comments
+:DESCRIPTION: Commands for inserting comments that show example usage of your
code
+:ALT_TITLE: Usage Comments
+:END:
+
+Beyond documenting your code with =PlDoc= comments as described in
+[[#sweeprolog-pldoc][Documenting Predicates]], you might want to have comments
in your source
+code that shows example usage of some predicate. Creating such
+comments usually involves posting queries in a Prolog top-level,
+copying the queries and their results into the relevant source code
+buffer, and formatting them as comments. Sweep provides the following
+command to streamline this process:
+
+#+FINDEX: sweeprolog-make-example-usage-comment
+- Key: C-c C-% (sweeprolog-make-example-usage-comment) :: Start a
+ new top-level for recording example usage. When you finish
+ interacting with the top-level its contents are formatted as a
+ comment in the buffer and position where you invoked this command.
+
+The command ~sweeprolog-make-example-usage-comment~, bound to ~C-c
+C-%~ in ~sweeprolog-mode~ buffers, creates and switches to a new
+top-level buffer for recording example usage that you want to
+demonstrate. The /example usage top-level/ is a regular top-level
+buffer (see [[*The Prolog Top-Level][The Prolog Top-Level]]), except that it's
tied to the
+specific position in the source buffer where you invoke this command.
+You can post queries in the example usage top-level and edit it
+freely, then type ~C-c C-q~ in to quit the top-level buffer and format
+its contents as a comment in the source buffer.
+
+You can have multiple example usage top-levels for different parts of
+your code at the same time. To display the source position where you
+created a certain usage example top-level buffer by, type ~C-c C-b~ in
+that buffer.
+
** Displaying Predicate Documentation
:PROPERTIES:
:CUSTOM_ID: eldoc-integration
diff --git a/sweeprolog.el b/sweeprolog.el
index c90c30da06..240d26404f 100644
--- a/sweeprolog.el
+++ b/sweeprolog.el
@@ -448,6 +448,7 @@ use `autoload/2' for all added directives."
#'sweeprolog-show-diagnostics
#'flymake-show-diagnostics-buffer))
(define-key map (kbd "C-c C-&") #'sweeprolog-async-goal)
+ (define-key map (kbd "C-c C-%") #'sweeprolog-make-example-usage-comment)
(define-key map (kbd "C-c C--") #'sweeprolog-decrement-numbered-variables)
(define-key map (kbd "C-c C-+") #'sweeprolog-increment-numbered-variables)
(define-key map (kbd "C-M-^") #'kill-backward-up-list)
@@ -518,6 +519,13 @@ use `autoload/2' for all added directives."
map)
"Keymap for moving to next hole with TAB.")
+(defvar sweeprolog-top-level-example-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c C-b")
#'sweeprolog-top-level-example-display-source)
+ (define-key map (kbd "C-c C-q") #'sweeprolog-top-level-example-done)
+ map)
+ "Keymap for example top-level buffer.")
+
;;;; Menu bar
(easy-menu-define sweeprolog-menu (list sweeprolog-mode-map
@@ -605,6 +613,8 @@ use `autoload/2' for all added directives."
(defvar-local sweeprolog-top-level-thread-id nil
"Prolog top-level thread ID corresponding to this buffer.")
+(defvar-local sweeprolog-top-level-example-marker nil)
+
(defvar-local sweeprolog--buffer-last-modified-time nil)
(defvar-local sweeprolog--buffer-modified nil)
@@ -6433,6 +6443,75 @@ Return nil if POS is not the beginning of a macro
invocation."
(unless (sweeprolog-expand-macro-at-pos point)
(user-error "No macro invocation at point")))
+(define-minor-mode sweeprolog-top-level-example-mode
+ "Minor mode for example top-level sessions.
+This mode is enabled in top-level buffers created by
+\\[sweeprolog-make-example-usage-comment]."
+ :lighter " Example"
+ :group 'sweeprolog)
+
+(defun sweeprolog-top-level-example-display-source ()
+ "Pop to the source position where this example session was started.
+This is the position where
+`sweeprolog-make-example-usage-comment' was invoked to create
+the current top-level buffer, and where
+\\[sweeprolog-top-level-example-done] inserts its contents of as
+a comment."
+ (interactive "" sweeprolog-top-level-mode)
+ (unless sweeprolog-top-level-example-mode
+ (user-error "Not in an example top-level session"))
+ (let ((source-buffer (marker-buffer sweeprolog-top-level-example-marker)))
+ (unless (buffer-live-p source-buffer)
+ (user-error "Source buffer for this example session no longer alive"))
+ (let ((marker sweeprolog-top-level-example-marker))
+ (display-buffer source-buffer)
+ (goto-char marker))))
+
+(defun sweeprolog-top-level-example-done ()
+ "Finalize the current example top-level session.
+This kills the current top-level buffer and inserts its contents
+as a comment in the source location where you invoked
+`sweeprolog-make-example-usage-comment' to create it."
+ (interactive "" sweeprolog-top-level-mode)
+ (unless sweeprolog-top-level-example-mode
+ (user-error "Not in an example top-level session"))
+ (let ((source-buffer (marker-buffer sweeprolog-top-level-example-marker)))
+ (unless (buffer-live-p source-buffer)
+ (user-error "Source buffer for this example session no longer alive"))
+ (let ((top-level-buffer (current-buffer))
+ (example (replace-regexp-in-string
+ (rx "?- " eos) ""
+ (string-replace
+ "\n\n" "\n"
+ (buffer-substring-no-properties (point-min)
+ (point-max)))))
+ (marker sweeprolog-top-level-example-marker))
+ (pop-to-buffer source-buffer)
+ (unless (string-empty-p example)
+ (save-excursion
+ (goto-char marker)
+ (insert example)
+ (comment-region marker (point))))
+ (delete-process (get-buffer-process top-level-buffer))
+ (kill-buffer top-level-buffer))))
+
+(defun sweeprolog-make-example-usage-comment (point)
+ "Start a top-level and record it as a comment at POINT.
+This creates a new example top-level buffer where you can perform
+queries in this top-level as usual. Use
+\\<sweeprolog-top-level-example-mode-map>\\[sweeprolog-top-level-example-done]
+in the example top-level buffer to finish and format the session
+as a comment in the source buffer at starting at POINT."
+ (interactive "d" sweeprolog-mode)
+ (let ((marker (copy-marker point))
+ (buffer (sweeprolog-top-level-buffer (generate-new-buffer-name
+ "*Example Session*"))))
+ (pop-to-buffer buffer)
+ (setq sweeprolog-top-level-example-marker marker
+ header-line-format (substitute-command-keys
+ (format
"`\\<sweeprolog-top-level-example-mode-map>\\[sweeprolog-top-level-example-done]'
to quit and write contents as a comment in buffer %s" (buffer-name
(marker-buffer marker)))))
+ (sweeprolog-top-level-example-mode)))
+
;;;; Footer
(provide 'sweeprolog)