From 554fee51d153866bd8aad350977868d9dd8eef22 Mon Sep 17 00:00:00 2001 From: Lin Sun Date: Sat, 27 Apr 2024 06:54:27 +0000 Subject: [PATCH] New function 'python-shell-send-block' for python-mode * lisp/progmodes/python.el: Add implemention of the function. * test/lisp/progmodes/python-tests.el: Test case for the function. * etc/NEWS: Document for the function. --- etc/NEWS | 4 ++++ lisp/progmodes/python.el | 25 +++++++++++++++++++++++++ test/lisp/progmodes/python-tests.el | 22 ++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index fea27bb8a3..974e0c35dc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1319,6 +1319,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. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 85279d3e84..fd9e7060b8 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -350,6 +350,7 @@ python-mode-map (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 @@ python-mode-map :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 @@ -4136,6 +4139,27 @@ python-shell-send-statement (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 @@ -7177,6 +7201,7 @@ python-ts-mode python-nav-up-list python-remove-import python-shell-send-buffer + python-shell-send-block python-shell-send-defun python-shell-send-statement python-sort-imports)) diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index e11440cdb5..7a4186eef2 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -7465,6 +7465,28 @@ python-tests--flymake-command-output-pattern "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(f'current {x}')" + (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) + ;; send block body only + (goto-line 3) + (python-shell-send-block t) + (python-tests-shell-wait-for-prompt) + (python-shell-with-shell-buffer + (goto-char (point-min)) + (should (python-tests-look-at "current 1")) + (should-not (python-tests-look-at "current 1")) + (should (python-tests-look-at "current 2")) + (should (python-tests-look-at "current 2"))))) + ;;; python-ts-mode font-lock tests (defmacro python-ts-tests-with-temp-buffer (contents &rest body) -- 2.20.5