永久观看系统剪贴板的功能

时间:2014-08-13 08:12:39

标签: emacs elisp clipboard infinite-loop

我刚刚开始学习编程,所以我希望这个问题不是太愚蠢。

我想为Emacs创建一个永久监视系统剪贴板的函数(在我的案例中是Windows 8),并将每个更改附加到Emacs的当前缓冲区。这是我对该功能的想法:

(defun watch-clipboard ()
  "Watches Clipboard and appends every change to buffer."
  (interactive)
  (let ((old-clipboard)
        (new-clipboard)) ; two local variables for comparison
    (setq old-clipboard (current-kill 0))
    (while t             ; infinite loop
      (setq new-clipboard (current-kill 0)) 
      (if (not (string= old-clipboard new-clipboard)) ; check for change
        (progn (insert new-clipboard)
               (insert "\n")
               (setq old-clipboard new-clipboard))))))

不幸的是这个功能有问题:

结果非常不可靠。有时,每个更改都会被缓冲到缓冲区中,但大多数时候只有一半的剪贴板发生更改,或者只识别出最后一次更改。

2 个答案:

答案 0 :(得分:2)

我认为你应该直接拨打interprogram-paste-function,而不是通过current-kill,当它返回nil时会做出时髦的东西。

另外,我建议sleep-for避免繁忙的循环:

(defun my-watch-clipboard ()
  "Watches Clipboard and appends every change to buffer."
  (interactive)
  (while t             ; infinite loop
    (let ((clipboard (funcall interprogram-paste-function)))
      (when clipboard
        (insert clipboard)
        (insert "\n")))
    (sleep-for 1))) ; or maybe `sit-for` if you want screen updates

顺便说一句,上面的代码可以通过awhenanaphoric macro)进行简化。 不是我自己用它们......

答案 1 :(得分:1)

我认为在这个帖子中拥有该函数的最终版本可能会很好。 (根据sds的建议;再次感谢)所以这里是:

(defun watch-clipboard ()
  "Watches Clipboard and appends every change to buffer."
  (interactive)
  (let (clipboard)
    (while t
      (setq clipboard (funcall interprogram-paste-function))
      (unless (null clipboard)
        (insert clipboard)
        (insert "\n"))
      (sit-for 1)))) ; screen updates are indeed better so I did not use 'sleep-for'

因为 interprogram-paste-function 在第一次评估后发出 nil ,所以无需检查剪贴板是否有变化。因此,现在只有一个局部变量而不是两个。此外除非只需要检查一个条件。它比上面稍微有点苗条,它可以做到应有的一切。