unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Ian Kelling <ianowl@gmail.com>
To: help-gnu-emacs@gnu.org
Subject: Useful elisp I wrote, send-region-to-shell-mode
Date: Thu, 13 Mar 2014 20:18:52 -0700	[thread overview]
Message-ID: <5322751C.3020108@gmail.com> (raw)

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



             reply	other threads:[~2014-03-14  3:18 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-14  3:18 Ian Kelling [this message]
2014-03-14 10:59 ` Useful elisp I wrote, send-region-to-shell-mode Alan Schmitt
2014-03-15  7:54 ` Ian Kelling
2014-03-15  7:58 ` Ian Kelling

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5322751C.3020108@gmail.com \
    --to=ianowl@gmail.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).