Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running interactive python script from emacs

Tags:

python

emacs

I am a fairly proficient vim user, but friends of mine told me so much good stuff about emacs that I decided to give it a try -- especially after finding about the aptly-named evil mode...

Anyways, I am currently working on a python script that requires user input (a subclass of cmd.Cmd). In vim, if I wanted to try it, I could simply do :!python % and then could interact with my script, until it quits. In emacs, I tried M-! python script.py, which would indeed run the script in a separate buffer, but then RETURNs seems not to be sent back to the script, but are caught by the emacs buffer instead. I also tried to have a look at python-mode's C-c C-c, but this runs the script in some temporary directory, whereas I just want to run it in (pwd).

So, is there any canonical way of doing that?

like image 436
antony Avatar asked Feb 17 '12 08:02

antony


People also ask

How do I run a Python script in Emacs?

Once you open your python file in Emacs, you will need to start the python process with: M-x run-python or C-c C-p , which creates an inferior python shell buffer. This buffer will be created by a horizontal split, and the active buffer will be the one containing the python file.

How do I run code in Emacs?

To execute a file of Emacs Lisp code, use M-x load-file . This command reads a file name using the minibuffer and then executes the contents of that file as Lisp code. It is not necessary to visit the file first; in any case, this command reads the file as found on disk, not text in an Emacs buffer.

What is Emacs ELPY?

Elpy is an Emacs package to bring powerful Python editing to Emacs. It combines and configures a number of other packages, both written in Emacs Lisp as well as Python. Elpy is fully documented at Readthedocs.


3 Answers

I don't know about canonical, but if I needed to interact with a script I'd do M-xshellRET and run the script from there.

There's also M-xterminal-emulator for more serious terminal emulation, not just shell stuff.

like image 92
Teddy Avatar answered Oct 02 '22 18:10

Teddy


I like to use the Emacs "compile" command to test/run my python scripts. M-XcompileRET will pull up the default "make -k" but if you delete that and put in the command line for your script (including options), subsequent "compiles" will provide the new "compile" command automatically. All the output from your script will appear in the compile buffer. (As opposed to the shell, this provides a nice clean buffer each time it is invoked. Good for searching and such. If you forget to save your script before your run, compile will ask you if you would like to save the file.)

You will lose your the command line when you restart Emacs. But you can get Emacs to set the compile-command for the buffer holding your script by putting at the bottom of the python script this sort of code (actually a python comment):

 # Trigger emacs to run this script using the "compile" command
 # ;;; Local Variables: ***
 # ;;; compile-command: "my_cool_script.py --complicated_option some_filename.txt" ***
 # ;;; end: ***

This is handy for scripts with complicated invocations. Note: The python comment character '#' protects this from the python interpreter while Emacs knows to set these variables because it looks at the bottom of every file when it opens them.

I'd love to be able to jump to 'compile errors' in my python script the way the compile command does when you use it for compiling C code but I'm too lazy to create the Emacs regular expression to make this work. Perhaps that would make another great question for stack overflow!

like image 37
user1040087 Avatar answered Oct 02 '22 16:10

user1040087


I currently use these hook to define my compilation commands:

(defun convert-filename-to-executable (file)
  (if (eq system-type 'windows-nt)
      (concat (file-name-sans-extension file) ".exe")
    ;; linux
    (concat "./" (file-name-sans-extension file))))


(add-hook 'c++-mode-hook
          (lambda ()
            (unless (file-exists-p "Makefile")
              (set (make-local-variable 'compile-command)
                   (let* ((file (file-name-nondirectory buffer-    file-name))
                      (executable (convert-filename-to-executable file)))
                 (concat "g++ -g -Wall -o "
                         (file-name-sans-extension file)
                         " "
                         file
                         " && "
                         executable))))))

(add-hook 'c-mode-hook
      (lambda ()
        (unless (file-exists-p "Makefile")
          (set (make-local-variable 'compile-command)
               (let* ((file (file-name-nondirectory buffer-file-name))
                      (executable (convert-filename-to-executable file)))
                 (concat "gcc -g -ansi -Wall -Wpedantic -Wextra -Wc++-compat -Wconversion -o "
                         (file-name-sans-extension file)
                         " "
                         file
                         " && "
                         executable))))))    
(add-hook 'python-mode-hook
          (lambda ()
              (set (make-local-variable 'compile-command)
                   (concat "python " buffer-file-name))))

(add-hook 'perl-mode-hook
          (lambda ()
              (set (make-local-variable 'compile-command)
                   (concat "python " buffer-file-name))))

Together with this lambda set to call the compile function interactively:

(global-set-key (kbd "<f4>") (lambda () (interactive) (setq current-prefix-arg '(4)) (call-interactively 'compile)))

One button to rule them all!

If you press F4 (in my case, you can set the key yourself in the lambda for global-set-key), then a file opened in C++ or C mode will be compiled and a file in python or perl mode will be run (interactively)

like image 38
MartenBE Avatar answered Oct 02 '22 17:10

MartenBE