0

TL;DR

When trying to paste text copied/killed in Emacs to another program while Emacs is waiting for a synchronous subprocess to finish, the target program hangs until Emacs becomes responsive again.

Reproducing the issue

This happens to me especially when running M-x shell-command git commit.

  1. Kill/copy some text to be used in the commit message inside Emacs.
  2. Run M-x shell-command git commit --all
  3. Try to paste the text.

If the editor registered with git has means for cancelling the paste (e.g. C-g when using emacs -Q as editor), this state can be recovered from, but generally the editor effectively crashes.

Is it possible to fix this behavior? The current behavior looks like Emacs is not actually putting the text into the clipboard, but rather a reference to internal state.

This behavior occurs on both Linux and Windows.

Workarounds

  1. Paste the text to a separate program, and cut it there, before running M-x shell command. This places the text in a buffer, that is separate from Emacs, which I want Emacs to do in the first place.

  2. Run the command asynchronously, e.g. M-x shell-command git commit --all &.

1 Answer 1

2

There are several ways of copying text between programs on Linux. I'm just guessing that you're using Linux, but I don't think that this problem could occur on Windows or OSX. I also surmise that you're running Emacs as an X Windows application, not inside a terminal, else you wouldn't have this problem.

The first is by selecting text in program A and pasting it into program B. This is called the "primary selection", but the "secondary selection" is used so rarely that the name is becoming obsolete. When you select text, program A sends a message saying that the user has selected some text in one of its windows. All other programs hear this message and cancel any selections you might have made in their windows. When you paste, the current program sends a message to the program where the selection is asking it to send the text over to be pasted. By convention, you paste from the primary selection by clicking the middle mouse button.

The second is called the clipboard. When you copy some text in program A, it sends the text to the clipboard manager right away. Later, when you paste from the clipboard into program B, program B asks the clipboard manager for the text to be inserted. By convention, you paste from the clipboard with a keyboard shortcut or by selecting the action from a menu.

There's also a third method called cut buffers, but it's obsolete and you're probably not using it.

I surmise that you have selected some text in Emacs, and want to paste it into the editor launched by git commit. That editor could be any program, but might be another instance of Emacs. Then you're running M-x shell-command git commit, which synchronously executes git commit. Then you try to paste into the new editor, but it fails. This is to be expected, because you selected text in Emacs, but then made Emacs synchronously execute some program. No program can respond to messages while taking any synchronous action, so of course the other editor might hang while waiting for the reply.

There are two ways to fix this. You already know that running git commit asynchronously will fix it. You can also fix it by explicitly copying the text after selecting it. In the default configuration, Emacs sends whatever you copy to the clipboard as well as to the kill ring whenever you copy or kill text, so just hit M-w (kill-ring-save) before running git. Then, in the other editor, paste from the clipboard rather than the primary selection. Chapter 12.3 "Cut and Paste" Operationson Graphical Displays covers all the details if you want even more information.

5
  • AFAIK (and I may not know far enough), your paragraph about the clipboard is not quite right: there is a CLIPBOARD selection in X (in addition to primary and secondary selections) which acts as the destination of the usual Copy/Cut menu items of various applications but it behaves the same way as any other selection. What you are describing with the "clipboard manage" is what happens when somebody is running xclipboard - which is not always the case.
    – NickD
    Commented Aug 12, 2020 at 13:41
  • I just tested at home (Windows 10), and using kill-ring-save makes no difference. The options described in Chapter 12.3 are already enabled in the way that uses the clipboard. Regardless, running M-x shell-command notepad and pasting there causes Notepad to crash. Under windows, running xclipboard is no option either -- but the behavior is all the more unexpected, since in Windows having a program-independent clipboard buffer is the default behavior (viewable with clipbrd.exe).
    – kdb
    Commented Aug 13, 2020 at 7:10
  • Or maybe I am misunderstanding; Having clipbrd.exe open in the background prevents the synchronous subprocess from hanging on paste, so it probably kind of behaves like a graphical xclipboard. But when closing Emacs, the clipboard contents are retained which, as I understand, shouldn't be the case by default on Linux.
    – kdb
    Commented Aug 13, 2020 at 7:11
  • With the information gained from db48x's replay and NickD's comment, it looks like the solution on Linux is to ensure that xclipboard is running, but it isn't clear how to change the behavior on Windows without having the extraneous clipbrd.exe window open at all times. Probably the best solution will be to overwrite the M-! keybinding with something that behaves like shell-command from a user-perspective but keeps Emacs responsive. (It is a bit funny, that only Emacs brings up this issue; I know no other GUI program, where synchronous subprocess calls are common.)
    – kdb
    Commented Aug 13, 2020 at 7:21
  • ... though I lack a way to achieve the last idea, since async-shell-command with a process-live-p/sleep-for loop still blocks pasting :/
    – kdb
    Commented Aug 13, 2020 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.