Emacs のおすすめ基本設定

Emacs では、何も設定せずに使うと、ビープ音がうるさかったり、 ~(チルダ)がついたファイルがたくさんできてうっとうしかったりと ハッキリいって使いづらいです。 そのため設定はしないといけないのですが、 今度は設定できることが豊富すぎて「何からやればいいのかわからない」といったことにもなります。
そこで、今回は Emacs を使う上で「これだけはやっとけ」という最低限必要なお勧めの設定について紹介したいと思います。

そのまま使える設定ファイル(init.el)を用意し、各設定について説明を書いています。 以前の記事などでより詳しい説明をかいている項目はそのリンクを付けています。

設定ファイル

設定ファイルは以下の init.el をダウンロード(名前をつけて保存)して、 ~/.emacs.d 以下においてください。
なお、 ~(チルダ) はホームディレクトリーを意味しており、環境変数 HOME で指定したディレクトリーです。 ~/.emacs.d がない場合は作成してください。
また、 Emacst は古いバージョンでは ~/.emacs, ~/.emacs.el などのファイルを設定ファイルとして使っていて、 これらのファイルがあると ~/.emacs.d/init.el はロードされないので注意してください。

設定ファイルは一応、 Windows, Linux のどちらでもそのまま使えるようにしているつもりです。また、ある程度古いバージョンでもエラーにはならないようにしてます。
変更もコメントを外したり、数値を変えたりぐらいでできるようにしてますが、設定の内容についてより理解したい場合は 以下の記事をみてみてください。

カスタマイズ

Emacs では GUI 風に設定ができるカスタマイズやメニューから保存すると、 ~/.emacs.d/init.el に設定が書きこまれます。 あまり勝手に書きこまれる部分が混じるのがいやなのと、 ロードのタイミングを調整する必要が出てくることもあるので、 ファイルを分けておくのがお勧めです。
以下の記述により、カスタマイズ内容は "~/.emacs.d/custom_setttings.el" のファイルに書き込まれるようになります。
 ;; カスタマイズ用のファイルを設定
 (setq custom-file "~/.emacs.d/custom_setttings.el")
 
 ;; カスタマイズ用ファイルをロード
 (load custom-file t)
なお、このカスタマイズの設定は、説明は最初にもってきましたが、 設定ファイルでの実際の記述はデフォルトの書き込み位置に合わせて末尾の方にしています。

メニューによる設定

設定のうち、いくつかはメインメニューの [Options] の設定項目から設定できます。

emacs_settings_menu.png

設定後は [Save Options] の項目で変更した内容を保存しておく必要があります。 その際、前章の場所に保存されます。


ちなみにターミナルでメニューを使いたいという場合は M-`(バッククォート) で 擬似的に使用できます。

フォント

Emacs で、まず直したいのはフォントだと思います。これは [Options] → [Set Default font...] の項目で設定します。
Unix 系の場合は利用可能なフォントセット、 Windows ではフォントダイアログが表示され、 選択します。これだと実際に表示を確認してフォントを選べます。

Font dialog

その他のお勧めメニュー項目

その他のメニューから設定できる項目で知っておいた方がいいものをあげます。

項目 説明
Highlight Active Region 選択領域をハイライト表示
Highlight Matching Parentheses 対応する括弧をハイライト
Ignore Case for Search 検索時に大文字、小文字を区別しない
Use Directory Names in Buffer Name ファイルのベース名が同じ場合にモード行にディレクトリー名も表示
Save Place in Files between Sessions ファイルを開くときに前回閉じた時の位置にカーソルを移動
Blink Cursor カーソルの点滅
Show/Hide ツールバー、メニューバーやモードラインの内容などの表示 / 非表示
emacs_settings_menu_sh.png

初期表示位置、サイズ

フォントなど見た目を変更した後は画面の表示位置、サイズを指定します。
Emacs では前回の位置、サイズを覚えてくれませんが、 初期表示位置、サイズは指定することができます。

設定する値は、まず好きな位置サイズに画面(frame)を変更して、 その現在の値を元に決めます。
現在の frame の値は *scratch* バッファで、 frame-parameters を評価すると表示されます。
(frame-parameters) [C-j]

以前の記事ではカスタマイズを使った方法を紹介しましたが、 設定ファイルに直接書くと次のようになります。
 (setq initial-frame-alist
       '((left   . 100)                 ; 位置 (X)
        (top    .  50)                  ; 位置 (Y)
        (width  . 120)                  ; サイズ(幅)
        (height .  40)                  ; サイズ(高さ)
        ))

スクロール量の調整

デフォルトだとスクロールする時、ガクガクと動く感じがするので、その調整です。
 ;; スクロールした際のカーソルの移動行数
 (setq scroll-conservatively 1)
 
 ;; スクロール開始のマージンの行数
 (setq scroll-margin 10)
 
 
 ;; 1 画面スクロール時に重複させる行数
 (setq next-screen-context-lines 10)
 
 ;; 1 画面スクロール時にカーソルの画面上の位置をなるべく変えない
 (setq scroll-preserve-screen-position t)

日本語文字コードの設定

Emacs ではファイル、ファイルパス、コマンド実行など細かく文字コードを設定することができます。

文字コードは基本的に言語環境を設定すれば、 Windows だと Shift-JIS というようにデフォルトを設定してくれます。
それでうまくいかない場合や別のコードにしたい場合には prefer-coding-system で指定すると文字コードをまとめて変更します。
 ;; 環境に合わせた日本語文字コードに設定
 ;;  Windows => SJIS
 ;;  Linux => 環境変数 LANG から
 (set-language-environment "Japanese")
 
 ;; set-language-environment でうまくいかない場合に設定
 ;; (setq prefer-coding-system 'utf-8)
また、 BOM 付き UTF-8 などファイル作成時のデフォルト文字コードだけ変えたい場合には buffer-file-coding-systemsetq-default で指定します。
なお、 buffer-file-coding-systemバッファーローカル変数といって、 バッファー(開いているファイル)ごとに別々の値をとります。 そのため、setq ではカレントバッファーの値しか変わらないので、setq-default で指定しなければなりません。
 ;; ファイルの文字コードだけ別に指定したい場合に設定
 ;; (setq-default buffer-file-coding-system 'utf-8-with-signature) ; BOM 付き UTF-8
なお、上記のリンク先でも説明していますが、オプションの言語の設定でも文字コードが変わります。 そのため、文字コードはカスタマイズの後(一番最後)に記述しています。

キーカスタマイズ

自分好みにキーを設定するのが Emacs の醍醐味なのですが、 ここでは最小限のものだけ書いています。

キーバインディングを自分好みに変えたい場合は以前の記事を参考にしてください。

Window での IME キー

Windows の IME を使えるようにした Emacs を使う場合、 [変換] や [半角/ 全角] キーを押すと エラーがうるさいです。それを抑制するための設定です。
 ;; Windows の場合、 IME の変換でエラーがでないようにする
 (when (eq system-type 'windows-nt)
   (global-set-key [M-kanji] 'ignore)
   (global-set-key [kanji] 'ignore)
   )

ターミナルでの C-h

Emacs は GUI だけでなく、ターミナル上の CUI としても動作します。
ただ、ターミナルで問題になるのは [Back space]C-h と同じキーコードであり、 Emacs では C-h がヘルプ用のキーになっている点です。
 ;; ターミナルの場合(window-system が nil)、
 ;; <backspace> が C-h になるので、 C-h で <delete> (C-?) が押されたことにする
 (unless window-system
   (keyboard-translate ?\C-h ?\C-?))
 ;; C-h 以外もヘルプキーに割り当て
 (global-set-key (kbd "M-?") 'help-command)
上記の設定ではターミナルの場合は C-h[Delete] のキーを入れ替えを行っています。
また、 ヘルプのキーを M-? にも割り当ています。これはターミナルかどうかにかかわらず、使えるようにしています。

検索、置換時の大文字、小文字の区別

検索や置換の際、大文字、小文字を区別するかどうかのお勧め設定です。
検索の最初の二つの項目は、 メニューのは [Ignore Case for Search] を有効にした場合と同じです。
 ;; オプションの "Ignore Case for Search" で設定可
 ;;
 ;; ;; 検索(全般)
 ;; (setq case-fold-search t)
 ;;
 ;; ;; インクリメンタルサーチ
 ;; (setq isearch-case-fold-search nil)
 
 
 ;; バッファー名の検索
 (setq read-buffer-completion-ignore-case t)
 
 ;; ファイル名の検索
 (setq read-file-name-completion-ignore-case t)
 
 
 ;;;置換(全般)
 ;; (setq case-replace t)
 
 ;; dabbrev 時の置換
 (setq dabbrev-case-replace nil)
検索に関しては大文字、小文字しないようにしておいても、区別しないのは検索文字がすべて小文字の場合だけで、 大文字を混ぜるとちゃんと区別してくれます。 そのため、検索では大文字小文字は区別はしない(無視する)ようにしておくのがお勧めです。

置換の挙動に関しては、一言ではいいづらいので、以前の記事をみてください。

自動作成ファイル

編集すると、デフォルトではバックアップファイルという~(チルダ)の付いたファイルができてしまい、これが結構うっとうしかったりします。
Emacs ではバックアップファイル以外にも自動で作成するファイルがあり、それらを次のように設定します。
  • バックアップファイルは一カ所(~/.ehist)にまとめて作成
    • 履歴もつけて
  • 自動保存ファイルは作成
    • デフォルトで作成するけど、タイミングは調整
  • 自動保存リスト、ロックファイルは作成しない
なお、バックアップファイルをおく "~/.ehist" はディレクトリーを作成していないと作らないので、 ディレクトリーは作成してください。
;; backup ファイルオープン時のバックアップ (xxx~)
;; -------------------------------------------

;; 実行の有無
(setq make-backup-files t)

;; 格納ディレクトリーの変更
;;   (対象ディレクトリー . 格納ディレクトリー) のリスト
(setq backup-directory-alist '((".*" . "~/.ehist")))


;; 番号付けによる複数保存
(setq version-control     t)  ;; 実行の有無
(setq kept-new-versions   5)  ;; 最新の保持数
(setq kept-old-versions   1)  ;; 最古の保持数
(setq delete-old-versions t)  ;; 範囲外を削除



;; auto-save 自動保存ファイル (#xxx#)
;; -------------------------------------------

 ;; ;; 実行の有無
 ;; (setq auto-save-default nil)
 
 ;; ;; 格納ディレクトリーの変更
 ;; ;;   (対象ファイルのパターン . 保存ファイルパス) のリスト
 ;; (setq auto-save-file-name-transforms
 ;;       (append auto-save-file-name-transforms
 ;;            '((".*" "~/tmp/" t))))
 
 
 ;; 保存の間隔
 (setq auto-save-timeout 10)     ;; 秒   (デフォルト : 30)
 (setq auto-save-interval 100)   ;; 打鍵 (デフォルト : 300)
 
 
 
 
 ;; auto-save-list 自動保存のリスト  (~/.emacs.d/auto-save-list/.saves-xxx)
 ;; --------------------------------------------------------------------
 
 ;; 実行の有無
 (setq auto-save-list-file-prefix nil)
 
 ;; ;; 格納ディレクトリーの変更
 ;; (setq auto-save-list-file-prefix "~/tmp/.saves-")
 
 
 
 ;; lock ロックファイル (.#xxx)
 ;; -------------------------------------------
 
 ;; 実行の有無
 (setq create-lockfiles nil)

パッケージ管理

Emacs にはパッケージ管理機能がついており、 ネット上からパッケージを取得、インストールすることができます。 その取得先のサイトのデフォルトは "http://elpa.gnu.org/packages/" ですが、ここだけだとパッケージの数が少ないです。
以下で取得先サイトの追加とパッケージ管理の初期化を行っています。
 (when (require 'package nil t)
   (setq package-archives
        (append package-archives '(("melpa" . "http://melpa.milkbox.net/packages/")
                                   ("marmalade" . "http://marmalade-repo.org/packages/"))))
   (package-initialize))

auto-complete

お勧めのパッケージもいっぱいあって、また別の機会にと思っているのですが、 auto-complete は便利さが別格なので、ここで設定を書いておきます。
ちなみに設定はインストール前でもエラーはでないようにしています。
 (when (require 'auto-complete-config nil t)
   (ac-config-default))
パッケージ管理で次の 2 つを入れてください。
  • auto-complete
  • ac-dabbrev
auto-complete は言語モード別など多くの拡張用パッケージもあります。
そのうちの一つである ac-dabbrev は auto-complete から dabbrev を使えるようにするパッケージで、 これで便利さが少し理解してもらえるのではないかと思います。

ロードパスの設定

Emacs に機能を追加する場合、パッケージを追加するのですが、 パッケージに対応していないものも結構あります。
こういった場合、 load-path に登録されたディレクトリーに Emacs Lisp のファイルをおいて、ロードします。

以下は "~/.emacs.d/site-lisp" を load-path に追加するコードです。 ファイルを追加する場合は "~/.emacs.d/site-lisp" のディレクトリーを作成し、そこにおくようにしてください。
 (add-to-list 'load-path "~/.emacs.d/site-lisp")
 
 ;; ;; load-path に登録されたディレクトリーを subdir 扱い
 ;; ;;   注:アクセス件でエラーになりやすい
 ;; (normal-top-level-add-subdirs-to-load-path)
"site-lisp" というディレクトリー名は Emacs で外部ファイルをおく場所として、慣例的に使われている名前です。 ただ、元から用意されている site-lisp ではサブディレクトリーを含めてロード時の検索対象となります。
ロードパスに追加しただけだと、そのディレクトリーだけですが、 normal-top-level-add-subdirs-to-load-path を実行するとサブディレクトリーも対象になります。

ただ、 Unix など一部の環境では、この関数を init.el で実行するとエラーがでる場合があります。
サブディレクトリーも含めたい場合、エラーがでないならば、コメントを外すだけいいですが、 エラーの場合は以下のファイルを作成した site-lisp のディレクトリーにおくようにしてください。

自作ファイルのロード

Emacs Lisp ファイルのロードは、ダウンロードしたファイルだけでなく、 自分の書いた設定ファイルを分割したりする場合にも使います。 設定が多くなってくると設定ファイルは分割した方が管理しやすく、余分なバイトコンパイルも減らせます。

ロードパスの利用のサンプルとして私のキー設定ファイルのロードも記述しています。
以下のファイルを "~/.emacs.d/site-lisp" におき、コメントアウトを外してください。
 ;; ;; キー設定ファイルのロード
 ;; (load "my-keyset-light")
なお、require でロードする場合は、ロードされる側のファイルもちょこっと対応がいるため、 load の方を使っています。

プログラミング用設定

プログラミング用モードは言語ごとにあり、最小限というのが難しいので、 C, C++ 系の設定を中心に少しだけ紹介したいと思います。

共通

C, C++, Java, C# など C 系統の言語は cc-mode をベースとして作成されています。 cc-mode のうち便利な機能のいくつかが他のモードでも使えるようになりました。
機能 機能名
がっつり削除 hungry-delete
自動インデント electric-indent, c-elecric-state
自動改行 electric-layout, c-auto-newline
タブキーの挙動の変更 tab-always-indent


これらの機能は基本的に全部使うのがお勧めです。
ただ、自動改行は { ; などの特殊キーを押すと改行する機能ですが、 インデントのスタイルなどをちゃんと設定していないと、 逆に邪魔なので、コメントアウトしています。
また、自動改行は改行時にインデントも行う機能ですが、 こちらも勝手に有効にするような機能ではありませんが、 デフォルトで有効なため、無効にする設定を記述しています。
;; 共通
;; ================================================================

;; 左端(文字の前)ではインデント、それ以外はタブの挿入
(setq tab-always-indent nil)
(setq c-tab-always-indent nil)
 
 ;; 空白を一度に削除
 (if (fboundp 'global-hungry-delete-mode)
     (global-hungry-delete-mode 1))
 
 ;; 改行時などに自動でインデント 
 ;;   (C-j と C-m の入れ替え)
 (if (fboundp 'electric-indent-mode)
     (electric-indent-mode 0))
 
 ;; 特定の文字を入力すると自動で改行、インデント
 ;; (electric-layout-mode 1)
 
 
 ;; C 系共通
 ;; ================================================================
 
 (defun my-all-cc-mode-init ()
   ;; C 系(cc-mode を継承した)モード共通の設定を記述
 
   ;; 空白などを一度に削除
   (c-toggle-hungry-state 1)
 
   ;; 改行時などで自動インデント
   ;; (c-toggle-electric-state 1)
   ;; 
   ;; ";", "}" などを入力したときに自動改行
   ;; 自動インデントも一緒に ON になる
   ;; (c-toggle-auto-newline 1)
 
   )
 (add-hook 'c-mode-common-hook 'my-all-cc-mode-init)

モード別の設定とインデント

モード別に設定を行う場合はホックを使って設定します。
基本はモード毎に設定すればいいのですが、 C, C++ のモードでは同じ設定をすることが多いので、 次のように共通する関数を定義して、それぞれホックに追加します。
なお、前節の c-mode-common-hook では、 cc-mode を元にしたすべてのモードでホックが実行されます。 そのため、 Java, C# などのモードでも実行されるため、 別途していていた方がよいです。
 (autoload 'vs-set-c-style "vs-set-c-style"
   "Set the current buffer's c-style to Visual Studio like style. ")
 
 (defun my-c-c++-mode-init ()
   ;; C, C++ 用の設定を記述
   
 
   ;; Visual Studio 風の設定
   ;; (vs-set-c-style)
   )
 (add-hook 'c-mode-hook 'my-c-c++-mode-init)
 (add-hook 'c++-mode-hook 'my-c-c++-mode-init)
C, C++ モードではインデントなどのルールをちゃんと設定しておかないと使いづらいです。
コメントアウトしていますが、 Visual Studio 風でよければ簡単に設定できるようにしています。 詳しくは以下のリンクを見てください。

ファイル判定の追加

ファイルに対してどのモードになるのかというのは、auto-mode-alist で管理されています。 auto-mode-alist は ("正規表現" . モード) のコンスセルのリストです。

メジャーな言語のモードはあらかじめ設定されていますし、 パッケージで追加した場合も自動で追加されるので、基本的に自分で変更する必要はありません。
ただ、設定されていなかったり、変えたい時もあるので、 C++ の変更を参考がてら記述しています。


C++ のヘッダーファイルは ".h" を使うことが多いですが、 これは C 言語でも使うので、 デフォルトではヘッダーを開くと C 言語用のモードになってしまいます。
これを ".h" で C++ モードにする設定です。
 ;; .h でも C++
 (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
auto-mode-alist に .h なら c++-mode という要素を追加しています。
add-to-list は先頭に要素を追加する関数です。 リストの先頭から一致するかの判定を行うので、この要素で先にマッチし、 C++ 用のモードになるという仕組みです。 ファイルの判定には正規表現を使っています。
"." は正規表現で任意の文字に特殊文字なので、 エスケープの "\" を付けています。文字列ですので、さらにエスケープが必要で "\\." となっています。
"\\`" は文字列の末尾を表します。 これは "$" でもかまいません。正確には "$" は行末ですが、ファイル名に改行が入ることはないので、同じことになります。

Tips

最後に、残りの一行で終わるようなちょっとしたおすすめ設定をまとめてみました。 とはいえ、ビープ音の禁止など必須のような設定も入っています。

ビープ音禁止
デフォルトのままだとすぐベル音がブッブッとなってうるさいです。 そのベル音をならないようにします。
 ;; ビープ音禁止
 (setq ring-bell-function 'ignore)

スタート画面(メッセージ)の非表示
Emacs を起動すると最初にスタートメッセージを表示する画面になります。
これを表示しないようにするには inhibit-startup-screen を t に設定します。 ちなみに inhibit-startup-message でも設定できます。これはただの alias なので、どちらを使っても同じです。
 ;; スタート画面(メッセージ)を表示しない
 (setq inhibit-startup-screen t)
選択領域を削除キーで一括削除
Windows のアプリのように、領域選択時に [Back space][Del] などの削除キーで、一括削除できるようになります。
慣れてる人は「カット(C-w)でいいやん」と思うかもしれませんが、ただ削除する目的なら kill-ring を使用しない分、メモリー的にお得です。
 ;; 選択領域を削除キーで一括削除
 (delete-selection-mode t)
shift + 矢印キーで領域選択
こちらも Windows っぽく、 shift + 矢印キーで領域選択できるようになります。
なお、最近のバージョンではデフォルトでできるようになっているので、定義されているかチェックしてから実行しています。
 ;; shift + 矢印キーで領域選択
 (if (fboundp 'pc-selection-mode)
     (pc-selection-mode))
行頭 kill-line で一行全カット
kill-line (C-k) を実行するとカーソル位置から行末までがカットされます。
これを行頭で行う時は行全体をカットしたい時が多いのですが、空行が残ってしまいます。 それを残らないようにする設定です。
 ;; 行頭 kill-line (C-k) で行全体をカット
 (setq kill-whole-line t)
読み取り専用でカット
Emacs には矩形領域でコピペする機能があります。
ただ、矩形領域に対してはなぜかカットはあるのに、コピーはありません。 そのため、読み取り専用のバッファーでは使えなくなります。

そういった場合など読み取り専用でカット系のコマンドを行うとコピーとして処理する設定です。 ただし、すべてのカット系のコマンドがこの変数に対応しているわけではありまえん。
 ;; 読み取り専用バッファーでもカット系でコピー可能
 (setq kill-read-only-ok t)

ediff
Emacs の差分表示機能(ediff)際に別フレームを使わずにする設定です。 ediff を使う場合には必須の設定ではないかと思います。
 ;; ediff 時にフレームを使わない
 (setq ediff-window-setup-function 'ediff-setup-windows-plain)
なお、以前の記事の説明ではカスタマイズによる設定方法で説明していましたが、そのまま使えるように init.el に書くコードにしています。
Emacs で画像表示
Emacs には png, jpg などのファイルを開くと画像を表示する機能があります。ただし、デフォルトでは有効になっていないので、これを有効にします。
 ;; png, jpg などのファイルを画像として表示
 (setq auto-image-file-mode t)



スポンサーサイト
 

私の Emacs キーバインドの紹介

Emacs のデフォルトのキーバインドって非常に押しづらい上に覚えづらいです。
でも、それって大した問題ではありません。 Emacs は自分好みにキー設定をいじれるところに醍醐味があります。 しかも、他のエディタでは設定できないようなトリッキーな設定も可能です。
そこで、今回は私が使っている Emacs のキー設定を紹介したいと思います。 誰でも気に入るようなものではありませんが、ハマると Emacs 以外のエディターでは満足できなくなるのは請け合いです。

なお、 Emacs でキーバインドを設定する場合、 Emacs Lisp の知識が必要になってきます。 キーの設定方法などもっとよく知りたい場合は、以前の記事を参考にしてください。

特徴

私のキー設定の最大の特徴は使わない文字を一つつぶし、それを使ったストロークでコマンドを実行することです。

使わないキーとしては "@" にしています。 メールアドレスなどでは使われますが、メールアドレスも 「使われてない文字」というのが選ばれた理由です。

この @ の後の組み合わせでコマンドを実行します。 例えば、 @ k で kill-line(C-k)、 @ s で「保存」 save-buffer(C-x C-s) という感じです。


Emacs ではほとんどのキーが割り当て済みですが、これだと既存の割り当てはほぼそのままで、 自分がわかりやすいように設定することができます。
また、 Ctrl キーなどと組み合わせる必要もないため、 個人的にはモードの変更無しで、 Vim のような操作性を実現できているのではないかと思います。

ただ、これはカーソル移動のように続けて押す必要があるものには向いていないため、 基本的に「保存」のように一回で終わるコマンドに割り当てています。

設定ファイル

私のキーバンドを使ってみたいという場合は以下のファイルを load-path の通ったところにおいて、 ロードしてください。
(load "my-keyset-light")
キーバインドを結構いじっていると、よその Emacs を使うと異常に使いづらくなります。 私が本当に普段使っている設定はインストールしたパッケージや自作の関数などもあり、実はもっと複雑になっています。
このファイルは短期的に使う場合などにファイル 1 つ持ってくるだけで、ある程度キー設定を近づけるために作成したものです。 私の普段のキー設定からデフォルトで使える基本的なコマンドだけ抜き出しています。

Windows における Emacs 外部でのキー設定

Windows 環境では Emacs のキー設定だけでなく、定番のキー設定アプリを使った変更も行っています。
  • ChgKey
    • 左 [Ctrl] <--> [Caps Lock]
    • [Esc] <--> [半角]
    • [無変換] -> [Back Space]
  • AltIME
    • [変換] キーでの IME の ON/OFF
[Caps Lock] 、 [Esc] キーの入れ替えは Emacs を使うなら基本です。
ただ、この 2 つだけだったら、 AltIME だけでもできるのですが、 ポイントは [無変換] を [Back Space] にしている点です。 [無変換] は押しやすい場所にあるわりにほとんど使ってません。 そこでよく使う割に遠い [Back Space] にしています。


AltIME の方は何に使っているかというと [変換] で IME を OFF にするためです。 [変換] で ON にはできますが、 OFF にするのが Alt + [半角] って めんどくさいです。 AltIME を使って簡単に切り替えられるようにしています。

カーソル移動

矢印キーはホームポジションから遠いところにあり、当然そんなキーは押しません。 とはいえ、 デフォルトの Emacs のカーソル移動のコマンドの割り当てもわかりづらいです。

デフォルト:
                          前の行 ↑ C-p
                               :
                               :
前の文字 ← C-b   ....   現在のカーソル位置   ....   次の文字 → C-f
                               :
                               :
                          次の行 ↓ C-n


p,n,f,b のキーが、上下左右を表すこともあるので、あまり変えるのもよくありません。
そこで、カーソル移動では、上下は C-pC-n のままにしておいて、 特にわかりづらい 左右の移動は C-kC-lにしています。
以下のように記述すると C-kC-l を押すとそれぞれ C-bC-f が押されたことになります。
 ;; 上下は C-p, C-n (そのまま)
 ;; 左右は C-k, C-l 
 (global-set-key "\C-l" "\C-f")
 (global-set-key "\C-k" "\C-b")
これでダイヤモンドキー配列とまで行きませんが、なんとなくイメージしやすい形になっています。


変更後:
                          前の行 ↑ C-p
                               :
                               :
前の文字 ← C-k   ....   現在のカーソル位置   ....   次の文字 → C-l
                               :
                               :
                          次の行 ↓ C-n
emacs_keybind_move.png

あまり使わないコマンドの割り当て

「キーバインディング」の記事でも書いていますが、あまり使わないコマンドに割り当てられているキーと Function キーの割り当てです。
 ;; あまり使ってないキーの割り当て
 
 (global-set-key "\C-o" 'dabbrev-expand)
 (global-set-key "\C-z" 'undo)
 ;; F7  コンパイル
 ;; F8  eshell
 
 (global-set-key (kbd "<f7>") 'compile)
 (global-set-key (kbd "<f8>") 'eshell)

あまり使用しない文字(@)との組み合わせ

ここから @ キーとの組み合わせによる設定について記述します。


まず、変更などをやり易いようにキーマップを作って、@ キーに割り当てています。
(defvar my-atkey-prefix (kbd "@"))

(setq my-atkey-map (make-keymap))
(define-key global-map my-atkey-prefix my-atkey-map)

(defun my-set-key-atkey-map ()
  (local-set-key my-atkey-prefix my-atkey-map))
(add-hook `hexl-mode-hook 'my-set-key-atkey-map)
(add-hook `view-mode-hook 'my-set-key-atkey-map)
(add-hook `ediff-keymap-setup-hook '(lambda ()
                                      (define-key ediff-mode-map my-atkey-prefix my-atkey-map)))
global-map に割り当てるだけだとモードによっては割り当てられないので、特殊なモードには個別に割り当てています。
個別の設定をしないようにするには C-t などに割り当てた後、 keyboard-translate で入れ替えるといった方法もあります。 ただ、今回はキーを 2 つもつぶすのはどうかなと思ってやめています。



作成したキーマップに対してコマンドをずらずらっと割り当てています。
どんなキーに割り当てられているコマンドが良く分からない方は、 以前に書いた記事で紹介したコマンドと順番がだいたい同じなので、そちらを参考にしてください。
;; ヘルプ
(define-key my-atkey-map "h" 'help-command)


;; カーソル移動
(define-key my-atkey-map "a" 'beginning-of-line)
(define-key my-atkey-map "e" 'end-of-line)

(define-key my-atkey-map "p" 'beginning-of-buffer)
(define-key my-atkey-map "n" 'end-of-buffer)

(define-key my-atkey-map "l" 'recenter)
(define-key my-atkey-map "j" 'goto-line)


;; コマンド呼び出し
(define-key my-atkey-map " " 'execute-extended-command)



;; ファイル
(define-key my-atkey-map "f" 'find-file)
(define-key my-atkey-map "s" 'save-buffer)
(define-key my-atkey-map "w" 'write-file)
(define-key my-atkey-map "F" 'set-buffer-file-coding-system)

;; バッファー
(define-key my-atkey-map "d" 'kill-buffer)
(define-key my-atkey-map "b" 'switch-to-buffer)
(define-key my-atkey-map "\C-b" 'list-buffers)

;; Window
(define-key my-atkey-map "o" 'other-window)
(define-key my-atkey-map "2" 'split-window-vertically)
(define-key my-atkey-map "1" 'delete-other-windows)
(define-key my-atkey-map "." 'delete-other-windows)
(define-key my-atkey-map "0" 'delete-window)



;; クリップボード
(define-key my-atkey-map "c" 'kill-ring-save)
(define-key my-atkey-map "x" 'kill-region)
(define-key my-atkey-map "k" 'kill-line)

;; Ctrl-x r
(define-key my-atkey-map "r" ctl-x-r-map)
(define-key my-atkey-map "C" 'copy-to-register)
(define-key my-atkey-map "y" 'insert-register)


;; 検索、置換
(define-key my-atkey-map "m" 'isearch-forward)
(define-key my-atkey-map "u" 'isearch-backward)
(define-key my-atkey-map "q" 'query-replace)
(define-key my-atkey-map "5" 'query-replace-regexp)


;; プログラミング
(define-key my-atkey-map "\t" "\M-\t")
(define-key my-atkey-map "t" 'indent-region)
(define-key my-atkey-map ";" 'comment-region)


;; キーボードマクロ
(define-key my-atkey-map "8" 'kmacro-start-macro)
(define-key my-atkey-map "9" 'kmacro-end-macro)
(define-key my-atkey-map "7" 'kmacro-end-and-call-macro)



;; その他
(define-key my-atkey-map "+" 'make-directory)
(define-key my-atkey-map "z" 'suspend-frame)


;; 占有したキーの代替
(define-key my-atkey-map my-atkey-prefix '(lambda () (interactive) (insert "@")))
最後の割り当てで、"@" の文字を入力したい場合は 2 回押すことで入力できるようになっています。




 

自動インデントなど C, C++ 系モード以外でも使えるようになった Emacs 機能の設定

Emacs では C, C++ を始め、 Java 、 JavaScript 、 C# などのモードは cc-mode を元に作られています。 これらの言語はよく使われるせいか cc-mode には自動改行など便利な機能がたくさんあります。
そういった機能を使うのに慣れていると他の言語の編集中にめんどくさいなと思うことがよくあります。 そう思う人は多いようで、 Emacs のバージョンがあがって、他の言語モードでも使えるように格上げ(?) された機能があります。
今回はそんな C 系モード以外でも使えるようになった機能のいくつかを設定方法を含めて紹介したいと思います。

紹介する機能はモード行で "/lah" 表示されている 3 つとタブを押した時の挙動の設定です。
機能 機能名
がっつり削除 hungry-delete
自動インデント electric-indent, c-elecric-state
自動改行 electric-layout, c-auto-newline
タブキーの挙動の変更 tab-always-indent


なお、これらの機能は基本的に C 系モードではそちらの設定が使われます。 そのため、設定方法については一般、 C 系モードの両方について説明しています。

変数設定の注意点

各機能の設定方法の前に注意点をいくつか説明しておきます。

バッファーローカル変数

変数には Emacs 全体で同じ値を使う通常の変数とバッファー毎に違った値を保持できる バッファーローカル変数があります。
バッファーローカルな変数は setq などでそのまま設定しても意味がありません。 ホックを使って、バッファーを開いた時に設定する必要があります。

C 系モードすべて
 (defun my-all-cc-mode-init ()
   ;; C 系(cc-mode を継承した)モード共通の設定を記述
 
   (setq tab-width 8)
   )
 (add-hook 'c-mode-common-hook 'my-all-cc-mode-init)
C, C++ モード
(defun my-c-c++-mode-init ()
  ;; C, C++ 用の設定を記述  

  (setq tab-width 4)
  )
(add-hook 'c-mode-hook 'my-c-c++-mode-init)
(add-hook 'c++-mode-hook 'my-c-c++-mode-init)
バッファーローカル変数に対して、 Emacs で共通した値を設定することもできます。 正確にいうとバッファーローカル変数のデフォルト値を指定する感じです。
それには次のカスタマイズで設定するか、 setq ではなく setq-default などで設定します。
(setq-default tab-width 8)

カスタマイズ

Emacs では GUI 風に設定が可能なカスタマイズという機能があります。
これを使用する場合、 M-x customize-option の後に設定したい変数名を指定して起動します。 なお、前節でも触れたようにカスタマイズで設定した値はバッファーローカルにならないということも注意する必要があります。

トグル系の有効/無効の指定

変数で機能の ON/OFF を設定する場合、通常 t, nil を使います。
これがモードの有効/ 無効など関数で指定する場合、 1, 0 を使って設定します。 1 と t はどちらでもよいのですが、 nil を指定すると、 ON/OFF の切り替えになるため、 OFF にするには 0 を指定します。
 (c-toggle-hungry-state 1) ;; 有効
 (c-toggle-hungry-state 0) ;; 無効

がっつり削除 (hungry-delete)

まずは分かりやすい機能から説明します。
コーディングの場合、インデントや空行などを大量に使います。 がっつり削除(hungry-delete) の機能を使うと [Back Space][Delete](C-d) で スペース、タブ、改行の空白文字をまとめて一気に削除します。

emacs_hungry_delete.png


この機能に慣れてしまうと、他の言語での削除がかなりタルく感じます。実際、私は我慢できず自分で削除用の関数を作って使っていました。
今ではそんなことをしなくても、一行設定を書くだけでどのモードでも使えるようになっています。

この機能を有効にする場合、バッファーローカルな機能なので、各モードのホックで (hungrry-delete-mode 1) の記述を行います。
ただ、できて困るものでもないですし、全モードで有効にした方が簡単です。そういった場合、 init.el に以下の記述を行います。
(global-hungry-delete-mode 1)
ただし、 C 系モードの場合、そちらの設定が使われるため、別途設定する必要があります。 こちらは C 系共通のホックなどに以下の記述を行います。
(c-toggle-hungry-state 1)
C 系モードではこの hungry-delete 機能が有効になっているとモード行に "/h" が表示されます。

C 系モードでの自動インデント、自動改行

C 系モードでの自動インデント、自動改行の機能について説明します。 この 2 つは設定変更時に連動することが多く、セットで使うと覚えておいた方が簡単です。

自動インデント(c-electric-state)は、改行や { などのキーを入力した時に インデントも自動で行う機能です。
有効時には "/l" が付きます。

自動改行(c-auto-newline)は、 {; などのキーを入力した時に 自動で改行を行う機能です。
有効時には "/a" が付きます。

emacs_electric_state.png


有効にする場合は C 系共通のホックなどで以下を記述します。
(c-toggle-auto-newline 1)
これらの機能は非常に便利です。 ただ、有効に利用するにはスタイル、インデント量などをちゃんと設定しておく必要があります。

自動インデント (electric-indent-mode)

C 系モードの自動インデントの機能は 24.4 のバージョンで Emacs 全体で使えるようになり、 しかもデフォルトで有効になっています。 ただ、これがかなりタチが悪いです。

機能は C 系と同じような感じで改行や特定の文字(electric-indent-chars で指定)で自動でインデントします。
問題なのは C-j[Return](C-m) が入れ替えられるということです。 もともと C-j に "改行してインデント" という機能が割り当てられたいるのですが、これを入れ替えることによって 改行時のインデントが実現されています。

C-j での改行に慣れている人間にとっては、これがめちゃくちゃ邪魔で、「何勝手なことしてるんだ」って気がします。 ということで、この機能を無効にします。
無効にする場合には以下の記述を init.el に追加します。 この機能はバッファーローカルではないので、ホックで記述する必要もありません。
(electric-indent-mode 0)
ただ、今まで "リターンで改行して、タブでインデント" とやっていた人にとっては 便利だと思うので、そのままでもいいかもしれません。

自動改行 (electric-layout-mode)

Emacs 全体での自動改行の機能は electric-layout-mode です。 こちらは特定の文字を入力すると自動で改行を行います。

これを有効にする場合は以下の記述をします。こちらもバッファーローカルではありません。
(electric-layout-mode 1)
しかし、これは設定してもそのままでは特に何もかわりません。 というのも改行を挿入する文字は electric-layout-rules で設定するのですが、 ここに何も設定されていないからです。
こういうは言語のモード作成者側で設定するようなものだと思うので、 これからの機能ではないかと思います。



とはいえ、一応、設定方法も紹介しておきます。

electric-layout-rules は (対象文字 . 改行位置) のコンスセルのリストで設定します。 改行位置は befor(前)、 after(後)、 around(前後) などで指定します。

C 系の言語以外だとあまりこの機能が役立つものを思いつかないのですが、 唯一使っている CMake モードの設定を例としてあげます。
以下の記述で ")" の文字を入力すると改行するようになります。
 (add-hook 'cmake-mode-hook '(lambda ()
                              (setq-local electric-layout-rules '((?\) . after)))
                              ))
ここで注意点ですが、 electric-layout-rules はバッファーローカルではありません。
そのため、ホックに書いたからといって普通に setq で設定すると、全モードで ")" で改行するようになります。 それだと問題なので、 setq-local を使って、バッファーローカルにして値を設定しています。


この手の変数は明らかにバッファーローカルにしておくべきです。 しかし、"モード毎に設定が必要な変数" に対する Emacs の方針が、"バッファーローカルな変数を必要な場合に setq-defalut などで設定する" から "通常の変数としておいて setq-local で設定する" というように変わってきたのかもしれません。
ただ、自動インデントのことも考えると electric.el を書いた人が「単にどうかしている」という可能性も捨てきれません。

[Tab] キーの挙動の変更 (tab-always-indent)

Emacs では基本 [Tab] キーはインデントで、 本当にタブを挿入したい場合、 C-q [Tab]M-i を使います。
これだとタブ挿入したい場合にめんどくさいのですが、 tab-always-indent の設定を変えると、 挙動を変えることができます。

動作
t 常にインデント (デフォルト)
nil 左端(文字の前)ではインデント、それ以外はタブの挿入
t, nil 以外 コメント、文字列などではタブ、それ以外はインデント

nil を設定しておくのが一番使いやすいのではないかと思います。

emacs_tab_always_indent.png


こちらも C 系モード用の両方を設定する必要があります。
 (setq tab-always-indent nil)
 (setq c-tab-always-indent nil)
これらの変数はバッファーローカルではないため、そのまま設定ファイルに記述できます。

設定の記述

最後に今までの項目をまとめた設定を記述しておきます。
自動改行はスタイルなどをちゃんと設定していないと逆に邪魔なのでコメントアウトしていますが、 設定をして、有効に変えた方がよいです。
 ;; がっつり削除
 (global-hungry-delete-mode 1)

 ;; 改行時などの自動インデント(C-j と C-m の入れ替え)を禁止
 (electric-indent-mode 0)
 
 ;; 特定の文字を入力すると自動で改行
 ;; (electric-layout-mode 1)
 
 ;; 左端(文字の前)ではインデント、それ以外はタブの挿入
 (setq tab-always-indent nil)
 (setq c-tab-always-indent nil)
 
 
 
 ;; C 系(cc-mode を継承した)モード共通の設定を記述
 (defun my-all-cc-mode-init ()
 
   ;; がっつり削除
   (c-toggle-hungry-state 1)
 
   ;; ";", "}" などを入力したときに自動改行
   ;; 自動インデントも一緒に ON になる
   ;; (c-toggle-auto-newline 1)
 
   )
 (add-hook 'c-mode-common-hook 'my-all-cc-mode-init)
 
 
 ;;  C, C++ モードのみで有効にしたい場合はこちらに記述
 (defun my-c-c++-mode-init ()
   ;; C, C++ 用の設定を記述  
 
   )
 (add-hook 'c-mode-hook 'my-c-c++-mode-init)
 (add-hook 'c++-mode-hook 'my-c-c++-mode-init)
 
このページをシェア
アクセスカウンター
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

08月 | 2016年09月 | 10月
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。