"yank" does not paste text when using Emacs over SSH - emacs

When I tried to run Emacs on a remote server through ssh, the C-y (even M-x yank) can't work.
Every time I press C-y, it says "Mark set", but nothing else happens. I'm working under Linux and the remote server is a Mac pro.
Now I can only download the file to my pc. Any ideas on how to better solve this problem?

I suspect your problem is not due to Emacs running remotely, but instead it is due to Emacs running in "text mode" (i.e. running inside a terminal emulator). When running in such a mode, Emacs does not know about any surrounding GUI that might be running, so C-y only yanks text you have previously killed in the same Emacs session via something like C-w or M-w.
You can try to do a "paste" in your terminal emulator (probably Cmd-v), which will send the selected text to the underlying application (in this case, Emacs) as if it had been typed. As long as the text you're pasting is made of "simple enough" characters it might work fine. If it contains any funny control chars, all bets are off (if it contains non-ASCII chars it may also behave in a funny way, depending on whether the whole "terminal-emulator+ssh+Emacs" are configured just right or not).

The text-mode thing wasn't my problem.
I have a macbook where I run emacs. I use tramp-mode to edit files (remotely) on a linux box. There is no remote emacs. It's all local.
I had copy/paste set like this on the mac, so I could "yank" from the system clipboard outside of emacs:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; handle copy/paste intelligently
(defun copy-from-osx ()
"Handle copy/paste intelligently on osx."
(let ((pbpaste (purecopy "/usr/bin/pbpaste")))
(if (and (eq system-type 'darwin)
(file-exists-p pbpaste))
(shell-command-to-string pbpaste))))
(defun paste-to-osx (text &optional push)
"Handle copy/paste intelligently on osx.
TEXT gets put into the Macosx clipboard.
The PUSH argument is ignored."
(let* ((process-connection-type nil)
(proc (start-process "pbcopy" "*Messages*" "pbcopy")))
(process-send-string proc text)
(process-send-eof proc)))
(setq interprogram-cut-function 'paste-to-osx
interprogram-paste-function 'copy-from-osx)
Apparently tramp-mode tries to be smart, and when yanking text, it runs the pbpaste command that I've set up, remotely. Or tries to. Which I don't want. So I modified the copy-from-osx to be like this:
(defun copy-from-osx ()
"Handle copy/paste intelligently on osx."
(let ((pbpaste (purecopy "/usr/bin/pbpaste")))
(if (and (eq system-type 'darwin)
(file-exists-p pbpaste))
(let ((tramp-mode nil)
(default-directory "~"))
(shell-command-to-string pbpaste)))))
Notice it sets tramp-mode to nil, temporarily, before running pbpaste.
Works for me.

Related

emacs terminal mode: how to copy and paste efficiently

I'm having a hard time making this emacs -nw work effectively under the terminal mode (emacs -nw).
Some setup information:
The working server is connected via SSH, and emacs is running on the server. Usually I'm connecting using SSH and "emacs -nw" to work on my files.
The emacs config is picked up from: https://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/
;; make mouse selection to be emacs region marking
(require 'mouse)
(xterm-mouse-mode t)
(defun track-mouse (e))
(setq mouse-sel-mode t)
;; enable clipboard in emacs
(setq x-select-enable-clipboard t)
;; enable copy/paste between emacs and other apps (terminal version of emacs)
(unless window-system
(when (getenv "DISPLAY")
;; Callback for when user cuts
(defun xsel-cut-function (text &optional push)
;; Insert text to temp-buffer, and "send" content to xsel stdin
(with-temp-buffer
(insert text)
;; I prefer using the "clipboard" selection (the one the
;; typically is used by c-c/c-v) before the primary selection
;; (that uses mouse-select/middle-button-click)
(call-process-region (point-min) (point-max) "xsel" nil 0 nil "--clipboard" "--input")))
;; Call back for when user pastes
(defun xsel-paste-function()
;; Find out what is current selection by xsel. If it is different
;; from the top of the kill-ring (car kill-ring), then return
;; it. Else, nil is returned, so whatever is in the top of the
;; kill-ring will be used.
(let ((xsel-output (shell-command-to-string "xsel --clipboard --output")))
(unless (string= (car kill-ring) xsel-output)
xsel-output )))
;; Attach callbacks to hooks
(setq interprogram-cut-function 'xsel-cut-function)
(setq interprogram-paste-function 'xsel-paste-function)
;; Idea from
;; http://shreevatsa.wordpress.com/2006/10/22/emacs-copypaste-and-x/
;; http://www.mail-archive.com/help-gnu-emacs#gnu.org/msg03577.html
))
The reason to have:
(require 'mouse)
(xterm-mouse-mode t)
(defun track-mouse (e))
(setq mouse-sel-mode t)
is to enable mouse selection over text such that the text region is highlighted just as "C-x SPC" marking the region. Then I can use "M-x w" to copy and "C-x y" to paste text within emacs and between emacs and other apps.
All look perfect except that any operations related to X are REALLY SLOW! My connection to the remote server is smooth -- the latency is usually under 100ms. But to kill one line of text using "C-x k", it takes ~5 seconds! To paste it, it takes another 5 seconds!
When copy/paste is frequent sometimes, this becomes really annoying. I think this is related to the X sever messaging, but not sure if there is good way to fix this.
Any ideas?
Thanks!
This is not an ideal solution per se, but i figured out a way that I feel better than the previous one.
The idea is to get rid of X which causes heavy latency issues, i.e. keep only the following:
;; enable clipboard in emacs
(setq x-select-enable-clipboard t)
The results are:
copy/paste within Emacs is straightforward and fast.
copy from other apps to Emacs: Ctrl+Shift+v
copy from Emacs to other apps: mouse selection is now on X Selection, so right-click and copy shall copy the text into the Selection. Note that 'M-w" now won't copy anything into Selection or system clipboard.
This is again a compromise rather than a solution, but considering the fact that i copy/paste more often than inter-app operations, this is acceptable at the moment.
Still looking forward to a good solution!
You can accomplish this by using a terminal escape code!
There is a unique category of terminal escape codes called "Operating System Controls" (OSC) and one of these sequences (\033]52) is meant for interacting with the system clipboard. The great thing is that your terminal doesn't care where the code came from so it will work in remote sessions as well.
Most terminal emulators support it (iTerm2, OS X Terminal, and I think all Linux terminals besides GNOME). You can test if your terminal supports this sequence by simply running:
$ printf "\033]52;c;$(printf "Hello, world" | base64)\a"
Then paste from your system clipboard. If it pastes "Hello, world" then your terminal supports it!
I have this function in my init.el so when I call yank-to-clipboard Emacs will yank the value from my kill ring into the system clipboard:
(defun yank-to-clipboard ()
"Use ANSI OSC 52 escape sequence to attempt clipboard copy"
(interactive)
(send-string-to-terminal
(format "\033]52;c;%s\a"
(base64-encode-string
(encode-coding-string
(substring-no-properties
(nth 0 kill-ring)) 'utf-8) t))))
As I type this, I stumbled upon an almost-identical script supported by Chromium community: https://chromium.googlesource.com/apps/libapps/+/master/hterm/etc/osc52.el
For those running Emacs inside Tmux:
Tmux consumes the sequence, so you'll need to pipe the sequence to the Tmux active tty for this to work. I have a solution in my blog post here: https://justinchips.medium.com/have-vim-emacs-tmux-use-system-clipboard-4c9d901eef40
To extend on #justinokamoto's answer for use in tmux, it works great and is truly amazing. I haven't debugged it with e.g. tramp or other fancy emacs settings but to get it to work
Follow https://sunaku.github.io/tmux-yank-osc52.html great instructions, modifying your tmux.conf and ~/bin/yank
Make sure terminal access to your clipboard is enabled on your terminal
Then to pull into emacs you can use a function like:
(Caveat emptor, I am very new to elisp. This writes to a temporary file in /tmp/yank)
(defun custom-terminal-yank (&rest args)
(message "-> CLIP")
;; FOR EVIL MODE: UNCOMMENT SO FIRST YANKS TO KILL RING
;; need to yank first, with all those args
;; ;; https://emacs.stackexchange.com/questions/19215/how-to-write-a-transparent-pass-through-function-wrapper
;; (interactive (advice-eval-interactive-spec
;; (cadr (interactive-form #'evil-yank))))
;; (apply #'evil-yank args)
;; https://stackoverflow.com/questions/27764059/emacs-terminal-mode-how-to-copy-and-paste-efficiently
;; https://sunaku.github.io/tmux-yank-osc52.html
(f-write-text (nth 0 kill-ring) 'utf-8 "/tmp/yank")
(send-string-to-terminal (shell-command-to-string "~/bin/yank /tmp/yank"))
)
If anyone else uses evil mode as well (just to make things complicated) you can uncomment those lines and use something like
(define-key evil-visual-state-map "Y" 'jonah-terminal-yank)
So that normal "y" is for normal yanking in visual mode, but "Y" is for cross-clipboard yanking

How can I load changes of .el file at startup in Emacs?

I have installed Emacs under Windows 7 and want to use it in my everyday work. Unfortunately Emacs world and other text editors world are completely different and I am getting stuck on every third sequence of keys pressed on keyboard - it's doing something that I don't expect it would do.
I want to make a panic command - when I press ESC ESC ESC it stops doing everything, quitting from minibuffer, stops entering command, unhighlight regexps, etc. It already does what I want, except it killing buffers, the layout of my workspace. So I modified keyboard-escape-quit function in simple.el file (found it by C-h k ESC ESC ESC)
(defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
; Stop highlighting regexp
(unhighlight-regexp)
(cond ((eq last-command 'mode-exited) nil)
((region-active-p)
(deactivate-mark))
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
;((not (one-window-p t))
; (delete-other-windows))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
I have byte-compiled and loaded this file and it works ok. But I can't figure out why it is not loading at startup.
You cannot modify some special built-in libraries, including simple.el. Emacs never actually loads these special libraries from their source or byte code files. Their byte code is directly included in the Emacs executable at build time, by a process called “dumping”. Emacs loads these libraries from its own binary.
Generally, should not modify any built-in libraries anyway. Your risk breakage, and your customizations are lost when you update Emacs.
Instead, do what you are supposed to do: Add custom functions to your init.el.
Hence, instead of modifying the built-in keyboard-escape-quit, create your own function, e.g. my-emergency-quit, in your init.el, and bind it to a global key, e.g. C-c q, with
(global-set-key (kbd "C-c q") #'my-emergency-quit)
Some final words of advice: I do not think that such a panic command does any good. The first rule of Emacs is: Don't panic. If you are stuck, don't try to quit and kill everything. Rather, try to find out why you are stuck, and how to get “un-stuck” by normal means. You'll learn Emacs better this way, imho.

How do I configure Emacs to dedicate the Calculator window?

I'm using emacs 24.3 from emacsformacosx.com on OS X 10.9 (Mavericks). The behavior is the same on emacs 23.4.1 on Debian Wheezy.
I want to automate applying set-window-dedicated-p so switching/opening a buffer won't use certain windows. For example, if I'm in the Calculator and manually use Meta-: and enter (set-window-dedicated-p (get-buffer-window) t) then it works great - my Calculator window doesn't get hijacked by other buffers. I want it to work like that automatically.
I put this in my .emacs file:
(add-hook 'calc-mode-hook
(lambda ()
(message "Dedicating %s" (buffer-name))
(set-window-dedicated-p (get-buffer-window) t)
(message "Dedication %s" (window-dedicated-p (get-buffer-window "*Calculator*")))))
Then I start up emacs, switch to the *Messages* window, and Meta-x calc. The *Messages* buffer shows
Dedicating *Calculator*
Dedication t
so I know my hook was called and what buffer it operated on. But the *Calculator* buffer is not dedicated - it doesn't behave properly and Meta-: (window-dedicated-p) returns nil. The *Messages* buffer is dedicated instead.
Why is the *Calculator* window shown as dedicated in the hook but not afterwards? What am I doing wrong here?
Unfortunately the *Calculator* buffer is not displayed in any window at the point your code runs.
Your 'validation' messages were misleading you. (buffer-name) is certainly the buffer you want, but it's not in any window, and so you're actually passing a nil argument for the window in all situations. i.e. You're setting the current window dedicated, and then confirming that it's dedicated (which it should indeed be).
I think after advice to calc is what you need here. e.g.:
(defadvice calc (after my-dedicated-calc-window)
"Make the *Calculator* window dedicated."
(let ((win (get-buffer-window "*Calculator*")))
(when win
(set-window-dedicated-p win t))))
(ad-activate 'calc)
n.b. I'm not sure exactly how the arguments to calc affect the window display, but I think with the test for the window wrapping the call to set-window-dedicated-p this code is probably fine in all cases.

Prevent Emacs from exiting once the exit procedure has initiated?

Is there a way to prevent Emacs from exiting once I initiate the exit process?
I occasionally fat finger C-xC-s as C-xC-c. It isn't an awful process to get back up and running but I am curious if there is a way I can stop the exit process so that I can continue uninterrupted with all my files open.
Using GNU Emacs 24.3.1. Running on Cygwin under Window 7.
There is a built-in variable you can set to a function like so:
(setq confirm-kill-emacs 'y-or-n-p)
scottfrazer's answer's the more appropriate, to me, than what follows.
Enable Emacs Lock minor mode (emacs-lock-mode) on any of the buffers, to prevent Emacs from exiting in case you accidentally hit C-xC-c.
From the Emacs Wiki page:
Emacs cannot exit until the buffer is killed or unlocked
Add (emacs-lock-mode) to your .emacs/init.el file so that this lock is enabled in every Emacs session. Adding this will lock the *scratch* buffer which will have to be unlocked in case you really want to exit Emacs.
Another way/hack of doing this is to start a process in Emacs e.g. M-xshell or have an unsaved file associated to a buffer, doing this will prompt you for confirmations when Emacs is exiting.
Yes one more, unset C-xC-c using global-unset-key. And then if you want to exit Emacs M-xkill-emacs.
Using confirm-kill-emacs, as #scottfrazer suggested, is one approach.
More generally, you can use kill-emacs-query-functions to do whatever you want in this regard. (There was no real need for them to add confirm-kill-emacs, but they did.)
You probably do not want to use kill-emacs-hook in this regard (that's what kill-emacs-query-functions is for), but be aware of it, in case you come across it using apropos etc.
One advantage of kill-emacs-query-functions over justconfirm-kill-emacs is that you can require a better confirmation: yes instead of just hitting key y. For example:
(add-hook 'kill-emacs-query-functions
(lambda () (y-or-n-p "Do you really want to exit Emacs? "))
'append)
That is what I do. It is too easy to be hitting keys and accidentally hit C-x C-c y, especially since I have similar keys bound (e.g., C-x c, C-x C-x, C-x C-y).
If you're looking for a shorter answer, I've had this line at the bottom of all my .emacs files since the last century:
(shell)
I've added the following to my emacs configuration to prevent accidental closes. I didn't like having to confirm close emacs for something like a one off commit, but I hate losing my emacs session accidentally while deep in a problem.
This adds a global state flag to emacs describing whether or not it's locked. This flag is set either automatically after emacs is open for 5 minutes, or manually using the lock-emacs command. The lock can later be removed manually by using the unlock-emacs command.
If emacs is locked, and you attempt to close it (presumably accidentally), emacs will instead give you a message saying that emacs has been locked, and cannot be closed. If it's unlocked, close behaves exactly as it does by default.
;; don't close emacs on accident
(setq emacs-locked nil)
(setq confirm-kill-emacs
(lambda (&rest args)
(if emacs-locked
(progn
(message "%s" "Emacs is locked, and cannot be closed.")
nil)
t)
))
(defun lock-emacs-silently ()
(progn
(setq emacs-locked t))
)
(defun lock-emacs ()
"Prevent emacs from being closed."
(interactive)
(progn
(lock-emacs-silently)
(message "%s" "Emacs is now locked."))
)
(defun unlock-emacs ()
"Allow emacs to be closed."
(interactive)
(progn
(setq emacs-locked 'nil)
(message "%s" "Emacs can now be closed."))
)
(run-at-time "5 minutes" nil 'lock-emacs-silently)
(Open to suggestions on how to make the confirm-kill-emacs portion nicer, I'm a lisp novice :) ).
After using this for a couple of years, I ended up going to something much simpler:
;; Unbind the normal close
(global-unset-key (kbd "C-x C-c"))
;; Require C-c 3 times before closing
(global-set-key (kbd "C-x C-c C-c C-c") 'save-buffers-kill-terminal)

Getting rid of backslash at the end of wrapped lines (for copy-paste)

Emacs in text-mode puts a \ character (backslash) at the end of a wrapped line.
I would like to not have that displayed, so I can copy-paste from such a window into another one, without getting the \ in the pasted text.
I'm sure there is an easy solution for this, but I couldn't find it (neither online, nor in the emacs manual). The closest seems to be Disable little arrows on far end of line.
Distilled from all the replies and links therein, this is what I ended up using for emacs (22.1.1) included in Mac OS X 10.8.3. It works great. Thanks again for all the help!
;; copy to Mac clipboard (for copying text the wrapped '\' lines
(defun copy-to-mac-clipboard ()
"Copy currently selected region to Mac clipboard (useful for wrapped '\\' lines)"
(interactive)
(if (> (- (region-end) (region-beginning)) 0)
(progn
(shell-command-on-region (region-beginning) (region-end) "pbcopy")
(message "region copied to Mac clipboard (%d chars)" (- (region-end) (region-beginning)))
(if (and transient-mark-mode mark-active)
(deactivate-mark)))
(progn
(message "no region active"))
))
;; put this next to M-w, which is kill-ring-save (copy to emacs clipboard)
(global-set-key "\M-e" 'copy-to-mac-clipboard)
These \ (and $) thingies are placed in what we call "the fringe". And sadly, Emacs does not currently let you control the fringe when running in text mode. I think the answer pointed out by Angus is "the best we have" so far.
OTOH, for your specific problem, other than running Emacs in GUI mode, you might be able to let Emacs communicate directly with your desktop's clipboard (rather than let the terminal emulator), which then solves this problem as well as letting you copy text even if it's not displayed.
There is the xclip.el package for that under X11, and someone has posted a patch (not yet integrated) to make it work under Mac OS X as well.