visual selection and X primary behavior
Hello all, In regular Emacs (with Evil mode turned on, of course), I can (1) do visual selection of a region, and it will automatically copy that selection into the X primary selection buffer. This way, I can simply do SHIFT+INSERT in another X program (e.g., Firefox) and I will paste the selection that way. Conversely, I can (2) SHIFT+INSERT into Emacs/Evil (in Insert mode), and it will paste whatever is in the X primary buffer. However, behavior (1) does not work in terminal-mode Emacs (`emacs -nw`), although behavior (2) works as expected. I have tried to work around this by using my `"+y` macro which is enabled with (define-key evil-normal-state-map ",y" "\"+y") in my .emacs, but it fails with the message After 0 kbd macro iterations: X selection unavailable for this frame . Is this a bug in Evil or is it something in Emacs itself? -L
Did you mean this (without the comma)? (define-key evil-normal-state-map "y" "\"+y") Also, do you get the same error when you manually type the "+y (not using the macro)? What key sequence causes the failure? On 7/26/14, Linus Arver <[email protected]> wrote:
Hello all,
In regular Emacs (with Evil mode turned on, of course), I can (1) do visual selection of a region, and it will automatically copy that selection into the X primary selection buffer. This way, I can simply do SHIFT+INSERT in another X program (e.g., Firefox) and I will paste the selection that way. Conversely, I can (2) SHIFT+INSERT into Emacs/Evil (in Insert mode), and it will paste whatever is in the X primary buffer.
However, behavior (1) does not work in terminal-mode Emacs (`emacs -nw`), although behavior (2) works as expected. I have tried to work around this by using my `"+y` macro which is enabled with
(define-key evil-normal-state-map ",y" "\"+y")
in my .emacs, but it fails with the message
After 0 kbd macro iterations: X selection unavailable for this frame
. Is this a bug in Evil or is it something in Emacs itself?
-L
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
On Sat, Jul 26, 2014 at 06:31:06PM -0400, Gordon Gustafson wrote:
Did you mean this (without the comma)?
(define-key evil-normal-state-map "y" "\"+y")
Well, I use the comma as my "leader" key. I don't want to use just "y" itself because that would overwrite the default "y" command.
Also, do you get the same error when you manually type the "+y (not using the macro)? What key sequence causes the failure?
If I don't use the macro and just type "+y into a `emacs -nw` session, I get the error message X selection unavailable for this frame . -L
On 7/26/14, Linus Arver <[email protected]> wrote:
Hello all,
In regular Emacs (with Evil mode turned on, of course), I can (1) do visual selection of a region, and it will automatically copy that selection into the X primary selection buffer. This way, I can simply do SHIFT+INSERT in another X program (e.g., Firefox) and I will paste the selection that way. Conversely, I can (2) SHIFT+INSERT into Emacs/Evil (in Insert mode), and it will paste whatever is in the X primary buffer.
However, behavior (1) does not work in terminal-mode Emacs (`emacs -nw`), although behavior (2) works as expected. I have tried to work around this by using my `"+y` macro which is enabled with
(define-key evil-normal-state-map ",y" "\"+y")
in my .emacs, but it fails with the message
After 0 kbd macro iterations: X selection unavailable for this frame
. Is this a bug in Evil or is it something in Emacs itself?
-L
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
I can reproduce this. Some quick googling confirms that it comes from Emacs not being able to access the X clipboard when it's not run under X, so it's not an issue with Evil. Unfortunately I didn't see any fixes along the way... On 7/26/14, Linus Arver <[email protected]> wrote:
On Sat, Jul 26, 2014 at 06:31:06PM -0400, Gordon Gustafson wrote:
Did you mean this (without the comma)?
(define-key evil-normal-state-map "y" "\"+y")
Well, I use the comma as my "leader" key. I don't want to use just "y" itself because that would overwrite the default "y" command.
Also, do you get the same error when you manually type the "+y (not using the macro)? What key sequence causes the failure?
If I don't use the macro and just type
"+y
into a `emacs -nw` session, I get the error message
X selection unavailable for this frame
.
-L
On 7/26/14, Linus Arver <[email protected]> wrote:
Hello all,
In regular Emacs (with Evil mode turned on, of course), I can (1) do visual selection of a region, and it will automatically copy that selection into the X primary selection buffer. This way, I can simply do SHIFT+INSERT in another X program (e.g., Firefox) and I will paste the selection that way. Conversely, I can (2) SHIFT+INSERT into Emacs/Evil (in Insert mode), and it will paste whatever is in the X primary buffer.
However, behavior (1) does not work in terminal-mode Emacs (`emacs -nw`), although behavior (2) works as expected. I have tried to work around this by using my `"+y` macro which is enabled with
(define-key evil-normal-state-map ",y" "\"+y")
in my .emacs, but it fails with the message
After 0 kbd macro iterations: X selection unavailable for this frame
. Is this a bug in Evil or is it something in Emacs itself?
-L
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
Hi, Terminal emacs can't access X libraries, hence clipboard. I had similar issue and the only solution is to combine it with external tools, like 'xsel'. Here is nice post how to do it: http://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/ Good thing about above approach is that all Evil yanks and cuts will work with clipboard out of the box (no need to change anything, just load that code). Bad thing is if you use tramp for editing remote file, emacs will expect 'xsel' to be installed on that host too. This can be easily hacked with tramp hooks. Best, Sanel On 07/26/14,Gordon Gustafson wrote:
I can reproduce this. Some quick googling confirms that it comes from Emacs not being able to access the X clipboard when it's not run under X, so it's not an issue with Evil. Unfortunately I didn't see any fixes along the way...
On 7/26/14, Linus Arver <[email protected]> wrote:
On Sat, Jul 26, 2014 at 06:31:06PM -0400, Gordon Gustafson wrote:
Did you mean this (without the comma)?
(define-key evil-normal-state-map "y" "\"+y")
Well, I use the comma as my "leader" key. I don't want to use just "y" itself because that would overwrite the default "y" command.
Also, do you get the same error when you manually type the "+y (not using the macro)? What key sequence causes the failure?
If I don't use the macro and just type
"+y
into a `emacs -nw` session, I get the error message
X selection unavailable for this frame
.
-L
On 7/26/14, Linus Arver <[email protected]> wrote:
Hello all,
In regular Emacs (with Evil mode turned on, of course), I can (1) do visual selection of a region, and it will automatically copy that selection into the X primary selection buffer. This way, I can simply do SHIFT+INSERT in another X program (e.g., Firefox) and I will paste the selection that way. Conversely, I can (2) SHIFT+INSERT into Emacs/Evil (in Insert mode), and it will paste whatever is in the X primary buffer.
However, behavior (1) does not work in terminal-mode Emacs (`emacs -nw`), although behavior (2) works as expected. I have tried to work around this by using my `"+y` macro which is enabled with
(define-key evil-normal-state-map ",y" "\"+y")
in my .emacs, but it fails with the message
After 0 kbd macro iterations: X selection unavailable for this frame
. Is this a bug in Evil or is it something in Emacs itself?
-L
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
On Sun, Jul 27, 2014 at 03:00:10PM +0200, Sanel Zukan wrote:
Here is nice post how to do it: http://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/
Good thing about above approach is that all Evil yanks and cuts will work with clipboard out of the box (no need to change anything, just load that code).
It appears that Evil yanks into the clipboard by default (at least in GUI Emacs).
Bad thing is if you use tramp for editing remote file, emacs will expect 'xsel' to be installed on that host too. This can be easily hacked with tramp hooks.
I don't use tramp (yet?), so all is good for now. ;) Anyway, sorry for the late response, but I finally got GUI emacs and terminal emacs to have the EXACT same behavior, when using visual selections and also yanking/pasting! As a refresher, this is how Vim (GVim and terminal vim) works: 1) Visual selection: any visual selection updates the X primary buffer (for Shift-Inserting into any other X application). 2) Yank: yanks into vim's own buffer; does not modify X primary or X clipboard. 3) "+y: yanks into special X clipboard (the '+') register. With my settings, in both terminal and GUI Emacs, you get (1), and (2) becomes (3)'s behavior (where plain yanking with 'y' yanks into clipboard as well as yanking into Evil's own default buffer). The first part involves redefining the default `evil-visual-update-x-selection` function provided by Evil, as this is what is called when we use visual selection mode (both in gui and terminal Emacs). With this, we make the visual selection update the X primary selection buffer: ; Vim-like visual selection. Make the visual selection update the X primary ; buffer. (defun evil-visual-update-x-selection (&optional buffer) "Update the X selection with the current visual region." (let ((buf (or buffer (current-buffer)))) (when (buffer-live-p buf) (with-current-buffer buf (when (and (evil-visual-state-p) (fboundp 'x-select-text) (or (not (boundp 'ns-initialized)) (with-no-warnings ns-initialized)) (not (eq evil-visual-selection 'block))) ; ; Vanilla evil, as of commit ; ; 1def26dc9c4d084e766364eff2d9f3aa51613cf7. ; (x-select-text (buffer-substring-no-properties ; evil-visual-beginning ; evil-visual-end)) ; ; from Hans-Peter Deifel's email on Nov 1 2012, to the ; ; [email protected] mailing list ; ; (http://permalink.gmane.org/gmane.emacs.vim-emulation/1715), which ; ; makes visual selections from Evil update the X11 primary ; ; selection; this version does not work with the latest Evil ; ; 1def26dc9c4d084e766364eff2d9f3aa51613cf7 because of a "X selection ; ; unavailable for this frame" error. ; (x-set-selection 'PRIMARY ; (buffer-substring-no-properties ; evil-visual-beginning ; evil-visual-end)) ; (setq x-last-selected-text-primary) ; ; We explicitly use 'xsel' to update the primary selection; this ; ; way, we can emulate Vim's behavior in both terminal and GUI emacs. (call-process-region evil-visual-beginning evil-visual-end "xsel" nil 0 nil "--primary" "--input" ) ))))) Please excuse the ugly formatting; I use tabs for indentation (heretic!) for emacs --- I would make it consistent, but for purposes of this email I wanted to preserve some of the whitespace so you can diff it if you want against the original Evil version. I've also left a lot of comments and preserved Hans-Peter Deifel's version for comparison. The second part involves making terminal Emacs yank into the clipboard when we press 'y'. This mirrors the behavior of GUI Emacs/Evil, so I suppose everyone should be using this part if you use terminal Emacs/Evil. ; When yanking ('y' key) in terminal Emacs, copy into the X clipboard. As ; suggested from http://permalink.gmane.org/gmane.emacs.vim-emulation/2023, the ; blog post at ; http://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/ ; touches on this topic; here is a modified version of that blog post: (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/[email protected]/msg03577.html ) ) Please let me know if what I've done can be improved upon.
If you plan to use Emacs from terminal a lot (as I do) with this approach, be warned that for every 'x' (character delete), 'xsel' would be called. This is not that bad, as 'xsel' is pretty fast, but with many x-ing, things can be noticeable; also for every clipboard cut/past X11 server has to be notified. That is why (I think) Vim makes this available only from specific registers. Because of that, here is updated version: -------------------------->8--------------------------- (defadvice x-set-selection (around my-x-set-selection (type data)) (message "Copied to %s selection" type) (let ((sel-type (cond ((eq type 'PRIMARY) "--primary") ((eq type 'CLIPBOARD) "--clipboard") (t (error "Got unknown selection type: %s" type))))) (with-temp-buffer (insert text) (call-process-region (point-min) (point-max) "xsel" nil 0 nil sel-type "--input")))) (defadvice x-get-selection-value (before my-x-get-selection-value) (message "Paste from PRIMARY selection") (insert (shell-command-to-string "xsel --primary --output"))) (defadvice x-get-clipboard (before my-x-get-clipboard) (message "Paste from CLIPBOARD selection") (insert (shell-command-to-string "xsel --clipboard --output"))) (ad-activate 'x-set-selection) (ad-activate 'x-get-selection-value) (ad-activate 'x-get-clipboard) --------------------------8<--------------------------- Now it behaves just like Vim: copy/paste to '*' register will copy/paste to primary selection and copy/paste to '+' will do the same to clipboard selection. And no more hammering 'xsel' for every 'd' or 'x' combos :) Cheers, Sanel Linus Arver <[email protected]> writes:
The second part involves making terminal Emacs yank into the clipboard when we press 'y'. This mirrors the behavior of GUI Emacs/Evil, so I suppose everyone should be using this part if you use terminal Emacs/Evil.
; When yanking ('y' key) in terminal Emacs, copy into the X clipboard. As ; suggested from http://permalink.gmane.org/gmane.emacs.vim-emulation/2023, the ; blog post at ; http://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/ ; touches on this topic; here is a modified version of that blog post: (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/[email protected]/msg03577.html ) )
Please let me know if what I've done can be improved upon.
Hello Sanel, On Fri, Nov 14, 2014 at 04:09:43PM +0100, Sanel Zukan wrote:
If you plan to use Emacs from terminal a lot (as I do) with this approach, be warned that for every 'x' (character delete), 'xsel' would be called. This is not that bad, as 'xsel' is pretty fast, but with many x-ing, things can be noticeable; also for every clipboard cut/past X11 server has to be notified. That is why (I think) Vim makes this available only from specific registers.
All very good points --- I agree fully.
Because of that, here is updated version:
-------------------------->8--------------------------- (defadvice x-set-selection (around my-x-set-selection (type data)) (message "Copied to %s selection" type) (let ((sel-type (cond ((eq type 'PRIMARY) "--primary") ((eq type 'CLIPBOARD) "--clipboard") (t (error "Got unknown selection type: %s" type))))) (with-temp-buffer (insert text) (call-process-region (point-min) (point-max) "xsel" nil 0 nil sel-type "--input"))))
(defadvice x-get-selection-value (before my-x-get-selection-value) (message "Paste from PRIMARY selection") (insert (shell-command-to-string "xsel --primary --output")))
(defadvice x-get-clipboard (before my-x-get-clipboard) (message "Paste from CLIPBOARD selection") (insert (shell-command-to-string "xsel --clipboard --output")))
(ad-activate 'x-set-selection) (ad-activate 'x-get-selection-value) (ad-activate 'x-get-clipboard) --------------------------8<---------------------------
Now it behaves just like Vim: copy/paste to '*' register will copy/paste to primary selection and copy/paste to '+' will do the same to clipboard selection. And no more hammering 'xsel' for every 'd' or 'x' combos :)
This works beautifully well in terminal Emacs, but in GUI Emacs regular 'd' or 'x' combo calls 'xsel'. So, the intention to avoid hammering 'xsel' is lost. Can you reproduce this behavior? I'm using Emacs 24.4.1 and Evil evil-20150121.106 from MELPA. I imagine this has something to do with some core underlying Emacs mechanism... At the same time, I don't think it's a high priority because I don't press and hold down 'x' or 'd' much at all --- so the concerns behind hammering xsel, at least for me, aren't as important. I apologize for the late response. -L
Cheers, Sanel
Linus Arver <[email protected]> writes:
The second part involves making terminal Emacs yank into the clipboard when we press 'y'. This mirrors the behavior of GUI Emacs/Evil, so I suppose everyone should be using this part if you use terminal Emacs/Evil.
; When yanking ('y' key) in terminal Emacs, copy into the X clipboard. As ; suggested from http://permalink.gmane.org/gmane.emacs.vim-emulation/2023, the ; blog post at ; http://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/ ; touches on this topic; here is a modified version of that blog post: (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/[email protected]/msg03577.html ) )
Please let me know if what I've done can be improved upon.
Hi, Linus Arver <[email protected]> writes:
Hello Sanel,
On Fri, Nov 14, 2014 at 04:09:43PM +0100, Sanel Zukan wrote:
If you plan to use Emacs from terminal a lot (as I do) with this approach, be warned that for every 'x' (character delete), 'xsel' would be called. This is not that bad, as 'xsel' is pretty fast, but with many x-ing, things can be noticeable; also for every clipboard cut/past X11 server has to be notified. That is why (I think) Vim makes this available only from specific registers.
All very good points --- I agree fully.
Because of that, here is updated version: [...] This works beautifully well in terminal Emacs, but in GUI Emacs regular 'd' or 'x' combo calls 'xsel'. So, the intention to avoid hammering 'xsel' is lost.
Hm... GUI Emacs should not call 'xsel' for 'd' and 'x. Can you drop me your code sample? You will need to detect if GUI Emacs is running and disable this feature. Also, you must detect (in case if terminal Emacs is running) that you are actually running X server, or 'xsel' will fail. Here is updated version that works for all three cases: -------------------------->8--------------------------- (unless window-system ;; make sure X server is running (when (getenv "DISPLAY") (defadvice x-set-selection (around my-x-set-selection (type data)) (message "Copied to %s selection" type) (let ((sel-type (cond ((eq type 'PRIMARY) "--primary") ((eq type 'CLIPBOARD) "--clipboard") (t (error "Got unknown selection type: %s" type))))) (with-temp-buffer (insert text) (call-process-region (point-min) (point-max) "xsel" nil 0 nil sel-type "--input")))) (defadvice x-get-selection-value (before my-x-get-selection-value) (message "Paste from PRIMARY selection") (insert (shell-command-to-string "xsel --primary --output"))) (defadvice x-get-clipboard (before my-x-get-clipboard) (message "Paste from CLIPBOARD selection") (insert (shell-command-to-string "xsel --clipboard --output"))) (ad-activate 'x-set-selection) (ad-activate 'x-get-selection-value) (ad-activate 'x-get-clipboard))) --------------------------8<--------------------------- Now, if GUI Emacs is running it will do nothing, defaulting to Evil copy/paste that are already working as intended. In case of pure terminal (without running X server), clipboard is not available anyway. Maybe this sounds confusing (as is indeed), here is the list of cases we should cover to emulate Vim copy/paste: * Emacs GUI - copy/past to clipboard/primary works out of the box with Evil * Emacs terminal + X running - above hack with xsel to use it * Emacs terminal and no X - no clipboard/primary selection are present Again, here we want to have cross-application copy/paste using '+' and '*' registers, as Vim does, instead of using 'xsel' for every line/character manipulation.
Can you reproduce this behavior? I'm using Emacs 24.4.1 and Evil evil-20150121.106 from MELPA. I imagine this has something to do with some core underlying Emacs mechanism... At the same time, I don't think it's a high priority because I don't press and hold down 'x' or 'd' much at all --- so the concerns behind hammering xsel, at least for me, aren't as important.
I apologize for the late response.
-L
Best, Sanel
participants (3)
-
Gordon Gustafson -
Linus Arver -
Sanel Zukan