EmacsのショートカットキーをWindows風にカスタム

Emacsのショートカットキーって複雑で覚えるのが大変ですよね？
Windows風にカスタムしましょう！

#はじめに
Emacsのショートカットキーは謎だらけです。
`C-x C-s`でセーブ？ `M-x なんちゃら`？
たくさんありすぎて正直覚えたくない人も多いはず。

`Ctrl+s`でセーブ、`Ctrl+c`でコピー、`Ctrl+x`で切り取りしたいんじゃああああ！っていうEmacs初心者向けに記事を書きます。

また、Emacs初心者が不便だと感じそうな部分もカスタムしていきます。

##前提
私はUbuntuでEmacs 25.2.2を使っています。
この環境で説明していきます。

#準備
Emacsの設定をいじる前に、いろいろと準備をしていきます。ターミナルを開き、コマンドを実行していきましょう。

##Emacsのインストール
そもそもEmacsが入っていないと話にならないので、入っていない人はEmacsをインストールしてください。

```:bash
sudo apt update
sudo apt upgrade
sudo apt install -y emacs
```

##設定ファイルの作成
以下のコマンドを実行して、設定ファイルを作成します。

```:bash
mkdir ~/.emacs.d
mkdir ~/.emacs.d/elisp
touch ~/.emacs.d/init.el
```

一応簡単に説明すると、~/.emacs.d はEmacsの設定ファイルをまとめて置いておくディレクトリです。
~/.emacs.d/init.elはEmacsの設定ファイルです。
~/.emacs.d/elispはEmacs用の便利なパッケージ（拡張機能）を置くための場所です。

##wgetのインストール
インターネット上からファイルをダウンロードするソフトである、*wget* がインストールされているかを確認します。以下のコマンドを実行し、バージョンが表示されるか確認してみてください。

```:bash
wget --version
```

もしバージョンが表示されなければ、以下のコマンドを入力してインストールしましょう。

```:bash
sudo apt update
sudo apt install -y wget
```

##redo+のダウンロード
Emacsで「進む」を実現するための*redo+*というパッケージがあるのですが、これは自動でインストールできないので、以下のコマンドでインストールします。

```:bash
wget https://www.emacswiki.org/emacs/download/redo%2b.el -O ~/.emacs.d/elisp/redo+.el
```

redo+については https://www.emacswiki.org/emacs/RedoPlus を参照してください。

#Emacsのカスタマイズ
ここまで来ればあとは簡単です。
以下の内容を~/.emacs.d/init.elに書き込んでEmacsを再起動するだけで、ショートカットキーWindows風に変更されます！！！

```:~/.emacs.d/init.el

;; 全画面で起動
;; (set-frame-parameter nil 'fullscreen 'maximized)

;; 自動インストールするパッケージのリスト
(defvar my-favorite-package-list
  '(which-key
    company
    flycheck
    tabbar
    tabbar-ruler
    bind-key
    whitespace
    auto-save-buffers-enhanced
    volatile-highlights
    goto-chg
    anzu)
  "packages to be installed")

;; emacsのバグ対策
;; 何故かパッケージの署名を読めないので，無効化する
(setq package-check-signature nil)

;; melpha (packageのリスト)
(require 'package)
(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                    (not (gnutls-available-p))))
       (proto (if no-ssl "http" "https")))
  (when no-ssl
    (warn "\
Your version of Emacs does not support SSL connections,
which is unsafe because it allows man-in-the-middle attacks.
There are two things you can do about this warning:
1. Install an Emacs version that does support SSL and be safe.
2. Remove this warning from your init file so you won't see it again."))
  ;; (add-to-list 'package-archives
  ;;            '("melpa-stable" . "https://stable.melpa.org/packages/") t)
  (add-to-list 'package-archives
               (cons "melpa" (concat proto "://melpa.org/packages/")) t)
  (when (< emacs-major-version 24)
    (add-to-list 'package-archives
                 (cons "gnu" (concat proto "://elpa.gnu.org/packages/")))))
(package-initialize)

;; package自動インストール
(unless package-archive-contents (package-refresh-contents))
(dolist (pkg my-favorite-package-list)
  (unless (package-installed-p pkg)
    (package-install pkg)))


;; ~/.emacs.d/elispにある.elファイルを読み込む
(setq load-path (cons "~/.emacs.d/elisp" load-path))

;; 10秒に一度自動保存する
(require 'auto-save-buffers-enhanced)
(setq auto-save-buffers-enhanced-interval 10)
;; Wroteのメッセージを抑制
(setq auto-save-buffers-enhanced-quiet-save-p t)
(auto-save-buffers-enhanced t)

;; Ctrl+yが使えるようになるパッケージ
(require 'redo+)
(setq undo-no-redo t)    ; 過去のundoがredoされないようにする
(setq undo-limit 600000) ; undoをたくさんできるようにする
(setq undo-strong-limit 900000)

;; キーマップの変更をかんたんにしてくれるパッケージ
(require 'bind-key)

;; キーバインドの候補
(require 'which-key)
(which-key-mode)

;; 自動補完
(require 'company)
(add-hook 'after-init-hook 'global-company-mode) ;; 有効化 
(setq company-idle-delay 0.5) ; デフォルトは0.5
(setq company-minimum-prefix-length 2) ; デフォルトは4
;; 候補の一番下でさらに下に行こうとすると一番上に戻る
(setq company-selection-wrap-around t)
;; タブで補完する．tabでのインデントと共存可能．
;; (global-set-key (kbd "<tab>") 'company-indent-or-complete-common)

;; タブエディタ化
(require 'tabbar)
(tabbar-mode 1)
(require 'tabbar-ruler)
(setq tabbar-ruler-global-tabbar t)
;; タブ上でマウスホイール操作無効
(tabbar-mwheel-mode -1)
;; グループ化しない
(setq tabbar-buffer-groups-function nil)
;; キーに割り当てる (Chromeと同じ設定)
(global-set-key (kbd "C-<tab>") 'tabbar-forward-tab)
(global-set-key (kbd "<C-iso-lefttab>") 'tabbar-backward-tab) ;; C-S-tabのこと

;; 全角スペースを強調
(require 'whitespace)
(set-face-foreground 'whitespace-space "gray")
(set-face-background 'whitespace-space nil)
(set-face-bold-p 'whitespace-space t)
(setq whitespace-style '(face spaces space-mark))
(setq whitespace-space-regexp "\\(\x3000+\\)")
(setq whitespace-display-mappings
      '((space-mark ?\x3000 [?\□])))
(global-whitespace-mode 1)

;; 単語を検索した時に何番目のマッチかを表示
(require 'anzu)
(global-anzu-mode +1)
;; 入力に 1000個以上マッチする場合はそれ以上数え上げを行わない
(setq anzu-search-threshold 1000)

;; ペースト, UNDO, REDOによって増えた場所を強調
(require 'volatile-highlights)
(volatile-highlights-mode t)
(set-face-attribute
 'vhl/default-face nil :background "#FFEEFF")

;;日本語印刷の文字化け回避
(setq ps-multibyte-buffer 'non-latin-printer)
(require 'ps-mule)
(defalias 'ps-mule-header-string-charsets 'ignore)

;; スタートアップメッセージを表示させない
(setq inhibit-startup-message t)

;; スクロールの加速をやめる
(setq mouse-wheel-progressive-speed nil)

;;行間
(setq-default line-spacing 2)

;; タイトルバーにファイルのフルパスを表示する
(setq frame-title-format "%f")

;; 行番号を表示する
(global-linum-mode t)

;; 桁番号をモードラインに表示。
(setq column-number-mode t)

;; カーソルのある行をハイライトする
(global-hl-line-mode t)

;; スクロールは１行ごとに
(setq scroll-conservatively 1)

;; 対応する括弧を表示
(show-paren-mode t)
(setq show-paren-delay 0)

;; tabをスペースに
(setq-default tab-width 4 indent-tabs-mode nil)

;; Emacsからの質問をy/nで回答する
(fset 'yes-or-no-p 'y-or-n-p)

;; 以前開いていた場所の復元(Emacs 25以上)
(when (>= emacs-major-version 25) (save-place-mode 1))

;; バックアップファイルを作成させない
(setq make-backup-files nil)

;; 終了時にオートセーブファイルを削除する
(setq delete-auto-save-files t)

;; シンタックスチェック
(add-hook 'after-init-hook #'global-flycheck-mode)

;; 以下、Windows風キーバインド
;; CUAモードが有効な場合、C-x、C-c、C-v、C-zなどのキーは、
;; カット(kill)、コピー、ペースト(yank)、アンドウのコマンドを呼び出します。
;; C-xとC-cによるカットとコピーは、リージョンがアクティブなときだけ
;; 処理されます。リージョンが非アクティブのときはプレフィクスキーとして
;; 動作するので、C-x C-cのような標準のEmacsコマンドは正常に機能します。
;; 変数mark-even-if-inactiveはC-xとC-cに影響を及ぼさないことに
;; 注意してください(Using Regionを参照してください)。
;; マークがアクティブのときにC-x C-fのようなEmacsコマンドを
;; 入力するには、Shiftを押しながらプレフィクスキーを押す
;; (例 S-C-x C-f)か、プレフィクスキーを素早く2回タイプ
;; (例 C-x C-x C-f)します。
(cua-mode t)

;; 不足部分
(bind-key* "C-y" 'redo)  ;; 進む
(bind-key* "C-a" 'mark-whole-buffer) ;; 全選択
(bind-key* "C-s" 'save-buffer) ;; 保存
;; (bind-key* "C-f" 'isearch-forward-regexp) ;; 検索(正規表現)
(bind-key* "C-f" 'isearch-forward) ;; 検索(正規表現なし版)
(bind-key* "C-h" 'query-replace) ;; 置換
(bind-key* "C-S-s" 'write-file) ;; 名前をつけて保存
(bind-key* [f12] 'write-file) ;; 名前をつけて保存
(bind-key* "C-n" 'find-file) ;; ファイル新規作成
(bind-key* "C-o" 'find-file) ;; ファイルを開く
(bind-key* [C-home] 'backward-page) ;; Ctrl+Homeでページ一番上へ
(bind-key* [C-end] 'forward-page)   ;; Ctrl+endで一番下へ
(bind-key* "C-+" 'text-scale-adjust) ;; 文字拡大
(bind-key* "C--" 'text-scale-adjust) ;; 文字縮小
(bind-key* [M-f4] 'save-buffers-kill-terminal) ;; 終了
(bind-key* "C-g" 'goto-line) ;; 指定行にジャンプ
(bind-key* "C-q" 'goto-last-change) ;; 最終編集場所へジャンプ

;; 検索のとき、f3またはEnterで進む
;; Shift+f3またはShift+Enterで戻る
(define-key isearch-mode-map [S-return] 'isearch-repeat-backward)
(define-key isearch-mode-map [return] 'isearch-repeat-forward)
(define-key isearch-mode-map [S-f3] 'isearch-repeat-backward)
(define-key isearch-mode-map [f3] 'isearch-repeat-forward)

;; packege-elが自動生成するコードの書き込み先・読み込み先を .emacs.d/custom.el に変更
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
  (load custom-file))
```

## ~/.emacs.d/init.elへの書き込み方がわからない人へ

まず、以下のコマンドで~/.emacs.d/init.elをEmacsで開きます。

```:bash
emacs ~/.emacs.d/init.el
```

次に、先ほどの長いコマンドをコピーして、Emacsに貼り付けます。
貼り付けは`Ctrl+y`でできます。

最後に、ウインドウ上部の`Save`ボタンをクリックして内容を保存し、右上の`×`を押してEmacsを閉じます。

#変更点
## ショートカットキー
かなりWindowsに似せました。以下のショートカットキーをEmacsで使えるようになったはずです！

|キー  |動作|
|---|---|
|Ctrl+s |保存|
|Ctrl+Shift+s　または　F12|名前を付けて保存|
|Ctrl+n|新規作成|
|Ctrl+o|ファイルを開く|
|Ctrl+c  |選択範囲のコピー|
|Ctrl+x  |選択範囲の切り取り|
|Ctrl+v  |貼り付け|
|Ctrl+a  |全選択|
|Ctrl+z  |戻る|
|Ctrl+y  |進む（戻るのキャンセル）|
|Ctrl+f  |検索|
|F3　または　Enter |検索結果の次を表示|
|Shift+F3　または　Shift+Enter|検索結果の前を表示|
|Ctrl+h  |置換|
|Ctrl+g|指定行にジャンプ|
|Ctrl+q|最後に編集した箇所へジャンプ|
|Home|行頭へ|
|End|行末へ|
|Ctrl+Home|ファイル先頭へ|
|Ctrl+End|ファイル末尾へ|
|Ctrl++(Ctrlと+の同時押し)|拡大|
|Ctrl+-(Ctrlと-の同時押し)|縮小|
|Ctrl+Tab|タブの移動|
|Ctrl+Shift+Tab|タブの(左への)移動|
|Alt+F4|Emacsの終了|

なお、行が選択されていなければ`C-x`や`C-c`は今まで通りに使えます。つまり、`C-x C-s`などは普通に使えます。
もし選択されている場合は、`S-C-x`や`S-C-c`を使ってください。

##その他の変更点
- タブエディタ化 (tabbar.el, tabbar-ruler.el)
- 10秒に一度の自動保存(auto-save-buffers-enhanced.el)
- キーバインド候補の表示(which-key.el)
- 自動補完(company.el)
- 全角スペースの表示(whitespace.el)
- 検索時にマッチした単語数を表示(anzu.el)
- ペースト, UNDO, REDOによって増えた場所を強調(volatile-highlights)
- 行番号を表示
- カーソルのある行をハイライト
- 対応する括弧を表示
- 以前開いていた場所の復元
- バックアップファイルを作成させない
- シンタックスチェック(flycheck.el)

#最後に
EmacsのショートカットキーがWindowsに似て、親近感が湧いた人が増えてくれると嬉しいです！
Emacsの魅力はこのように自由にカスタマイズできるところにあると思うので、ぜひ自分でもいろいろとカスタムしてみてください！！

##P.S.
内容的にEmacs使いの人に怒られてしまいそうで怖いです。
一応言っておくと、私はアンチEmacsではありません。むしろ毎日Emacsを使っています。
初心者の入門ハードルが少しでも下がって、Emacsユーザの人口が増えることを祈って記事にしました。