3

I have "elpy / jedi" installed on Emacs. And using the customization provided by DJJ I can now use C-c C-RET to send an individual line to python interpreter. Below is the customization

(defun my-python-line ()
 (interactive)
  (save-excursion
  (setq the_script_buffer (format (buffer-name)))
  (end-of-line)
  (kill-region (point) (progn (back-to-indentation) (point)))
  ;(setq the_py_buffer (format "*Python[%s]*" (buffer-file-name)))
  (setq the_py_buffer "*Python*")
  (switch-to-buffer-other-window  the_py_buffer)
  (goto-char (buffer-end 1))
  (yank)
  (comint-send-input)
  (switch-to-buffer-other-window the_script_buffer)
  (yank)
  )
  (next-line)
)

(eval-after-load "elpy"
 '(define-key elpy-mode-map (kbd "C-c <C-return>") 'my-python-line))

The snippet above is mostly same as suggested by DDJ with some minor modification like moving the cursor to the next line and the shortcut.

I would like to modify the behavior such that all lines from where the cursor is till a new line is encountered to be sent to the python interpreter. And the cursors position should move to the empty newline. This would mimic the behavior of Spyder.

update 1 So after updating my .emacs with the following code. I can get the desired result when I execute the individual statements like M-x beginning-of-line, M-x push-mark...

But when I use the keyboard shortcut C-c <C-return> somehow it evaluates the entire buffer.

(defun forward-block (&optional φn)
  (interactive "p")
  (let ((φn (if (null φn) 1 φn)))
    (search-forward-regexp "\n[\t\n ]*\n+" nil "NOERROR" φn)))

(defun elpy-shell-send-current-block ()
  "Send current block to Python shell."
  (interactive)
  (beginning-of-line)
  (push-mark)
  (forward-block)
  (elpy-shell-send-region-or-buffer)
  (display-buffer (process-buffer (elpy-shell-get-or-create-process))
                  nil
                  'visible))


(eval-after-load "elpy"
 '(define-key elpy-mode-map (kbd "C-c <C-return>") 'elpy-shell-send-current-block))

Python code that I am trying this shortcut is below with the cursor at the second print statement.

import os

print("Line 1: Should Execute")
print("Line 2: Should Execute")

print("Line 3: Should Not Execute")
Community
  • 1
  • 1
datafig
  • 305
  • 1
  • 8

1 Answers1

0

You can write a function to select whatever region you want and call elpy-shell-send-region-or-buffer to send it.

Here is a piece of code that does it.

(defun forward-block (&optional n)
  (interactive "p")
  (let ((n (if (null n) 1 n)))
    (search-forward-regexp "\n[\t\n ]*\n+" nil "NOERROR" n)))

(defun elpy-shell-send-current-block ()
  "Send current block to Python shell."
  (interactive)
  (beginning-of-line)
  (push-mark)
  (forward-block)
  (elpy-shell-send-region-or-buffer)
  (display-buffer (process-buffer (elpy-shell-get-or-create-process))
                  nil
                  'visible))
Chillar Anand
  • 27,936
  • 9
  • 119
  • 136
  • 1
    Thanks @ChillarAnand. Maybe I am missing something, but this snippet has the same behavior as the one I shared. The behavior I am looking for is that if I have 3 lines of Python Code with a blank space between line 2 and 3 and the cursor is on line 1. Then pressing C-c C-RET should execute the first 2 lines. – datafig Aug 13 '15 at 05:44