在Emacs for OSX上,如何将kill ring和剪贴板分开?

时间:2014-04-03 21:22:43

标签: emacs clipboard aquamacs kill-ring

在GNU Emacs for OSX中,如何将kill ring和OSX剪贴板分开? (这样我基本上有两个独立的杀戮戒指。)

有了预期的行为,这将起作用:
1. C 将文本从Web复制到OSX剪贴板。
2. control k 杀死Emacs中的一行。
3. control y 将Emacs kill ring中的文本从当前Emacs缓冲区中删除。 4. v 将原始Web文本从OSX剪贴板粘贴到当前的Emacs缓冲区。

这在Aquamacs开箱即用。如何在GNU Emacs中工作?

这里讨论了与Windows有关的问题: Emacs: How to separate the kill ring from the system clipboard?

在这里: http://lists.gnu.org/archive/html/help-emacs-windows/2010-02/msg00001.HTML

...但此解决方案在OSX中不起作用。我想要一个适用于Mac OSX的解决方案。

6 个答案:

答案 0 :(得分:10)

Emacs: How to separate the kill ring from the system clipboard?中的解决方案确实有效,但并不完整。您可以自己致电pbcopy以使剪贴板正确粘贴。例如,请在.emacs中尝试以下操作。请注意,s-v适用于OS X窗口系统中的Cmd+V。同样适用于s-c

;;; Tested on:
;;; 1.  GNU Emacs 24.3.1 (x86_64-apple-darwin13.0.0)
;;;     of 2013-12-22 on tennine-slave.macports.org
;;;     (MacPorts emacs@24.3_1)
;;;
;;; 2.  GNU Emacs 24.3.1 (x86_64-apple-darwin, NS apple-appkit-1038.36)
;;;     of 2013-03-12 on bob.porkrind.org
;;;     (Emacs For Mac OS X)

(defun isolate-kill-ring()
  "Isolate Emacs kill ring from OS X system pasteboard.
This function is only necessary in window system."
  (interactive)
  (setq interprogram-cut-function nil)
  (setq interprogram-paste-function nil))

(defun pasteboard-copy()
  "Copy region to OS X system pasteboard."
  (interactive)
  (shell-command-on-region
   (region-beginning) (region-end) "pbcopy"))

(defun pasteboard-paste()
  "Paste from OS X system pasteboard via `pbpaste' to point."
  (interactive)
  (shell-command-on-region
   (point) (if mark-active (mark) (point)) "pbpaste" nil t))

(defun pasteboard-cut()
  "Cut region and put on OS X system pasteboard."
  (interactive)
  (pasteboard-copy)
  (delete-region (region-beginning) (region-end)))

(if window-system
    (progn
      (isolate-kill-ring)
      ;; bind CMD+C to pasteboard-copy
      (global-set-key (kbd "s-c") 'pasteboard-copy)
      ;; bind CMD+V to pasteboard-paste
      (global-set-key (kbd "s-v") 'pasteboard-paste)
      ;; bind CMD+X to pasteboard-cut
      (global-set-key (kbd "s-x") 'pasteboard-cut))

  ;; you might also want to assign some keybindings for non-window
  ;; system usage (i.e., in your text terminal, where the
  ;; command->super does not work)
  )

如果您遇到UTF-8问题,请考虑以下可能的解决方案:

;; handle emacs utf-8 input
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setenv "LANG" "en_US.UTF-8")

答案 1 :(得分:1)

经过多次摆弄后,我非常确定实现此功能的唯一方法是覆盖x-select-text方法。有关所有详细信息,请在此处查看我的答案:https://stackoverflow.com/a/23254771/71522

答案 2 :(得分:1)

注意:此草案解决方案意味着将Emacs系统范围内的修改分隔为剪贴板 - 而不是,这是一个自定义解决方案,专门用于在专门使用这些自定义函数时,仅在interactive 的基础上保持剪贴板分离。其他功能 使用kill-ring的Emacs可以使用类似方法进行修改 - 变量interprogram-cut-functioninterprogram-paste-function可以在let-bound期间设置为nil值特定功能(通过advice,或修改源本身,或创建新功能和/或使用defalias)。但是,后者超出了这个有限的范例。


初稿(2014年12月23日):这是初稿,它基于这样一种想法,即只有在调用之前使用C-u才能访问OSX剪贴板复制或粘贴功能。如果首先调用C-u,则使用OSX剪贴板。由于我每天更多地使用这些功能,我可能会对此代码进行额外修订,我会不时更新它们:

编辑(2014年12月24日):从*的交互式命令语句中删除lawlist-copy-selected-region - 这是粘贴所需的read-only项检查,但不是复制。添加了关于此示例的一般性质的声明。

编辑(2014年12月28日):修改了代码,以便在用户忘记选择某个区域之前更好地处理lawlist-copy-selected-region。小修订使代码更简洁。


  
(defun lawlist-copy-selected-region (&optional arg)
(interactive "P")
  (let* (
      (interprogram-cut-function
        (when (equal arg '(4)) interprogram-cut-function))
      (interprogram-paste-function
        (when (equal arg '(4)) interprogram-paste-function))
      (region-active-p (region-active-p))
      (beg (when region-active-p (region-beginning)))
      (end (when region-active-p (region-end)))
      (copied-string
        (when region-active-p (buffer-substring-no-properties beg end))) )
    (unless region-active-p
      (let ((debug-on-quit nil))
        (signal 'quit `("No region has been selected!"))))
    (copy-region-as-kill beg end)
    (when (not (active-minibuffer-window))
      (message "%s"
        (concat
          (if (and interprogram-cut-function interprogram-paste-function)
            "OSX+Emacs:  "
            "Emacs:  ")
          (truncate-string-to-width copied-string 40)
          (when (> (length copied-string) 40)
            " . . .")))) ))

(defun lawlist-yank (&optional arg)
  (interactive "*P")
  (unless arg (setq arg 1))
  (setq yank-window-start (window-start))
  (setq this-command t)
  (push-mark (point))
  (insert-for-yank
    (lawlist-current-kill
      (cond
        ((listp arg)
          arg)
        ((eq arg '-)
          -2)
        (t
          (1- arg) ))))
  (if (consp arg)
      (goto-char (prog1 (mark t)
       (set-marker (mark-marker) (point) (current-buffer)))))
  (if (eq this-command t)
      (setq this-command 'yank))
  (when (region-active-p)
    (setq mark-active nil))
  nil)

(defun lawlist-current-kill (n &optional do-not-move)
  (let ((interprogram-paste
          (and
            (equal n '(4))
            interprogram-paste-function
            (funcall interprogram-paste-function))))
    (cond
      (interprogram-paste
        (let ((interprogram-cut-function nil))
          (if (listp interprogram-paste)
            (mapc 'kill-new (nreverse interprogram-paste))
            (kill-new interprogram-paste)))
        (car kill-ring))
      ((and (equal n '(4)) (not interprogram-paste))
        (car kill-ring))
      (t
        (or kill-ring 
          (let ((debug-on-quit nil))
            (signal 'quit `("The kill-ring is empty."))))
        (let (
            (ARGth-kill-element
              (nthcdr
                (mod (- n (length kill-ring-yank-pointer)) (length kill-ring))
                kill-ring)))
          (unless do-not-move
            (setq kill-ring-yank-pointer ARGth-kill-element)
            (when
                (and
                  yank-pop-change-selection
                  (> n 0)
                  interprogram-cut-function)
              (funcall interprogram-cut-function (car ARGth-kill-element))))
        (car ARGth-kill-element))))))

答案 3 :(得分:0)

(global-set-key (kbd "C-x M-y")
              (lambda ()
                (interactive)
                (insert-string (ns-get-pasteboard))))

(global-set-key (kbd "C-x M-w")
              (lambda ()
                (interactive)
                (when (region-active-p)
                  (ns-set-pasteboard
                   (buffer-substring (region-beginning)
                                     (region-end))))))

答案 4 :(得分:0)

simpleclip 可能会有所帮助 -

  

简化了对Emacs中系统剪贴板的访问。

     

simpleclip-mode从根本上简化了剪贴板处理:系统   剪贴板和Emacs杀戮戒指完全独立,并且   永远不要互相影响。

     

超级键绑定对于OS X是友好的:通常映射超级   到"命令"键即⌘。

     

在OS X,X11和MS Windows上测试

https://github.com/rolandwalker/simpleclip

答案 5 :(得分:-2)

这有用吗:

(setq x-select-enable-clipboard nil)

这只会将两个剪贴板分开,对于 Cmd + c Cmd + v 按照提到的方式工作,你必须将它们重新绑定到clipboard-kill-ring-saveclipboard-yank

我正在使用此Emacs:https://github.com/railwaycat/emacs-mac-port