7

I wrote a very simple function to properly restart ipython console with elpy when evaluating the buffer or region:

(defun my-restart-python-console ()
  "Restart python console before evaluate buffer or region to avoid various uncanny conflicts, like not reloding modules even when they are changed"
  (interactive)
  (kill-process "Python")
  (kill-buffer "*Python*")
  (elpy-shell-send-region-or-buffer))

Itt works but always ask confirmation, because "*Python*" has a running process, however I kill the process before killing the buffer.

The fun part: If I evaluate the function body line by line it works...

Drew
  • 75,699
  • 9
  • 109
  • 225
atevm
  • 928
  • 7
  • 16
  • 1
    Well, this function is very useful. When I edit two or more python buffers then I need restart the python interpreter. Do you want to open an issue on elpy's repository? Sorry for write here, I can't write comments yet. I set my key binding (global-set-key (kbd "C-c C-x C-c") 'my-restart-python-console) – cactus Jul 09 '16 at 05:10
  • @cactus good idea I will even write a commit, alter I make the code a bit elegant. Namely it should wait until the process is properly killed. Now I have some very intensive work but it will be on my TODO list. Thanks – atevm Jul 09 '16 at 14:48

4 Answers4

5

Well I figured it out: kill-process kills the process as a side effect, so it returns before that is really killed. So a function like this works:

(defun my-restart-python-console ()
  "Restart python console before evaluate buffer or region to avoid various uncanny conflicts, like not reloding modules even when they are changed"
  (interactive)
  (kill-process "Python")
  (sleep-for 0.05)
  (kill-buffer "*Python*")
  (elpy-shell-send-region-or-buffer))
atevm
  • 928
  • 7
  • 16
4

If you're using ipython, why not just use the baked-in %reset magic command? You can also use:

%load_ext autoreload
%autoreload

To automatically reload imported modules on change.

Gastove
  • 1,511
  • 9
  • 15
0

Add the following to your Emacs configuration file:

(defun my-restart-python-console ()
  "Restart python console before evaluate buffer or region to avoid various uncanny conflicts, like not reloding modules even when they are changed"
  (interactive)
  (if (get-buffer "*Python*")
      (let ((kill-buffer-query-functions nil)) (kill-buffer "*Python*")))
  (elpy-shell-send-region-or-buffer))

(global-set-key (kbd "C-c C-x C-c") 'my-restart-python-console)

restart your Emacs run your code using C-c C-x C-c

In short, this code has the "if clause" for checking if Python buffer is open. This will help to be able to run C-c C-x C-c at any time of development even when there is no Python process already open. Another part is kill-buffer-query-functions which neglects the prompt for killing the Python buffer. In the original answer sleep-for is used which is not always functioning as expected and the provided code is more robust in some senses.

Mahyar
  • 1
  • 1
  • Welcome to emacs.SE and thanx for your answer! It would be even more usefull if you add a short explanation of what the code is doing, especially how it differs from the code in the question. – JeanPierre Aug 28 '19 at 19:15
  • Thanks and you're absolutely welcome, I hope it helps. I have added a brief explanation. – Mahyar Aug 29 '19 at 12:37
  • If you let bind `kill-buffer-query-functions` like `(let ((kill-buffer-query-functions nil)) (kill-buffer "*Python*"))` you avoid the side effect of changing the value for any code running afterwards. – clemera Aug 29 '19 at 12:47
  • @clemera Thanks! I have updated the function as you suggested. – Mahyar Aug 29 '19 at 13:05
0

From kill-buffer function documentation:

The functions in kill-buffer-query-functions are called with the buffer to be killed as the current buffer. If any of them returns nil, the buffer is not killed.

From kill-buffer-query-functions documentation:

kill-buffer-query-functions is a variable defined in C source code. Its value is (process-kill-buffer-query-function)

And process-kill-buffer-query-function:

Ask before killing a buffer that has a running process.

So to kill buffer that has a running process you can disable kill buffer query functions like this:

(let ((kill-buffer-query-functions nil))
  (kill-buffer "*Python*"))
muffinmad
  • 2,250
  • 7
  • 11