首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >emacs终端模式:如何有效地复制和粘贴

emacs终端模式:如何有效地复制和粘贴
EN

Stack Overflow用户
提问于 2015-01-04 09:11:46
回答 3查看 9.2K关注 0票数 12

我很难让这个emacs -nw在终端模式(emacs -nw)下有效工作。一些设置信息:工作服务器通过SSH连接,emacs正在服务器上运行。通常,我使用SSH和"emacs -nw“连接来处理我的文件。

emacs配置是从:https://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/获取的。

代码语言:javascript
复制
;; 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
 ))

其理由是:

代码语言:javascript
复制
 (require 'mouse)
 (xterm-mouse-mode t)
 (defun track-mouse (e)) 
 (setq mouse-sel-mode t)

在文本上启用鼠标选择,使文本区域被高亮显示为“C”标记该区域。然后,我可以使用“text”复制,使用“copy”粘贴文本在emacs内部和emacs与其他应用程序之间。

除了任何与X相关的操作都很慢外,所有这些看起来都很完美!我与远程服务器的连接是平滑的--延迟通常在100 My以下。但是用“C”杀死一行文字需要5秒的时间!粘贴它需要5秒的时间!

当复制/粘贴有时频繁时,这会变得非常烦人。我认为这与X服务器消息传递有关,但不确定是否有很好的方法来解决这个问题。

有什么想法吗?谢谢!

EN

回答 3

Stack Overflow用户

发布于 2015-01-07 04:44:51

这本身并不是一个理想的解决方案,但我想出了一种比前一种更好的方法。

这样做的目的是消除引起严重延迟问题的X,即只保留以下内容:

代码语言:javascript
复制
;; enable clipboard in emacs
(setq x-select-enable-clipboard t)

研究结果如下:

  1. 在Emacs中复制/粘贴是简单而快速的。
  2. 从其他应用程序复制到Emacs: Ctrl+Shift+v
  3. 复制从Emacs到其他应用程序:鼠标选择现在在X选择,所以右击和复制将文本复制到选择。请注意,‘M’现在不会将任何内容复制到选择或系统剪贴板中。

这也是一个妥协,而不是一个解决方案,但考虑到我复制/粘贴比应用程序间操作更频繁的事实,这在目前是可以接受的。

仍然期待着一个好的解决方案!

票数 6
EN

Stack Overflow用户

发布于 2021-01-10 19:16:11

您可以通过使用终端转义代码来实现这一点!有一种独特的终端转义代码称为“操作系统控制”(Operating),其中一个序列(\033]52)用于与系统剪贴板交互。最重要的是,您的终端不关心代码来自何处,因此它也将在远程会话中工作。

大多数终端模拟器都支持它(iTerm2、OS终端,我认为除了GNOME之外,所有的Linux终端都支持它)。只需运行以下命令,就可以测试终端是否支持此序列:

代码语言:javascript
复制
$ printf "\033]52;c;$(printf "Hello, world" | base64)\a"

然后从系统剪贴板粘贴。如果它粘贴“你好,世界”,那么你的终端支持它!

我的init.el中有这个函数,所以当我调用yank-to-clipboard时,Emacs会将yank-to-clipboard环中的值提取到系统剪贴板中:

代码语言:javascript
复制
(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))))

当我键入这个脚本时,我偶然发现了一个几乎相同的脚本,它是由Chromium社区支持的:https://chromium.googlesource.com/apps/libapps/+/master/hterm/etc/osc52.el

对于那些在 Tmux中运行Emacs 的人来说: Tmux消耗了这个序列,因此您需要将该序列输送到Tmux,这样才能工作。我的博客文章中有一个解决方案:https://justinchips.medium.com/have-vim-emacs-tmux-use-system-clipboard-4c9d901eef40

票数 1
EN

Stack Overflow用户

发布于 2021-03-03 22:50:32

为了在tmux中使用@justinokamoto的答案,它工作得很好,而且真的很棒。我并没有用tramp或其他漂亮的emacs设置来调试它,而是让它开始工作。

  1. 遵循https://sunaku.github.io/tmux-yank-osc52.html很好的说明,修改tmux.conf~/bin/yank
  2. 确保在终端上启用了对剪贴板的终端访问。

然后,要进入emacs,可以使用如下函数:

(请注意,我对私奔很陌生。这将写入/tmp/yank中的临时文件)

代码语言:javascript
复制
(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"))
  )

如果其他人也使用邪恶模式(只是为了使事情变得复杂),您可以取消对这些行的注释,并使用类似于(define-key evil-visual-state-map "Y" 'jonah-terminal-yank)的东西,使普通的"y“表示在视觉模式下的正常拉出,而"Y”则用于跨剪贴板拉法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27764059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档