Reputation: 57973
Is there some module or command that'll let me send the current region to shell?
I want to have something like Python-mode's python-send-region
which sends the selected region to the currently running Python shell.
Upvotes: 52
Views: 13082
Reputation:
Update
The above (brilliant and useful) answers look a bit incomplete as of mid-2020: sh-mode
has a function for sending shell region to non-interactive shell with output in the minibuffer called sh-send-line-or-region-and-step
.
Alternatively: click Shell-script
in the mode bar at the bottom of the window, then Mouse-1
, then Execute region
. The output is sent to the minibuffer and #<*Messages*>
.
If minibuffer output is not enough, there are referenced techniques to redirect output to other buffers (not only the shell one, see for example "How to redirect message/echo output to a buffer in Emacs?").
You can also execute all the script with C-c C-x
. Voilà.
Upvotes: 2
Reputation: 512
I adapted the accepted answer for ansi-term / sane-term.
Changes:
(defun ansi-term-send-line-or-region (&optional step)
(interactive ())
(let ((proc (get-process "*ansi-term*"))
pbuf
min
max
command)
(unless proc
(let ((currbuff (current-buffer)))
(sane-term)
(switch-to-buffer currbuff)
(setq proc (get-process "*ansi-term*"))))
(setq pbuff (process-buffer proc))
(if (use-region-p)
(setq min (region-beginning)
max (region-end))
(setq min (point-at-bol)
max (point-at-eol)))
(setq command (concat (buffer-substring min max) "\n"))
(process-send-string proc command)
(display-buffer (process-buffer proc) t)
(when step
(goto-char max)
(next-line))))
(defun sh-send-line-or-region-and-step ()
(interactive)
(sh-send-line-or-region t))
(defun sh-switch-to-process-buffer ()
(interactive)
(pop-to-buffer (process-buffer (get-process "*ansi-term*")) t))
(define-key sh-mode-map [(control ?j)] 'sh-send-line-or-region-and-step)
(define-key sh-mode-map [(control ?c) (control ?z)] 'sh-switch-to-process-buffer)
Upvotes: 1
Reputation: 2549
Here is another solution from this post.
Just copying it for convenience. The print statement is key here.
(add-hook 'python-mode-hook
'my-python-send-statement)
(defun my-python-send-statement ()
(interactive)
(local-set-key [C-return] 'my-python-send-statement)
(end-of-line)
(set-mark (line-beginning-position))
(call-interactively 'python-shell-send-region)
(python-shell-send-string "; print()"))
Upvotes: 1
Reputation: 11728
Modifying Jurgens answer above to operate on a specific buffer gives the following function, which will send the region and then switch to the buffer, displaying it in another window, the buffer named PYTHON is used for illustration. The target buffer should already be running a shell.
(defun p-send(start end)
(interactive "r") ;;Make the custom function interactive and operative on a region
(append-to-buffer (get-buffer "*PYTHON*") start end) ;;append to the buffer named *PYTHON*
(switch-to-buffer-other-window (get-buffer "*PYTHON*")) ;;switches to the buffer
(execute-kbd-macro "\C-m")) ;;sends the enter keystroke to the shell
Upvotes: 3
Reputation: 121
I wrote a package that sends/pipes lines or regions of code to shell processes, basically something similar that ESS is for R. It also allows for multiple shell processes to exist, and lets you choose which one to send the region to.
Have a look here: http://www.emacswiki.org/emacs/essh
Upvotes: 12
Reputation: 8533
Ok, wrote an easy bit. Will probably spend some time to write a complete minor mode.
For time being the following function will send current line (or region if the mark is active). Does quite a good job for me:
(defun sh-send-line-or-region (&optional step)
(interactive ())
(let ((proc (get-process "shell"))
pbuf min max command)
(unless proc
(let ((currbuff (current-buffer)))
(shell)
(switch-to-buffer currbuff)
(setq proc (get-process "shell"))
))
(setq pbuff (process-buffer proc))
(if (use-region-p)
(setq min (region-beginning)
max (region-end))
(setq min (point-at-bol)
max (point-at-eol)))
(setq command (concat (buffer-substring min max) "\n"))
(with-current-buffer pbuff
(goto-char (process-mark proc))
(insert command)
(move-marker (process-mark proc) (point))
) ;;pop-to-buffer does not work with save-current-buffer -- bug?
(process-send-string proc command)
(display-buffer (process-buffer proc) t)
(when step
(goto-char max)
(next-line))
))
(defun sh-send-line-or-region-and-step ()
(interactive)
(sh-send-line-or-region t))
(defun sh-switch-to-process-buffer ()
(interactive)
(pop-to-buffer (process-buffer (get-process "shell")) t))
(define-key sh-mode-map [(control ?j)] 'sh-send-line-or-region-and-step)
(define-key sh-mode-map [(control ?c) (control ?z)] 'sh-switch-to-process-buffer)
Enjoy.
Upvotes: 55
Reputation: 19757
(defun shell-region (start end)
"execute region in an inferior shell"
(interactive "r")
(shell-command (buffer-substring-no-properties start end)))
Upvotes: 13
Reputation: 73345
Do you want the command to be executed automatically, or just entered into the command line in preparation?
M-x append-to-buffer
RET will enter the selected text into the specified buffer at point, but the command would not be executed by the shell.
A wrapper function for that could automatically choose *shell*
for the buffer (or more smartly select/prompt based on current buffers in shell-mode), and then call append-to-buffer.
You could trivially record a keyboard macro to copy the region, switch to *shell*
, yank, and enter (if required).
F3M-wC-xb*shell*
RETC-yRETF4
C-xC-knmy-execute-region-in-shell
RET
M-xinsert-kbd-macro
RETmy-execute-region-in-shell
RET
(global-set-key (kbd "C-c e") 'my-execute-region-in-shell)
Upvotes: 2