branch: externals/eev
commit 35f33e17914b524c8127e713138a079d91401d57
Author: Eduardo Ochs <[email protected]>
Commit: Eduardo Ochs <[email protected]>

    Finished the code and the documentation for `eepitch-b'.
---
 ChangeLog         |  82 ++++++++++++++
 VERSION           |   4 +-
 eepitch.el        | 260 ++++++++++++++++++++++++++++---------------
 eev-elinks.el     |   3 +-
 eev-intro.el      | 321 ++++++++++++++++++++++++++++++++++++++++++++++--------
 eev-load.el       |   9 +-
 eev-testblocks.el | 195 ++++++++++++++++++++++++++-------
 eev-tlinks.el     |  13 ++-
 eev.el            |   2 +-
 9 files changed, 707 insertions(+), 182 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9f2ff967b0..13f0d73a95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,85 @@
+2025-11-23  Eduardo Ochs  <[email protected]>
+
+       * eepitch.el (eepitch-b-show-source, eepitch-b-set-source)
+       (eepitch-b-show-target, eepitch-b-set-target)
+       (eepitch-b-show-source-and-target, eepitch-b)
+       (eepitch-b-set-target-and-show, ee-buffers-in-modes)
+       (ee-buffers-in-mode, ee-buffers-with-minor-mode)
+       (ee-buffers-with-name-matching, ee-kill-buffers)
+       (ee-kill-buffers-in-modes, ee-kill-buffers-in-mode)
+       (ee-kill-buffers-with-minor-mode)
+       (ee-kill-buffers-with-name-matching, find-ebuffer-in-mode)
+       (eepitch-gdb-kill, eepitch-gdb-select)
+       (ee-slime-inferior-lisp-buffers, ee-slime-buffers)
+       (eepitch-slime-kill, eepitch-slime-select)
+       (eepitch-slime-pkgbuffers, eepitch-slime-set-pkgbuffers)
+       (eepitch-slime-get-pkgbuffer, eepitch-slime-select-pkgbuffer)
+       (eepitch-sly-kill, eepitch-sly-select, eepitch-sly-pkgbuffers)
+       (eepitch-sly-set-pkgbuffers, eepitch-sly-get-pkgbuffer)
+       (eepitch-sly-select-pkgbuffer): these are all the functions in the
+       section "badly-behaved targets" of eepitch.el - I rewrote the code
+       and the comments for most of them.
+
+       * eev-testblocks.el (ee-insert-test-lisp-mode)
+       (ee-insert-test-lisp-mode-nil, ee-insert-test-lisp-mode-1)
+       (ee-insert-test-lisp-mode-2, ee-insert-test-lisp-mode-3)
+       (ee-insert-test-lisp-mode-4, ee-insert-test-lisp-mode-5):
+       rewritten.
+
+2025-11-21  Eduardo Ochs  <[email protected]>
+
+       * eev-intro.el (find-eepitch-intro): rewrote the sections about
+       badly-behaved targets (sections 4 to 4.7).
+
+2025-11-16  Eduardo Ochs  <[email protected]>
+
+       * eepitch.el (eepitch-slime-pkgbuffers): new variable.
+       (eepitch-slime-pkgbuffers, eepitch-slime-set-pkgbuffers)
+       (eepitch-slime-get-pkgbuffer, eepitch-slime-select-pkgbuffer): new
+       functions.
+
+2025-10-22  Eduardo Ochs  <[email protected]>
+
+       * eepitch.el (ee-buffers-with-name-matching)
+       (ee-kill-buffers-with-name-matching): new functions.
+       (eepitch-sly-kill): use `ee-kill-buffers-with-name-matching'.
+       (eepitch-b): new function.
+       (eepitch-b-set-target): FIX?
+
+       * eev-tlinks.el (ee-dot-emacs-eepitchb): new function.
+
+2025-10-08  Eduardo Ochs  <[email protected]>
+
+       * eepitch.el (ee-buffers-with-minor-mode, ee-kill-buffers)
+       (ee-kill-buffers-with-minor-mode): new functions.
+       (eepitch-sly-kill, eepitch-sly-start, eepitch-sly-select)
+       (eepitch-sly-connect): new functions.
+       (eepitch-sly-pkgbuffers): new variable.
+       (eepitch-sly-pkgbuffers, eepitch-sly-set-pkgbuffers)
+       (eepitch-sly-get-pkgbuffer, eepitch-sly-select-pkgbuffer): new
+       functions.
+
+2025-10-05  Eduardo Ochs  <[email protected]>
+
+       * eev-elinks.el (find-pdflike-page-links): new argument: target.
+
+2025-09-27  Eduardo Ochs  <[email protected]>
+
+       * eepitch.el (eepitch-gdb-start, eepitch-slime-start): made the
+       arguments optional.
+
+       * eev-testblocks.el (ee-insert-test-lisp-mode-2): new function.
+       (ee-insert-test-lisp-mode-3): new function.
+       (ee-insert-test-lisp-mode-4): new function.
+       (ee-insert-test-lisp-mode-5): new function.
+
+       * eev-tlinks.el: added a link like `(find-eev "eev-testblocks.el"
+       "lua-mode")'.
+
+2025-09-16  Eduardo Ochs  <[email protected]>
+
+       * eepitch.el (eepitch-gdb-select): fixed a typo.
+
 2025-09-14  Eduardo Ochs  <[email protected]>
 
        * eev-mode.el (ee-kill-this-buffer): use `kill-current-buffer'
diff --git a/VERSION b/VERSION
index db68a0ca01..205f3664de 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-Sun Sep 14 22:12:31 GMT 2025
-Sun Sep 14 19:12:31 -03 2025
+Sun Nov 23 23:05:39 GMT 2025
+Sun Nov 23 20:05:39 -03 2025
diff --git a/eepitch.el b/eepitch.el
index 33f876e152..c3fa594a70 100644
--- a/eepitch.el
+++ b/eepitch.el
@@ -19,7 +19,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20250914
+;; Version:    20251123
 ;; Keywords:   e-scripts
 ;;
 ;; Latest version: <http://anggtwu.net/eev-current/eepitch.el>
@@ -54,9 +54,11 @@
 ;;   «.eepitch-sly»            (to "eepitch-sly")
 ;; «.badly-behaved»            (to "badly-behaved")
 ;;   «.eepitch-b»              (to "eepitch-b")
-;;   «.ee-buffers-in-mode»     (to "ee-buffers-in-mode")
-;;   «.eepitch-gdb»            (to "eepitch-gdb")
-;;   «.eepitch-slime»          (to "eepitch-slime")
+;;   «.ee-kill-buffers»                (to "ee-kill-buffers")
+;;   «.find-ebuffer-in-mode»   (to "find-ebuffer-in-mode")
+;;   «.eepitch-b-gdb»          (to "eepitch-b-gdb")
+;;   «.eepitch-b-slime»                (to "eepitch-b-slime")
+;;   «.eepitch-b-sly»          (to "eepitch-b-sly")
 ;;
 ;; «.eepitch-langs»            (to "eepitch-langs")
 ;; «.eepitch-langs-vterm»      (to "eepitch-langs-vterm")
@@ -1082,51 +1084,32 @@ If the mrepl doesn't start in 30 seconds this function 
yields an error."
 ;;;                      |___/                                          
 ;;
 ;; «badly-behaved»  (to ".badly-behaved")
+;; WARNING: EXPERIMENTAL! ADVANCED! NEEDS CONFIGURATION!
 ;; See: (find-eepitch-intro "4. Badly-behaved targets")
 ;;      (find-eepitch-intro "4. Badly-behaved targets" "For example")
-;; Warning: EXPERIMENTAL! BADLY DOCUMENTED! BADLY TESTED!
-;;
-;; Sometimes a target is so badly behaved - for example: Slime - that
-;; I don't know how to write a sexp like this for it,
-;;
-;;   (eepitch CODE)
-;;
-;; that would pitch to the right target buffer... in the case of Slime
-;; the target buffer is a buffer with a name like "*slime-repl sbcl*"
-;; or "*slime-repl sbcl*<4>", that is in `slime-repl-mode', and that
-;; has an active `slime-buffer-connection', but there may be several
-;; buffers like that, and writing a trick with hooks that would select
-;; the right buffer - as `find-slyprocess' does, above - turned out to
-;; be too hard...
-;;
-;; In cases like that the best solution is to treat the `eepitch' in
-;; `(eepitch CODE)' as a black box that needs to be opened, that needs
-;; to have its components run step by step by hand, and that the user
-;; needs to select the right target buffer by running `M-x b' on it.
-;; For example, in...
-;;
-;;   [I need to rewrite the rest!]
-
+;;      (find-eepitch-intro "4.2. `eepitch-b'")
+;;      (find-eepitch-intro "4.3. Configuring `eepitch-b'")
 
 ;; «eepitch-b»  (to ".eepitch-b")
 ;; The basic functions for the support for badly-behaved targets.
+;;   See: (find-eepitch-intro "4.2. `eepitch-b'")
+;; Tests: (eepitch-b-set-source)
+;;        (find-2a nil '(eepitch-b-show-source))
+;;        (eepitch-b-set-source 2)
+;;        (find-2a nil '(eepitch-b-show-source))
+;;        (eepitch-to-buffer "TODO")
+;;        (eepitch-b-set-source 3)
+;;        (delete-other-windows)
+;;        (eepitch-b-show-source-and-target)
 ;;
 (defvar eepitch-b-source-buffer "")
 (defvar eepitch-b-source-marker nil)
 
+;; Low-level functions
 (defun eepitch-b-show-source ()
   (interactive)
   (find-emarker eepitch-b-source-marker))
 
-(defun eepitch-b-show-target ()
-  (interactive)
-  (find-ebuffer eepitch-buffer-name))
-
-;; Test:
-;; (eepitch-b-set-source)
-;; (find-2a nil '(eepitch-b-show-source))
-;; (eepitch-b-set-source 2)
-;; (find-2a nil '(eepitch-b-show-source))
 (defun eepitch-b-set-source (&optional n)
   (interactive)
   (setq eepitch-b-source-buffer (buffer-name))
@@ -1135,60 +1118,99 @@ If the mrepl doesn't start in 30 seconds this function 
yields an error."
          (if n (forward-line n))
          (point-marker))))
 
-;; Test:
-;; (eepitch-to-buffer "TODO")
-;; (eepitch-b-set-source 3)
-;; (eek "C-x 1")
-;; (eepitch-b-show-source-and-target)
-(defun eepitch-b-show-source-and-target ()
+(defun eepitch-b-show-target ()
   (interactive)
-  (find-2a '(eepitch-b-show-source) '(eepitch-b-show-target))
-  (message "%S -> %S" eepitch-b-source-buffer eepitch-buffer-name)
-  (format  "`%s' -> `%s'" eepitch-b-source-buffer eepitch-buffer-name))
+  (find-ebuffer eepitch-buffer-name))
 
 (defun eepitch-b-set-target ()
-  "An internal function used by `eepitch-set-source-and-M-x-b'."
   (interactive)
   (setq eepitch-buffer-name (buffer-name))
-  (eepitch-b-show-source-and-target))
+  (setq eepitch-code `(find-ebuffer ,(buffer-name))))
 
-;; See: (find-eepitch-intro "4. Badly-behaved targets" "For example")
-(defun eepitch-set-source-and-M-x-b (&optional n)
+(defun eepitch-b-show-source-and-target ()
   (interactive)
-  (eepitch-b-set-source n)
-  (defalias 'b 'eepitch-b-set-target)
-  (format "`M-x b' will set the eepitch target and return to `%s'"
-         eepitch-b-source-buffer))
-
-;; Unused at the moment!
-(defun eepitch-b-insert ()
+  (find-2a '(eepitch-b-show-source) '(eepitch-b-show-target))
+  (message "%S -> %S" eepitch-b-source-buffer eepitch-buffer-name)
+  (format "`%s' -> `%s'" eepitch-b-source-buffer eepitch-buffer-name))
+
+;; High-level functions.
+;; See: (find-eepitch-intro "4.2. `eepitch-b'")
+;;      (find-eepitch-intro "4.3. Configuring `eepitch-b'")
+;;      (find-eepitch-intro "4.3. Configuring `eepitch-b'" "<f9>")
+;;
+(defun eepitch-b (sexp)
+  "This is like `eepitch', but SEXP may be a badly-behaved target.
+This function sets the source, runs SEXP, and it waits until the user
+types <f9> to set the target; then it creates a two-window setting with
+the source at the left and the target at the right."
+  (eepitch-b-set-source 1)
+  (eval sexp)
+  "Type <f9> to tell to `eepitch-b' that we're on the target buffer.")
+
+(defun eepitch-b-set-target-and-show ()
+  "Run this to signal to `eepitch-b' that we're on the target buffer.
+Read the comments in the source to see how to configure this."
   (interactive)
-  (let* ((sexp `(eepitch-to-buffer ,eepitch-buffer-name))
-        (line (format " %s\n" (ee-S sexp))))
-    (move-beginning-of-line nil)
-    (insert line)))
+  (eepitch-b-set-target)
+  (eepitch-b-show-source-and-target))
+
 
 
-;; «ee-buffers-in-mode»  (to ".ee-buffers-in-mode")
-;; These functions are used by some badly behaved targets - like gdb.
-;;
-(defun ee-buffers-in-mode (majormode)
-  (ee-buffers-in-modes (list majormode)))
+
+;;;  _  ___ _ _   _            __  __               
+;;; | |/ (_) | | | |__  _   _ / _|/ _| ___ _ __ ___ 
+;;; | ' /| | | | | '_ \| | | | |_| |_ / _ \ '__/ __|
+;;; | . \| | | | | |_) | |_| |  _|  _|  __/ |  \__ \
+;;; |_|\_\_|_|_| |_.__/ \__,_|_| |_|  \___|_|  |___/
+;;;                                                 
+;; «ee-kill-buffers»  (to ".ee-kill-buffers")
+;; Some badly-behaved targets use the functions in this block to kill
+;; the buffers associated to a target. See this for an example:
+;; (find-eepitch-intro "4.1. Killing Slime")
 
 (defun ee-buffers-in-modes (majormodes)
   (sort (cl-loop for b in (buffer-list)
                 if (member (with-current-buffer b major-mode) majormodes)
                 collect (buffer-name b))))
 
-(defun ee-kill-buffers-in-mode (majormode)
-  (ee-kill-buffers-in-modes (list majormode)))
+(defun ee-buffers-in-mode (majormode)
+  (ee-buffers-in-modes (list majormode)))
+
+(defun ee-buffers-with-minor-mode (minormode)
+  (sort (cl-loop for b in (buffer-list)
+                if (with-current-buffer b (symbol-value minormode))
+                collect (buffer-name b))))
 
-(defun ee-kill-buffers-in-modes (majormodes)
-  (let* ((bufs (ee-buffers-in-modes majormodes)))
-    (cl-loop for b in bufs
+(defun ee-buffers-with-name-matching (regexp)
+  (sort (cl-loop for b in (buffer-list)
+                if (string-match regexp (buffer-name b))
+                collect (buffer-name b))))
+
+(defun ee-kill-buffers (buffernames &optional show-only)
+  (if show-only
+      `(Buffers that will be killed: ,(or buffernames 'none))
+    (cl-loop for b in buffernames
             do (ee-kill-buffer b))
-    `(Buffers killed: ,(or bufs 'none))))
+    `(Buffers killed: ,(or buffernames 'none))))
+
+(defun ee-kill-buffers-in-modes (majormodes &optional show-only)
+  (ee-kill-buffers (ee-buffers-in-modes majormodes) show-only))
+
+(defun ee-kill-buffers-in-mode (majormode &optional show-only)
+  (ee-kill-buffers-in-modes (list majormode) show-only))
+
+(defun ee-kill-buffers-with-minor-mode (minormode &optional show-only)
+  (ee-kill-buffers (ee-buffers-with-minor-mode minormode) show-only))
 
+(defun ee-kill-buffers-with-name-matching (regexp &optional show-only)
+  (ee-kill-buffers (ee-buffers-with-name-matching regexp) show-only))
+
+
+;; «find-ebuffer-in-mode»  (to ".find-ebuffer-in-mode")
+;; Some badly-behaved targets use this to select a target buffer.
+;; See the explanation for `eepitch-slime-select' in:
+;; (find-eepitch-intro "4.4. `eepitch-slime-select'")
+;;
 (defun find-ebuffer-in-mode (majormode &rest pos-spec-list)
   "Similar to `find-ebuffer', but goes to the only buffer in MAJORMODE.
 If the number of buffers with major mode MAJORMODE is not exactly one,
@@ -1200,33 +1222,101 @@ raise an error."
             majormode (or buffers 'none)))))
 
 
-;; «eepitch-gdb»  (to ".eepitch-gdb")
-;; See: (find-eepitch-intro "4. Badly-behaved targets" "For example")
 
+;; «eepitch-b-gdb»  (to ".eepitch-b-gdb")
+;; GDB is a simple badly-behaved target.
+;; A typical eepitch block for GDB looks like this:
+;;
+;;    (eepitch-gdb-kill)
+;;    (eepitch-b '(gdb "gdb -i=mi"))
+;;    (eepitch-gdb-select)
+;;
+;; Compare that with the simpler example of eepitching to slime, in:
+;; (find-eepitch-intro "4. Badly-behaved targets")
+;;
 (defun eepitch-gdb-kill ()
   (ee-kill-buffers-in-mode 'gud-mode))
 
-(defun eepitch-gdb-start (command-line)
-  (eepitch-set-source-and-M-x-b 1)
-  (gdb command-line))
-
 (defun eepitch-gdb-select ()
-  (eepitch '(find-buffer-in-mode 'gud-mode)))
+  (eepitch '(find-ebuffer-in-mode 'gud-mode)))
+
 
 
-;; «eepitch-slime»  (to ".eepitch-slime")
-;; See: (find-eev "eev-testblocks.el" "slime")
+;; «eepitch-b-slime»  (to ".eepitch-b-slime")
+;; Slime is a very badly-behaved target.
+;; These are the functions specific to it.
+;; See: (find-eepitch-intro "4.1. Killing Slime")
+;;      (find-eepitch-intro "4.4. `eepitch-slime-select'")
+;;      (find-eev "eev-testblocks.el" "lisp-mode-slime")
+;;      (find-eev "eev-testblocks.el" "lisp-mode-maxima-slime")
 ;;
-(defun eepitch-slime-kill ()
-  (ee-kill-buffers-in-mode 'slime-repl-mode))
+(defun ee-slime-inferior-lisp-buffers ()
+  (cl-loop for b in (ee-buffers-with-name-matching "^\\*inferior-lisp")
+          if (with-current-buffer b slime-inferior-lisp-args)
+          collect b))
 
-(defun eepitch-slime-start (command)
-  (eepitch-set-source-and-M-x-b 1)
-  (slime command))
+(defun ee-slime-buffers ()
+  (append (ee-buffers-with-name-matching "^\\*slime-")
+         (ee-slime-inferior-lisp-buffers)))
+
+(defun eepitch-slime-kill (&optional show-only)
+  (ee-kill-buffers (ee-slime-buffers) show-only))
 
 (defun eepitch-slime-select ()
   (eepitch '(find-ebuffer-in-mode 'slime-repl-mode)))
 
+;; This is for when we have several buffers in `slime-repl-mode'.
+;; See: (find-eepitch-intro "4.5. Slime and Maxima")
+;;      (find-eepitch-intro "4.6. The pkgbuffers")
+;;      (find-eev "eev-testblocks.el" "lisp-mode-maxima-slime")
+;;
+(defvar eepitch-slime-pkgbuffers nil)
+
+(defun eepitch-slime-pkgbuffers ()
+  (cl-loop for b in (ee-buffers-in-mode 'slime-repl-mode)
+          for p = (with-current-buffer b (slime-current-package))
+          collect (cons p b)))
+
+(defun eepitch-slime-set-pkgbuffers ()
+  (setq eepitch-slime-pkgbuffers (eepitch-slime-pkgbuffers)))
+
+(defun eepitch-slime-get-pkgbuffer (pkg)
+  (alist-get pkg eepitch-slime-pkgbuffers nil nil 'equal))
+
+(defun eepitch-slime-select-pkgbuffer (pkg)
+  (eepitch-to-buffer (eepitch-slime-get-pkgbuffer pkg)))
+
+
+;; «eepitch-b-sly»  (to ".eepitch-b-sly")
+;; This is similar to `eepitch-b-slime', for for Sly.
+;; See: (find-eev "eev-testblocks.el" "lisp-mode-sly")
+;;
+(defun eepitch-sly-kill (&optional show-only)
+  (ee-kill-buffers-with-name-matching "^\\*sly-" show-only))
+
+(defun eepitch-sly-select ()
+  (eepitch '(find-ebuffer-in-mode 'sly-mrepl-mode)))
+
+(defvar eepitch-sly-pkgbuffers nil)
+
+(defun eepitch-sly-pkgbuffers ()
+  (cl-loop for b in (ee-buffers-in-mode 'sly-mrepl-mode)
+          for p = (with-current-buffer b (sly-current-package))
+          collect (cons p b)))
+
+(defun eepitch-sly-set-pkgbuffers ()
+  (setq eepitch-sly-pkgbuffers (eepitch-sly-pkgbuffers)))
+
+(defun eepitch-sly-get-pkgbuffer (pkg)
+  (alist-get pkg eepitch-sly-pkgbuffers nil nil 'equal))
+
+(defun eepitch-sly-select-pkgbuffer (pkg)
+  (eepitch-to-buffer (eepitch-sly-get-pkgbuffer pkg)))
+
+
+
+
+
 
 
 
diff --git a/eev-elinks.el b/eev-elinks.el
index be8d97a2a6..d7c30a9783 100644
--- a/eev-elinks.el
+++ b/eev-elinks.el
@@ -1169,11 +1169,12 @@ when this is true remove the prefix D from FNAME, and 
put the sexp
 ;;
 ;; Skel: (find-find-links-links-new "pdflike-page" "page bufname offset" "")
 ;;
-(defun find-pdflike-page-links (&optional page bufname offset &rest 
pos-spec-list)
+(defun find-pdflike-page-links (&optional page bufname offset target &rest 
pos-spec-list)
 "Visit a temporary buffer containing hyperlinks to a pdf-like document.
 See: (find-pdf-like-intro)
      (find-pdf-like-intro \"refining hyperlinks to pages\")"
   (interactive)
+  (if target (setq offset (- page target)))
   (setq page    (or page (ee-current-page)))
   (setq bufname (or bufname (buffer-name)))
   (setq offset  (or offset ee-page-offset))
diff --git a/eev-intro.el b/eev-intro.el
index 70d22b92e7..d1a9f5ca08 100644
--- a/eev-intro.el
+++ b/eev-intro.el
@@ -19,7 +19,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20250913
+;; Version:    20251121
 ;; Keywords:   e-scripts
 ;;
 ;; Latest version: <http://anggtwu.net/eev-current/eev-intro.el>
@@ -6510,8 +6510,8 @@ scripts etc\]
 ;; (find-eev "eepitch.readme")
 
 (defun find-eepitch-intro (&rest rest) (interactive)
-  (let ((ee-buffer-name "*(find-eepitch-intro)*"))
-    (apply 'find-eintro "\
+       (let ((ee-buffer-name "*(find-eepitch-intro)*"))
+        (apply 'find-eintro "\
 \(Re)generate: (find-eepitch-intro)
 Source code:  (find-eev \"eev-intro.el\" \"find-eepitch-intro\")
 More intros:  (find-eev-quick-intro)
@@ -7157,65 +7157,294 @@ In an eepitch block like this one
 the first two red star lines are typically only used when we want to kill
 a current shell target - if it exists - and then create a new one.
 
-For \"badly-behaved targets\" - I will explain the term precisely in the
-next section - it is hard to define a function `eepitch-BBT' that would
-work well enough in an eepitch block like this one,
+For \"badly-behaved targets\" we may need eepitch blocks that are much
+more complex than that. For example, for Slime we need this:
 
- (eepitch-BBT)
- (eepitch-kill)
- (eepitch-BBT)
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
+ (eepitch-b '(slime \"sbcl\"))
+ (eepitch-slime-select)
 
-and it is more practical to have a eepitch block with functions specific
-for the target BBT, like this one:
+I will explain its parts in the following subsections.
 
- (eepitch-BBT-kill)
- (eepitch-BBT-start)
- (eepitch-BBT-select)
 
-but sometimes it is better to replace the middle red star line by
-several lines, and make them remind us how to go back to our source
-buffer. For example, here,
 
- (eepitch-gdb-kill)
- To restart gdb:
-    (eepitch-set-source-and-M-x-b 2)
-    (gdb \"gdb -i=mi\")
- (eepitch-gdb-select)
+4.1. Killing Slime
+------------------
+Slime uses several buffers, and the best way to kill a previous instance
+of Slime is with:
 
-the sexp `(gdb \"gdb -i=mi\")' asks some questions, messes up our window
-configuration, and only leaves us at the target buffer after too many
-keystrokes.
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
 
-Note that running the sexp `(eepitch-set-source-and-M-x-b 2)' prints
-instructions in the echo area - it says:
+The first `eepitch-slime-kill' above only shows the buffers that will,
+or would, be killed, by the second \"kill\". It shows something like
+this in the echo area:
 
-  \"`M-x b' will set the eepitch target and return to 
`*(find-eepitch-intro)*'\"
+  (Buffers that will be killed: (\"*slime-events*\"
+   \"*slime-repl sbcl*\" \"*inferior-lisp*\"))
 
-So after the `(gdb \"gdb -i=mi\")' finishes we need to run `M-x b'. The
-sexp `(eepitch-set-source-and-M-x-b 2)' has saved the source buffer -
-\"*(find-eepitch-intro)*\" - and the line that we need to return to,
-that is 2 lines below the `(eepitch-set-source-and-M-x-b 2)' itself;
-when we type `M-x b' Emacs interprets that as: this is the target
-<b>uffer - go <b>ack to the source <b>uffer and use this window setup:
+The second `eepitch-slime-kill' kills those buffers, but some of them
+issue messages when they die that take over the echo area. These
+messages are shown,
 
-   _____________________
-  |          |          |
-  |  source  |  target  |
-  |  buffer  |  buffer  |
-  |          |          |
-  |__________|__________|
+   (Buffers killed: (\"*slime-events*\" \"*slime-repl sbcl*\"
+    \"*slime-repl sbcl<2>*\" \"*inferior-lisp*\"))
+   Lisp connection closed unexpectedly: connection broken by remote peer
 
+but the user only sees the last one, with \"Lisp connection closed
+unexpectedly\". Adding this line
 
+ (eepitch-slime-kill 'show-only)
 
+makes things less mysterious, and less blackbox-ish.
 
-4.1. What are badly-behaved targets?
-------------------------------------
-(Examples: gdb, slime)
-(Compare with Sly)
 
-UNFINISHED!!!
-See: (find-eev \"eepitch.el\" \"badly-behaved\")
 
+4.2. `eepitch-b'
+----------------
+The third line of
+
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
+ (eepitch-b '(slime \"sbcl\"))
+ (eepitch-slime-select)
+
+starts with an `eepitch-b', that is a variant of `eepitch' that we can
+use in cases in which it is so hard to detect automatically when the
+target is ready that it is better to leave that task to the user. In
+short...
+
+  `eepitch-b' considers that the target is ready
+  when the user types <f9>
+  to signal that the target is ready.
+
+`eepitch-b' was inspired by the difficulties of writing a function based
+on `eepitch-sly' that would work for Slime (Sly is a fork of Slime).
+
+Writing a `eepitch-sly' was very hard, because the plain `eepitch'
+expects \"shell-like programs\", and to make Sly behave like a
+shell-like program I had to find a way to \"wait for hooks\" in exactly
+the right way. The technical details are explained in these places:
+
+  (find-eev \"eepitch.el\" \"eepitch\" \"(defun eepitch \")
+  (find-eev \"eepitch.el\" \"wait-for-hooks\")
+
+Slime was much more badly-behaved than Sly. At some point I discovered -
+with a LOT of help - that I could consider that Sly \"was ready\" when
+it ran the hook `sly-mrepl-hook'... but with Slime I decided to delegate
+that to the user.
+
+The line
+
+ (eepitch-b '(slime \"sbcl\"))
+
+works like this: it saves the current position in these variables,
+
+  (find-evariable 'eepitch-b-source-buffer)
+  (find-evariable 'eepitch-b-source-marker)
+
+it runs `(slime \"sbcl\")', and it waits until the user types <f9>.
+When the user types <f9> this means:
+
+  1) the user is saying that Slime is ready,
+  2) the point is at the target buffer for eepitch, and
+  3) now please rearrange the windows like this:
+
+     ____________________
+    |          |         |
+    |  source  |  slime  |
+    |  buffer  |  mrepl  |
+    |          |         |
+    |__________|_________|
+
+
+
+4.3. Configuring `eepitch-b'
+----------------------------
+At this moment eev doesn't bind <f9> by default.
+To bind it correctly you need the last block of:
+
+  (find-dot-emacs-links \"eev angges melpa epl eepitchb\")
+
+that contains these lines:
+
+  ;; See: (find-eepitch-intro \"4.3. Configuring `eepitch-b'\")
+  (define-key eev-mode-map (kbd \"<f9>\") 'eepitch-b-set-target-and-show)
+
+
+
+
+4.4. `eepitch-slime-select'
+---------------------------
+The last line of
+
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
+ (eepitch-b '(slime \"sbcl\"))
+ (eepitch-slime-select)
+
+calls `eepitch-slime-select', whose definition is:
+
+  (defun eepitch-slime-select ()
+    (eepitch '(find-ebuffer-in-mode 'slime-repl-mode)))
+
+In most cases when we use Slime we are only interested in using one of
+its buffers as a target for eepitch. The name of that buffer is
+something like \"*slime-repl sbcl*\" or \"*slime-repl sbcl<n>*\", and it
+will be the only buffer whose major mode is `slime-repl-mode'. The
+
+  (find-ebuffer-in-mode 'slime-repl-mode)
+
+switches to that buffer if there is exactly one buffer with that major
+mode, and yields an error if there zero or two or more.
+
+
+
+
+4.5. Slime and Maxima
+---------------------
+My current favorite way of debugging Maxima with _Sly_ is with this,
+
+  (find-try-sly-intro \"8. Inspect Maxima with Sly\")
+
+that may need some updates, but it works, or used to work.
+
+My current favorite way of debugging Maxima with _Slime_ is with this -
+but I haven't documented its full setup yet:
+
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
+ (eepitch-b '(slime \"sbcl\"))
+ (eepitch-slime-select)
+   (eepitch-maxima)
+   (eepitch-kill)
+   (eepitch-maxima)
+      load(\"startslime\");
+ (eepitch-b '(slime-connect \"localhost\" 4005))
+ (eepitch-slime-set-pkgbuffers)
+ (eepitch-slime-select-pkgbuffer \"MAXIMA\")
+ (eepitch-maxima)
+
+We understood its first four lines in the previous subsections. The
+following four lines,
+
+   (eepitch-maxima)
+   (eepitch-kill)
+   (eepitch-maxima)
+      load(\"startslime\");
+
+are easy to understand - it deletes a previous Maxima if there was one
+running, it creates a new Maxima, and it makes it load \"startslime\",
+that is this file:
+
+  (find-angg \".maxima/startslime.lisp\")
+
+Loading \"startslime\" takes several seconds, and we need to wait until
+it finishes before typing more <f8>s. At that point we have two
+interesting targets, and we can switch between them with:
+
+ (eepitch-slime-select)
+ (eepitch-maxima)
+
+The next line is 
+
+ (eepitch-b '(slime-connect \"localhost\" 4005))
+
+and it will only work correctly if it is run after the
+
+  load(\"startslime\");
+
+has finished executing, because \"startslime\" makes Maxima listen on a
+certain port, and the `slime-connect' makes Slime connect to that port.
+
+When Slime connects to Maxima this won't work anymore,
+
+ (eepitch-slime-select)
+
+because now there are two buffers in `slime-repl-mode'. It aborts with
+this message:
+
+  Error - buffers with major mode slime-repl-mode:
+  (\"*slime-repl sbcl*\" \"*slime-repl sbcl<2>*\")
+
+
+
+
+4.6. The pkgbuffers
+-------------------
+These lines
+
+ (eepitch-slime-set-pkgbuffers)
+ (eepitch-slime-select-pkgbuffer \"MAXIMA\")
+
+let us handle several buffers in `slime-repl-mode'. The first line sets
+the variable `eepitch-slime-pkgbuffers' and shows its value in the echo
+area - it will be something like this:
+
+  ((\"COMMON-LISP-USER\" . \"*slime-repl sbcl*\")
+   (\"MAXIMA\" . \"*slime-repl sbcl<2>*\"))
+
+This variable lets us convert between the name of a Common Lisp package
+and the name of the Slime REPL buffer that was \"in that package\" when
+`eepitch-slime-set-pkgbuffers' was run. If you have everything working,
+you can try this
+
+ (eepitch-slime-select-pkgbuffer \"COMMON-LISP-USER\")
+*package*
+ (eepitch-slime-select-pkgbuffer \"MAXIMA\")
+*package*
+
+to start to understand the precise meaning of being \"in a certain
+package\".
+
+At that point we have three targets, and we can select between them
+with:
+
+ (eepitch-slime-select-pkgbuffer \"COMMON-LISP-USER\")
+ (eepitch-slime-select-pkgbuffer \"MAXIMA\")
+ (eepitch-maxima)
+
+
+
+
+4.7. Attention
+--------------
+My main motivation for writing the tools for creating eepitch blocks
+like this one
+
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
+ (eepitch-b '(slime \"sbcl\"))
+ (eepitch-slime-select)
+   (eepitch-maxima)
+   (eepitch-kill)
+   (eepitch-maxima)
+      load(\"startslime\");
+ (eepitch-b '(slime-connect \"localhost\" 4005))
+ (eepitch-slime-set-pkgbuffers)
+ (eepitch-slime-select-pkgbuffer \"MAXIMA\")
+ (eepitch-maxima)
+
+is that I needed to have a way to restart some eepitch targets without
+paying much attention to the \"restarting\" part; I wanted to be able to
+keep my mind on, say, the Maxima functions that I am trying to
+understand and the tests that I am writing for them - and \"restarting
+Maxima and Slime\" should take very little of my attention.
+
+In the block above I only need to pay attention when I'm on the lines
+with `eepitch-b' and on the load(\"startslime\"); those lines require
+waiting until something is finished, and some of them require an <f9> or
+answering a yes-or-no prompt. The other lines only require <f8>s, and I
+can type those <f8>s at any speed.
+
+Before `eepitch-b' and the other techniques above a badly-behaved
+target, like Sly, would only become \"usable\" to me - in the sense of:
+\"restarting it takes very little attention\" - after hours or days of
+work, and, for some very badly-behaved targets, like, Slime, they would
+be unusable for me for years. With the techniques above they become
+usable, but with eepitch blocks that take _some_ attention - and I can
+start with that, and optimize their eepitch blocks gradually.
 
 
 
diff --git a/eev-load.el b/eev-load.el
index 10eed7fafd..8fa580c8d7 100644
--- a/eev-load.el
+++ b/eev-load.el
@@ -1,7 +1,7 @@
 ;;; eev-load.el -- load all the main modules of eev.  -*- lexical-binding: 
nil; -*-
 ;;; This can also be used as an index to the main source files.
 
-;; Copyright (C) 2019-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GNU eev.
 ;;
@@ -20,7 +20,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20240619
+;; Version:    20251122
 ;; Keywords:   e-scripts
 ;;
 ;; Supersedes: (find-eev "eev-all.el")
@@ -195,14 +195,13 @@
 ;; See: (find-eev-levels-intro)
 ' (require 'eev-aliases)        ; (find-eev "eev-aliases.el")
 
-;; This is experimental and very incomplete.
+;; These things are experimental and very incomplete.
 ;; See: (find-lean4-intro)
 ' (require 'eev-lean4)          ; (find-eev "eev-lean4.el")
 
-
 ;; Make `M-x eev-beginner' work in the "expert setups" too.
 ;; See: (find-efunctiondescr 'autoload "If FUNCTION is already defined")
-(autoload 'eev-beginner "eev-beginner" 
+(autoload 'eev-beginner "eev-beginner"
   "Load all basic modules of eev, turn eev-mode on, and open a tutorial."
   'interactive)                 ; (find-eev "eev-beginner.el")
 
diff --git a/eev-testblocks.el b/eev-testblocks.el
index 347b0961c9..0110d11c23 100644
--- a/eev-testblocks.el
+++ b/eev-testblocks.el
@@ -19,7 +19,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20250913
+;; Version:    20251123
 ;; Keywords:   e-scripts
 ;;
 ;; Latest version: <http://anggtwu.net/eev-current/eev-testblocks.el>
@@ -40,40 +40,43 @@
 ;;   http://anggtwu.net/emacsconf2021.html
 ;;   http://anggtwu.net/LATEX/2021emacsconf.pdf
 
-;; «.eeit»                     (to "eeit")
-;; «.ee-insert-test»           (to "ee-insert-test")
-;; «.ee-insert-test-block»     (to "ee-insert-test-block")
-;; «.examples»                 (to "examples")
-;;   «.c-mode»                 (to "c-mode")
-;;   «.elixir-mode»            (to "elixir-mode")
-;;   «.fennel-mode»            (to "fennel-mode")
-;;   «.f90-mode»               (to "f90-mode")
-;;   «.gnuplot-mode»           (to "gnuplot-mode")
-;;   «.haskell-mode»           (to "haskell-mode")
-;;   «.js-mode»                        (to "js-mode")
-;;   «.julia-mode»             (to "julia-mode")
-;;   «.latex-mode»             (to "latex-mode")
-;;   «.lisp»                   (to "lisp")
-;;   «.lisp-mode»              (to "lisp-mode")
-;;     «.slime»                        (to "slime")
-;;   «.lua-mode»               (to "lua-mode")
-;;   «.makefile-gmake»         (to "makefile-gmake")
-;;   «.makefile-mode»          (to "makefile-mode")
-;;   «.maxima-mode»            (to "maxima-mode")
-;;   «.octave-mode»            (to "octave-mode")
-;;   «.org-mode»               (to "org-mode")
-;;   «.php-mode»               (to "php-mode")
-;;   «.python-mode»            (to "python-mode")
-;;   «.racket-mode»            (to "racket-mode")
-;;   «.raku-mode»              (to "raku-mode")
-;;   «.ruby-mode»              (to "ruby-mode")
-;;   «.scheme-mode»            (to "scheme-mode")
-;;   «.sml-mode»               (to "sml-mode")
-;;   «.sh-mode»                        (to "sh-mode")
-;;   «.sql-mode»               (to "sql-mode")
-;;   «.subed-vtt-mode»         (to "subed-vtt-mode")
-;;   «.tcl-mode»               (to "tcl-mode")
-;;   «.tuareg-mode»            (to "tuareg-mode")
+;; «.eeit»                             (to "eeit")
+;; «.ee-insert-test»                   (to "ee-insert-test")
+;; «.ee-insert-test-block»             (to "ee-insert-test-block")
+;; «.examples»                         (to "examples")
+;;   «.c-mode»                         (to "c-mode")
+;;   «.elixir-mode»                    (to "elixir-mode")
+;;   «.fennel-mode»                    (to "fennel-mode")
+;;   «.f90-mode»                       (to "f90-mode")
+;;   «.gnuplot-mode»                   (to "gnuplot-mode")
+;;   «.haskell-mode»                   (to "haskell-mode")
+;;   «.js-mode»                                (to "js-mode")
+;;   «.julia-mode»                     (to "julia-mode")
+;;   «.latex-mode»                     (to "latex-mode")
+;;   «.lisp-mode»                      (to "lisp-mode")
+;;     «.lisp-mode-slime»              (to "lisp-mode-slime")
+;;     «.lisp-mode-sly»                        (to "lisp-mode-sly")
+;;     «.lisp-mode-maxima»             (to "lisp-mode-maxima")
+;;     «.lisp-mode-maxima-sly»         (to "lisp-mode-maxima-sly")
+;;     «.lisp-mode-maxima-slime»       (to "lisp-mode-maxima-slime")
+;;   «.lua-mode»                       (to "lua-mode")
+;;   «.makefile-gmake»                 (to "makefile-gmake")
+;;   «.makefile-mode»                  (to "makefile-mode")
+;;   «.maxima-mode»                    (to "maxima-mode")
+;;   «.octave-mode»                    (to "octave-mode")
+;;   «.org-mode»                       (to "org-mode")
+;;   «.php-mode»                       (to "php-mode")
+;;   «.python-mode»                    (to "python-mode")
+;;   «.racket-mode»                    (to "racket-mode")
+;;   «.raku-mode»                      (to "raku-mode")
+;;   «.ruby-mode»                      (to "ruby-mode")
+;;   «.scheme-mode»                    (to "scheme-mode")
+;;   «.sml-mode»                       (to "sml-mode")
+;;   «.sh-mode»                                (to "sh-mode")
+;;   «.sql-mode»                       (to "sql-mode")
+;;   «.subed-vtt-mode»                 (to "subed-vtt-mode")
+;;   «.tcl-mode»                       (to "tcl-mode")
+;;   «.tuareg-mode»                    (to "tuareg-mode")
 
 
 
@@ -263,11 +266,22 @@ include(\"%s\")
 ))))
 
 
+
+
+
 ;; «lisp-mode»  (to ".lisp-mode")
 (defun ee-insert-test-lisp-mode ()
-  (funcall (ee-intern "ee-insert-test-lisp-mode-%s" current-prefix-arg)))
+  "Insert a test block for Lisp. Use a numeric prefix to select a variant.
+With just `M-x eeit' run `ee-insert-test-lisp-mode-nil', that calls SBCL.
+With an invalid prefix, like `M-9 M-x eeit', display a help message."
+  (let ((f (ee-intern "ee-insert-test-lisp-mode-%s" current-prefix-arg)))
+    (if (fboundp f)
+       (funcall f)
+      (error "Valid prefixes: 1.slime, 2.sly, 3.maxima, 4.maxima+slime, 
5.maxima+sly"))))
+
 
 (defun ee-insert-test-lisp-mode-nil ()
+  "Use `M-x eeit' on a Lisp mode buffer to run this."
   (interactive)
   (insert (ee-adjust-red-stars (format "
 #|
@@ -280,16 +294,16 @@ include(\"%s\")
 " (buffer-name)))))
 
 
-;; «slime»  (to ".slime")
-;; See: (find-eev "eepitch.el" "eepitch-slime")
+;; «lisp-mode-slime»  (to ".lisp-mode-slime")
+;; See: (find-eev "eepitch.el" "eepitch-b-slime")
 (defun ee-insert-test-lisp-mode-1 ()
+  "Use `M-1 M-x eeit' on a Lisp mode buffer to run this."
   (interactive)
   (insert (ee-adjust-red-stars (format "
 #|
+ (eepitch-slime-kill 'show-only)
  (eepitch-slime-kill)
- To restart Slime:
-    (eepitch-set-source-and-M-x-b 2)
-    (slime \"sbcl\")
+ (eepitch-b '(slime \"sbcl\"))
  (eepitch-slime-select)
 (load \"%s\")
 
@@ -297,8 +311,107 @@ include(\"%s\")
 " (buffer-name)))))
 
 
+;; «lisp-mode-sly»  (to ".lisp-mode-sly")
+;; See: (find-eev "eepitch.el" "eepitch-b-sly")
+(defun ee-insert-test-lisp-mode-2 ()
+  "Use `M-2 M-x eeit' on a Lisp mode buffer to run this."
+  (interactive)
+  (insert (ee-adjust-red-stars (format "
+#|
+ (eepitch-sly-kill 'show-only)
+ (eepitch-sly-kill)
+ (eepitch-sly)
+(load \"%s\")
+
+|#
+" (buffer-name)))))
+
+
+;; «lisp-mode-maxima»  (to ".lisp-mode-maxima")
+(defun ee-insert-test-lisp-mode-3 ()
+  "Use `M-3 M-x eeit' on a Lisp mode buffer to run this."
+  (interactive)
+  (insert (ee-adjust-red-stars (format "
+#|
+ (eepitch-maxima)
+ (eepitch-kill)
+ (eepitch-maxima)
+load(\"%s\");
+to_lisp();
+  (load \"%s\")
+  (to-maxima)
+
+|#
+" (buffer-name) (buffer-name)))))
+
+
+;; «lisp-mode-maxima-slime»  (to ".lisp-mode-maxima-slime")
+;; See: (find-eev "eepitch.el" "eepitch-b-slime")
+;;      (find-angg ".maxima/startslime.lisp")
+(defun ee-insert-test-lisp-mode-4 ()
+  "Use `M-4 M-x eeit' on a Lisp mode buffer to run this."
+  (interactive)
+  (insert (ee-adjust-red-stars (format "
+#|
+ (eepitch-slime-kill 'show-only)
+ (eepitch-slime-kill)
+ (eepitch-b '(slime \"sbcl\"))
+ (eepitch-slime-select)
+   (eepitch-maxima)
+   (eepitch-kill)
+   (eepitch-maxima)
+      load(\"startslime\");
+ (eepitch-b '(slime-connect \"localhost\" 4005))
+ (eepitch-slime-set-pkgbuffers)
+ (eepitch-slime-select-pkgbuffer \"COMMON-LISP-USER\")
+ (eepitch-slime-select-pkgbuffer \"MAXIMA\")
+(load \"%s\")
+ (eepitch-maxima)
+load(\"%s\");
+
+|#
+" (buffer-name) (buffer-name)))))
+
+
+;; «lisp-mode-maxima-sly»  (to ".lisp-mode-maxima-sly")
+;; See: (find-eev "eepitch.el" "eepitch-b-sly")
+;;      (find-angg ".maxima/startsly.lisp")
+(defun ee-insert-test-lisp-mode-5 ()
+  "Use `M-5 M-x eeit' on a Lisp mode buffer to run this."
+  (interactive)
+  (insert (ee-adjust-red-stars (format "
+#|
+ (eepitch-sly-kill 'show-only)
+ (eepitch-sly-kill)
+ (eepitch-sly)
+   (eepitch-maxima)
+   (eepitch-kill)
+   (eepitch-maxima)
+      load(\"startsly\");
+ (eepitch-b '(sly-connect \"localhost\" 56789))
+ (eepitch-sly-set-pkgbuffers)
+ (eepitch-sly-select-pkgbuffer \"common-lisp-user\")
+ (eepitch-sly-select-pkgbuffer \"maxima\")
+(load \"%s\")
+ (eepitch-maxima)
+load(\"%s\");
+
+|#
+" (buffer-name) (buffer-name)))))
+
+
+
+
+
+
+
+
+
+
+
 ;; «lua-mode»  (to ".lua-mode")
 (defun ee-insert-test-lua-mode ()
+  "Insert a test block for Lua. With a numeric prefix N, use N `='s."
   (interactive)
   (let ((equals (make-string (or current-prefix-arg 0) ?=)))
     (insert (ee-adjust-red-stars (format "
diff --git a/eev-tlinks.el b/eev-tlinks.el
index 320cfe8350..142f7e9595 100644
--- a/eev-tlinks.el
+++ b/eev-tlinks.el
@@ -19,7 +19,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20250425
+;; Version:    20251022
 ;; Keywords:   e-scripts
 ;;
 ;; Latest version: <http://anggtwu.net/eev-current/eev-tlinks.el>
@@ -3000,6 +3000,7 @@ wget -nc -O {yyyy}-{mm}-{dd}-emacs-news.org \\
 ;; (find-eepitch-intro \"3. Test blocks\")
 ;; (find-eepitch-intro \"3.1. `find-eeit-links'\")
 ;; (find-eev \"eev-testblocks.el\" \"examples\")
+;; (find-eev \"eev-testblocks.el\" \"{majormodestr}\")
 
 ;; Current definition:
 ;; (find-efunction              '{eeitfun})
@@ -3969,6 +3970,7 @@ is nil, use the result of (ee-1stclassvideos)."
        (find-dot-emacs-links "eev angges")
        (find-dot-emacs-links "eev angges melpa edrxmaxima mfms")
        (find-dot-emacs-links "eev angges melpa lean4 edrxmaxima mfms")
+       (find-dot-emacs-links "eev angges melpa epl eepitchb")
        ;; Convention: the first sexp always regenerates the buffer.
        (find-efunction 'find-dot-emacs-links)
        ";;"
@@ -4056,6 +4058,12 @@ is nil, use the result of (ee-1stclassvideos)."
   (replace-regexp-in-string eepitch-preprocess-regexp \"\" line))
 ")
 
+;; Test: (find-estring-elisp (ee-dot-emacs-eepitchb))
+(defun ee-dot-emacs-eepitchb (&rest rest) "\
+;; See: (find-eepitch-intro \"4.3. Configuring `eepitch-b'\")
+(define-key eev-mode-map (kbd \"<f9>\") 'eepitch-b-set-target-and-show)
+")
+
 ;; Test: (find-estring-elisp (ee-dot-emacs-lean4))
 (defun ee-dot-emacs-lean4 (&rest rest) "\
 ;; See: (find-lean4-intro)
@@ -4379,6 +4387,9 @@ import {pkg_}
 dist = importlib.metadata.distribution('{distr}')
 dist = importlib.metadata.distribution('{pkg}')
 pprint.pprint(dist.files)
+dist.files[1]
+dist.files[1].locate()
+
 md = dist.metadata
 print('\\n'.join(md.keys()))
 md['Name']
diff --git a/eev.el b/eev.el
index 9d76d1b912..01d3169e82 100644
--- a/eev.el
+++ b/eev.el
@@ -6,7 +6,7 @@
 ;; Package-Requires: ((emacs "25.1"))
 ;; Keywords: lisp e-scripts
 ;; URL: http://anggtwu.net/#eev
-;; Version: 20250914
+;; Version: 20251123
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by


Reply via email to