branch: externals/termint
commit 2d99e98d00ccb32da43b2800c5b7c5873a5b28d0
Author: Milan Glacier <[email protected]>
Commit: Milan Glacier <[email protected]>

    refactor(termint): generalize region dispatch and keymap generation
    
    Introduce `termint-region-dispatchers` to define customizable region
    types and their dispatcher functions, replacing the hardcoded
    paragraph, buffer, and defun handlers.  Add
    `termint-mode-map-additional-keys` to control REPL keymap bindings
    dynamically.
    
    This makes region handling and keymap generation extensible for new
    REPL schemas or custom region types.
---
 termint.el | 137 +++++++++++++++++++++++++++++--------------------------------
 1 file changed, 66 insertions(+), 71 deletions(-)

diff --git a/termint.el b/termint.el
index 2c37246cb6..b0c50166eb 100644
--- a/termint.el
+++ b/termint.el
@@ -326,6 +326,34 @@ line of that matches SOURCE-COMMAND."
       (message "No defun found at point")
       nil)))
 
+(defvar termint-region-dispatchers
+  '(("paragraph" . termint--dispatch-paragraph)
+    ("buffer" . termint--dispatch-buffer)
+    ("defun" . termint--dispatch-defun))
+  "Alist mapping dispatchable region types to dispatcher functions.
+Each element is of the form (NAME . DISPATCHER).  The NAME is appended
+to generated command names (e.g., `termint-ipython-send-NAME' and
+`termint-ipython-source-NAME' for an ipython schema), while DISPATCHER
+should be a function returning a cons cell (BEG . END) for the
+corresponding region.  Customize this before calling `termint-define'
+to generate additional region commands automatically for each REPL
+schema.")
+
+(defvar termint-mode-map-additional-keys
+  '(("f" . "send-defun")
+    ("F" . "source-defun")
+    ("b" . "send-buffer")
+    ("B" . "source-buffer")
+    ("p" . "send-paragraph")
+    ("P" . "source-paragraph"))
+  "Alist of keys and command suffixes to add to generated REPL keymaps.
+Each element is a cons cell of the form (KEY . SUFFIX).  KEY is the
+string sequence to bind.  SUFFIX is a string appended to
+`termint-REPL-NAME-' to resolve the actual command symbol (e.g.,
+\"send-defun\" becomes `termint-ipython-send-defun' when defining an
+ipython REPL).  This variable should be modified before calling
+`termint-define' to affect the generated keymaps.")
+
 (defun termint--dispatch-region-and-send
     (dispatcher repl-name session source-syntax)
   "Get region via DISPATCHER, optionally transform for sourcing, and send.
@@ -480,15 +508,16 @@ enabled.  The default value is nil."
         (start-pattern-name (intern (concat "termint-" repl-name 
"-start-pattern")))
         (end-pattern-name (intern (concat "termint-" repl-name 
"-end-pattern")))
         (send-delayed-final-ret-name (intern (concat "termint-" repl-name 
"-send-delayed-final-ret")))
-        ;; send paragraph and source paragraph
-        (send-paragraph-func-name (intern (concat "termint-" repl-name 
"-send-paragraph")))
-        (source-paragraph-func-name (intern (concat "termint-" repl-name 
"-source-paragraph")))
-        ;; send buffer and source buffer
-        (send-buffer-func-name (intern (concat "termint-" repl-name 
"-send-buffer")))
-        (source-buffer-func-name (intern (concat "termint-" repl-name 
"-source-buffer")))
-        ;; send defun and source defun
-        (send-defun-func-name (intern (concat "termint-" repl-name 
"-send-defun")))
-        (source-defun-func-name (intern (concat "termint-" repl-name 
"-source-defun"))))
+        (region-definitions
+         (cl-loop for entry in termint-region-dispatchers
+                  for region-name = (car entry)
+                  for dispatcher = (cdr entry)
+                  for send-func-name = (intern (format "termint-%s-send-%s" 
repl-name region-name))
+                  for source-func-name = (intern (format 
"termint-%s-source-%s" repl-name region-name))
+                  collect (list :name region-name
+                                :dispatcher dispatcher
+                                :send send-func-name
+                                :source source-func-name))))
 
     `(progn
 
@@ -565,62 +594,27 @@ process with that number."
                                ,str-process-func-name
                                ,send-delayed-final-ret-name))
 
-       (defun ,send-paragraph-func-name (&optional session)
-         ,(format
-           "Send the current paragraph to %s.
-With numeric prefix SESSION, send paragraph to the process associated
-with that number." repl-name)
-         (interactive "P")
-         (termint--dispatch-region-and-send
-          #'termint--dispatch-paragraph ,repl-name session nil))
-
-       (defun ,source-paragraph-func-name (&optional session)
-         ,(format
-           "Source the current paragraph to %s.
-With numeric prefix SESSION, send paragraph to the process associated
-with that number." repl-name)
-         (interactive "P")
-         (termint--dispatch-region-and-send
-          #'termint--dispatch-paragraph ,repl-name
-          session ,source-syntax-name))
-
-       (defun ,send-buffer-func-name (&optional session)
-         ,(format
-           "Send the current buffer to %s.
-With numeric prefix SESSION, send buffer to the process associated
-with that number." repl-name)
-         (interactive "P")
-         (termint--dispatch-region-and-send
-          #'termint--dispatch-buffer ,repl-name session nil))
-
-       (defun ,source-buffer-func-name (&optional session)
-         ,(format
-           "Source the current buffer to %s.
-With numeric prefix SESSION, send buffer to the process associated
-with that number." repl-name)
-         (interactive "P")
-         (termint--dispatch-region-and-send
-          #'termint--dispatch-buffer ,repl-name
-          session ,source-syntax-name))
-
-       (defun ,send-defun-func-name (&optional session)
-         ,(format
-           "Send the current defun to %s.
-With numeric prefix SESSION, send defun to the process associated
-with that number." repl-name)
-         (interactive "P")
-         (termint--dispatch-region-and-send
-          #'termint--dispatch-defun ,repl-name session nil))
-
-       (defun ,source-defun-func-name (&optional session)
-         ,(format
-           "Source the current defun to %s.
-With numeric prefix SESSION, send defun to the process associated
-with that number." repl-name)
-         (interactive "P")
-         (termint--dispatch-region-and-send
-          #'termint--dispatch-defun ,repl-name
-          session ,source-syntax-name))
+       ,@(cl-loop for entry in region-definitions append
+                  (list
+                   `(defun ,(plist-get entry :send) (&optional session)
+                      ,(format
+                        "Send the current %s to %s.
+With numeric prefix SESSION, send %s to the process associated
+with that number."
+                        (plist-get entry :name) repl-name (plist-get entry 
:name))
+                      (interactive "P")
+                      (termint--dispatch-region-and-send
+                       #',(plist-get entry :dispatcher) ,repl-name session 
nil))
+                   `(defun ,(plist-get entry :source) (&optional session)
+                      ,(format
+                        "Source the current %s to %s.
+With numeric prefix SESSION, send %s to the process associated
+with that number."
+                        (plist-get entry :name) repl-name (plist-get entry 
:name))
+                      (interactive "P")
+                      (termint--dispatch-region-and-send
+                       #',(plist-get entry :dispatcher) ,repl-name
+                       session ,source-syntax-name))))
 
        (when (require 'evil nil t)
          (evil-define-operator ,send-region-operator-name (beg end session)
@@ -655,12 +649,13 @@ suffix." repl-name)
            (define-key map "r" #',send-region-func-name)
            (define-key map "R" #',source-region-func-name)
            (define-key map "e" #',send-string-func-name)
-           (define-key map "p" #',send-paragraph-func-name)
-           (define-key map "f" #',send-defun-func-name)
-           (define-key map "P" #',source-paragraph-func-name)
-           (define-key map "b" #',send-buffer-func-name)
-           (define-key map "B" #',source-buffer-func-name)
-           (define-key map "F" #',source-defun-func-name)
+           (dolist (binding termint-mode-map-additional-keys)
+             (let ((key (car binding))
+                   (suffix (cdr binding)))
+               (when-let* ((command (intern-soft (format "termint-%s-%s"
+                                                         ,repl-name suffix)))
+                           ((fboundp command)))
+                 (define-key map key command))))
            (define-key map "h" #',hide-window-func-name)
            (when (require 'evil nil t)
              (define-key map "r" #',send-region-operator-name)

Reply via email to