vimとemacsのコマンド比較

# はじめに

普段 Linux 環境での作業は vim を使っていますが、手元の OS X 環境では emacs を使ってメモなどを取っています。が、やはり vim ほど emacs は使えていないのであのコマンドはどうやるんだっけ？というときの Vimmer 視点のメモ書きです。思いついた時々で更新します。

* エディタの標準機能についてのみです
* GUI はほとんど使わないので CUI で利用可能なコマンドです
* 以下のバージョンで確認しています
  * vim: 7.4.542 - homebrew HEAD
  * emacs: 24.3.1 - [MacEmacs JP](http://sourceforge.jp/projects/macemacsjp/releases/p13490) Emacs24.3-with-inline-patch-R1


# コマンド比較表

## 表記について

* `C-a` は `Ctrl` を押しながら `a` を押すことを意味します
* `M-v` は多くの場合 `ESC` を押したあとに `v` を押すことを意味します。`ESC` は `C-[` でも代用できます。
* キーマップに割り当てられているコマンドについては括弧書きで併記します
  * vim: `:sp[lit]` ※ `[]`内は省略可能
  * emacs: `split-window-vertically`
* 特殊キーについてはそれぞれのエディタでよく使われている形式で表記します
  * vim: `<Tab>` `<Enter>` `<Space>` `<Esc>` `<F1>`
  * emacs: `TAB` `RET` `SPC` `ESC` `<f-1>`
* 省略可能な引数については `[count]` と表記します
* 入力必須な引数については `{char}` と表記します


## 数引数

数値を指定することで実行する回数を指定できるコマンドが幾つかあります。

|コマンド | vim | emacs |
|---------|-----|-------|
|数引数      | `[count]` | `M` `[-]{count}` (`digit-argument`)|
|前置引数 *1 | | `C-u` `[-][count]` (`universal-argument`)|
|負の前置引数| | `C--` `[-][count]` (`negative-argument`)|

1. 前置引数は数値を省略した場合、`C-u` で 4、`C-u` `C-u` で 16、`C-u` `C-u` `C-u` で 64 ... を指定したことになります


## カーソル移動

文字や単語、ページの移動については vim、emacs ともに数引数が使えます。

|コマンド | vim | emacs |
|---------|-----|-------|
|行先頭          | `0` | `C-a` (`beginning-of-line`) |
|行末尾          | `$` | `C-e` (`end-of-line`) |
|行頭の非空白文字| `^` | `M-m` (`back-to-indentation`) |
|1文字次         | `l` | `C-f` (`forward-char`) |
|1文字前         | `h` | `C-b` (`backward-char`) |
|1単語次 *1      | `w` | `M-f` (`forward-word`) |
|1単語前         | `b` | `M-b` (`backward-word`) |
|1行下           | `j` | `C-n` (`next-line`) |
|1行上           | `k` | `C-p` (`previous-line`) |
|1文次 *2        | `)` | `M-e` (`forward-sentence`) |
|1文前           | `(` | `M-a` (`backward-sentence`) |
|1ページ下       | `C-f` | `C-v` (`scroll-up`)|
|1ページ上       | `C-b` | `M-v` (`scroll-down`)|
|ウィンドウ分割時に<br>別のウィンドウを1ページ下| | `C-M-v` (`scroll-other-window`) |
|ウィンドウ分割時に<br>別のウィンドウを1ページ上| | `C-M-S-v` (`scroll-other-window-down`) |
|バッファ先頭    | `gg`<br>`1G` | `M-<` (`beginning-of-buffer`)|
|バッファ末尾    | `G`          | `M->` (`end-of-buffer`)|
|指定行へ移動    | `[count]` `G` | `M-g` `M-g` (`goto-line`)<br>`M-g` `g` |
|指定列へ移動    | `[count]` &#124; | `M-x` `move-to-column` |
|カーソルをウィンドウの最上部に   | `H` | `M-r` `M-r` (`move-to-window-line`)||
|カーソルをウィンドウの中央に   *3| `M` | `M-r` (`move-to-window-line`)|
|カーソルをウィンドウの最下部に   | `L` | `M-r` `M-r` `M-r` (`move-to-window-line`)||
|カーソル行をウィンドウの最上部に | `z<Enter>` | `C-l` `C-l` (`recenter-top-bottom`) |
|カーソル行をウィンドウの中央に   | `z.`       | `C-l` (`recenter-top-bottom`) |
|カーソル行をウィンドウの最下部に | `z-`       | `C-l` `C-l` `C-l` (`recenter-top-bottom`) |

1. 1単語次への移動については、単語の区切りが少し異なります
  * vim: カーソル下の単語から、次の単語の先頭文字
  * emacs: 次の単語の先頭文字の左
2. 1文次への移動については、移動先が少し異なります
  * vim: 次の文の先頭文字
  * emacs: 文末文字
3. 移動後の列位置が異なります
  * vim: 行頭の非空白文字
  * emacs: 1列目 


## 編集

|コマンド | vim | emacs |
|---------|-----|-------|
|1文字削除         | `x`  | `C-d` (`delete-char`) |
|1単語削除         | `de` | `M-d` (`kill-word`) |
|1行削除           | `dd` | `C-k` (`kill-line`) |
|1文削除           | `d)` | `M-k` (`kill-sentence`) |
|特定の文字まで削除| `d/{char}` | `M-z` `{char}` (`zap-to-char`) |
|インデント        | `>>` | `C-i` (`indent-for-tab-command`) |
|すべてを選択	   |  | `C-x` `h`|
|矩形選択 *1  	   | `C-v` (で矩形ビジュアルモードを<br>開始して範囲を設定して) | (リージョンを設定して) |
|　置換(空白文字)  | `r` `<Space>` | `C-x` `r` `c` (`clear-rectangle`)|
|　置換(任意文字)  | `c` `{string}` `<Esc>` | `C-x` `r` `t` `{string}` `RET` (`string-rectangle`)|
|　挿入(空白文字)  | `yPgvr<Space>` *2 | `C-x` `r` `o` (`open-rectangle`)|
|　削除            | `d` | `C-x` `r` `d` (`delete-rectangle`)|
|単語を小文字に    | `veu` | `M-l` (`downcase-word`)|
|単語を大文字に    | `veU` | `M-u` (`upcase-word`) |
|特殊文字の入力    | (インサートモードで)<br>`C-v` `{char}` | `C-q` `{char}` (`quoted-insert`) |
|直前のコマンドを繰り返す| `.` | `C-x` `z` (`repeat`) |

1. Emacs 24.4の矩形選択機能は試していないので分かりません
2. [Vim equivalent of Emacs' open-rectangle - Stack Overflow](http://stackoverflow.com/questions/13097548/vim-equivalent-of-emacs-open-rectangle)
  * (矩形選択範囲を)コピー(`y`)してカーソル前に貼り付け(`P`)、最後に使用した範囲(`gv`)を空白で置換(`r<Space>`)


## 検索と置換

|コマンド | vim | emacs |
|---------|-----|-------|
|行末に向けて文字検索 | `f{char}` *1 | |
|行頭に向けて文字検索 | `F{char}` *1 | |
|バッファ末尾に向けて順方向検索 *2  | `/` `[word]` `<Enter>` | `C-s` `{word}` (`isearch-forward`) |
|バッファ先頭に向けて逆方向検索 *2  | `?` `[word]` `<Enter>` | `C-r` `{word}` (`isearch-backward`)|
|置換 | `:%s/{pattern}/{string}/gc` *3 | `M-%` (`query-replace`) *4 |
|grepによる検索 *5| `:grep {arguments}` | `M-x` `grep` `RET`|

1. `f`/`F` では見つかった文字上にカーソルが移動しますが、`t`/`T` を使うとその一つ前の文字に移動します
  * 直前の文字検索コマンドの繰り返しは、`;` で検索をはじめた方向に、`,` でその逆方向に
2. 検索で複数見つかった場合の次の単語へのカーソル移動
  * vim: `n` で検索をはじめた方向に、`N` でその逆方向に
     * `/` `<Enter>` でバッファ末尾に向けて、`?` `<Enter>` でバッファ先頭に向けて
  * emacs: `C-s` でバッファ末尾に向けて、`C-r` でバッファ先頭に向けて
3. 置換フラグについて
  * `g` を指定しない場合は、各行ではじめに見つかった単語のみ置換されます
  * `c` を指定しない場合は、確認なしで置換されます
4. ミニバッファに検索する単語、置換する単語を入力します
  * 見つかった単語を置換する場合は `y`、スキップする場合は `n`
5. エディタから外部の grep コマンドを実行します
  * vim: `grepprg` に指定されたコマンドを使って実行されます
      * 例) `:grep 'vim' *`
      * 検索結果は quickfix ウィンドウに格納されますので、`:cope[n]` で表示して結果にジャンプできます
  * emacs: ミニバッファに grep コマンドとしての検索文字、対象などを入力します
      * 例) `grep -nH -e "emacs" *`
      * 検索結果は \*grep\* バッファに格納されますので、そこから結果にジャンプできます


## バッファ

|コマンド | vim | emacs |
|---------|-----|-------|
|保存               | `:w` | `C-x` `C-s` (`save-bufffer`) |
|ファイルに保存     | `:sav[e] {filename}` | `C-x` `C-w` (`write-file`)<br>でファイル名入力プロンプト|
|一覧               | `:ls` | `C-x` `C-b` (`list-buffers`) |
|削除               | `:bd[elete]` | `C-x` `C-k` (`kill-buffer`) |
|切り替え         *1| `:b[uffer]` `[bufnum]`| `C-x` `b` (`switch-to-buffer`) |
|読み取り専用に   *2| `:setl[ocal] ro!` | `C-x` `C-q` (`read-only-mode`) |
|行の折り返し設定 *2| `:setl[ocal] wrap!` | `M-x` `toggle-truncate-lines` |
|改行コードの変更 *3| `:setl[ocal] fileformat={eol}` | `C-x` `RET` `f` (`set-buffer-coding-system`) *5 |
|文字エンコーディングの変更 *4| `:se[t] enc[oding]={encoding}` | `C-x` `RET` `f` (`set-buffer-coding-system`) *5 |
|文字エンコーディングを変更して開き直す | `:e[dit] ++enc[oding]={encoding}` *5 | `C-x` `RET` `r` (`revert-buffer-with-coding-system`) *5 |
|ファイル形式の変更 *6| `:setl[ocal] filetype={filetype}` | `M-x` `{mode-name}` |

1. 一つ前に表示していたバッファに切り替える場合
  * vim: `:b#`
  * emacs: `C-x` `b` `RET`
2. 変更するコマンドは実行のたびにオン・オフを切り替えられます
  * vim: `setlocal`で指定する値を`!`で切り替えています。切替が不要なら`!`は要りません
3. 指定できる改行コード(vim、emacsともに)
  * `dos`(CR+LF), `unix`(LF), `mac`(CR)
4. 指定できるエンコーディングの確認
  * vim: `:h[elp] encoding-names`
  * emacs: `M-x` `list-coding-systems`
5. 文字コードと改行コードを同時に指定できます
  * vim: `:se[t] enc=utf8 ff=dos` (`ff` は `fileformat` の略記)
  * emacs: ミニバッファで `文字コード名-改行コード名` (例: `utf-8-dos`)
6. ファイルタイプ／メジャーモードの変更 (HTML形式に変更する例)
  * vim: `:setl[ocal] ft=html` (`ft` は `filetype` の略記)
  * emacs: `M-x` `html-mode`


## ウィンドウ

|コマンド | vim | emacs |
|---------|-----|-------|
|上下2分割              | `C-w` `s` (`:sp[lit]`) | `C-x` `2` (`split-window-vertically`) |
|左右2分割              | `C-w` `v` (`:vsp[lit]`) | `C-x` `3` (`split-window-horizontally`) |
|カレントを閉じる       | `C-w` `c` (`:clo[se]`) | `C-x` `0` (`delete-window`) |
|カレント以外を閉じる   | `C-w` `o` (`:on[ly]`) | `C-x` `1` (`delete-other-windows`) |
|別を選択               | `C-w` `w`<br>`C-w` `C-w` | `C-x` `o` (`other-window`) |
|別を選択2              | ※左下上右<br>`C-w` `{hjkl}`<br>`C-w` `C-{hjkl}`<br>`C-w` `{←↓↑→}` ||
|全てを同じ高さにする   | `C-w` `=` | `C-x` `+` (`balance-windows`) |
|大きすぎる場合は縮める | | `C-x` `-` (`shrink-window-if-larger-than-buffer`) |
|高さを広げる           | `C-w` `[count]` `+` | `[count]` `C-x` `^` (`enlarge-window`)|
|高さを狭める           | `C-w` `[count]` `-` | `[count]` `M-x` `shrink-window` |
|幅を狭める             | `C-w` `[count]` `<` | `[count]` `C-x` `{` (`shrink-window-horizontally`)|
|幅を広げる             | `C-w` `[count]` `>` | `[count]` `C-x` `}` (`enlarge-window-horizontally`)|


## タブ／フレーム

vim のタブ(`tabpage`)と emacs のフレームを同じカテゴリにするには少し無理がありますが、複数のウィンドウをまとめたもの、ということで。なお、タブは Vim 7.3 から使えます。

|コマンド | vim | emacs |
|---------|-----|-------|
|新規作成            | `:tabnew` | `C-x` `5` `2` (`make-frame-command`) |
|カレントを閉じる    | `:tabc[lose]` | `C-x` `5` `0` (`delete-frame`) |
|カレント以外を閉じる| `:tabo[nly]` | `C-x` `5` `1` (`delete-other-frames`) |
|別を選択            | `gt` (`:tabn[ext]`) | `C-x` `5` `o` (`switch-to-buffer-other-frame`) |
|別を選択2           | `gT` (`:tabp[revious]`) <br> `:tabfir[st]` <br> `:tabr[ewind]` <br> `:tabl[ast]`| |
|一覧                | `:tabs` | |


## マクロ

マクロを実行する目的のコマンドの連続実行なので、多くの場合は数引数をつけて実行します。

|コマンド | vim | emacs |
|---------|-----|-------|
|記録開始 | `q``{レジスタ(a-z0-9")}`     | `C-x` `(` (`start-kbd-macro`)    |
|記録終了 | `q`                          | `C-x` `)` (`end-kbd-macro`)      |
|実行     | `@``{レジスタ(a-z0-9".=*+})` | `C-x` `e` (`call-last-kbd-macro`)|
|編集     | *1  | `C-x` `C-k` (`edit-kbd-macro`)|				  

1. Vimのマクロはレジスタに記録された文字列に過ぎないので、一度それをバッファに展開して編集したあとにレジスタに登録し直します。
  * 追記する場合: `q``{レジスタの大文字(A-Z)}`
  * 編集する場合: レジスタの内容をバッファに表示して編集し、レジスタに書き戻します
      1. `:put {レジスタ(a-z)}`
      2. バッファに貼り付けられたレジスタ内容を編集
      3. `0"{レジスタ(a-z)}y$` (行の先頭にカーソルを移動して、末尾までの内容を任意のレジスタにコピー)
      4. レジスタの内容を確認する場合は `:reg[isters]`


## ヘルプ

|コマンド | vim | emacs |
|---------|-----|-------|
|ヘルプ          | `:h[elp]` | `M-x` `info` |
|キー割り当て一覧| `:map` | `C-h` `b` (`describe-bindings`) |
|キー割り当て確認| `:h[elp]` `{subject}` *1| `C-h` `w` `{command}` `RET` (`where-is`) |
|キー割り当てで<br>実行するコマンドの説明表示|| `C-h` `k` `{keybind}` (`describe-key`) |
|入力文字が含まれるコマンド一覧を表示 || `C-h` `a` `{word}` `RET` (`command-apropos`) |

1. 調べるキーの例(vim)
  * `CTRL-[` (ノーマルモードの `C-[`)
  * `CTRL-W_=` (ノーマルモードの `C-w` `=`)
  * `i_CTRL-X_CTRL-F` (インサートモードの `C-x` `C-f`)
  * `c_CTRL-F` (コマンドモードの `C-f`)
  * `v_>` (ビジュアルモードの `>`)


## その他

|コマンド | vim | emacs |
|---------|-----|-------|
|チュートリアル       | `vimtutor` *1| `<f1>` `t` (`help-with-tutorial`) |
|コマンドの中断       | `<Esc>` | `C-g` (`keyboard-quit`) |
|外部プログラムの実行 | `:!{command}` | `M-x` `{command}` (`shell-command`) |
|ファイラ             | `:Ex[plore]` | `C-x` `d` (`dired`)|

1. `vim` とは別の `vimtutor` を実行します
  * [香り屋版Vim](http://www.kaoriya.net/software/vim/) の場合は `:Tutorial` コマンドを実行します


# 参考資料

* [Vim documentation: help](http://vim-jp.org/vimdoc-ja/)
* [GNU Emacsマニュアル](http://www.bookshelf.jp/texi/emacs-man/21-3/jp/emacs.html)
* 『[実践Vim](http://ascii.asciimw.jp/books/books/detail/978-4-04-891659-2.shtml)』
* 『[Emacs実践入門](http://gihyo.jp/magazine/wdpress/plus/978-4-7741-5002-4)』
* 『[Emacsテクニックバイブル](http://gihyo.jp/book/2010/978-4-7741-4327-9)』