4

I'm learning how to use Perl in Emacs. I used to run R with R-Studio.

How do I execute a command without leaving Emacs?

Example: In R-studio I type

    print("hello world") 

and press Ctrl+Enter and R-studio executes the command and prints "hello world". How do I do the same in Emacs for a Perl command?

I usually type Ctrl+X Ctrl+F test.pl

    print "hello world";

and then I don't know what to do for Emacs to execute the command.

Michal Klouda
  • 14,263
  • 7
  • 53
  • 77
Federico C
  • 132
  • 2
  • 8

4 Answers4

4

For all kinds of interpreted languages, I use isend-mode, which allows sending parts of a buffer to a terminal in another buffer.

Here is how you would use it (after having installed it):

  1. Open an ansi-term buffer:

    M-xansi-termRET/bin/bashRET

    and run an interactive perl session inside:

    perl -d -e 42RET

    Alternatively, install term-run.el and directly launch the interactive perl session in a term buffer:

    M-xterm-run-shell-commandRETperl -d -e 42RET

  2. Open the buffer with the code you want to execute, and associate it to the interpreter buffer:

    M-xisendRET*ansi-term*RET

  3. Hit C-RET in the perl buffer to send the current line to the interpreter in the ansi-term buffer. If a region is active, all lines spanning the region will be sent.


Below is a proposed setup allowing to better take advantage of the perl debugger specific commands. With the following customization, x is prepended to all instructions (so that you see the results), except print commands.

(defun isend--perl (buf-name)
  "Prepend 'x ' to normal perl instructions.
Leave 'print' instructions untouched."
  (with-current-buffer buf-name
    (goto-char (point-min))
    (unless (looking-at "[[:space:]]*print")
      (insert "x ")))
  (insert-buffer-substring buf-name))

(defun isend-default-perl-setup ()
  (when (eq major-mode 'perl-mode)
    (set (make-local-variable 'isend-send-line-function) #'isend--perl)))

(add-hook 'isend-mode-hook #'isend-default-perl-setup)
François Févotte
  • 19,520
  • 4
  • 51
  • 74
  • I'm working on getting isend-mode, hopefully this will work out. thanks for the help. I'll update when I manage to get the extension. – Federico C Nov 30 '12 at 18:28
  • @Francesco. This is great, but in my experiments the interpreter will not print or run anything until you send EOF to the interpreter (which you have to do from the buffer running the interpreter). Any way `isend-mode` could do this for you somehow? – Amelio Vazquez-Reina Apr 01 '13 at 18:57
  • You can start `perl` in debugging mode to get an interactive perl environment (in which lines are interpreted on the fly). The perldebug(1) man page has all the details, but you can start with `perl -d -e 42` – François Févotte Apr 01 '13 at 19:44
  • @Francesco This solution is not working for me. How do I start perl in debug mode in ansi-term. Also how can I pass the EOF char if perl is not running in debug mode? Thanks! – Kaushal Modi Feb 03 '15 at 14:42
  • @kaushalmodi `ansi-term` only accepts a program name; you can not give arguments. A first solution is to run a regular shell (e.g. `bash`) in your `ansi-term` and from there run `perl -d -e 42`. A second solution consists in creating a custom shell script which runs the perl debugger for you. – François Févotte Feb 03 '15 at 15:40
  • @kaushalmodi as for sending `EOF`, it is currently not a feature of `isend-mode`. But I don't think it would be appropriate here: once you send `EOF` to the perl interpreter, it executes your code and the (not so) interactive session terminates. In this case, I would say you'd be better off with a plain perl scripts in a file. – François Févotte Feb 03 '15 at 15:42
  • @Francesco Thanks for the tip to run `bash` in ansi-term. But I am still missing something. I can't run any perl script right away in the perl debugger that is now running in the bash shell instance in ansi-term. I need a custom elisp to send a line `LINE` in my script.pl as `x LINE` in the ansi-term buffer, correct? And the `print` statements would look better if `print LINE` in my script.pl were sent as `p LINE` in the ansi-term buffer. – Kaushal Modi Feb 03 '15 at 15:56
  • @kaushalmodi `isend` supports transformations of the buffer contents before sending it to the interpreter. But you're right, you'll have to write a bit of elisp to instruct it exactly what you need. The following [gist](https://gist.github.com/ffevotte/20285943998c12aab27b) should give you a rough idea of the way it should be done. – François Févotte Feb 03 '15 at 20:14
  • @Francesco Thank you! I finally now have a workable flow: [my perl setup](https://github.com/kaushalmodi/.emacs.d/blob/8d30dd54a13920aa1a8119be099440b95f8f7cf6/setup-files/setup-perl.el). – Kaushal Modi Feb 03 '15 at 20:51
  • 1
    @kaushalmodi [term-run](https://github.com/10sr/term-run-el) seems to allow running programs with arguments in a `term` buffer. This would help launching perl's interactive debugger. – François Févotte Feb 25 '15 at 02:57
2

This is what I use:

Meta-x shell

perl test.pl

mob
  • 117,087
  • 18
  • 149
  • 283
2

If you can load CPerl mode (Emacs should do that by default if you load a file with the .pl extension), you should also get the Perl menu in your menubar (assuming you're running in a GUI, not a simple terminal).

From the Perl menu, just choose "Run"! The current buffer (Perl script) will be run (you'll be prompted for any arguments first), and the results displayed in a new buffer.

jimtut
  • 2,366
  • 2
  • 16
  • 37
1

If I'm running Perl from within Emacs, it's typically to process a region of text or to insert the results of a command into the buffer.

M-! (that's Meta-Shift-1) will execute a shell command, and display the results in the mini buffer.

Prefixing the command with a prefix argument (M-1) will insert the command's output at point.

For example, stubbing out an (x)HTML file into an empty buffer: M-1 M-! perl -MCGI=:standard -e 'print start_html("Hello World"),end_html'

will produce the following:

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Hello World</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
willwillis
  • 108
  • 3
  • 8