System clipboard always view function

I am just starting to learn programming, so I hope this question is not too stupid.

I want to create a function for Emacs that constantly monitors my system's clipboard (Windows 8 in my case) and adds each change to the current Emacs clipboard. This is my idea for a function:

(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))))))

      

Unfortunately there is a problem with this function:

The result is very unreliable. Sometimes every change is jerked in the clipboard, but most of the time only half of the clipboard changes, or only the recognition of the last change.

+3


source to share


2 answers


I think you should be calling interprogram-paste-function

directly and not via current-kill

, which makes it funky when it returns nil

.

Also, I suggest sleep-for

to avoid the busy loop:



(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

      

BTW, the above code can be simplified with awhen

( anaphoric macro ). Not that I used them myself ...

+2


source


I think it might be helpful to have the final version of the function in this thread. (based on advice from sds, thanks again) So here it is:

(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'

      



Since the interprogram-paste function returns nil after the first evaluation, there is no need to check if there was a change in the clipboard. Therefore, currently there is only one local variable instead of two. Also, unless you need to check one condition. It's a little thinner than the one above, and it does whatever it takes.

+1


source







All Articles