Copy/Paste in emacs ansi-term shell
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.