WSL上のEmacs(nw)とWindowsとでクリップボードを共有する方法

WSLで動くLinuxとクリップボードを共有する方法は僕が知るかぎりでも、

  1. clip.exeを使う
  2. X Window Serverを経由する

などがある。自分はGUIアプリを使うこともあるので、もともとX Serverを立てているということもあり、汎用性が高い2のほうを使っている。

実際、

# copy
cat foo.txt | xsel -bi

# paste
xsel -bo > foo.txt

というような操作はLinuxを使う時と一緒なので覚えやすい。自分はtmuxでcopyすると自動でXのクリップボードにもcopyされるという設定をもともと使っているので、それがそのまま使えるというのもありがたい。

ただ、このXのクリップボードをWindows側と共有してくれるには、それに対応したX Window Serverを使う必要がある。 自分は X410 というのを使っている。[1]

WSL上のLinuxとWindowsクリップボードの共有に関してはこのXを使う方法でほぼ問題ない。やることは、

  • Windows側でX Serverをあげておく
  • Linux側でDISPLAY環境変数にその情報を入れておく[2]

だけ。

GUIでEmacsを使っていればこれだけで良いのだが、今はbug.nの操作に慣れていないということもあり、CLI上でEmacsを使っていて、そちらでも自動でXのクリップボードが同期されてくれるとうれしい。

ググるとstackoverflowにxselを使った良い設定を書いている人がいたので、それをそのまま拝借して以下の設定を追加:

;; sync with x clipboard
(unless window-system
  (when (getenv "DISPLAY")
    ;; Callback for when user cuts
    (defun xsel-cut-function (text &optional push)
      ;; Insert text to temp-buffer, and "send" content to xsel stdin
      (with-temp-buffer
        (insert text)
        ;; I prefer using the "clipboard" selection (the one the
        ;; typically is used by c-c/c-v) before the primary selection
        ;; (that uses mouse-select/middle-button-click)
        (call-process-region (point-min) (point-max) "xsel" nil 0 nil "--clipboard" "--input")))
    ;; Call back for when user pastes
    (defun xsel-paste-function()
      ;; Find out what is current selection by xsel. If it is different
      ;; from the top of the kill-ring (car kill-ring), then return
      ;; it. Else, nil is returned, so whatever is in the top of the
      ;; kill-ring will be used.
      (let ((xsel-output (shell-command-to-string "xsel --clipboard --output")))
        (unless (string= (car kill-ring) xsel-output)
          xsel-output )))
    ;; Attach callbacks to hooks
    (setq interprogram-cut-function 'xsel-cut-function)
    (setq interprogram-paste-function 'xsel-paste-function)
    ;; Idea from
    ;; http://shreevatsa.wordpress.com/2006/10/22/emacs-copypaste-and-x/
    ;; http://www.mail-archive.com/help-gnu-emacs@gnu.org/msg03577.html
    ))

これでかなり便利に。bug.nに慣れたらGUI版に戻そうとおもっていたが、このままでもいいかもなぁと思いはじめている。