coLinux で Emacs の kill-ring の内容をWindowsのクリップボードと同期する

Emacs で kill したバッファを Windowsクリップボードに入れたいんだけど。みんなどうしてるのかな...。というかそもそも coLinuxWindows 間でクリップボード共有する方法がわからない。常識っぽいんだが。

Linux 自体にクリップボードの概念がないような気がする。あるのは X とか Gnome とか KDE とかのレベルでは。
それはともかく、s/バッファ/region/ と読み替えて、Python での XMLRPC + advice でやってみた。要 Python Win32 Extension。
まず、Windows で動かす XML-RPC Server。

#!/usr/bin/env python

import sys
import select
from SimpleXMLRPCServer import SimpleXMLRPCServer
from win32clipboard import *
import win32con

_HOST = '192.168.10.1'
_PORT = 10050
_SYSTEM_ENCODING = 'cp932'

class MyXMLRPCServer(SimpleXMLRPCServer):
    def get_request(self):
        while True:
            r = select.select([self.socket], [], [], 1)
            if len(r[0]) > 0:
                return self.socket.accept()

def set_clipboard(text):
    if type(text) is str:
        text = text.decode('us-ascii')
    OpenClipboard()
    SetClipboardData(win32con.CF_UNICODETEXT, text.replace(u"\n", u"\r\n"))
    SetClipboardText(text.encode(_SYSTEM_ENCODING).replace("\n", "\r\n"))
    CloseClipboard()
    return True

server = MyXMLRPCServer((_HOST, _PORT))
server.register_function(set_clipboard)
try:
    server.serve_forever()
except KeyboardInterrupt:
    pass

coLinux 側で走らせる XML-RPC Client

#!/usr/bin/env python

import sys
from xmlrpclib import ServerProxy

_HOST = "192.168.10.1"
_PORT = 10050
_ENCODING = "utf-8"

def usage():
    print "usage: %s [text]" % sys.argv[0]

if len(sys.argv) == 1:
    text = sys.stdin.read().decode(_ENCODING)
elif len(sys.argv) == 2:
    text = sys.argv[1].decode(_ENCODING)
else:
    usage()

url = "http://%s:%d/" % (_HOST, _PORT)
server = ServerProxy(url)
server.set_clipboard(text)

Client を cl-sync.py という名前にしてPATHの通ったところに置き、.emacs に関数定義と advice 定義を追加。

(defvar cl-sync-command "cl-sync.py"
  "*The command for clipboard sync")

(defun cl-sync (beg end)
  (interactive "r")
  (call-process-region beg end shell-file-name nil nil nil shell-command-switch cl-sync-command))

(defadvice copy-region-as-kill
  (before clipboard-sync (beg end) activate)
  (cl-sync beg end))

(defadvice kill-region
  (before clipboard-sync (beg end) activate)
  (cl-sync beg end))

とりあえず、まともに動いているように見えるね、うん。
bind する IP とか port とかは環境に合わせて適宜編集。当然だけど、外部からアクセスできるような IP に bind しないように。
あとで、xml-rpc.el も使ってみよう。