OS Xのクリップボードを監視して,なにかコピーされていればEmacsのkill-ringに記録していくEmacs Lispを作った.
kill-ring
Emacsにはkill-ringという機能があって,過去にコピーした文字列が記録されている.
メニューから,以前にコピーした文字を選んで貼り付けられたり,いいEmacs Lispを入れると,リストから絞り込んで選んだりできる.
便利なので使ってないひとは使えばよいと思う.以下のキーワードで検索するとたぶん見つかる.
OS Xのクリップボードとkill-ringの関係
Ctrl-y を押して何か貼り付けすると,OS Xのクリップボードに何か入っているか調べて,そうでなければ kill-ringから,最後にEmacs内でコピーした文字列が出てくる.
逆に,Emacsで何かコピーするとOS Xのクリップボードにもコピーされる.
OS Xのクリップボードとkill-ringはだいたい同期して使えるようになっているけど,OS Xのアプリケーションでコピーしたものは,kill-ringに記録されないので,たまに困ることがある.
さっきメールからコピーしたURLをkill-ringから検索して貼り付けようとしても,うまくいかない.
なにをどこからコピーしたか人間が覚えておく必要があってつらい.
作った
タイマーで1秒ごとにOS Xのクリップボードを監視して,なにかコピーされていれば,Emacs内でコピーされた文字列と同じように扱えるように,kill-ringに記録していく,というEmacs Lispを作った.
;;; clipboard-to-kill-ring.el ;;; * 概要 ;;; OS Xのクリップボードを定期的に監視してkill-ringに入れます ;;; deferred.elが必要です ;;; ;;; * 使い方 ;;; (clipboard-to-kill-ring t) ;;; で監視を始めます ;;; clipboard-to-kill-ring:interval を設定するとポーリングの間隔を変えられます. ;;; デフォルトで1秒です. (require 'deferred) (defcustom clipboard-to-kill-ring:interval 1.0 "ポーリング間隔") (defvar clipboard-to-kill-ring:timer nil) (defun clipboard-to-kill-ring:observe () (let ((clip (x-cut-buffer-or-selection-value))) (when (and clip (not (string= (car kill-ring) clip))) (kill-new clip) (message clip)))) (defun clipboard-to-kill-ring (enable) "enableがtrueのときクリップボードの監視を始めます" (if (and enable clipboard-to-kill-ring:timer) (clipboard-to-kill-ring nil)) (if enable (setq clipboard-to-kill-ring:timer (run-with-timer clipboard-to-kill-ring:interval clipboard-to-kill-ring:interval 'clipboard-to-kill-ring:observe)) (when clipboard-to-kill-ring:timer (cancel-timer clipboard-to-kill-ring:timer) (setq clipboard-to-kill-ring:timer nil)))) (provide 'clipboard-to-kill-ring)
使い方
clipboard-to-kill-ring をrequireして, clipboard-to-kill-ring tを呼ぶ.
(require 'clipboard-to-kill-ring) (clipboard-to-kill-ring t)
あとは,普通にEmacsを使うだけで,ユーザー体験が向上する.
クリップボードマネージャみたいなやつを入れなくても,Emacsだけでクリップボードの履歴を取ることができる.
おまけ
1秒ずつクリップボードを監視するRubyスクリプト,内容が変わってたら標準出力に表示する.
なにかコピーするとすぐに表示されてちょっとおもしろい.
これはpbpasteを呼んでるけど,Emacsからは,ns-winにあった関数を呼んでる.
#! /usr/bin/env ruby last = nil loop { current = `pbpaste` if last != current puts current last = current end sleep 1 }
追記
ウィンドウズのemacs-w32でも動くようです.便利ですね.