Copy/Paste in emacs ansi-term shell - shell

I have configured my emacs to run zsh shell within ansi-term. However, copy/paste no longer works i.e. nothing is getting pasted from kill-ring to the terminal.
Changing the TERM to vt100, or eterm doesn't solve the problem.
Would appreciate any ideas or solution.
To provide context I have configured ansi-term as follows:
(global-set-key "\C-x\C-a" '(lambda ()(interactive)(ansi-term "/bin/zsh")))
(global-set-key "\C-x\ a" '(lambda ()(interactive)(ansi-term "/bin/zsh")))

You may want to simply switch between character mode and line mode while using the terminal. C-c C-j will run term-line-mode, which treats the terminal buffer more like a normal text-buffer in which you can move the cursor and yank text. You can switch back to character mode by running term-char-mode with C-c C-k.

As described in this lovely blog snippet, there's a function, term-paste, in term.el, that does exactly what you want. By default it's bound only to S-insert but the blog's recommended C-c C-y seems like a good suggestion.

ansi-term, in char-mode, takes the ordinary bindings for the terminal emulation. You need a new binding, plus a way to output to ansi-term correctly. I use this:
(defun ash-term-hooks ()
;; dabbrev-expand in term
(define-key term-raw-escape-map "/"
(lambda ()
(interactive)
(let ((beg (point)))
(dabbrev-expand nil)
(kill-region beg (point)))
(term-send-raw-string (substring-no-properties (current-kill 0)))))
;; yank in term (bound to C-c C-y)
(define-key term-raw-escape-map "\C-y"
(lambda ()
(interactive)
(term-send-raw-string (current-kill 0)))))
(add-hook 'term-mode-hook 'ash-term-hooks)
When you do this, C-c C-y will yank. It only does one yank, though, and you can't cycle through your kill-buffer. It's possible to do this, but I haven't implemented it yet.

The above solutions work well for copying text from some buffer to ansi-term, but they aren't able to copy text from ansi-term to another buffer (eg copy a command you just ran to a shell script you're editing). Adding this to my .emacs file solved that problem for me (in Emacs 24.4):
(defun my-term-mode-hook ()
(define-key term-raw-map (kbd "C-y") 'term-paste)
(define-key term-raw-map (kbd "C-k")
(lambda ()
(interactive)
(term-send-raw-string "\C-k")
(kill-line))))
(add-hook 'term-mode-hook 'my-term-mode-hook)
Note that if you want to bind kill/yank to a keystroke that starts with the ansi-term escape characters (by default C-c and C-x), and want this to work in the unlikely event that those change, you can instead define your keystrokes (without the leading escape) to term-raw-escape-map, as is done in user347585's answer.

These other solutions don't work well for me, switching between character mode and line mode causes ansi-term to stop working properly randomly, and setting ansi-term's term-paste to C-c C-y (based on Glyph's link), didn't work the code snippet was for term, not ansi-term:
(eval-after-load "ansi-term"
'(define-key ansi-term-raw-map (kbd "C-c C-y") 'term-paste))

I enabled xterm-mouse-mode, after that I was able to select text using mouse and copy using standard Mac command C button in ansi-term in emacs GUI in Mac OS X,

Related

How do you terminate a process inside a shell in emacs?

I work a lot in a shell inside emacs (on a Mac). It used to be that, when I typed control-Q control-C, that would kill a process running in the shell. About a year ago, though, that stopped working for some reason; now it has no effect. Anyone know why, or another way of doing this?
I had the same problem using term-mode.
I bound term-interrupt-subjob to my keybinding of choice with:
(add-hook 'term-mode-hook (lambda ()
(define-key term-raw-map (kbd "C-'") 'term-interrupt-subjob)
I am not sure which mode you are using to interact with a shell from Emacs (the inferior shell, Emacs shell, or the terminal emulator). So you might have to modify this a little by replacing term-interrupt-subjob by, for instance, comint-interrupt-subjob and changing the mode hook.
To answer your questions in the comments:
You add the function in your .emacs file. For it to take effect, you need to evaluate it: you can select it and run M-x eval-region or you can restart Emacs.
If you are running M-x shell, you are using shell-mode.
Note that to know which major mode you are using, you can run describe-mode.
Since you are using shell-mode, you want to use add-hook 'shell-mode-hook instead of add-hook 'term-mode-hook and shell-mode-map instead of term-raw-map.
However, in shell-mode, C-c C-c does by default run the command comint-interrupt-subjob. So this should work out of the box as Rorschach said. I am not sure why it isn't working for you.
You can try:
(add-hook 'shell-mode-hook (lambda ()
(define-key shell-mode-map (kbd "C-c C-c") 'comint-interrupt-subjob)
to see if that helps. But this should already be set since it is the default, so it is really unclear whether it will solve your problem.

Emacs on mac: bind command-v to C-u M-! pbpaste

On Mac OS X, I want cmd-v to execute C-u M-! pbpaste.
I want to do this because it makes pasting a very large amount of text faster.
How can I define that binding in my .emacs file?
if you really, really want to do it simply add this to your .emacs
(defun my-pbpaste ()
(interactive)
(shell-command "pbpaste" t)
)
(global-set-key '[M-v] 'my-pbpaste)

Why don't Shift+arrow bindings work in clojure-mode in emacs terminal?

If I runs emacs in a terminal (i.e start emacs in iTerm2 with emacs -nw)
using windmove and it's default bindings, I should be able to navigate between windows using various combinations of Shift + → ← ↑ ↓, Also paredit has bindings that involve Ctrl/Meta + → ← ↑ ↓, these all work fine in (say) an elisp mode buffer.
Looks like the arrow keys functionality relies on emacs decoding terminal escape sequences, via (I think) the input-decode-map
However, if I set the major mode as clojure-mode then the decoding of the escape sequences appears to be disabled (or overwritten). When I execute those bindings I just get the escape sequence instead.
What's going on with the bindings in clojure-mode ?
Versions:
emacs 24.3.1 (have tried maxosxforemacs.com version and homebrew)
clojure-mode 20131117.2306 (have tried other versions)
OSX 10.8.5
iTerm2 1.0.0.20131124
(disclaimer: I raised this as an issue on clojure-mode, but no solution is forthcoming)
UPDATE 2013/12/10: To be absolutely clear: this problem is specific to clojure-mode. emacs -nw in iTerm + arrow keys works fine in other major modes. I'm sure I'm doing something silly that is causing this, I'd like to know what.
Almost identical setup here, but no similar problem. Here's what I would do anyway. First, evaluate the following emacs-lisp code in the scratch buffer.
(progn
(define-key input-decode-map "\e[1;2D" [S-left])
(define-key input-decode-map (kbd "M-[ 1 ; 2 C") [S-right])
(define-key input-decode-map (kbd "M-[ 1 ; 2 B")[S-down])
(define-key input-decode-map "\e[1;2A" [S-up])
(define-key input-decode-map "\e[1;6A" [S-C-up])
(define-key input-decode-map "\e[1;6B" [S-C-down]))
Try the windmove bindings when clojure-mode is activated. If this fixes your problem, and assuming your TERM environment variable is set to xterm-256color, put the following in your init.el
(if (equal "xterm-256color" (tty-type))
(progn
(define-key input-decode-map "\e[1;2D" [S-left])
(define-key input-decode-map (kbd "M-[ 1 ; 2 C") [S-right])
(define-key input-decode-map (kbd "M-[ 1 ; 2 B")[S-down])
(define-key input-decode-map "\e[1;2A" [S-up])
(define-key input-decode-map "\e[1;6A" [S-C-up])
(define-key input-decode-map "\e[1;6B" [S-C-down])))
Hope this helps.
Check your settings in Iterm, more specifically the "Global shortcut keys". Those will take precedence over what is sent to emacs. C-Shift-Arrow is used to switch tabs in Iterm I believe and may be interfering with emacs.

Is it possible to send an 'cd' command to xterm from emacs?

In Emacs, I don't like shell-mode/eshell-mode since they cannot take full use of zsh and they suck much.
So I hope to use xterm as the external subprocess.
(global-set-key (kbd "M-<f2>")
(lambda () (interactive)
(start-process "XTerm" nil "xterm")))
And now the PWD of xterm is synced with Emacs default-directory and the term is now a full-feathered one. But there is ONE problem: I the startup time of the sub-rountine is always disappointing.
So I hope starting xterm only once and when in Emacs, if it finds there is a subprocess called XTerm running, 1) switch to it 2)set the PWD of shell running in xterm to default-directory of Emacs.
Is it possible to do so?
If neither is possible, then with tmux, can we achieve this goal?
Here's my setup:
(defvar terminal-process)
(defun terminal ()
"Switch to terminal. Launch if nonexistant."
(interactive)
(if (get-buffer "*terminal*")
(switch-to-buffer "*terminal*")
(term "/bin/bash"))
(setq terminal-process (get-buffer-process "*terminal*")))
(global-set-key "\C-t" 'terminal)
Could you elaborate more on the start-up time? Mine is around 0.3s.
UPD A small snippet from my dired customization
I've got this in my dired setup:
(add-hook
'dired-mode-hook
(lambda()
(define-key dired-mode-map (kbd "`")
(lambda()(interactive)
(let ((current-dir (dired-current-directory)))
(term-send-string
(terminal)
(format "cd %s\n" current-dir)))))))
where terminal is:
(defun terminal ()
"Switch to terminal. Launch if nonexistant."
(interactive)
(if (get-buffer "*terminal*")
(switch-to-buffer "*terminal*")
(term "/bin/bash"))
(setq terminal-process (get-buffer-process "*terminal*")))
What this does is it opens a terminal for the same directory as dired buffer,
reusing the existing *terminal*, or creating a new one if it's absent.
To summarize the answer to your question:
Yes, it's possible. It's done with:
(term-send-string
(terminal)
(format "cd %s\n" default-directory))
If xterm is not a hard requirement, only that you somehow launch zsh from emacs, then take a look at AnsiTerm, or my preference, MultiTerm. They implement a terminal emulator (like xterm) in emacs, so you can run whatever terminal application (e.g. zsh) in a buffer. I like MultiTerm because it has better defaults IMO.
Then you can change directories with
(defun term-send-cd (&optional dir)
(interactive "DDirectory: ")
(let ((dir (if dir (expand-file-name dir) "")))
(term-send-raw-string (format "cd '%s'\n" dir))))

Emacs M-x shell and the overriding of bash keyboard bindings

If I understand correctly, when running bash under M-x shell, Emacs overrides some of the bash keyboard bindings, and can make some bash commands and features not work as in "native bash" (for an example see this thread)
One of the commands that I use frequently in bash is clear-screen (bounded to Ctrl-l by default ).
Is there an easy way of asking Emacs to reproduce the same behavior in shell-mode so that I can clear my bash screen within Emacs?
I know I can always use M-x term to get a real terminal, but I would like to work out a solution for M-x shell
EDIT: When I type C-l C-l, Emacs moves the current line to the top of the window, but as soon as I enter a new command in bash, the window is scrolled again to the original position.
Thanks
Just type M-> to go to the bottom of the buffer (if necessary), then C-l C-l to move the current line to the top of the window. It looks as if you've cleared your screen, but all of the content that would have been erased is still present above the top of the window.
EDIT:
To keep Emacs from scrolling the window as you described, put this in your .emacs file:
(remove-hook 'comint-output-filter-functions
'comint-postoutput-scroll-to-bottom)
I found that behavior irritating as well.
You could re-bind C-l in shell mode to make it function in the manner you want:
(define-key shell-mode-map (kbd "C-l")
(lambda ()
(interactive)
(previous-line)
(end-of-line)
(let ((start (point))
(end (goto-char (point-min))))
(delete-region start end)
(kill-line)
(end-of-buffer))))

Resources