views:

312

answers:

4

Hi! In python-mode, there is a function called py-execute-region which sends a highlighted region of code to the Python buffer for evaluation. After evaluation, the cursor is in the Python buffer, but I would prefer that it remain in the script buffer so I can continue producing more code. I wrote a simple advising function:

(defadvice py-execute-region                                                
   (after py-execute-region-other-window activate)                          
   """ After execution, return cursor to script buffer """                  
   (other-window 1)                                                         
)

But this does not do anything at all. I've tried other variants like using 'around' rather than 'after'; setting a variable to the script buffer name and then pop-to-buffer to that buffer and stuff like that. No success! I wonder if the mechanics of this is obvious to someone... Thanks!

+1  A: 

What you have there works fine for me. And it should auto-activate, so a separate activation should be unnecessary. However, you do need to de-active and re-activate advice for changes to take effect:

1) define and activate advice

2) it doesn't do what you want, so change the advice

3) deactivate it: (ad-deactivate 'py-execute-region)

4) reactivate it: (ad-activate 'py-execute-region)

Step 4 should pick up the changes you made in step 2. Alternately, you can change the code in step 2 and then just re-evaluate the code in step 4 (assuming the activate flag is set).

Joe Casadonte
Thanks!... but still doesn't work for me. If I replace the body of the defadvice with (other-window 1) (insert "x"), it puts "x" in the script buffer but the cursor is still in the Python buffer... very confusing.
Stephen
Is there any other advice activated for the same function?At this point, I would start up a plain vanilla emacs (emacs -q), load python mode, define and activate your advice, and see if it still fails to work. There may be some odd interaction going on.
Joe Casadonte
+1  A: 

Use around-advice to wrap the function in a call to save-window-excursion, which will restore the previous window configuration after the command completes.

(defadvice py-execute-region
   (around preserve-window-configuration activate)
   "After execution, return cursor to script buffer"
   (save-window-excursion ad-do-it))

Keep in mind, though, that if the Python buffer wasn't already shown, it will still be hidden after the command completes. To remedy that, you can add another piece of advice to call switch-to-buffer-other-window at the end:

(defadvice py-execute-region
   (after show-pybuf-other-window activate)
   "After execution, show the python buffer in another window."
   (switch-to-buffer-other-window "[PYTHON BUFFER NAME]"))

Also, make sure you don't use """triple quotes""" in elisp. I don't think they work.

Ryan Thompson
Thanks! But doesn't work either... save-window-excursion sounds like what I want but it doesn't appear to do anything, and the second one flips the position of Python and script buffers (though it does put the cursor in the window where the script buffer originally was). I had originally tried something similar with pop-to-buffer instead of switch-to-buffer-other-window and it put the Python buffer in the script window also!
Stephen
If you run a command inside a save-window-excursion, then after it finishes, your window configuration should be identical to when you ran the command before. Make sure you don't have any other old pieces of advice enabled as well that are interfering.
Ryan Thompson
Thanks - yes, my window configuration is unchanged but the cursor ends up in the Python buffer... I think I get the concept but it's baffling me as to why this or none of the other trials work...
Stephen
From M-x describe-function save-window-excursion:"Also restore the choice of selected window. Also restore which buffer is current."So save-window-excursion *should* be what you want. I tried(save-window-excursion (other-window 1)), and it did what I expected, which is put me right back where I was.
Ryan Thompson
Yes... I've tried all of your suggestions after having loaded fresh emacs instances but they just don't seem to work... I've used the insert function in place of other-window and the text I specify appears in the correct (script) buffer but the cursor always ends up in the python buffer. I also tried wrapping py-execute-region in a function called my-py-execute-region (which I bind to C-c|) that uses save-window-excursion, other-window, and all the other alternatives listed here and still no lock. Thanks for the heads up on the triple quotes also - but nothing seems to work! Perplexed...
Stephen
Please edit your original answer with a horzontal bar and add some of the things you tried. If you post the code, we can help you debug it.
Ryan Thompson
+1  A: 

In this case the solution appears to be

(custom-set-variables
 '(py-shell-switch-buffers-on-execute nil))
Stephen
A: 

I haven't actually tried this out, but I did do something similar for find-file, and over there I needed to call interactive before calling other-window. I actually have no real idea of Emacs Lisp, but this may work.

(defadvice py-execute-region                                                
   (after py-execute-region-other-window activate)                          
   (interactive)
   (other-window 1)                                                         
)
Nikwin