読者です 読者をやめる 読者になる 読者になる

multiple-cursors.el を使おう

年の瀬ですね。 来年、良い年になると良いですね。

さてちょっと話題となった multiple-cursors.el の紹介です。 github のドキュメントや動画できちんと使い方が説明されていますので そちらもご覧ください、というか是非元ドキュメントにあたってください。

magnars/multiple-cursors.el · GitHub
    https://github.com/magnars/multiple-cursors.el
    git://github.com/magnars/multiple-cursors.el.git

動画はこちら

Emacs Rocks! - http://emacsrocks.com/e13.html

multiple-cursors.el ってなに?

その名の通り、カーソルキーを複数作成することが出来ます。 この説明だけでは何が嬉しいのか分かりにくいですが嬉しいことです。

まずこんなテキストがあったとします。

f:id:nishikawasasaki:20121231090431p:plain

"cd" という文字列を一気に修正したくなった場合に、 "cd" をリージョンに入れます。

f:id:nishikawasasaki:20121231090839p:plain

ここで multiple-cursors.el の mc/mark-all-like-this を実行します。

f:id:nishikawasasaki:20121231090943p:plain

リージョンと一致する要素、ここでは全ての "cd" がリージョンに入り、 "cd" の後ろにカーソルが追加されました。

リージョン選択されている状態ですので、 このまま文字を入力すると全てのリージョンに入力が行われて 一気に編集することが出来ます。 "cd" を "hogehoge" に編集するとこんな感じです。

f:id:nishikawasasaki:20121231091309p:plain

ここまでであれば magnars 氏が別に用意されている mark-multiple.el でも可能です。 しかし multiple-cursors.el はここからが本領発揮です。 マルチカーソルというくらいですので C-a して行頭に移動してそれぞれの行に文字列を追加したり……

f:id:nishikawasasaki:20121231091505p:plain

そのまま C-e して行末に追加することも可能です。

f:id:nishikawasasaki:20121231091603p:plain

もちろん、行頭行末でなくても C-f や C-b で全てのカーソルを1文字ずつ移動することも可能ですし、 C-n や C-p も出来てしまいます。

用意されているコマンド

multiple-cursors.el には、どのようにカーソルを追加するかが 異なるコマンドが定義されています。 その内よく使いそうなものをピックアップしてみます。

mc/mark-next-like-this と mc/mark-previous-like-this

リージョン状態で実行すると、リージョンと同じ内容の位置にカーソルを追加します。 next の方で現在行より下の候補を、previous で上の候補です。

リージョンが存在しない場合は、現在のカーソル位置の丁度上下に新たなカーソルを追加します。 文字列の置き換えをしないのであれば、リージョン選択せずにカーソルを増やして一括編集が可能です。

行頭と文頭のインデントのスペースを一括で取り除く場合に 矩形選択して削除という方法が考えられますが、 行頭にカーソルを置いて mc/mark-next-like-this で下の行に次々カーソルを追加すれば あとは C-d で全ての行のインデントを1つずつ消していけますね。

こんな風に設定しています。

;; リージョンと一致する箇所で現在行より下にあるもの1つを追加
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
;; リージョンと一致する箇所で現在行より上にあるもの1つを追加
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)

mc/mark-more-like-this-extended

上の項目の拡張版です。 矢印キー↑↓を使ってリージョンと同じ内容へのカーソル追加が行えます。

← で要素を1つ飛ばしでカーソルを追加出来ます。 ところどころ編集したく無い要素がある場合に便利ですね。

もし間違えて要素を追加してしまった場合は → キーで直前の追加をキャンセルして戻ることが出来ます。 何度も可能です。

mc/mark-all-like-this

上記の例で紹介済みですがリージョンに一致する項目全てにカーソルを追加します。 リファクタリングで変数名を変えたり……なんて場合に便利です。

mc/mark-sgml-tag-pair

HTML などで、対応するタグにカーソルを追加します。 開始タグで mc/mark-sgml-tag-pair すれば閉じタグに、 閉じタグで mc/mark-sgml-tag-pair すれば 開始タグにカーソルが追加されますので 対応するタグを一緒に編集することが出来ます。

mc/mark-all-like-this-dwim

DWIM、良い感じにカーソルを追加してくれます。 通常時は mc/mark-all-like-this のように動作し、 タグ上で使うと mc/mark-sgml-tag-pair のように動作するスマートな子です。

その他

multiple-cursors.el でカーソルを追加中はモードラインに何箇所追加したかが "mc:n" (n は整数)で表示されています。

また、表示している領域外にある要素の追加を確認したい場合 C-v と M-v で通常の画面送りではなく、要素をひとつずつ確認することが出来ます。

ちなみに リージョン選択が便利になる er/expand-region との併用が作者からオススメされています。

おわりに

どうでしょうか。 使いこなす方に頭を使いそうな気がする elisp ですが 状況によっては大変便利だと思います。

それでは良いお年を、また来年!!