]> git.eshelyaron.com Git - emacs.git/commitdiff
New function 'python-shell-send-block' for python-mode
authorLin Sun <sunlin7@hotmail.com>
Sat, 27 Apr 2024 06:54:27 +0000 (06:54 +0000)
committerEshel Yaron <me@eshelyaron.com>
Mon, 6 May 2024 16:33:53 +0000 (18:33 +0200)
* lisp/progmodes/python.el (python-shell-send-block): New
function.
* test/lisp/progmodes/python-tests.el
(python-test--shell-send-block): Test case for the new
function.
* etc/NEWS: Document 'python-shell-send-block'.
(Bug#70609)

(cherry picked from commit b2e92c746eb7d1135d3d4ccecc774d79555ffb99)

etc/NEWS
lisp/progmodes/python.el
test/lisp/progmodes/python-tests.el

index de5a35975f4b568b1616eb6a9b287e1def51baff..7c8a613722d3d6a80b1b3057a151e0b2d72d13f4 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1445,6 +1445,10 @@ instead of:
 This allows the user to specify command line arguments to the non
 interactive Python interpreter specified by 'python-interpreter'.
 
+*** New function 'python-shell-send-block'.
+It sends the python block delimited by 'python-nav-beginning-of-block'
+and 'python-nav-end-of-block' to the inferior Python process.
+
 ** Scheme mode
 Scheme mode now handles regular expression literal '#/regexp/' that is
 available in some Scheme implementations.
index ecbec18f518edfa3d9f8d4f6837b9ca616f4204d..57cdf68fc25dc33456de5f82b9b304c685ce7370 100644 (file)
@@ -350,6 +350,7 @@ To customize the Python interpreter for interactive use, modify
     (define-key map "\C-c\C-e" #'python-shell-send-statement)
     (define-key map "\C-c\C-r" #'python-shell-send-region)
     (define-key map "\C-\M-x"  #'python-shell-send-defun)
+    (define-key map "\C-c\C-b" #'python-shell-send-block)
     (define-key map "\C-c\C-c" #'python-shell-send-buffer)
     (define-key map "\C-c\C-l" #'python-shell-send-file)
     (define-key map "\C-c\C-z" #'python-shell-switch-to-shell)
@@ -390,6 +391,8 @@ To customize the Python interpreter for interactive use, modify
          :help "Switch to running inferior Python process"]
         ["Eval string" python-shell-send-string
          :help "Eval string in inferior Python session"]
+        ["Eval block" python-shell-send-block
+         :help "Eval block in inferior Python session"]
         ["Eval buffer" python-shell-send-buffer
          :help "Eval buffer in inferior Python session"]
         ["Eval statement" python-shell-send-statement
@@ -4141,6 +4144,27 @@ interactively."
      (save-excursion (python-nav-end-of-statement))
      send-main msg t)))
 
+(defun python-shell-send-block (&optional arg msg)
+  "Send the block at point to inferior Python process.
+The block is delimited by `python-nav-beginning-of-block' and
+`python-nav-end-of-block'.  When optional argument ARG is non-nil, send
+the block body without its header.  When optional argument MSG is
+non-nil, forces display of a user-friendly message if there's no process
+running; defaults to t when called interactively."
+  (interactive (list current-prefix-arg t))
+  (let ((beg (save-excursion
+               (when (python-nav-beginning-of-block)
+                 (if (null arg)
+                     (beginning-of-line)
+                   (python-nav-end-of-statement)
+                   (beginning-of-line 2)))
+               (point-marker)))
+        (end (save-excursion (python-nav-end-of-block)))
+        (python-indent-guess-indent-offset-verbose nil))
+    (if (and beg end)
+        (python-shell-send-region beg end nil msg t)
+      (user-error "Can't get code block from current position."))))
+
 (defun python-shell-send-buffer (&optional send-main msg)
   "Send the entire buffer to inferior Python process.
 When optional argument SEND-MAIN is non-nil, allow execution of
@@ -7181,6 +7205,7 @@ implementations: `python-mode' and `python-ts-mode'."
                python-nav-if-name-main
                python-nav-up-list
                python-remove-import
+               python-shell-send-block
                python-shell-send-buffer
                python-shell-send-defun
                python-shell-send-statement
index e3b1642a9755df77b5617c82df8e8c4bca2db8c9..889038d0f8c3c9c536bd58b3ebab3cf72c1a9fc3 100644 (file)
@@ -7466,6 +7466,33 @@ buffer with overlapping strings."
                          "Unused import a.b.c (unused-import)"
                        "W0611: Unused import a.b.c (unused-import)"))))))
 
+(ert-deftest python-test--shell-send-block ()
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (python-tests-with-temp-buffer-with-shell
+    "print('current 0')
+for x in range(1,3):
+    print('current %s' % x)
+print('current 3')"
+    (goto-line 1)
+    (should-error (python-shell-send-block) :type 'user-error)
+    (goto-line 2)
+    (python-shell-send-block)
+    (python-tests-shell-wait-for-prompt)
+    (python-shell-with-shell-buffer
+      (goto-char (point-min))
+      (should-not (re-search-forward "current 0" nil t))
+      (should (re-search-forward "current 1" nil t))
+      (should (re-search-forward "current 2" nil t))
+      (should-not (re-search-forward "current 3" nil t)))
+    (goto-line 3)
+    (python-shell-send-block t) ;; send block body only
+    (python-tests-shell-wait-for-prompt)
+    (python-shell-with-shell-buffer
+      ;; should only 1 line output from the block body
+      (should (re-search-forward "current"))
+      (should (looking-at " 2"))
+      (should-not (re-search-forward "current" nil t)))))
+
 ;;; python-ts-mode font-lock tests
 
 (defmacro python-ts-tests-with-temp-buffer (contents &rest body)