[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Useful elisp I wrote, send-region-to-shell-mode
From: |
Ian Kelling |
Subject: |
Useful elisp I wrote, send-region-to-shell-mode |
Date: |
Thu, 13 Mar 2014 20:18:52 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131103 Icedove/17.0.10 |
I just switched over to shell-mode and definitely recommend it over a normal
terminal in general. This elisp seems to fill in an obviously missing piece of
integration with emacs. It's currently too hackish to recommend for going into
emacs, but I figured I would share and see if anyone had feedback or found it
useful. I'll post this it on the emacs wiki as well.
(defun send-region-to-shell-mode ()
"Send region as input to shell in a shell-mode buffer.
Temporarily hide shell prompts for multi-line input.
Create & show shell buffer in a new window if needed.
Main use = enhance workflow when editing shell a script.
Minimal setup needed:
1. Adjust the arguments within this function
depending on how you set and unset the prompt in your shell.
2. Make a keybind to this function."
(interactive)
(send-region-comint "*shell*"
"unset PROMPT_COMMAND; unset PS1"
"PROMPT_COMMAND=prompt_command"
'shell))
;; supporting functions
(defun send-region-comint (buffer-name &optional before after init)
"Input the region to BUFFER-NAME, assuming it is a comint-derived buffer.
Show BUFFER-NAME if it is not show.
Call INIT if BUFFER-NAME does not exist.
Invisibly execute BEFORE & AFTER by comint process."
(interactive)
(let ((input (buffer-substring-no-properties (mark) (point)))
(buffer (get-buffer buffer-name)))
(unless buffer
;; save-excursion etc. don't work for (shell), so I do this instead
(if init (let ((original-buffer (current-buffer)))
(funcall init)
(switch-to-buffer original-buffer))
(error "No existing buffer found and no init function argument. ")))
(setq buffer (get-buffer buffer-name))
(buffer-window-show buffer)
(with-current-buffer buffer
(let ((proc (get-buffer-process buffer)))
(if before (send-invisible-string proc before))
(goto-char (process-mark proc))
(insert input)
(comint-send-input)
(if after (send-invisible-string proc after))))))
(defun send-invisible-string (proc string)
"Like send-invisible, but non-interactive"
(comint-snapshot-last-prompt)
(funcall comint-input-sender proc string))
;; modified version of temp-buffer-window-show,
;; only removed a few initial lines which set buffer read only etc.
;; I tried to find an existing function, but no dice
(defun buffer-window-show (&optional buffer action)
"Like temp-buffer-window-show, but without any modifications to the buffer,
like read only etc."
(let (window frame)
(with-current-buffer buffer
(when (let ((window-combination-limit
;; When `window-combination-limit' equals
;; `temp-buffer' or `temp-buffer-resize' and
;; `temp-buffer-resize-mode' is enabled in this
;; buffer bind it to t so resizing steals space
;; preferably from the window that was split.
(if (or (eq window-combination-limit 'temp-buffer)
(and (eq window-combination-limit
'temp-buffer-resize)
temp-buffer-resize-mode))
t
window-combination-limit)))
(setq window (display-buffer buffer action)))
(setq frame (window-frame window))
(unless (eq frame (selected-frame))
(raise-frame frame))
(setq minibuffer-scroll-window window)
(set-window-hscroll window 0)
(with-selected-window window
(run-hooks 'temp-buffer-window-show-hook)
(when temp-buffer-resize-mode
(resize-temp-buffer-window window)))
;; Return the window.
window))))
- Ian Kelling
- Useful elisp I wrote, send-region-to-shell-mode,
Ian Kelling <=