From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Ian Kelling Newsgroups: gmane.emacs.help Subject: Re: Useful elisp I wrote, send-region-to-shell-mode Date: Sat, 15 Mar 2014 00:54:35 -0700 Message-ID: <5324073B.1070209@iankelling.org> References: <5322751C.3020108@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="----enig2GREOWOQMWMIHUQGNLSGS" X-Trace: ger.gmane.org 1394891441 10496 80.91.229.3 (15 Mar 2014 13:50:41 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 15 Mar 2014 13:50:41 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Mar 15 14:50:50 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WOozC-0005fI-G1 for geh-help-gnu-emacs@m.gmane.org; Sat, 15 Mar 2014 14:50:50 +0100 Original-Received: from localhost ([::1]:50141 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WOozC-0000Uz-6R for geh-help-gnu-emacs@m.gmane.org; Sat, 15 Mar 2014 09:50:50 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36351) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WOjR4-0000Oa-7t for help-gnu-emacs@gnu.org; Sat, 15 Mar 2014 03:55:20 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WOjQy-0002Ww-0u for help-gnu-emacs@gnu.org; Sat, 15 Mar 2014 03:55:14 -0400 Original-Received: from out1-smtp.messagingengine.com ([66.111.4.25]:47440) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WOjQx-0002Wf-TF for help-gnu-emacs@gnu.org; Sat, 15 Mar 2014 03:55:07 -0400 Original-Received: from compute4.internal (compute4.nyi.mail.srv.osa [10.202.2.44]) by gateway1.nyi.mail.srv.osa (Postfix) with ESMTP id 1E8E6205B6 for ; Sat, 15 Mar 2014 03:55:07 -0400 (EDT) Original-Received: from frontend1 ([10.202.2.160]) by compute4.internal (MEProxy); Sat, 15 Mar 2014 03:55:07 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=message-id:date:from:mime-version:to :subject:references:in-reply-to:content-type; s=smtpout; bh=jerR dVW2/Viw+ER3fEyMliNlU2A=; b=uP9Oeb+n9ioynrwoaity0TIIV5u/kZZG2Dom hlvq1NqCOXKkt5fk9hbCulyGXw6wVfSOsjjXE02DhmSb7tnofJO3dm/72r2vrK+X IdWYUlAStKv32oKmWR1nhp0PE4q4g0M+ON+sdM9a/yb/K2Dr1bqAuaaAKIQbPvMg 4qpAnbI= X-Sasl-enc: DEvI52MLoUH7g2QNRZtHS9/ZQufSJsOjSFFHOu53/BN7 1394870106 Original-Received: from [192.168.1.2] (unknown [67.160.118.141]) by mail.messagingengine.com (Postfix) with ESMTPA id A43A6C00003 for ; Sat, 15 Mar 2014 03:55:06 -0400 (EDT) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131103 Icedove/17.0.10 In-Reply-To: <5322751C.3020108@gmail.com> X-Enigmail-Version: 1.5.1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.111.4.25 X-Mailman-Approved-At: Sat, 15 Mar 2014 09:50:32 -0400 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:96518 Archived-At: This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ------enig2GREOWOQMWMIHUQGNLSGS Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On 03/14/2014 03:59 AM, Alan Schmitt wrote:> Hello Ian, > > Ian Kelling writes: > >> I just switched over to shell-mode and definitely recommend it over >> a normal terminal in general. > > I'm curious about this. I tried several times to use a shell in emacs > instead of a terminal, and I have always gone back. The main two reason= s > I could not keep using them are some incompatibilities with some shells= > (I use fish, for instance, which can only run in ansi-term, and even > there it's not perfect), and window management (having a quick access > to a shell window). You get emacs window management, it is what it is. I'm happy with it. I c= an put shell-mode's in their own frames. > This is very nice, thanks for sharing. I often use org-mode when > developing scripts, but this could be a useful alternative. I'm using org-babel in conjunction with this :) Related: I'm going to sen= d a patch to org-mode which sends std-err to babel results. > Do you have tips for using a shell in emacs? In > particular, what shell do you run? I use bash, which luckily is very compatible. You lose the bash keybinds = and replace them with emacs ones, which are generally the same or better. The only notable thing you lose is compatibility with interactive shell p= rograms that do anything more interactive than prompting for input. If you use th= ose enough, shell-mode is a no go. term/ansi-term mode is one avenue to try, = but I wouldn't bother. Tips, yes. A bit of reading in ctrl-h m in shell-mode covers almost every= thing. I use the bash-completion elisp package via melpa. It enables the smart c= ommand argument completions of http://bash-completion.alioth.debian.org/, which = come standard in most gnu/linux distros. ;; don't store successive duplicates in comint command history (setq comint-input-ignoredups t) I also bound 'comint-previous-input / 'comint-next-input to the up/down k= eys I'm used to in a shell. After sending off my first email, I realized some more functionality I wa= nted in my function; Send the current line if region isn't active. Also, when in = shell mode, send lines BACK to the previous window. The new version: ;; example keybind (global-set-key (kbd "") 'send-shell) ;; optional variables used by send-shell (setq shell-unset-prompt "unset PROMPT_COMMAND; unset PS1") (setq shell-set-prompt "PROMPT_COMMAND=3Dprompt_command") (setq shell-send-yank-key (kbd "C-v")) (defun send-shell () "Send current line or region (if active) to shell-mode buffer. When in shell-mode, copy the current line, paste it in the most recently visited visible window. Optional variables: `shell-unset-prompt/shell-set-prompt': shell commands invisibly sent to temporarily hide shell prompts for multi-line input. `send-shell-buffer-name': Use this instead of default *shell* `shell-send-yank-key' key to use instead of yank to paste into recent window. This allows compatibility with modes like org-mode which have their own yank function. Creates & shows shell-mode buffer in a new window if needed." (interactive) (if (string-equal mode-name "Shell") (progn (call-interactively 'copy-line) (select-window (previous-window nil nil 'visible)) (if (and (boundp 'shell-send-yank-key) shell-send-yank-key) (call-interactively (global-key-binding shell-send-yank-key))= (yank)) (select-window (next-window nil nil 'visible))) (let (start end) (if mark-active (setq start (mark) end (point)) (setq start (save-excursion (beginning-of-line) (point)) end (save-excursion (end-of-line) (point))) (next-line)) (send-comint-input (or (and (boundp 'send-shell-buffer-name) send-shell-buffer-name) = "*shell*") start end 'shell)))) ;; supporting functions (defun copy-line (arg) "Copy lines (as many as prefix argument) in the kill ring. Pretend the last line of the buffer has a trailing newline to avoid insan= ity." (interactive "p") (kill-ring-save (line-beginning-position) (line-end-position arg)) (kill-append "\n" nil) (if (and arg (not (=3D 1 arg))) (message "%d lines copied" arg))) (defun send-comint-input (buffer-name start end &optional init) "Input the region to BUFFER-NAME, assuming it is a comint-derived buffe= r. 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 (filter-buffer-substring start end)) (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 (and (boundp 'send-shell-buffer-name) send-shell-buffer-name)) (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 (boundp 'shell-unset-prompt) (send-invisible-string proc shell-unset-prompt)) (goto-char (process-mark proc)) (insert input) (comint-send-input) (if (boundp 'shell-set-prompt) (send-invisible-string proc shell-set-prompt)))))) (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 buf= fer, 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)))) ------enig2GREOWOQMWMIHUQGNLSGS Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Icedove - http://www.enigmail.net/ iQIcBAEBCgAGBQJTJAc7AAoJEKrMwkDpacZ78V4P/iLz9ZvJaot/bfjMiDsvdwsu 47U0RidBz7mf9Id1YtkRm/XHgm+vKlZ6kuNfNduWEOi9+jdMd+2V9nroGRUhRatd JrN7uwSMJMkaXVekaWaUuwarkgHk8gzEiOm7TmmtsMJoAp3CNp1lMkLnnbaBZqUl eJmNY+pprGpsAxOn53VfIQDhVS6D02X2K7CeIMiXbexG0Xm/aPJJN8NutGtxuWmU cehvIUZ33FNwanjgUtRFn0jPE1NxijycPxTpSSCh4Qed+YwWDCrST4QN3X0ls/pD r3j0+AQP4Pjg/uaH8ean6k76Fo/RGTkxZgdNNBe3Br/0nNgcJp4XJFS8KR4UJiCr V9W65JRgcjoe0wXu8iZXh4iv6UFGRiajcWe2Gm6CrCbx1mVAYIiN9QOQvPhRaSKV 3V8zP3ZkPLsaLHh75ZaSJePFKsP3sB+jo0zjsANb0MLWBHj8Dr6eyHIHqKIZtbNj 2G6mhx/w2EcJMEnKhJ+1vmXaGD3OKTSXTeR1hc5VdcYmxnIvODrkddVdCKqkQKgs l5bZhLG4Q1NpiUm7/BZ9/2XFG1L6o0QAyNTv3cBcLEe4pgRrhYgC45YcYcdaTXXq r1VtGvcbhsovRSqjXdLVe8Xq68bqHZloplTtqIpwrYnxs+UVIcxWUzL60XgTrqV6 0Z4qmFQ65lMk1PoLQPki =/Iqy -----END PGP SIGNATURE----- ------enig2GREOWOQMWMIHUQGNLSGS--