Emacsを便利に使うための提案(行のcopy・kill編)

Emacs を使用していると,行全体をコピーしたくなることがよくある.そういうときは

  • C-a C-k C-y
  • C-a C-k C-/
  • C-a C-SPC C-e M-w

のどれかで行っているのだが,利用する頻度の割に入力するキーが多くて面倒だ.そこで,行全体をコピーするキーを定義したいと思う.

都合よく M-k が空いているのでそれを使用することにする. M-k は kill-sentence だが私はまず使用しない.また,C-w が kill に対し M-w が copy の対応に似ていて覚えやすいという利点もある(完全に対応させるなら末尾までコピーが正しいのだが,行copyの方が頻繁に使うし必要なキー操作が多いのでこちらを M-k とする).

また,行 copy があるなら行 kill もほしい.そこで,そちらは M-K に割り当てることにする.それでは .emacs の設定に移ろう.

emacs23 には行 kill を行う kill-whole-line が標準で用意されているので使用する.一方,行 copy はないので以下を .emacs に記述する.

(defun copy-whole-line (&optional arg)
  "Copy current line."
  (interactive "p")
  (or arg (setq arg 1))
  (if (and (> arg 0) (eobp) (save-excursion (forward-visible-line 0) (eobp)))
      (signal 'end-of-buffer nil))
  (if (and (< arg 0) (bobp) (save-excursion (end-of-visible-line) (bobp)))
      (signal 'beginning-of-buffer nil))
  (unless (eq last-command 'copy-region-as-kill)
    (kill-new "")
    (setq last-command 'copy-region-as-kill))
  (cond ((zerop arg)
         (save-excursion
           (copy-region-as-kill (point) (progn (forward-visible-line 0) (point)))
           (copy-region-as-kill (point) (progn (end-of-visible-line) (point)))))
        ((< arg 0)
         (save-excursion
           (copy-region-as-kill (point) (progn (end-of-visible-line) (point)))
           (copy-region-as-kill (point)
                                (progn (forward-visible-line (1+ arg))
                                       (unless (bobp) (backward-char))
                                       (point)))))
        (t
         (save-excursion
           (copy-region-as-kill (point) (progn (forward-visible-line 0) (point)))
           (copy-region-as-kill (point)
                                (progn (forward-visible-line arg) (point))))))
  (message (substring (car kill-ring-yank-pointer) 0 -1)))

kill-whole-line の "kill-region" を "copy-region-as-kill" に置換したものである.コピーしたことが確認できるよう,関数末尾に kill-ring の先頭をミニバッファに表示するコードも付け足した.

そして,以下を .emacs に記述する.

(global-set-key (kbd "M-k") 'copy-whole-line)
(global-set-key (kbd "M-K") 'kill-whole-line)

ここまで設定すれば M-k で行 copy,M-K で行 kill ができるようになる.M-k を使用しないのであれば,ぜひ試してみてほしい.